Add ability to use go-getter for fetching remote manifests directory as chart (#1374)
This, in combination with #1172, allows you to use `go-getter`-supported URL for K8s manifests on `chart`, so that Helmfile automatically fetches it and then turning it into a temporary local chart, which is then installed by Helmfile as similar as standard Helm charts. An example usecase of this is to install cert-manager CRDs which is distributed separately from the chart: ``` releases: - name: cert-manager-crds chart: git::http://github.com/jetstack/cert-manager.git@deploy/crds?ref=v0.15.2 ``` I'm adding this based on discussion with @lukasmrtvy. He was trying to install cert-manager and prometheus-opreator with Helmfile, and this combined with #1373 should do the job. Thanks for the input!
This commit is contained in:
		
							parent
							
								
									4fde6e13db
								
							
						
					
					
						commit
						b5830a3011
					
				|  | @ -2373,16 +2373,16 @@ func TestTemplate_SingleStateFile(t *testing.T) { | |||
| 		"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: myrelease1 | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
| - name: myrelease2 | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
| `, | ||||
| 	} | ||||
| 
 | ||||
| 	var helm = &mockHelmExec{} | ||||
| 	var wantReleases = []mockTemplates{ | ||||
| 		{name: "myrelease1", chart: "mychart1", flags: []string{"--namespace", "testNamespace", "--set", "foo=a", "--set", "bar=b", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}}, | ||||
| 		{name: "myrelease2", chart: "mychart2", flags: []string{"--namespace", "testNamespace", "--set", "foo=a", "--set", "bar=b", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease2"}}, | ||||
| 		{name: "myrelease1", chart: "stable/mychart1", flags: []string{"--namespace", "testNamespace", "--set", "foo=a", "--set", "bar=b", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}}, | ||||
| 		{name: "myrelease2", chart: "stable/mychart2", flags: []string{"--namespace", "testNamespace", "--set", "foo=a", "--set", "bar=b", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease2"}}, | ||||
| 	} | ||||
| 
 | ||||
| 	var buffer bytes.Buffer | ||||
|  | @ -2407,7 +2407,9 @@ releases: | |||
| 		valsRuntime: valsRuntime, | ||||
| 	}, files) | ||||
| 
 | ||||
| 	app.Template(configImpl{set: []string{"foo=a", "bar=b"}}) | ||||
| 	if err := app.Template(configImpl{set: []string{"foo=a", "bar=b"}}); err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	for i := range wantReleases { | ||||
| 		if wantReleases[i].name != helm.templated[i].name { | ||||
|  | @ -2438,13 +2440,13 @@ apiVersions: | |||
| - helmfile.test/v2 | ||||
| releases: | ||||
| - name: myrelease1 | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
| `, | ||||
| 	} | ||||
| 
 | ||||
| 	var helm = &mockHelmExec{} | ||||
| 	var wantReleases = []mockTemplates{ | ||||
| 		{name: "myrelease1", chart: "mychart1", flags: []string{"--api-versions", "helmfile.test/v1", "--api-versions", "helmfile.test/v2", "--namespace", "testNamespace", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}}, | ||||
| 		{name: "myrelease1", chart: "stable/mychart1", flags: []string{"--api-versions", "helmfile.test/v1", "--api-versions", "helmfile.test/v2", "--namespace", "testNamespace", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}}, | ||||
| 	} | ||||
| 
 | ||||
| 	var buffer bytes.Buffer | ||||
|  | @ -2469,7 +2471,9 @@ releases: | |||
| 		valsRuntime: valsRuntime, | ||||
| 	}, files) | ||||
| 
 | ||||
| 	app.Template(configImpl{}) | ||||
| 	if err := app.Template(configImpl{}); err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	for i := range wantReleases { | ||||
| 		if wantReleases[i].name != helm.templated[i].name { | ||||
|  | @ -2803,16 +2807,16 @@ backend-v1 | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   installed: false | ||||
|   needs: | ||||
|   - bar | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: nil, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: nil, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{ | ||||
| 				exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: ``, | ||||
|  | @ -2833,19 +2837,19 @@ bar 	4       	Fri Nov  1 08:40:07 2019	DEPLOYED	mychart2-3.1.0	3.1.0      	defau | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: baz | ||||
|   chart: mychart3 | ||||
|   chart: stable/mychart3 | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   needs: | ||||
|   - bar | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "baz", Chart: "mychart3", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "baz", Chart: "stable/mychart3", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{}, | ||||
| 			upgraded: []exectest.Release{ | ||||
|  | @ -2862,13 +2866,13 @@ first-pass rendering output of "helmfile.yaml.part.0": | |||
|  0:  | ||||
|  1: releases: | ||||
|  2: - name: baz | ||||
|  3:   chart: mychart3 | ||||
|  3:   chart: stable/mychart3 | ||||
|  4: - name: foo | ||||
|  5:   chart: mychart1 | ||||
|  5:   chart: stable/mychart1 | ||||
|  6:   needs: | ||||
|  7:   - bar | ||||
|  8: - name: bar | ||||
|  9:   chart: mychart2 | ||||
|  9:   chart: stable/mychart2 | ||||
| 10:  | ||||
| 
 | ||||
| first-pass produced: &{default map[] map[]} | ||||
|  | @ -2880,22 +2884,22 @@ second-pass rendering result of "helmfile.yaml.part.0": | |||
|  0:  | ||||
|  1: releases: | ||||
|  2: - name: baz | ||||
|  3:   chart: mychart3 | ||||
|  3:   chart: stable/mychart3 | ||||
|  4: - name: foo | ||||
|  5:   chart: mychart1 | ||||
|  5:   chart: stable/mychart1 | ||||
|  6:   needs: | ||||
|  7:   - bar | ||||
|  8: - name: bar | ||||
|  9:   chart: mychart2 | ||||
|  9:   chart: stable/mychart2 | ||||
| 10:  | ||||
| 
 | ||||
| merged environment: &{default map[] map[]} | ||||
| 3 release(s) found in helmfile.yaml | ||||
| 
 | ||||
| Affected releases are: | ||||
|   bar (mychart2) UPDATED | ||||
|   baz (mychart3) UPDATED | ||||
|   foo (mychart1) UPDATED | ||||
|   bar (stable/mychart2) UPDATED | ||||
|   baz (stable/mychart3) UPDATED | ||||
|   foo (stable/mychart1) UPDATED | ||||
| 
 | ||||
| processing 2 groups of releases in this order: | ||||
| GROUP RELEASES | ||||
|  | @ -2909,10 +2913,10 @@ processing releases in group 2/2: foo | |||
| getting deployed release version failed:unexpected list key: {^foo$ --kube-contextdefault--deployed--failed--pending} | ||||
| 
 | ||||
| UPDATED RELEASES: | ||||
| NAME   CHART      VERSION | ||||
| baz    mychart3           | ||||
| bar    mychart2           | ||||
| foo    mychart1           | ||||
| NAME   CHART             VERSION | ||||
| baz    stable/mychart3           | ||||
| bar    stable/mychart2           | ||||
| foo    stable/mychart1           | ||||
| 
 | ||||
| `, | ||||
| 		}, | ||||
|  | @ -2926,16 +2930,16 @@ foo    mychart1 | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   needs: | ||||
|   - bar | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "bar", Flags: []string{}}, | ||||
|  | @ -2949,16 +2953,16 @@ releases: | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   needs: | ||||
|   - foo | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "foo", Flags: []string{}}, | ||||
|  | @ -2973,16 +2977,16 @@ releases: | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   needs: | ||||
|   - bar | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "bar", Flags: []string{}}, | ||||
|  | @ -2997,16 +3001,16 @@ releases: | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   needs: | ||||
|   - foo | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--namespacetestNamespace--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "foo", Flags: []string{}}, | ||||
|  | @ -3020,18 +3024,18 @@ releases: | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   namespace: ns1 | ||||
|   needs: | ||||
|   - ns2/bar | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   namespace: ns2 | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "bar", Flags: []string{"--kube-context", "default", "--namespace", "ns2"}}, | ||||
|  | @ -3045,18 +3049,18 @@ releases: | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   namespace: ns2 | ||||
|   needs: | ||||
|   - ns1/foo | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   namespace: ns1 | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "foo", Flags: []string{"--kube-context", "default", "--namespace", "ns1"}}, | ||||
|  | @ -3071,20 +3075,20 @@ releases: | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   namespace: ns1 | ||||
|   tillerNamespace: tns1 | ||||
|   needs: | ||||
|   - tns2/ns2/bar | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   namespace: ns2 | ||||
|   tillerNamespace: tns2 | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--tiller-namespacetns2--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--tiller-namespacetns1--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--tiller-namespacetns2--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--tiller-namespacetns1--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "bar", Flags: []string{"--tiller-namespace", "tns2", "--kube-context", "default", "--namespace", "ns2"}}, | ||||
|  | @ -3098,20 +3102,20 @@ releases: | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   namespace: ns2 | ||||
|   tillerNamespace: tns2 | ||||
|   needs: | ||||
|   - tns1/ns1/foo | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   namespace: ns1 | ||||
|   tillerNamespace: tns1 | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--tiller-namespacetns2--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--tiller-namespacetns1--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--tiller-namespacetns2--kube-contextdefault--namespacens2--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--tiller-namespacetns1--kube-contextdefault--namespacens1--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			upgraded: []exectest.Release{ | ||||
| 				{Name: "foo", Flags: []string{"--tiller-namespace", "tns1", "--kube-context", "default", "--namespace", "ns1"}}, | ||||
|  | @ -3126,13 +3130,13 @@ first-pass rendering output of "helmfile.yaml.part.0": | |||
|  0:  | ||||
|  1: releases: | ||||
|  2: - name: bar | ||||
|  3:   chart: mychart2 | ||||
|  3:   chart: stable/mychart2 | ||||
|  4:   namespace: ns2 | ||||
|  5:   tillerNamespace: tns2 | ||||
|  6:   needs: | ||||
|  7:   - tns1/ns1/foo | ||||
|  8: - name: foo | ||||
|  9:   chart: mychart1 | ||||
|  9:   chart: stable/mychart1 | ||||
| 10:   namespace: ns1 | ||||
| 11:   tillerNamespace: tns1 | ||||
| 12:  | ||||
|  | @ -3146,13 +3150,13 @@ second-pass rendering result of "helmfile.yaml.part.0": | |||
|  0:  | ||||
|  1: releases: | ||||
|  2: - name: bar | ||||
|  3:   chart: mychart2 | ||||
|  3:   chart: stable/mychart2 | ||||
|  4:   namespace: ns2 | ||||
|  5:   tillerNamespace: tns2 | ||||
|  6:   needs: | ||||
|  7:   - tns1/ns1/foo | ||||
|  8: - name: foo | ||||
|  9:   chart: mychart1 | ||||
|  9:   chart: stable/mychart1 | ||||
| 10:   namespace: ns1 | ||||
| 11:   tillerNamespace: tns1 | ||||
| 12:  | ||||
|  | @ -3161,8 +3165,8 @@ merged environment: &{default map[] map[]} | |||
| 2 release(s) found in helmfile.yaml | ||||
| 
 | ||||
| Affected releases are: | ||||
|   bar (mychart2) UPDATED | ||||
|   foo (mychart1) UPDATED | ||||
|   bar (stable/mychart2) UPDATED | ||||
|   foo (stable/mychart1) UPDATED | ||||
| 
 | ||||
| processing 2 groups of releases in this order: | ||||
| GROUP RELEASES | ||||
|  | @ -3175,9 +3179,9 @@ processing releases in group 2/2: tns2/ns2/bar | |||
| getting deployed release version failed:unexpected list key: {^bar$ --tiller-namespacetns2--kube-contextdefault--deployed--failed--pending} | ||||
| 
 | ||||
| UPDATED RELEASES: | ||||
| NAME   CHART      VERSION | ||||
| foo    mychart1           | ||||
| bar    mychart2           | ||||
| NAME   CHART             VERSION | ||||
| foo    stable/mychart1           | ||||
| bar    stable/mychart2           | ||||
| 
 | ||||
| `, | ||||
| 		}, | ||||
|  | @ -3191,18 +3195,18 @@ bar    mychart2 | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   installed: false | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   installed: false | ||||
|   needs: | ||||
|   - bar | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{ | ||||
| 				exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME	REVISION	UPDATED                 	STATUS  	CHART        	APP VERSION	NAMESPACE | ||||
|  | @ -3224,18 +3228,18 @@ bar 	4       	Fri Nov  1 08:40:07 2019	DEPLOYED	mychart2-3.1.0	3.1.0      	defau | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   installed: false | ||||
|   needs: | ||||
|   - foo | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   installed: false | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{ | ||||
| 				exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME	REVISION	UPDATED                 	STATUS  	CHART        	APP VERSION	NAMESPACE | ||||
|  | @ -3260,17 +3264,17 @@ bar 	4       	Fri Nov  1 08:40:07 2019	DEPLOYED	mychart2-3.1.0	3.1.0      	defau | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   installed: false | ||||
|   needs: | ||||
|   - bar | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{ | ||||
| 				exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME	REVISION	UPDATED                 	STATUS  	CHART        	APP VERSION	NAMESPACE | ||||
|  | @ -3294,17 +3298,17 @@ bar 	4       	Fri Nov  1 08:40:07 2019	DEPLOYED	mychart2-3.1.0	3.1.0      	defau | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   installed: false | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   needs: | ||||
|   - bar | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{ | ||||
| 				exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME	REVISION	UPDATED                 	STATUS  	CHART        	APP VERSION	NAMESPACE | ||||
|  | @ -3328,17 +3332,17 @@ bar 	4       	Fri Nov  1 08:40:07 2019	DEPLOYED	mychart2-3.1.0	3.1.0      	defau | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
|   installed: false | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   needs: | ||||
|   - foo | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{ | ||||
| 				exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME	REVISION	UPDATED                 	STATUS  	CHART        	APP VERSION	NAMESPACE | ||||
|  | @ -3362,17 +3366,17 @@ bar 	4       	Fri Nov  1 08:40:07 2019	DEPLOYED	mychart2-3.1.0	3.1.0      	defau | |||
| 				"/path/to/helmfile.yaml": ` | ||||
| releases: | ||||
| - name: foo | ||||
|   chart: mychart1 | ||||
|   chart: stable/mychart1 | ||||
| - name: bar | ||||
|   chart: mychart2 | ||||
|   chart: stable/mychart2 | ||||
|   installed: false | ||||
|   needs: | ||||
|   - foo | ||||
| `, | ||||
| 			}, | ||||
| 			diffs: map[exectest.DiffKey]error{ | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "bar", Chart: "stable/mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 				exectest.DiffKey{Name: "foo", Chart: "stable/mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2}, | ||||
| 			}, | ||||
| 			lists: map[exectest.ListKey]string{ | ||||
| 				exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME	REVISION	UPDATED                 	STATUS  	CHART        	APP VERSION	NAMESPACE | ||||
|  |  | |||
|  | @ -1,7 +1,9 @@ | |||
| package state | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/roboll/helmfile/pkg/helmexec" | ||||
| 	"github.com/roboll/helmfile/pkg/remote" | ||||
| 	"github.com/variantdev/chartify" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | @ -22,20 +24,66 @@ func (st *HelmState) appendHelmXFlags(flags []string, release *ReleaseSpec) ([]s | |||
| 	return flags, nil | ||||
| } | ||||
| 
 | ||||
| func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) (bool, *chartify.ChartifyOpts, func(), error) { | ||||
| 	var opts chartify.ChartifyOpts | ||||
| func fileExistsAt(path string) bool { | ||||
| 	fileInfo, err := os.Stat(path) | ||||
| 	return err == nil && fileInfo.Mode().IsRegular() | ||||
| } | ||||
| 
 | ||||
| 	opts.WorkaroundOutputDirIssue = true | ||||
| func directoryExistsAt(path string) bool { | ||||
| 	fileInfo, err := os.Stat(path) | ||||
| 	return err == nil && fileInfo.Mode().IsDir() | ||||
| } | ||||
| 
 | ||||
| type Chartify struct { | ||||
| 	Opts  *chartify.ChartifyOpts | ||||
| 	Chart string | ||||
| 	Clean func() | ||||
| } | ||||
| 
 | ||||
| func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) (*Chartify, func(), error) { | ||||
| 	chartify := &Chartify{ | ||||
| 		Opts: &chartify.ChartifyOpts{ | ||||
| 			WorkaroundOutputDirIssue:    true, | ||||
| 			EnableKustomizeAlphaPlugins: true, | ||||
| 			ChartVersion:                release.Version, | ||||
| 			Namespace:                   release.Namespace, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	var filesNeedCleaning []string | ||||
| 
 | ||||
| 	clean := func() { | ||||
| 		st.removeFiles(filesNeedCleaning) | ||||
| 	} | ||||
| 
 | ||||
| 	var shouldRun bool | ||||
| 
 | ||||
| 	opts.EnableKustomizeAlphaPlugins = true | ||||
| 	chart := release.Chart | ||||
| 	if release.Directory != "" && chart == "" { | ||||
| 		chart = release.Directory | ||||
| 	} | ||||
| 
 | ||||
| 	opts.ChartVersion = release.Version | ||||
| 	_, err := remote.Parse(chart) | ||||
| 	if err != nil { | ||||
| 		if release.ForceGoGetter { | ||||
| 			return nil, clean, fmt.Errorf("Parsing url from directory of release %q failed due to error %q.\nContinuing the process assuming this is a regular Helm chart or a local directory.", release.Name, err.Error()) | ||||
| 		} | ||||
| 	} else { | ||||
| 		r := remote.NewRemote(st.logger, st.basePath, st.readFile, directoryExistsAt, fileExistsAt) | ||||
| 
 | ||||
| 	opts.Namespace = release.Namespace | ||||
| 		fetchedDir, err := r.Fetch(chart) | ||||
| 		if err != nil { | ||||
| 			return nil, clean, fmt.Errorf("fetching %q: %v", chart, err) | ||||
| 		} | ||||
| 
 | ||||
| 	dir := filepath.Join(st.basePath, release.Chart) | ||||
| 		chart = fetchedDir | ||||
| 
 | ||||
| 		filesNeedCleaning = append(filesNeedCleaning, fetchedDir) | ||||
| 	} | ||||
| 
 | ||||
| 	chartify.Chart = chart | ||||
| 
 | ||||
| 	dir := filepath.Join(st.basePath, chart) | ||||
| 	if stat, _ := os.Stat(dir); stat != nil && stat.IsDir() { | ||||
| 		if exists, err := st.fileExists(filepath.Join(dir, "Chart.yaml")); err == nil && !exists { | ||||
| 			shouldRun = true | ||||
|  | @ -61,28 +109,22 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp | |||
| 			dep += ":" + d.Version | ||||
| 		} | ||||
| 
 | ||||
| 		opts.AdhocChartDependencies = append(opts.AdhocChartDependencies, dep) | ||||
| 		chartify.Opts.AdhocChartDependencies = append(chartify.Opts.AdhocChartDependencies, dep) | ||||
| 
 | ||||
| 		shouldRun = true | ||||
| 	} | ||||
| 
 | ||||
| 	var filesNeedCleaning []string | ||||
| 
 | ||||
| 	clean := func() { | ||||
| 		st.removeFiles(filesNeedCleaning) | ||||
| 	} | ||||
| 
 | ||||
| 	jsonPatches := release.JSONPatches | ||||
| 	if len(jsonPatches) > 0 { | ||||
| 		generatedFiles, err := st.generateTemporaryValuesFiles(jsonPatches, release.MissingFileHandler) | ||||
| 		if err != nil { | ||||
| 			return false, nil, clean, err | ||||
| 			return nil, clean, err | ||||
| 		} | ||||
| 
 | ||||
| 		filesNeedCleaning = append(filesNeedCleaning, generatedFiles...) | ||||
| 
 | ||||
| 		for _, f := range generatedFiles { | ||||
| 			opts.JsonPatches = append(opts.JsonPatches, f) | ||||
| 			chartify.Opts.JsonPatches = append(chartify.Opts.JsonPatches, f) | ||||
| 		} | ||||
| 
 | ||||
| 		shouldRun = true | ||||
|  | @ -92,11 +134,11 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp | |||
| 	if len(strategicMergePatches) > 0 { | ||||
| 		generatedFiles, err := st.generateTemporaryValuesFiles(strategicMergePatches, release.MissingFileHandler) | ||||
| 		if err != nil { | ||||
| 			return false, nil, clean, err | ||||
| 			return nil, clean, err | ||||
| 		} | ||||
| 
 | ||||
| 		for _, f := range generatedFiles { | ||||
| 			opts.StrategicMergePatches = append(opts.StrategicMergePatches, f) | ||||
| 			chartify.Opts.StrategicMergePatches = append(chartify.Opts.StrategicMergePatches, f) | ||||
| 		} | ||||
| 
 | ||||
| 		filesNeedCleaning = append(filesNeedCleaning, generatedFiles...) | ||||
|  | @ -107,13 +149,15 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp | |||
| 	if shouldRun { | ||||
| 		generatedFiles, err := st.generateValuesFiles(helm, release, workerIndex) | ||||
| 		if err != nil { | ||||
| 			return false, nil, clean, err | ||||
| 			return nil, clean, err | ||||
| 		} | ||||
| 
 | ||||
| 		filesNeedCleaning = append(filesNeedCleaning, generatedFiles...) | ||||
| 
 | ||||
| 		opts.ValuesFiles = generatedFiles | ||||
| 		chartify.Opts.ValuesFiles = generatedFiles | ||||
| 
 | ||||
| 		return chartify, clean, nil | ||||
| 	} | ||||
| 
 | ||||
| 	return shouldRun, &opts, clean, nil | ||||
| 	return nil, clean, nil | ||||
| } | ||||
|  |  | |||
|  | @ -150,9 +150,15 @@ type RepositorySpec struct { | |||
| // ReleaseSpec defines the structure of a helm release
 | ||||
| type ReleaseSpec struct { | ||||
| 	// Chart is the name of the chart being installed to create this release
 | ||||
| 	Chart   string `yaml:"chart,omitempty"` | ||||
| 	Chart string `yaml:"chart,omitempty"` | ||||
| 	// Directory is an alias to Chart which may be of more fit when you want to use a local/remote directory containing
 | ||||
| 	// K8s manifests or Kustomization as a chart
 | ||||
| 	Directory string `yaml:"directory,omitempty"` | ||||
| 	// Version is the semver version or version constraint for the chart
 | ||||
| 	Version string `yaml:"version,omitempty"` | ||||
| 	Verify  *bool  `yaml:"verify,omitempty"` | ||||
| 	// Verify enables signature verification on fetched chart.
 | ||||
| 	// Beware some (or many?) chart repositories and charts don't seem to support it.
 | ||||
| 	Verify *bool `yaml:"verify,omitempty"` | ||||
| 	// Devel, when set to true, use development versions, too. Equivalent to version '>0.0.0-0'
 | ||||
| 	Devel *bool `yaml:"devel,omitempty"` | ||||
| 	// Wait, if set to true, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful
 | ||||
|  | @ -237,6 +243,13 @@ type ReleaseSpec struct { | |||
| 
 | ||||
| 	//version of the chart that has really been installed cause desired version may be fuzzy (~2.0.0)
 | ||||
| 	installedVersion string | ||||
| 
 | ||||
| 	// ForceGoGetter forces the use of go-getter for fetching remote directory as maniefsts/chart/kustomization
 | ||||
| 	// by parsing the url from `chart` field of the release.
 | ||||
| 	// This is handy when getting the go-getter url parsing error when it doesn't work as expected.
 | ||||
| 	// Without this, any error in url parsing result in silently falling-back to normal process of treating `chart:` as the regular
 | ||||
| 	// helm chart name.
 | ||||
| 	ForceGoGetter bool `yaml:"forceGoGetter,omitempty"` | ||||
| } | ||||
| 
 | ||||
| type Release struct { | ||||
|  | @ -534,6 +547,7 @@ func (st *HelmState) DeleteReleasesForSync(affectedReleases *AffectedReleases, h | |||
| 					} | ||||
| 					deletionFlags := st.appendConnectionFlags(args, release) | ||||
| 					m.Lock() | ||||
| 
 | ||||
| 					if err := helm.DeleteRelease(context, release.Name, deletionFlags...); err != nil { | ||||
| 						affectedReleases.Failed = append(affectedReleases.Failed, release) | ||||
| 						relErr = newReleaseFailedError(release, err) | ||||
|  | @ -638,6 +652,7 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme | |||
| 						} | ||||
| 						deletionFlags := st.appendConnectionFlags(args, release) | ||||
| 						m.Lock() | ||||
| 
 | ||||
| 						if err := helm.DeleteRelease(context, release.Name, deletionFlags...); err != nil { | ||||
| 							affectedReleases.Failed = append(affectedReleases.Failed, release) | ||||
| 							relErr = newReleaseFailedError(release, err) | ||||
|  | @ -745,6 +760,7 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre | |||
| 		chartPath   string | ||||
| 		err         error | ||||
| 	} | ||||
| 
 | ||||
| 	errs := []error{} | ||||
| 
 | ||||
| 	jobQueue := make(chan *ReleaseSpec, len(st.Releases)) | ||||
|  | @ -769,22 +785,23 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre | |||
| 			for release := range jobQueue { | ||||
| 				var chartPath string | ||||
| 
 | ||||
| 				shouldChartify, opts, clean, err := st.PrepareChartify(helm, release, workerIndex) | ||||
| 				chartification, clean, err := st.PrepareChartify(helm, release, workerIndex) | ||||
| 				defer clean() | ||||
| 				if err != nil { | ||||
| 					results <- &downloadResults{err: err} | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				if shouldChartify { | ||||
| 				if chartification != nil { | ||||
| 					c := chartify.New( | ||||
| 						chartify.HelmBin(st.DefaultHelmBinary), | ||||
| 						chartify.UseHelm3(helm3), | ||||
| 					) | ||||
| 
 | ||||
| 					out, err := c.Chartify(release.Name, release.Chart, chartify.WithChartifyOpts(opts)) | ||||
| 					out, err := c.Chartify(release.Name, chartification.Chart, chartify.WithChartifyOpts(chartification.Opts)) | ||||
| 					if err != nil { | ||||
| 						errs = append(errs, err) | ||||
| 						results <- &downloadResults{err: err} | ||||
| 						return | ||||
| 					} else { | ||||
| 						// TODO Chartify
 | ||||
| 						chartPath = out | ||||
|  | @ -810,7 +827,8 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre | |||
| 					if _, err := os.Stat(chartPath); os.IsNotExist(err) { | ||||
| 						fetchFlags = append(fetchFlags, "--untar", "--untardir", chartPath) | ||||
| 						if err := helm.Fetch(release.Chart, fetchFlags...); err != nil { | ||||
| 							errs = append(errs, err) | ||||
| 							results <- &downloadResults{err: err} | ||||
| 							return | ||||
| 						} | ||||
| 					} | ||||
| 					// Set chartPath to be the path containing Chart.yaml, if found
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue