Skip to content

Commit e4eb660

Browse files
committed
archive helm index in JSON format
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
1 parent cb4b660 commit e4eb660

File tree

2 files changed

+45
-32
lines changed

2 files changed

+45
-32
lines changed

internal/controller/helmrepository_controller.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ limitations under the License.
1717
package controller
1818

1919
import (
20+
"bytes"
2021
"context"
2122
"crypto/tls"
23+
"encoding/json"
2224
"errors"
2325
"fmt"
2426
"net/url"
@@ -476,11 +478,11 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
476478

477479
// Early comparison to current Artifact.
478480
if curArtifact := obj.GetArtifact(); curArtifact != nil {
479-
curDig := digest.Digest(curArtifact.Digest)
480-
if curDig.Validate() == nil {
481+
curRev := digest.Digest(curArtifact.Revision)
482+
if curRev.Validate() == nil {
481483
// Short-circuit based on the fetched index being an exact match to the
482484
// stored Artifact.
483-
if newDig := chartRepo.Digest(curDig.Algorithm()); newDig.Validate() == nil && (newDig == curDig) {
485+
if newRev := chartRepo.Digest(curRev.Algorithm()); newRev.Validate() == nil && (newRev == curRev) {
484486
*artifact = *curArtifact
485487
conditions.Delete(obj, sourcev1.FetchFailedCondition)
486488
return sreconcile.ResultSuccess, nil
@@ -500,13 +502,6 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
500502
// Delete any stale failure observation
501503
conditions.Delete(obj, sourcev1.FetchFailedCondition)
502504

503-
// Check if index has changed compared to current Artifact revision.
504-
var changed bool
505-
if artifact := obj.Status.Artifact; artifact != nil {
506-
curRev := digest.Digest(artifact.Revision)
507-
changed = curRev.Validate() != nil || curRev != chartRepo.Digest(curRev.Algorithm())
508-
}
509-
510505
// Calculate revision.
511506
revision := chartRepo.Digest(intdigest.Canonical)
512507
if revision.Validate() != nil {
@@ -519,16 +514,14 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
519514
}
520515

521516
// Mark observations about the revision on the object.
522-
if obj.Status.Artifact == nil || changed {
523-
message := fmt.Sprintf("new index revision '%s'", revision)
524-
if obj.GetArtifact() != nil {
525-
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", message)
526-
}
527-
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", message)
528-
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
529-
ctrl.LoggerFrom(ctx).Error(err, "failed to patch")
530-
return sreconcile.ResultEmpty, err
531-
}
517+
message := fmt.Sprintf("new index revision '%s'", revision)
518+
if obj.GetArtifact() != nil {
519+
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", message)
520+
}
521+
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", message)
522+
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
523+
ctrl.LoggerFrom(ctx).Error(err, "failed to patch")
524+
return sreconcile.ResultEmpty, err
532525
}
533526

534527
// Create potential new artifact.
@@ -593,8 +586,18 @@ func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pa
593586
}
594587
defer unlock()
595588

596-
// Save artifact to storage.
597-
if err = r.Storage.CopyFromPath(artifact, chartRepo.Path); err != nil {
589+
// Save artifact to storage in JSON format.
590+
b := &bytes.Buffer{}
591+
if err := json.NewEncoder(b).Encode(chartRepo.Index); err != nil {
592+
e := &serror.Event{
593+
Err: fmt.Errorf("unable to encode index to JSON: %w", err),
594+
Reason: sourcev1.ArchiveOperationFailedReason,
595+
}
596+
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
597+
return sreconcile.ResultEmpty, e
598+
}
599+
600+
if err = r.Storage.Copy(artifact, b); err != nil {
598601
e := &serror.Event{
599602
Err: fmt.Errorf("unable to save artifact to storage: %w", err),
600603
Reason: sourcev1.ArchiveOperationFailedReason,

internal/controller/helmrepository_controller_test.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package controller
1919
import (
2020
"context"
2121
"crypto/tls"
22+
"encoding/json"
2223
"errors"
2324
"fmt"
2425
"net/http"
@@ -633,28 +634,29 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
633634
want: sreconcile.ResultSuccess,
634635
},
635636
{
636-
name: "Stored index with different digest and same revision",
637+
name: "Stored index with different revision and same digest",
637638
protocol: "http",
638639
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) {
639640
obj.Status.Artifact = &sourcev1.Artifact{
640-
Revision: rev.String(),
641-
Digest: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
641+
Revision: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
642+
Digest: dig.String(),
642643
}
643644

644645
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
645646
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
646647
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, "foo", "bar")
647648
},
648649
assertConditions: []metav1.Condition{
649-
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
650-
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
650+
*conditions.TrueCondition(sourcev1.ArtifactOutdatedCondition, "NewRevision", "new index revision"),
651+
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
652+
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
651653
},
652654
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
653655
t.Expect(chartRepo.Path).ToNot(BeEmpty())
654656
t.Expect(chartRepo.Index).ToNot(BeNil())
655657

656-
t.Expect(artifact.Revision).To(Equal(obj.Status.Artifact.Revision))
657-
t.Expect(artifact.Digest).ToNot(Equal(obj.Status.Artifact.Digest))
658+
t.Expect(artifact.Revision).NotTo(Equal(obj.Status.Artifact.Revision))
659+
t.Expect(artifact.Digest).To(BeEmpty())
658660
},
659661
want: sreconcile.ResultSuccess,
660662
},
@@ -802,10 +804,12 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
802804
var rev, dig digest.Digest
803805
if validSecret {
804806
g.Expect(newChartRepo.CacheIndex()).To(Succeed())
805-
dig = newChartRepo.Digest(intdigest.Canonical)
807+
rev = newChartRepo.Digest(intdigest.Canonical)
806808

807809
g.Expect(newChartRepo.LoadFromPath()).To(Succeed())
808-
rev = newChartRepo.Digest(intdigest.Canonical)
810+
d := intdigest.Canonical.Digester()
811+
g.Expect(json.NewEncoder(d.Hash()).Encode(newChartRepo.Index)).To(Succeed())
812+
dig = d.Digest()
809813
}
810814
if tt.beforeFunc != nil {
811815
tt.beforeFunc(g, obj, rev, dig)
@@ -857,11 +861,17 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
857861
assertConditions []metav1.Condition
858862
}{
859863
{
860-
name: "Archiving artifact to storage makes ArtifactInStorage=True",
864+
name: "Archiving artifact to storage makes ArtifactInStorage=True and artifact is stored as JSON",
861865
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
862866
obj.Spec.Interval = metav1.Duration{Duration: interval}
863867
},
864868
want: sreconcile.ResultSuccess,
869+
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, cache *cache.Cache) {
870+
localPath := testStorage.LocalPath(*obj.GetArtifact())
871+
b, err := os.ReadFile(localPath)
872+
t.Expect(err).To(Not(HaveOccurred()))
873+
t.Expect(json.Valid(b)).To(BeTrue())
874+
},
865875
assertConditions: []metav1.Condition{
866876
*conditions.TrueCondition(sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact: revision 'existing'"),
867877
},

0 commit comments

Comments
 (0)