allow for charts from OCI registries to specify a chart path
This change allows for a HelmRepository to point to e.g. "ghcr.io" and then a HelmRelease pointing to the chart "stefanprodan/charts/podinfo" in its `.spec.chart.spec.chart` field. Related discussion: https://github.com/fluxcd/flux2/discussions/2959 Signed-off-by: Max Jonas Werner <max@e13.dev>
This commit is contained in:
parent
1db1626fe1
commit
64c1b065a8
|
@ -0,0 +1,11 @@
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: HelmChart
|
||||||
|
metadata:
|
||||||
|
name: helmchart-sample-oci
|
||||||
|
spec:
|
||||||
|
chart: stefanprodan/charts/podinfo
|
||||||
|
version: '>=6.0.0 <7.0.0'
|
||||||
|
sourceRef:
|
||||||
|
kind: HelmRepository
|
||||||
|
name: helmrepository-sample-oci
|
||||||
|
interval: 1m
|
|
@ -0,0 +1,8 @@
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: HelmRepository
|
||||||
|
metadata:
|
||||||
|
name: helmrepository-sample-oci
|
||||||
|
spec:
|
||||||
|
interval: 1m
|
||||||
|
type: oci
|
||||||
|
url: oci://ghcr.io/
|
|
@ -75,7 +75,9 @@ kubectl -n source-system rollout status deploy/source-controller --timeout=1m
|
||||||
kubectl -n source-system wait gitrepository/gitrepository-sample --for=condition=ready --timeout=1m
|
kubectl -n source-system wait gitrepository/gitrepository-sample --for=condition=ready --timeout=1m
|
||||||
kubectl -n source-system wait ocirepository/ocirepository-sample --for=condition=ready --timeout=1m
|
kubectl -n source-system wait ocirepository/ocirepository-sample --for=condition=ready --timeout=1m
|
||||||
kubectl -n source-system wait helmrepository/helmrepository-sample --for=condition=ready --timeout=1m
|
kubectl -n source-system wait helmrepository/helmrepository-sample --for=condition=ready --timeout=1m
|
||||||
|
kubectl -n source-system wait helmrepository/helmrepository-sample-oci --for=condition=ready --timeout=1m
|
||||||
kubectl -n source-system wait helmchart/helmchart-sample --for=condition=ready --timeout=1m
|
kubectl -n source-system wait helmchart/helmchart-sample --for=condition=ready --timeout=1m
|
||||||
|
kubectl -n source-system wait helmchart/helmchart-sample-oci --for=condition=ready --timeout=1m
|
||||||
kubectl -n source-system delete -f "${ROOT_DIR}/config/samples"
|
kubectl -n source-system delete -f "${ROOT_DIR}/config/samples"
|
||||||
|
|
||||||
echo "Run HelmChart values file tests"
|
echo "Run HelmChart values file tests"
|
||||||
|
|
|
@ -81,9 +81,9 @@ func (r RemoteReference) Validate() error {
|
||||||
if r.Name == "" {
|
if r.Name == "" {
|
||||||
return fmt.Errorf("no name set for remote chart reference")
|
return fmt.Errorf("no name set for remote chart reference")
|
||||||
}
|
}
|
||||||
name := regexp.MustCompile("^([-a-z0-9]*)$")
|
name := regexp.MustCompile("^([-a-z0-9]+/?)+$")
|
||||||
if !name.MatchString(r.Name) {
|
if !name.MatchString(r.Name) {
|
||||||
return fmt.Errorf("invalid chart name '%s': a valid name must be lower case letters and numbers and MAY be separated with dashes (-)", r.Name)
|
return fmt.Errorf("invalid chart name '%s': a valid name must be lower case letters and numbers and MAY be separated with dashes (-) or slashes (/)", r.Name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,7 +234,8 @@ func TestRemoteBuilder_BuildFromOCIChatRepository(t *testing.T) {
|
||||||
|
|
||||||
registryClient := &mockRegistryClient{
|
registryClient := &mockRegistryClient{
|
||||||
tags: map[string][]string{
|
tags: map[string][]string{
|
||||||
"localhost:5000/my_repo/grafana": {"6.17.4"},
|
"localhost:5000/my_repo/grafana": {"6.17.4"},
|
||||||
|
"localhost:5000/my_repo/another/grafana": {"6.17.4"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,6 +319,15 @@ func TestRemoteBuilder_BuildFromOCIChatRepository(t *testing.T) {
|
||||||
"replicaCount": float64(1),
|
"replicaCount": float64(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "default values",
|
||||||
|
reference: RemoteReference{Name: "another/grafana"},
|
||||||
|
repository: mockRepo(),
|
||||||
|
wantVersion: "0.1.0",
|
||||||
|
wantValues: chartutil.Values{
|
||||||
|
"replicaCount": float64(1),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "merge values",
|
name: "merge values",
|
||||||
reference: RemoteReference{Name: "grafana"},
|
reference: RemoteReference{Name: "grafana"},
|
||||||
|
|
|
@ -85,21 +85,34 @@ func TestRemoteReference_Validate(t *testing.T) {
|
||||||
name: "ref with name",
|
name: "ref with name",
|
||||||
ref: RemoteReference{Name: "valid-chart-name"},
|
ref: RemoteReference{Name: "valid-chart-name"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ref with single-character name",
|
||||||
|
ref: RemoteReference{Name: "a"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ref with invalid name",
|
name: "ref with invalid name",
|
||||||
ref: RemoteReference{Name: "iNvAlID-ChArT-NAmE!"},
|
ref: RemoteReference{Name: "iNvAlID-ChArT-NAmE!"},
|
||||||
wantErr: "invalid chart name 'iNvAlID-ChArT-NAmE!'",
|
wantErr: "invalid chart name 'iNvAlID-ChArT-NAmE!'",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ref with Artifactory specific invalid format",
|
name: "ref with Artifactory specific valid format",
|
||||||
ref: RemoteReference{Name: "i-shall/not"},
|
ref: RemoteReference{Name: "i-shall/not"},
|
||||||
wantErr: "invalid chart name 'i-shall/not'",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ref without name",
|
name: "ref without name",
|
||||||
ref: RemoteReference{},
|
ref: RemoteReference{},
|
||||||
wantErr: "no name set for remote chart reference",
|
wantErr: "no name set for remote chart reference",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ref with only a slash",
|
||||||
|
ref: RemoteReference{Name: "/"},
|
||||||
|
wantErr: "invalid chart name '/'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ref with double slash",
|
||||||
|
ref: RemoteReference{Name: "not//a/valid/chart"},
|
||||||
|
wantErr: "invalid chart name 'not//a/valid/chart'",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue