Skip to content

Commit

Permalink
Merge pull request #69 from justinmerrell/toml-path-name
Browse files Browse the repository at this point in the history
fix: windows compatibility and toml fix
  • Loading branch information
DireLines authored Jan 25, 2024
2 parents 42b3c5c + 004a306 commit 1b10de5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 40 deletions.
12 changes: 9 additions & 3 deletions cmd/project/example.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
# RunPod Project Configuration

title = "placeholder"
name = "placeholder"

[project]
uuid = "placeholder"
name = "placeholder"
base_image = "runpod/base:0.4.4-cuda11.8.0"
gpu_types = ["NVIDIA RTX A4000", "NVIDIA RTX A4500", "NVIDIA RTX A5000", "NVIDIA GeForce RTX 3090", "NVIDIA RTX A6000"]
gpu_types = [
"NVIDIA RTX A4000",
"NVIDIA RTX A4500",
"NVIDIA RTX A5000",
"NVIDIA GeForce RTX 3090",
"NVIDIA RTX A6000",
]
gpu_count = 1
volume_mount_path = "/runpod-volume"
ports = "8080/http, 22/tcp, 4040/http"
Expand All @@ -24,4 +30,4 @@ model_name = "None"
[runtime]
python_version = "3.10"
handler_path = "src/handler.py"
requirements_path = "builder/requirements.txt"
requirements_path = "builder/requirements.txt"
60 changes: 31 additions & 29 deletions cmd/project/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io/fs"
"os"
"path"
"path/filepath"
"strings"
"time"
Expand Down Expand Up @@ -66,13 +67,13 @@ func createNewProject(projectName string, cudaVersion string,
if modelType == "" {
modelType = "default"
}
templatePath := filepath.Join(basePath, modelType)
templatePath := fmt.Sprintf("%s/%s", basePath, modelType)
//load selected starter template
err = copyFiles(starterTemplates, templatePath, projectFolder)
if err != nil {
panic(err)
}
requirementsPath := filepath.Join(projectFolder, "builder", "requirements.txt")
requirementsPath := fmt.Sprintf("%s/builder/requirements.txt", projectFolder)
requirementsContentBytes, _ := os.ReadFile(requirementsPath)
requirementsContent := string(requirementsContentBytes)
//in requirements, replace <<RUNPOD>> with runpod-python import
Expand All @@ -85,12 +86,11 @@ func createNewProject(projectName string, cudaVersion string,
projectToml, _ := toml.LoadBytes(tomlBytes)
projectUuid := uuid.New().String()[0:8]
projectToml.SetComment("RunPod Project Configuration") //TODO why does this not appear
projectToml.SetPath([]string{"title"}, projectName)
projectToml.SetPath([]string{"project", "name"}, projectName)
projectToml.SetPath([]string{"name"}, projectName)
projectToml.SetPath([]string{"project", "uuid"}, projectUuid)
projectToml.SetPath([]string{"project", "base_image"}, baseDockerImage(cudaVersion))
projectToml.SetPath([]string{"template", "model_type"}, modelType)
projectToml.SetPath([]string{"template", "model_name"}, modelName)
// projectToml.SetPath([]string{"template", "model_type"}, modelType)
// projectToml.SetPath([]string{"template", "model_name"}, modelName)
projectToml.SetPath([]string{"runtime", "python_version"}, pythonVersion)
tomlPath := filepath.Join(projectFolder, "runpod.toml")
os.WriteFile(tomlPath, []byte(projectToml.String()), 0644)
Expand Down Expand Up @@ -150,7 +150,7 @@ func attemptPodLaunch(config *toml.Tree, networkVolumeId string, environmentVari
ImageName: projectConfig.Get("base_image").(string),
MinMemoryInGb: 1,
MinVcpuCount: 1,
Name: fmt.Sprintf("%s-dev (%s)", projectConfig.Get("name"), projectConfig.Get("uuid")),
Name: fmt.Sprintf("%s-dev (%s)", config.Get("name"), projectConfig.Get("uuid")),
NetworkVolumeId: networkVolumeId,
Ports: strings.ReplaceAll(projectConfig.Get("ports").(string), " ", ""),
SupportPublicIp: true,
Expand Down Expand Up @@ -208,13 +208,15 @@ func createEnvVars(config *toml.Tree) map[string]string {
environmentVariables["RUNPOD_PROJECT_ID"] = config.GetPath([]string{"project", "uuid"}).(string)
return environmentVariables
}

func mapToApiEnv(env map[string]string) []*api.PodEnv {
podEnv := []*api.PodEnv{}
for k, v := range env {
podEnv = append(podEnv, &api.PodEnv{Key: k, Value: v})
}
return podEnv
}

func formatAsDockerEnv(env map[string]string) string {
result := ""
for k, v := range env {
Expand All @@ -228,7 +230,7 @@ func startProject(networkVolumeId string) error {
config := loadProjectConfig()
fmt.Println(config)
projectId := config.GetPath([]string{"project", "uuid"}).(string)
projectName := config.GetPath([]string{"project", "name"}).(string)
projectName := config.GetPath([]string{"name"}).(string)
//check for existing pod
projectPodId, err := getProjectPod(projectId)
if projectPodId == "" || err != nil {
Expand All @@ -248,23 +250,23 @@ func startProject(networkVolumeId string) error {
//create remote folder structure
projectConfig := config.Get("project").(*toml.Tree)
volumePath := projectConfig.Get("volume_mount_path").(string)
projectPathUuid := filepath.Join(volumePath, projectConfig.Get("uuid").(string))
projectPathUuidDev := filepath.Join(projectPathUuid, "dev")
projectPathUuidProd := filepath.Join(projectPathUuid, "prod")
remoteProjectPath := filepath.Join(projectPathUuidDev, projectConfig.Get("name").(string))
projectPathUuid := path.Join(volumePath, projectConfig.Get("uuid").(string))
projectPathUuidDev := path.Join(projectPathUuid, "dev")
projectPathUuidProd := path.Join(projectPathUuid, "prod")
remoteProjectPath := path.Join(projectPathUuidDev, projectName)
fmt.Printf("Checking pod project folder: %s on pod %s\n", remoteProjectPath, projectPodId)
sshConn.RunCommands([]string{fmt.Sprintf("mkdir -p %s %s", remoteProjectPath, projectPathUuidProd)})
//rsync project files
fmt.Printf("Syncing files to pod %s\n", projectPodId)
cwd, _ := os.Getwd()
sshConn.Rsync(cwd, projectPathUuidDev, false)
//activate venv on remote
venvPath := "/" + filepath.Join(projectId, "venv")
archivedVenvPath := filepath.Join(projectPathUuid, "dev-venv.tar.zst")
venvPath := "/" + path.Join(projectId, "venv")
archivedVenvPath := path.Join(projectPathUuid, "dev-venv.tar.zst")
fmt.Printf("Activating Python virtual environment %s on pod %s\n", venvPath, projectPodId)
sshConn.RunCommands([]string{
fmt.Sprintf(`
if ! [ -f %s/bin/activate ]
if ! [ -f %s/bin/activate ]
then
if [ -f %s ]
then
Expand All @@ -275,17 +277,17 @@ func startProject(networkVolumeId string) error {
python%s -m virtualenv %s
fi
fi`, venvPath, archivedVenvPath, venvPath, archivedVenvPath, venvPath, config.GetPath([]string{"runtime", "python_version"}).(string), venvPath),
fmt.Sprintf(`source %s/bin/activate &&
cd %s &&
python -m pip install --upgrade pip &&
fmt.Sprintf(`source %s/bin/activate &&
cd %s &&
python -m pip install --upgrade pip &&
python -m pip install -v --requirement %s --report /installreport.json`,
venvPath, remoteProjectPath, config.GetPath([]string{"runtime", "requirements_path"}).(string)),
})
//create file watcher
go sshConn.SyncDir(cwd, projectPathUuidDev)
//run launch api server / hot reload loop
pipReqPath := filepath.Join(remoteProjectPath, config.GetPath([]string{"runtime", "requirements_path"}).(string))
handlerPath := filepath.Join(remoteProjectPath, config.GetPath([]string{"runtime", "handler_path"}).(string))
pipReqPath := path.Join(remoteProjectPath, config.GetPath([]string{"runtime", "requirements_path"}).(string))
handlerPath := path.Join(remoteProjectPath, config.GetPath([]string{"runtime", "handler_path"}).(string))
launchApiServer := fmt.Sprintf(`
pkill inotify
Expand Down Expand Up @@ -392,10 +394,10 @@ func deployProject(networkVolumeId string) (endpointId string, err error) {
config := loadProjectConfig()
projectId := config.GetPath([]string{"project", "uuid"}).(string)
projectConfig := config.Get("project").(*toml.Tree)
projectName := projectConfig.Get("name").(string)
projectPathUuid := filepath.Join(projectConfig.Get("volume_mount_path").(string), projectConfig.Get("uuid").(string))
projectPathUuidProd := filepath.Join(projectPathUuid, "prod")
remoteProjectPath := filepath.Join(projectPathUuidProd, projectConfig.Get("name").(string))
projectName := config.Get("name").(string)
projectPathUuid := path.Join(projectConfig.Get("volume_mount_path").(string), projectConfig.Get("uuid").(string))
projectPathUuidProd := path.Join(projectPathUuid, "prod")
remoteProjectPath := path.Join(projectPathUuidProd, projectConfig.Get("name").(string))
//check for existing pod
projectPodId, err := getProjectPod(projectId)
if projectPodId == "" || err != nil {
Expand All @@ -417,19 +419,19 @@ func deployProject(networkVolumeId string) (endpointId string, err error) {
cwd, _ := os.Getwd()
sshConn.Rsync(cwd, projectPathUuidProd, false)
//activate venv on remote
venvPath := filepath.Join(projectPathUuidProd, "venv")
venvPath := path.Join(projectPathUuidProd, "venv")
fmt.Printf("Activating Python virtual environment: %s on pod %s\n", venvPath, projectPodId)
sshConn.RunCommands([]string{
fmt.Sprintf("python%s -m venv %s", config.GetPath([]string{"runtime", "python_version"}).(string), venvPath),
fmt.Sprintf(`source %s/bin/activate &&
cd %s &&
python -m pip install --upgrade pip &&
fmt.Sprintf(`source %s/bin/activate &&
cd %s &&
python -m pip install --upgrade pip &&
python -m pip install -v --requirement %s`,
venvPath, remoteProjectPath, config.GetPath([]string{"runtime", "requirements_path"}).(string)),
})
env := mapToApiEnv(createEnvVars(config))
// Construct the docker start command
handlerPath := filepath.Join(remoteProjectPath, config.GetPath([]string{"runtime", "handler_path"}).(string))
handlerPath := path.Join(remoteProjectPath, config.GetPath([]string{"runtime", "handler_path"}).(string))
activateCmd := fmt.Sprintf(". %s/bin/activate", venvPath)
pythonCmd := fmt.Sprintf("python -u %s", handlerPath)
dockerStartCmd := "bash -c \"" + activateCmd + " && " + pythonCmd + "\""
Expand Down
17 changes: 9 additions & 8 deletions cmd/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,16 @@ Project Summary:
pythonVersion, modelType, modelName, initCurrentDir)
fmt.Printf("Project %s created successfully!", projectName)
fmt.Println()
fmt.Println("From your project root run `runpodctl project start` to start a development pod.")
fmt.Println("From your project root run `runpod project dev` to start a development pod.")
},
}

var StartProjectCmd = &cobra.Command{
Use: "start",
Args: cobra.ExactArgs(0),
Short: "start current project",
Long: "start a development pod session for the Runpod project in the current folder",
Use: "dev",
Aliases: []string{"start"},
Args: cobra.ExactArgs(0),
Short: "start current project",
Long: "start a development pod session for the Runpod project in the current folder",
Run: func(cmd *cobra.Command, args []string) {
config := loadProjectConfig()
projectId := config.GetPath([]string{"project", "uuid"}).(string)
Expand Down Expand Up @@ -233,7 +234,7 @@ var BuildProjectCmd = &cobra.Command{
// config := loadProjectConfig()
// projectConfig := config.Get("project").(*toml.Tree)
// projectId := projectConfig.Get("uuid").(string)
// projectName := projectConfig.Get("name").(string)
// projectName := config.Get("name").(string)
// //print next steps
// fmt.Println("Next steps:")
// fmt.Println()
Expand All @@ -253,8 +254,8 @@ var BuildProjectCmd = &cobra.Command{

func init() {
NewProjectCmd.Flags().StringVarP(&projectName, "name", "n", "", "project name")
NewProjectCmd.Flags().StringVarP(&modelName, "model", "m", "", "model name")
NewProjectCmd.Flags().StringVarP(&modelType, "type", "t", "", "model type")
// NewProjectCmd.Flags().StringVarP(&modelName, "model", "m", "", "model name")
// NewProjectCmd.Flags().StringVarP(&modelType, "type", "t", "", "model type")
NewProjectCmd.Flags().BoolVarP(&initCurrentDir, "init", "i", false, "use the current directory as the project directory")

StartProjectCmd.Flags().BoolVar(&setDefaultNetworkVolume, "select-volume", false, "select a new default network volume for current project")
Expand Down
2 changes: 2 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

dev:
env GOOS=darwin GOARCH=arm64 go build -ldflags "-X 'main.Version=1.0.0'" -o bin/runpodctl .
windows:
env GOOS=windows GOARCH=amd64 go build -ldflags "-X 'main.Version=1.0.0'" -o bin/runpodctl.exe .
lint:
golangci-lint run

0 comments on commit 1b10de5

Please sign in to comment.