From 84146a29cde6c66acf2bdde9a64c04940dc9f1df Mon Sep 17 00:00:00 2001
From: Matt Butcher <mbutcher@engineyard.com>
Date: Wed, 24 Feb 2016 17:24:54 -0700
Subject: [PATCH] feat(deploy): upload chart if its local

---
 cmd/helm/deploy.go | 19 ++++++++++++++++++-
 dm/client.go       | 20 ++++++++++++--------
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/cmd/helm/deploy.go b/cmd/helm/deploy.go
index bbb2576b9..196a226f0 100644
--- a/cmd/helm/deploy.go
+++ b/cmd/helm/deploy.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"io/ioutil"
+	"os"
 
 	"github.com/codegangsta/cli"
 	"github.com/kubernetes/deployment-manager/common"
@@ -60,7 +61,17 @@ func deploy(c *cli.Context) error {
 	// file with it.
 	args := c.Args()
 	if len(args) > 0 {
-		cfg.Resources[0].Type = args[0]
+		cname := args[0]
+		if isLocalChart(cname) {
+			// If we get here, we need to first package then upload the chart.
+			loc, err := doUpload(cname, "", c)
+			if err != nil {
+				return err
+			}
+			cfg.Resources[0].Name = loc
+		} else {
+			cfg.Resources[0].Type = cname
+		}
 	}
 
 	// Override the name if one is passed in.
@@ -82,6 +93,12 @@ func deploy(c *cli.Context) error {
 	return client(c).PostDeployment(cfg)
 }
 
+// isLocalChart returns true if the given path can be statted.
+func isLocalChart(path string) bool {
+	_, err := os.Stat(path)
+	return err == nil
+}
+
 // loadConfig loads a file into a common.Configuration.
 func loadConfig(c *common.Configuration, filename string) error {
 	data, err := ioutil.ReadFile(filename)
diff --git a/dm/client.go b/dm/client.go
index e48efb4a0..59ffa7d87 100644
--- a/dm/client.go
+++ b/dm/client.go
@@ -174,18 +174,21 @@ func (c *Client) ListDeployments() ([]string, error) {
 	return l, nil
 }
 
-// UploadChart sends a chart to DM for deploying.
-func (c *Client) PostChart(filename, deployname string) error {
+// PostChart sends a chart to DM for deploying.
+//
+// This returns the location for the new chart, typically of the form
+// `helm:repo/bucket/name-version.tgz`.
+func (c *Client) PostChart(filename, deployname string) (string, error) {
 	f, err := os.Open(filename)
 	if err != nil {
-		return err
+		return "", err
 	}
 
 	u, err := c.url("/v2/charts")
 	request, err := http.NewRequest("POST", u, f)
 	if err != nil {
 		f.Close()
-		return err
+		return "", err
 	}
 
 	// There is an argument to be made for using the legacy x-octet-stream for
@@ -206,7 +209,7 @@ func (c *Client) PostChart(filename, deployname string) error {
 
 	response, err := client.Do(request)
 	if err != nil {
-		return err
+		return "", err
 	}
 
 	// We only want 201 CREATED. Admittedly, we could accept 200 and 202.
@@ -214,12 +217,13 @@ func (c *Client) PostChart(filename, deployname string) error {
 		body, err := ioutil.ReadAll(response.Body)
 		response.Body.Close()
 		if err != nil {
-			return err
+			return "", err
 		}
-		return &HTTPError{StatusCode: response.StatusCode, Message: string(body), URL: request.URL}
+		return "", &HTTPError{StatusCode: response.StatusCode, Message: string(body), URL: request.URL}
 	}
 
-	return nil
+	loc := response.Header.Get("Location")
+	return loc, nil
 }
 
 // HTTPError is an error caused by an unexpected HTTP status code.
-- 
GitLab