Skip to content

Commit d7e36e2

Browse files
authored
Merge pull request fluxcd#685 from pjbgf/optimise-helm-load
helm: optimise repository index loading
2 parents 3c67efa + 009504b commit d7e36e2

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

api/v1beta2/artifact_types.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,24 @@ type Artifact struct {
5656
Size *int64 `json:"size,omitempty"`
5757
}
5858

59-
// HasRevision returns true if the given revision matches the current Revision
60-
// of the Artifact.
59+
// HasRevision returns if the given revision matches the current Revision of
60+
// the Artifact.
6161
func (in *Artifact) HasRevision(revision string) bool {
6262
if in == nil {
6363
return false
6464
}
6565
return in.Revision == revision
6666
}
6767

68+
// HasChecksum returns if the given checksum matches the current Checksum of
69+
// the Artifact.
70+
func (in *Artifact) HasChecksum(checksum string) bool {
71+
if in == nil {
72+
return false
73+
}
74+
return in.Checksum == checksum
75+
}
76+
6877
// ArtifactDir returns the artifact dir path in the form of
6978
// '<kind>/<namespace>/<name>'.
7079
func ArtifactDir(kind, namespace, name string) string {

controllers/helmrepository_controller.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, obj *sou
398398
return sreconcile.ResultEmpty, e
399399
}
400400
}
401+
402+
// Fetch the repository index from remote.
401403
checksum, err := newChartRepo.CacheIndex()
402404
if err != nil {
403405
e := &serror.Event{
@@ -410,6 +412,15 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, obj *sou
410412
}
411413
*chartRepo = *newChartRepo
412414

415+
// Short-circuit based on the fetched index being an exact match to the
416+
// stored Artifact. This prevents having to unmarshal the YAML to calculate
417+
// the (stable) revision, which is a memory expensive operation.
418+
if obj.GetArtifact().HasChecksum(checksum) {
419+
*artifact = *obj.GetArtifact()
420+
conditions.Delete(obj, sourcev1.FetchFailedCondition)
421+
return sreconcile.ResultSuccess, nil
422+
}
423+
413424
// Load the cached repository index to ensure it passes validation.
414425
if err := chartRepo.LoadFromCache(); err != nil {
415426
e := &serror.Event{
@@ -419,23 +430,24 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, obj *sou
419430
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
420431
return sreconcile.ResultEmpty, e
421432
}
422-
defer chartRepo.Unload()
433+
chartRepo.Unload()
423434

424435
// Mark observations about the revision on the object.
425-
if !obj.GetArtifact().HasRevision(checksum) {
436+
if !obj.GetArtifact().HasRevision(newChartRepo.Checksum) {
426437
message := fmt.Sprintf("new index revision '%s'", checksum)
427438
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", message)
428439
conditions.MarkReconciling(obj, "NewRevision", message)
429440
}
430441

431-
conditions.Delete(obj, sourcev1.FetchFailedCondition)
432-
433442
// Create potential new artifact.
434443
*artifact = r.Storage.NewArtifactFor(obj.Kind,
435444
obj.ObjectMeta.GetObjectMeta(),
436445
chartRepo.Checksum,
437446
fmt.Sprintf("index-%s.yaml", checksum))
438447

448+
// Delete any stale failure observation
449+
conditions.Delete(obj, sourcev1.FetchFailedCondition)
450+
439451
return sreconcile.ResultSuccess, nil
440452
}
441453

@@ -462,7 +474,7 @@ func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, obj *s
462474
}
463475
}()
464476

465-
if obj.GetArtifact().HasRevision(artifact.Revision) {
477+
if obj.GetArtifact().HasRevision(artifact.Revision) && obj.GetArtifact().HasChecksum(artifact.Checksum) {
466478
r.eventLogf(ctx, obj, events.EventTypeTrace, sourcev1.ArtifactUpToDateReason, "artifact up-to-date with remote revision: '%s'", artifact.Revision)
467479
return sreconcile.ResultSuccess, nil
468480
}

internal/helm/repository/chart_repository.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ type ChartRepository struct {
6666
// Index contains a loaded chart repository index if not nil.
6767
Index *repo.IndexFile
6868
// Checksum contains the SHA256 checksum of the loaded chart repository
69-
// index bytes.
69+
// index bytes. This is different from the checksum of the CachePath, which
70+
// may contain unordered entries.
7071
Checksum string
7172

7273
tlsConfig *tls.Config
@@ -87,7 +88,7 @@ type cacheInfo struct {
8788
RecordIndexCacheMetric RecordMetricsFunc
8889
}
8990

90-
// ChartRepositoryOptions is a function that can be passed to NewChartRepository
91+
// ChartRepositoryOption is a function that can be passed to NewChartRepository
9192
// to configure a ChartRepository.
9293
type ChartRepositoryOption func(*ChartRepository) error
9394

0 commit comments

Comments
 (0)