From ee3c69dee9c491b131a4369c2e1d8582e59a0b23 Mon Sep 17 00:00:00 2001 From: Cyril Diagne Date: Sun, 16 Feb 2020 19:36:04 +0100 Subject: [PATCH] allow deploying from release manifest --- README.md | 8 ++++-- cmd/cli/deploy.go | 20 ++++++++++++++- pkg/deploy/deploy.go | 60 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4afa2b3..a4c634a 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,19 @@ - Deploy a template ```bash -$ kuda deploy -f https://raw.githubusercontent.com/cyrildiagne/kuda/releases/v0.4.0/example-hello-gpu-flask.yaml +$ kuda deploy -f https://raw.githubusercontent.com/cyrildiagne/kuda/0.4/examples/hello-gpu-flask/kuda.yaml ``` - Call it! ```bash -$ curl -H 'x-api-key: $your_key' https://nvidiasmi.default.$your_domain +$ curl https://hello-gpu.default.$your_domain ``` + + ``` Hello GPU! diff --git a/cmd/cli/deploy.go b/cmd/cli/deploy.go index 7b34f94..800b3a3 100644 --- a/cmd/cli/deploy.go +++ b/cmd/cli/deploy.go @@ -44,7 +44,25 @@ func deployFromPublished(published string) error { fmt.Println("Deploying from published API image", published) params := url.Values{} - params.Set("from", published) + + if strings.HasPrefix(published, "http") { + // Download the file + resp, err := http.Get(published) + if err != nil { + return fmt.Errorf("error downloading %s: %w", published, err) + } + defer resp.Body.Close() + + // Attach the file to the POST + contents, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("error reading %s: %w", published, err) + } + params.Set("from-release", string(contents)) + } else { + params.Set("from", published) + } + body := strings.NewReader(params.Encode()) url := cfg.Provider.APIURL + "/deploy" diff --git a/pkg/deploy/deploy.go b/pkg/deploy/deploy.go index db03022..c8d99a2 100644 --- a/pkg/deploy/deploy.go +++ b/pkg/deploy/deploy.go @@ -6,12 +6,58 @@ import ( "net/http" "os" "path/filepath" + "strings" "github.com/cyrildiagne/kuda/pkg/api" "github.com/cyrildiagne/kuda/pkg/config" "github.com/cyrildiagne/kuda/pkg/utils" + + "github.com/cyrildiagne/kuda/pkg/manifest/latest" ) +func deployFromReleaseManifest(manifest *latest.Manifest, env *api.Env, w http.ResponseWriter, r *http.Request) error { + // Retrieve namespace. + namespace, err := api.GetAuthorizedNamespace(env, r) + if err != nil { + return err + } + + // Generate Knative YAML with appropriate namespace. + service := config.ServiceSummary{ + Name: manifest.Name, + Namespace: namespace, + DockerArtifact: manifest.Release, + } + knativeCfg, err := config.GenerateKnativeConfig(service, manifest.Deploy) + if err != nil { + return err + } + knativeYAML, err := config.MarshalKnativeConfig(knativeCfg) + if err != nil { + return err + } + // Create new temp directory. + tempDir, err := ioutil.TempDir("", namespace+"__"+manifest.Name) + if err != nil { + return err + } + defer os.RemoveAll(tempDir) + knativeFile := filepath.FromSlash(tempDir + "/knative.yaml") + if err := utils.WriteYAML(knativeYAML, knativeFile); err != nil { + return err + } + + // Run kubectl apply. + args := []string{"apply", "-f", knativeFile} + if err := RunCMD(w, "kubectl", args); err != nil { + return err + } + + // TODO: Add to the namespaces' deployments. + + return nil +} + func deployFromPublished(fromPublished string, env *api.Env, w http.ResponseWriter, r *http.Request) error { // Retrieve namespace. namespace, err := api.GetAuthorizedNamespace(env, r) @@ -129,10 +175,22 @@ func HandleDeploy(env *api.Env, w http.ResponseWriter, r *http.Request) error { fmt.Println("handle deploy") - // Check if deploying from published + // Check if deploying from published. from := r.FormValue("from") if from != "" { return deployFromPublished(from, env, w, r) } + + // Otherwise check if deploying from a release manifest. + release := r.FormValue("from-release") + if release != "" { + manifest := latest.Manifest{} + if err := manifest.Load(strings.NewReader(release)); err != nil { + return err + } + return deployFromReleaseManifest(&manifest, env, w, r) + } + + // Otherwise try to deploy from the files attached. return deployFromFiles(env, w, r) }