diff --git a/cmd/install_test.go b/cmd/install_test.go index a023b60..5438fc0 100644 --- a/cmd/install_test.go +++ b/cmd/install_test.go @@ -1,11 +1,14 @@ package cmd import ( + "io/ioutil" "os" + "path" "testing" "github.com/microsoft/fabrikate/util" "github.com/stretchr/testify/assert" + "github.com/timfpark/yaml" ) func TestInstallJSON(t *testing.T) { @@ -87,4 +90,17 @@ func TestInstallHelmMethod(t *testing.T) { // Change cwd to component directory assert.Nil(t, os.Chdir(componentDir)) assert.Nil(t, Install("./")) + + // Grafana chart should be version 3.7.0 + grafanaChartYaml := path.Join("helm_repos", "grafana", "Chart.yaml") + grafanaChartBytes, err := ioutil.ReadFile(grafanaChartYaml) + assert.Nil(t, err) + type helmChart struct { + Version string + Name string + } + grafanaChart := helmChart{} + assert.Nil(t, yaml.Unmarshal(grafanaChartBytes, &grafanaChart)) + assert.EqualValues(t, "grafana", grafanaChart.Name) + assert.EqualValues(t, "3.7.0", grafanaChart.Version) } diff --git a/docs/component.md b/docs/component.md index eb60ea8..767df4f 100644 --- a/docs/component.md +++ b/docs/component.md @@ -54,7 +54,8 @@ component with the following schema: component to a consistent version. - if `method: git`: a specific commit to checkout from the repository. - - if `method: helm`: noop + - if `method: helm`: defines the version of the helm chart to fetch. Value + provided will be piped into `helm fetch --version ...` - if `method: local`: noop - `branch`: For git `method` components, this specifies the branch that should diff --git a/generators/helm.go b/generators/helm.go index 81512c1..ffc5029 100644 --- a/generators/helm.go +++ b/generators/helm.go @@ -230,7 +230,7 @@ func (hg *HelmGenerator) Install(c *core.Component) (err error) { switch c.Method { case "helm": log.Info(emoji.Sprintf(":helicopter: Component '%s' requesting helm chart '%s' from helm repository '%s'", c.Name, c.Path, c.Source)) - if err = hd.downloadChart(c.Source, c.Path, helmRepoPath); err != nil { + if err = hd.downloadChart(c.Source, c.Path, c.Version, helmRepoPath); err != nil { return err } case "git": @@ -265,12 +265,13 @@ type helmDownloader struct { var hd = helmDownloader{} -// downloadChart downloads a target `chart` from `repo` and places it in `into` +// downloadChart downloads a target `chart` at version `version` from `repo` and +// places it in `into`. If `version` is blank, latest is automatically fetched. // -- `into` will be the dir containing Chart.yaml // The function will add a temporary helm repo, fetch from it, and then remove // the temporary repo. This is a to get around a limitation in Helm 2. // see: https://github.com/helm/helm/issues/4527 -func (hd *helmDownloader) downloadChart(repo, chart, into string) (err error) { +func (hd *helmDownloader) downloadChart(repo, chart, version, into string) (err error) { // generate random name to store repo in helm in temporarily randomUUID, err := uuid.NewRandom() if err != nil { @@ -289,8 +290,18 @@ func (hd *helmDownloader) downloadChart(repo, chart, into string) (err error) { // Fetch chart to random temp dir chartName := fmt.Sprintf("%s/%s", randomName, chart) randomDir := path.Join(os.TempDir(), randomName) - log.Info(emoji.Sprintf(":helicopter: Fetching helm chart '%s' into '%s'", chart, randomDir)) - if output, err := exec.Command("helm", "fetch", "--untar", "--untardir", randomDir, chartName).CombinedOutput(); err != nil { + downloadVersion := "latest" + if version != "" { + downloadVersion = version + } + log.Info(emoji.Sprintf(":helicopter: Fetching helm chart '%s' version '%s' into '%s'", chart, downloadVersion, randomDir)) + helmFetchCommandArgs := []string{"fetch", "--untar", "--untardir", randomDir} + // Append version if provided + if version != "" { + helmFetchCommandArgs = append(helmFetchCommandArgs, "--version", version) + } + helmFetchCommandArgs = append(helmFetchCommandArgs, chartName) + if output, err := exec.Command("helm", helmFetchCommandArgs...).CombinedOutput(); err != nil { log.Error(emoji.Sprintf(":no_entry_sign: Failed fetching helm chart '%s' from repo '%s'\n%s: %s", chart, repo, err, output)) return err } diff --git a/go.mod b/go.mod index d9282f6..54cb236 100644 --- a/go.mod +++ b/go.mod @@ -5,14 +5,14 @@ go 1.12 require ( github.com/google/uuid v1.1.1 github.com/kyokomi/emoji v2.1.0+incompatible - github.com/onsi/ginkgo v1.8.0 // indirect - github.com/onsi/gomega v1.5.0 // indirect + github.com/onsi/ginkgo v1.9.0 // indirect + github.com/onsi/gomega v1.6.0 // indirect github.com/otiai10/copy v1.0.1 github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 // indirect github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v0.0.5 github.com/spf13/viper v1.4.0 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.4.0 github.com/timfpark/conjungo v1.0.1 github.com/timfpark/yaml v0.0.0-20190612232118-2e9e29c9df01 ) diff --git a/go.sum b/go.sum index 9e9eb67..645b9c1 100644 --- a/go.sum +++ b/go.sum @@ -39,7 +39,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -70,23 +69,21 @@ github.com/kyokomi/emoji v2.1.0+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2px github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/ginkgo v1.9.0 h1:SZjF721BByVj8QH636/8S2DnX4n0Re3SteMmw3N+tzc= +github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.6.0 h1:8XTW0fcJZEq9q+Upcyws4JSGua2MFysCL5xkaSgHc+M= +github.com/onsi/gomega v1.6.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/otiai10/copy v1.0.1 h1:gtBjD8aq4nychvRZ2CyJvFWAw0aja+VHazDdruZKGZA= github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 h1:o59bHXu8Ejas8Kq6pjoVJQ9/neN66SM8AKh6wI42BBs= github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= -github.com/otiai10/mint v1.2.3 h1:PsrRBmrxR68kyNu6YlqYHbNlItc5vOkuS6LBEsNttVA= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.2.4 h1:DxYL0itZyPaR5Z9HILdxSoHx+gNs6Yx+neOGS3IVUk0= github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= @@ -126,10 +123,9 @@ github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/timfpark/conjungo v1.0.1 h1:W4v6Bvvz8fLGoZm2vqXUlRs14xwt9UH3H/zOOAQ5FpQ= github.com/timfpark/conjungo v1.0.1/go.mod h1:86oCya4EhpIkCOkNEkmYjCSlI55Ga7SIFlP3D8uHWyg= github.com/timfpark/yaml v0.0.0-20190612232118-2e9e29c9df01 h1:j6cfQEP5CoVnEWdKXq3zS8UjI34t4sMUZn9rgXpBkzE= @@ -174,7 +170,6 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= diff --git a/testdata/install-helm/component.yaml b/testdata/install-helm/component.yaml index 22e0f13..59187d2 100644 --- a/testdata/install-helm/component.yaml +++ b/testdata/install-helm/component.yaml @@ -9,6 +9,7 @@ subcomponents: method: helm source: https://kubernetes-charts.storage.googleapis.com path: grafana + version: 3.7.0 subcomponents: - name: strimzi-kafka-operator type: helm