Skip to content

Commit

Permalink
Merge pull request #905 from fluxcd/enable-ocirepo-sources
Browse files Browse the repository at this point in the history
Add support for `OCIRepository` as chartRef
  • Loading branch information
souleb authored Apr 18, 2024
2 parents 9059e7f + a98d957 commit 5e760db
Show file tree
Hide file tree
Showing 38 changed files with 2,143 additions and 233 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ jobs:
kubectl -n install-create-target-ns get deployment install-create-target-ns-install-create-target-ns-podinfo
kubectl -n helm-system delete -f config/testdata/install-create-target-ns
- name: Run install from ocirepo test
run: |
kubectl -n helm-system apply -f config/testdata/install-from-ocirepo-source
kubectl -n helm-system wait helmreleases/podinfo-from-ocirepo --for=condition=ready --timeout=4m
kubectl -n helm-system delete -f config/testdata/install-from-ocirepo-source
- name: Run install fail test
run: |
test_name=install-fail
Expand Down Expand Up @@ -458,6 +463,45 @@ jobs:
fi
kubectl delete -n helm-system -f config/testdata/$test_name/install.yaml
- name: Run upgrade from ocirepo source
run: |
test_name=upgrade-from-ocirepo-source
kubectl -n helm-system apply -f config/testdata/$test_name/install.yaml
echo -n ">>> Waiting for expected conditions"
count=0
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .Ready=="True"' )" ]; do
echo -n '.'
sleep 5
count=$((count + 1))
if [[ ${count} -eq 24 ]]; then
echo ' No more retries left!'
exit 1
fi
done
echo ' done'
# Validate release was installed.
REVISION_COUNT=$(helm -n helm-system history -o json $test_name | jq 'length')
if [ "$REVISION_COUNT" != 1 ]; then
echo -e "Unexpected revision count: $REVISION_COUNT"
exit 1
fi

kubectl -n helm-system apply -f config/testdata/$test_name/upgrade.yaml
echo -n ">>> Waiting for expected conditions"
count=0
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .Ready=="True"' )" ]; do
echo -n '.'
sleep 5
count=$((count + 1))
if [[ ${count} -eq 24 ]]; then
echo ' No more retries left!'
exit 1
fi
done
echo ' done'

kubectl delete -n helm-system -f config/testdata/$test_name/install.yaml
- name: Run upgrade fail with uninstall remediation strategy test
run: |
test_name=upgrade-fail-remediate-uninstall
Expand Down
32 changes: 29 additions & 3 deletions api/v2beta2/helmrelease_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,17 @@ type PostRenderer struct {
}

// HelmReleaseSpec defines the desired state of a Helm release.
// +kubebuilder:validation:XValidation:rule="(has(self.chart) && !has(self.chartRef)) || (!has(self.chart) && has(self.chartRef))", message="either chart or chartRef must be set"
type HelmReleaseSpec struct {
// Chart defines the template of the v1beta2.HelmChart that should be created
// for this HelmRelease.
// +required
Chart HelmChartTemplate `json:"chart"`
// +optional
Chart HelmChartTemplate `json:"chart,omitempty"`

// ChartRef holds a reference to a source controller resource containing the
// Helm chart artifact.
// +optional
ChartRef *CrossNamespaceSourceReference `json:"chartRef,omitempty"`

// Interval at which to reconcile the Helm release.
// +kubebuilder:validation:Type=string
Expand Down Expand Up @@ -996,10 +1002,16 @@ type HelmReleaseStatus struct {
LastAppliedRevision string `json:"lastAppliedRevision,omitempty"`

// LastAttemptedRevision is the Source revision of the last reconciliation
// attempt.
// attempt. For OCIRepository sources, the 12 first characters of the digest are
// appended to the chart version e.g. "1.2.3+1234567890ab".
// +optional
LastAttemptedRevision string `json:"lastAttemptedRevision,omitempty"`

// LastAttemptedRevisionDigest is the digest of the last reconciliation attempt.
// This is only set for OCIRepository sources.
// +optional
LastAttemptedRevisionDigest string `json:"lastAttemptedRevisionDigest,omitempty"`

// LastAttemptedValuesChecksum is the SHA1 checksum for the values of the last
// reconciliation attempt.
// Deprecated: Use LastAttemptedConfigDigest instead.
Expand Down Expand Up @@ -1052,6 +1064,10 @@ func (in HelmReleaseStatus) GetHelmChart() (string, string) {
return "", ""
}

func (in *HelmReleaseStatus) GetLastAttemptedRevision() string {
return in.LastAttemptedRevision
}

const (
// SourceIndexKey is the key used for indexing HelmReleases based on
// their sources.
Expand Down Expand Up @@ -1241,6 +1257,16 @@ func (in *HelmRelease) GetStatusConditions() *[]metav1.Condition {
return &in.Status.Conditions
}

// IsChartRefPresent returns true if the HelmRelease has a ChartRef.
func (in *HelmRelease) HasChartRef() bool {
return in.Spec.ChartRef != nil
}

// IsChartTemplatePresent returns true if the HelmRelease has a ChartTemplate.
func (in *HelmRelease) HasChartTemplate() bool {
return in.Spec.Chart.Spec.Chart != ""
}

// +kubebuilder:object:root=true

// HelmReleaseList contains a list of HelmRelease objects.
Expand Down
27 changes: 27 additions & 0 deletions api/v2beta2/reference_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,33 @@ type CrossNamespaceObjectReference struct {
Namespace string `json:"namespace,omitempty"`
}

// CrossNamespaceSourceReference contains enough information to let you locate
// the typed referenced object at cluster level.
type CrossNamespaceSourceReference struct {
// APIVersion of the referent.
// +optional
APIVersion string `json:"apiVersion,omitempty"`

// Kind of the referent.
// +kubebuilder:validation:Enum=OCIRepository
// +required
Kind string `json:"kind"`

// Name of the referent.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +required
Name string `json:"name"`

// Namespace of the referent, defaults to the namespace of the Kubernetes
// resource object that contains the reference.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:Optional
// +optional
Namespace string `json:"namespace,omitempty"`
}

// ValuesReference contains a reference to a resource containing Helm values,
// and optionally the key they can be found at.
type ValuesReference struct {
Expand Down
3 changes: 3 additions & 0 deletions api/v2beta2/snapshot_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ type Snapshot struct {
// run by the controller.
// +optional
TestHooks *map[string]*TestHookStatus `json:"testHooks,omitempty"`
// OCIDigest is the digest of the OCI artifact associated with the release.
// +optional
OCIDigest string `json:"ociDigest,omitempty"`
}

// FullReleaseName returns the full name of the release in the format
Expand Down
20 changes: 20 additions & 0 deletions api/v2beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 48 additions & 2 deletions config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,10 @@ spec:
description: Namespace is the namespace the release is deployed
to.
type: string
ociDigest:
description: OCIDigest is the digest of the OCI artifact associated
with the release.
type: string
status:
description: Status is the current state of the release.
type: string
Expand Down Expand Up @@ -1420,6 +1424,35 @@ spec:
required:
- spec
type: object
chartRef:
description: |-
ChartRef holds a reference to a source controller resource containing the
Helm chart artifact.
properties:
apiVersion:
description: APIVersion of the referent.
type: string
kind:
description: Kind of the referent.
enum:
- OCIRepository
type: string
name:
description: Name of the referent.
maxLength: 253
minLength: 1
type: string
namespace:
description: |-
Namespace of the referent, defaults to the namespace of the Kubernetes
resource object that contains the reference.
maxLength: 63
minLength: 1
type: string
required:
- kind
- name
type: object
dependsOn:
description: |-
DependsOn may contain a meta.NamespacedObjectReference slice with
Expand Down Expand Up @@ -2199,9 +2232,12 @@ spec:
type: object
type: array
required:
- chart
- interval
type: object
x-kubernetes-validations:
- message: either chart or chartRef must be set
rule: (has(self.chart) && !has(self.chartRef)) || (!has(self.chart)
&& has(self.chartRef))
status:
default:
observedGeneration: -1
Expand Down Expand Up @@ -2342,6 +2378,10 @@ spec:
description: Namespace is the namespace the release is deployed
to.
type: string
ociDigest:
description: OCIDigest is the digest of the OCI artifact associated
with the release.
type: string
status:
description: Status is the current state of the release.
type: string
Expand Down Expand Up @@ -2420,7 +2460,13 @@ spec:
lastAttemptedRevision:
description: |-
LastAttemptedRevision is the Source revision of the last reconciliation
attempt.
attempt. For OCIRepository sources, the 12 first characters of the digest are
appended to the chart version e.g. "1.2.3+1234567890ab".
type: string
lastAttemptedRevisionDigest:
description: |-
LastAttemptedRevisionDigest is the digest of the last reconciliation attempt.
This is only set for OCIRepository sources.
type: string
lastAttemptedValuesChecksum:
description: |-
Expand Down
14 changes: 14 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,17 @@ rules:
- helmcharts/status
verbs:
- get
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- ocirepositories
verbs:
- get
- list
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- ocirepositories/status
verbs:
- get
25 changes: 25 additions & 0 deletions config/testdata/install-from-ocirepo-source/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: podinfo-ocirepo
spec:
interval: 30s
url: oci://ghcr.io/stefanprodan/charts/podinfo
ref:
tag: 6.6.0
---
apiVersion: helm.toolkit.fluxcd.io/v2beta2
kind: HelmRelease
metadata:
name: podinfo-from-ocirepo
spec:
chartRef:
kind: OCIRepository
name: podinfo-ocirepo
interval: 30s
values:
resources:
requests:
cpu: 100m
memory: 64Mi
25 changes: 25 additions & 0 deletions config/testdata/upgrade-from-ocirepo-source/install.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: upgrade-from-ocirepo-source
spec:
interval: 30s
url: oci://ghcr.io/stefanprodan/charts/podinfo
ref:
digest: "sha256:cdd538a0167e4b51152b71a477e51eb6737553510ce8797dbcc537e1342311bb"
---
apiVersion: helm.toolkit.fluxcd.io/v2beta2
kind: HelmRelease
metadata:
name: upgrade-from-ocirepo-source
spec:
chartRef:
kind: OCIRepository
name: upgrade-from-ocirepo-source
interval: 30s
values:
resources:
requests:
cpu: 100m
memory: 64Mi
10 changes: 10 additions & 0 deletions config/testdata/upgrade-from-ocirepo-source/upgrade.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: upgrade-from-ocirepo-source
spec:
interval: 30s
url: oci://ghcr.io/stefanprodan/charts/podinfo
ref:
digest: "sha256:0cc9a8446c95009ef382f5eade883a67c257f77d50f84e78ecef2aac9428d1e5"
Loading

0 comments on commit 5e760db

Please sign in to comment.