From d3f0ac934349d19af364297dfdf62608d1e9b8d7 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 15 Apr 2019 11:17:19 -0700 Subject: [PATCH] ref(create): app version should be 0.1.0 When creating a Helm chart for the first time, the assumption should be that the app version is also 0.1.0, implying this is for a new application. Signed-off-by: Matthew Fisher --- cmd/helm/create.go | 4 +- cmd/helm/create_test.go | 6 +- cmd/helm/dependency_update_test.go | 26 +++++---- .../output/upgrade-with-install-timeout.txt | 5 -- .../testdata/output/upgrade-with-install.txt | 5 -- .../output/upgrade-with-reset-values.txt | 5 -- .../output/upgrade-with-reset-values2.txt | 5 -- .../testdata/output/upgrade-with-timeout.txt | 5 -- .../testdata/output/upgrade-with-wait.txt | 5 -- cmd/helm/testdata/output/upgrade.txt | 5 -- cmd/helm/upgrade_test.go | 35 +++++------- pkg/chartutil/create.go | 55 +++++++++++++------ pkg/chartutil/create_test.go | 8 +-- pkg/chartutil/save.go | 5 +- 14 files changed, 73 insertions(+), 101 deletions(-) diff --git a/cmd/helm/create.go b/cmd/helm/create.go index 6ab8dee24..4c26e4ca8 100644 --- a/cmd/helm/create.go +++ b/cmd/helm/create.go @@ -80,7 +80,7 @@ func (o *createOptions) run(out io.Writer) error { Description: "A Helm chart for Kubernetes", Type: "application", Version: "0.1.0", - AppVersion: "1.0", + AppVersion: "0.1.0", APIVersion: chart.APIVersionV1, } @@ -90,6 +90,6 @@ func (o *createOptions) run(out io.Writer) error { return chartutil.CreateFrom(cfile, filepath.Dir(o.name), lstarter) } - _, err := chartutil.Create(cfile, filepath.Dir(o.name)) + _, err := chartutil.Create(chartname, filepath.Dir(o.name)) return err } diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index 6ce88dbb7..bf36be68e 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -73,11 +73,7 @@ func TestCreateStarterCmd(t *testing.T) { // Create a starter. starterchart := hh.Starters() os.Mkdir(starterchart, 0755) - if dest, err := chartutil.Create(&chart.Metadata{ - APIVersion: chart.APIVersionV1, - Name: "starterchart", - Version: "0.1.0", - }, starterchart); err != nil { + if dest, err := chartutil.Create("starterchart", starterchart); err != nil { t.Fatalf("Could not create chart: %s", err) } else { t.Logf("Created %s", dest) diff --git a/cmd/helm/dependency_update_test.go b/cmd/helm/dependency_update_test.go index f724cbf68..bbe108973 100644 --- a/cmd/helm/dependency_update_test.go +++ b/cmd/helm/dependency_update_test.go @@ -46,8 +46,9 @@ func TestDependencyUpdateCmd(t *testing.T) { t.Logf("Listening on directory %s", srv.Root()) chartname := "depup" - md := createTestingMetadata(chartname, srv.URL()) - if _, err := chartutil.Create(md, hh.String()); err != nil { + ch := createTestingMetadata(chartname, srv.URL()) + md := ch.Metadata + if err := chartutil.SaveDir(ch, hh.String()); err != nil { t.Fatal(err) } @@ -203,14 +204,16 @@ func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) { // createTestingMetadata creates a basic chart that depends on reqtest-0.1.0 // // The baseURL can be used to point to a particular repository server. -func createTestingMetadata(name, baseURL string) *chart.Metadata { - return &chart.Metadata{ - APIVersion: chart.APIVersionV1, - Name: name, - Version: "1.2.3", - Dependencies: []*chart.Dependency{ - {Name: "reqtest", Version: "0.1.0", Repository: baseURL}, - {Name: "compressedchart", Version: "0.1.0", Repository: baseURL}, +func createTestingMetadata(name, baseURL string) *chart.Chart { + return &chart.Chart{ + Metadata: &chart.Metadata{ + APIVersion: chart.APIVersionV1, + Name: name, + Version: "1.2.3", + Dependencies: []*chart.Dependency{ + {Name: "reqtest", Version: "0.1.0", Repository: baseURL}, + {Name: "compressedchart", Version: "0.1.0", Repository: baseURL}, + }, }, } } @@ -220,6 +223,5 @@ func createTestingMetadata(name, baseURL string) *chart.Metadata { // The baseURL can be used to point to a particular repository server. func createTestingChart(dest, name, baseURL string) error { cfile := createTestingMetadata(name, baseURL) - _, err := chartutil.Create(cfile, dest) - return err + return chartutil.SaveDir(cfile, dest) } diff --git a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt index fb64f1f86..753979405 100644 --- a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt +++ b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt @@ -4,8 +4,3 @@ LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default STATUS: deployed -NOTES: -1. Get the application URL by running these commands: - export POD_NAME=$(kubectl get pods -l "app=testUpgradeChart,release=crazy-bunny" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:80 diff --git a/cmd/helm/testdata/output/upgrade-with-install.txt b/cmd/helm/testdata/output/upgrade-with-install.txt index 8aba923a8..d08b923e8 100644 --- a/cmd/helm/testdata/output/upgrade-with-install.txt +++ b/cmd/helm/testdata/output/upgrade-with-install.txt @@ -4,8 +4,3 @@ LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default STATUS: deployed -NOTES: -1. Get the application URL by running these commands: - export POD_NAME=$(kubectl get pods -l "app=testUpgradeChart,release=zany-bunny" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:80 diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values.txt b/cmd/helm/testdata/output/upgrade-with-reset-values.txt index 4b0f9c309..1cfe36a34 100644 --- a/cmd/helm/testdata/output/upgrade-with-reset-values.txt +++ b/cmd/helm/testdata/output/upgrade-with-reset-values.txt @@ -4,8 +4,3 @@ LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default STATUS: deployed -NOTES: -1. Get the application URL by running these commands: - export POD_NAME=$(kubectl get pods -l "app=testUpgradeChart,release=funny-bunny" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:80 diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt index 4b0f9c309..1cfe36a34 100644 --- a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt +++ b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt @@ -4,8 +4,3 @@ LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default STATUS: deployed -NOTES: -1. Get the application URL by running these commands: - export POD_NAME=$(kubectl get pods -l "app=testUpgradeChart,release=funny-bunny" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:80 diff --git a/cmd/helm/testdata/output/upgrade-with-timeout.txt b/cmd/helm/testdata/output/upgrade-with-timeout.txt index 4b0f9c309..1cfe36a34 100644 --- a/cmd/helm/testdata/output/upgrade-with-timeout.txt +++ b/cmd/helm/testdata/output/upgrade-with-timeout.txt @@ -4,8 +4,3 @@ LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default STATUS: deployed -NOTES: -1. Get the application URL by running these commands: - export POD_NAME=$(kubectl get pods -l "app=testUpgradeChart,release=funny-bunny" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:80 diff --git a/cmd/helm/testdata/output/upgrade-with-wait.txt b/cmd/helm/testdata/output/upgrade-with-wait.txt index fb64f1f86..753979405 100644 --- a/cmd/helm/testdata/output/upgrade-with-wait.txt +++ b/cmd/helm/testdata/output/upgrade-with-wait.txt @@ -4,8 +4,3 @@ LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default STATUS: deployed -NOTES: -1. Get the application URL by running these commands: - export POD_NAME=$(kubectl get pods -l "app=testUpgradeChart,release=crazy-bunny" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:80 diff --git a/cmd/helm/testdata/output/upgrade.txt b/cmd/helm/testdata/output/upgrade.txt index 4b0f9c309..1cfe36a34 100644 --- a/cmd/helm/testdata/output/upgrade.txt +++ b/cmd/helm/testdata/output/upgrade.txt @@ -4,8 +4,3 @@ LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default STATUS: deployed -NOTES: -1. Get the application URL by running these commands: - export POD_NAME=$(kubectl get pods -l "app=testUpgradeChart,release=funny-bunny" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:80 diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go index e8b31431e..d8f9d5bf0 100644 --- a/cmd/helm/upgrade_test.go +++ b/cmd/helm/upgrade_test.go @@ -18,6 +18,7 @@ package main import ( "fmt" + "path/filepath" "testing" "helm.sh/helm/pkg/chart" @@ -28,14 +29,16 @@ import ( func TestUpgradeCmd(t *testing.T) { tmpChart := testTempDir(t) - cfile := &chart.Metadata{ - APIVersion: chart.APIVersionV1, - Name: "testUpgradeChart", - Description: "A Helm chart for Kubernetes", - Version: "0.1.0", + cfile := &chart.Chart{ + Metadata: &chart.Metadata{ + APIVersion: chart.APIVersionV1, + Name: "testUpgradeChart", + Description: "A Helm chart for Kubernetes", + Version: "0.1.0", + }, } - chartPath, err := chartutil.Create(cfile, tmpChart) - if err != nil { + chartPath := filepath.Join(tmpChart, cfile.Metadata.Name) + if err := chartutil.SaveDir(cfile, tmpChart); err != nil { t.Fatalf("Error creating chart for upgrade: %v", err) } ch, err := loader.Load(chartPath) @@ -48,14 +51,9 @@ func TestUpgradeCmd(t *testing.T) { }) // update chart version - cfile = &chart.Metadata{ - Name: "testUpgradeChart", - Description: "A Helm chart for Kubernetes", - Version: "0.1.2", - } + cfile.Metadata.Version = "0.1.2" - chartPath, err = chartutil.Create(cfile, tmpChart) - if err != nil { + if err := chartutil.SaveDir(cfile, tmpChart); err != nil { t.Fatalf("Error creating chart: %v", err) } ch, err = loader.Load(chartPath) @@ -64,14 +62,9 @@ func TestUpgradeCmd(t *testing.T) { } // update chart version again - cfile = &chart.Metadata{ - Name: "testUpgradeChart", - Description: "A Helm chart for Kubernetes", - Version: "0.1.3", - } + cfile.Metadata.Version = "0.1.3" - chartPath, err = chartutil.Create(cfile, tmpChart) - if err != nil { + if err := chartutil.SaveDir(cfile, tmpChart); err != nil { t.Fatalf("Error creating chart: %v", err) } var ch2 *chart.Chart diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index dde89a752..e9e5e12e1 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -53,6 +53,29 @@ const ( HelpersName = "_helpers.tpl" ) +const defaultChartfile = `apiVersion: v1 +name: %s +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +appVersion: 0.1.0 +` + const defaultValues = `# Default values for %s. # This is a YAML-formatted file. # Declare variables to be passed into your templates. @@ -61,7 +84,6 @@ replicaCount: 1 image: repository: nginx - tag: stable pullPolicy: IfNotPresent nameOverride: "" @@ -189,7 +211,7 @@ spec: spec: containers: - name: {{ .Chart.Name }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + image: "{{ .Values.image.repository }}:{{ .Release.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http @@ -339,7 +361,7 @@ func CreateFrom(chartfile *chart.Metadata, dest, src string) error { // If Chart.yaml or any directories cannot be created, this will return an // error. In such a case, this will attempt to clean up by removing the // new chart directory. -func Create(chartfile *chart.Metadata, dir string) (string, error) { +func Create(name, dir string) (string, error) { path, err := filepath.Abs(dir) if err != nil { return path, err @@ -351,8 +373,7 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { return path, errors.Errorf("no such directory %s", path) } - n := chartfile.Name - cdir := filepath.Join(path, n) + cdir := filepath.Join(path, name) if fi, err := os.Stat(cdir); err == nil && !fi.IsDir() { return cdir, errors.Errorf("file %s already exists and is not a directory", cdir) } @@ -360,13 +381,6 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { return cdir, err } - cf := filepath.Join(cdir, ChartfileName) - if _, err := os.Stat(cf); err != nil { - if err := SaveChartfile(cf, chartfile); err != nil { - return cdir, err - } - } - for _, d := range []string{TemplatesDir, ChartsDir} { if err := os.MkdirAll(filepath.Join(cdir, d), 0755); err != nil { return cdir, err @@ -377,10 +391,15 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { path string content []byte }{ + { + // Chart.yaml + path: filepath.Join(cdir, ChartfileName), + content: []byte(fmt.Sprintf(defaultChartfile, name)), + }, { // values.yaml path: filepath.Join(cdir, ValuesfileName), - content: []byte(fmt.Sprintf(defaultValues, chartfile.Name)), + content: []byte(fmt.Sprintf(defaultValues, name)), }, { // .helmignore @@ -390,27 +409,27 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { { // ingress.yaml path: filepath.Join(cdir, TemplatesDir, IngressFileName), - content: transform(defaultIngress, chartfile.Name), + content: transform(defaultIngress, name), }, { // deployment.yaml path: filepath.Join(cdir, TemplatesDir, DeploymentName), - content: transform(defaultDeployment, chartfile.Name), + content: transform(defaultDeployment, name), }, { // service.yaml path: filepath.Join(cdir, TemplatesDir, ServiceName), - content: transform(defaultService, chartfile.Name), + content: transform(defaultService, name), }, { // NOTES.txt path: filepath.Join(cdir, TemplatesDir, NotesName), - content: transform(defaultNotes, chartfile.Name), + content: transform(defaultNotes, name), }, { // _helpers.tpl path: filepath.Join(cdir, TemplatesDir, HelpersName), - content: transform(defaultHelpers, chartfile.Name), + content: transform(defaultHelpers, name), }, } diff --git a/pkg/chartutil/create_test.go b/pkg/chartutil/create_test.go index 162168690..256360327 100644 --- a/pkg/chartutil/create_test.go +++ b/pkg/chartutil/create_test.go @@ -34,13 +34,7 @@ func TestCreate(t *testing.T) { } defer os.RemoveAll(tdir) - cf := &chart.Metadata{ - APIVersion: chart.APIVersionV1, - Name: "foo", - Version: "0.1.0", - } - - c, err := Create(cf, tdir) + c, err := Create("foo", tdir) if err != nil { t.Fatal(err) } diff --git a/pkg/chartutil/save.go b/pkg/chartutil/save.go index 1c9d9e5e5..bde902c98 100644 --- a/pkg/chartutil/save.go +++ b/pkg/chartutil/save.go @@ -36,7 +36,10 @@ var headerBytes = []byte("+aHR0cHM6Ly95b3V0dS5iZS96OVV6MWljandyTQo=") func SaveDir(c *chart.Chart, dest string) error { // Create the chart directory outdir := filepath.Join(dest, c.Name()) - if err := os.Mkdir(outdir, 0755); err != nil { + if fi, err := os.Stat(outdir); err == nil && !fi.IsDir() { + return errors.Errorf("file %s already exists and is not a directory", outdir) + } + if err := os.MkdirAll(outdir, 0755); err != nil { return err }