Skip to content

Commit b402e54

Browse files
committed
Refactor repository logic
Signed-off-by: Soule BA <[email protected]>
1 parent f7006e9 commit b402e54

File tree

7 files changed

+48
-82
lines changed

7 files changed

+48
-82
lines changed

controllers/helmchart_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
518518
}
519519

520520
// Initialize the chart repository
521-
var chartRepo chart.Remote
521+
var chartRepo chart.Repository
522522
switch repo.Spec.Type {
523523
case sourcev1.HelmRepositoryTypeOCI:
524524
if !helmreg.IsOCI(repo.Spec.URL) {

internal/helm/chart/builder_remote.go

Lines changed: 19 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
"path/filepath"
2626

2727
"github.com/Masterminds/semver/v3"
28-
"github.com/fluxcd/source-controller/internal/helm/repository"
2928
helmchart "helm.sh/helm/v3/pkg/chart"
3029
"helm.sh/helm/v3/pkg/chartutil"
3130
"helm.sh/helm/v3/pkg/repo"
@@ -37,22 +36,22 @@ import (
3736
"github.com/fluxcd/source-controller/internal/helm/chart/secureloader"
3837
)
3938

40-
// Remote is a repository.ChartRepository or a repository.OCIChartRepository.
39+
// Repository is a repository.ChartRepository or a repository.OCIChartRepository.
4140
// It is used to download a chart from a remote Helm repository or OCI registry.
42-
type Remote interface {
43-
// GetChart returns a chart.Chart from the remote repository.
44-
Get(name, version string) (*repo.ChartVersion, error)
41+
type Repository interface {
42+
// GetChartVersion returns the repo.ChartVersion for the given name and version.
43+
GetChartVersion(name, version string) (*repo.ChartVersion, error)
4544
// GetChartVersion returns a chart.ChartVersion from the remote repository.
4645
DownloadChart(chart *repo.ChartVersion) (*bytes.Buffer, error)
4746
}
4847

4948
type remoteChartBuilder struct {
50-
remote Remote
49+
remote Repository
5150
}
5251

5352
// NewRemoteBuilder returns a Builder capable of building a Helm
5453
// chart with a RemoteReference in the given repository.ChartRepository.
55-
func NewRemoteBuilder(repository Remote) Builder {
54+
func NewRemoteBuilder(repository Repository) Builder {
5655
return &remoteChartBuilder{
5756
remote: repository,
5857
}
@@ -83,31 +82,12 @@ func (b *remoteChartBuilder) Build(_ context.Context, ref Reference, p string, o
8382
return nil, &BuildError{Reason: ErrChartReference, Err: err}
8483
}
8584

86-
var (
87-
res *bytes.Buffer
88-
err error
89-
)
90-
91-
result := &Build{}
92-
switch b.remote.(type) {
93-
case *repository.ChartRepository:
94-
res, err = b.downloadFromRepository(b.remote.(*repository.ChartRepository), remoteRef, result, opts)
95-
if err != nil {
96-
return nil, &BuildError{Reason: ErrChartPull, Err: err}
97-
}
98-
if res == nil {
99-
return result, nil
100-
}
101-
case *repository.OCIChartRepository:
102-
res, err = b.downloadFromOCIRepository(b.remote.(*repository.OCIChartRepository), remoteRef, result, opts)
103-
if err != nil {
104-
return nil, &BuildError{Reason: ErrChartPull, Err: err}
105-
}
106-
if res == nil {
107-
return result, nil
108-
}
109-
default:
110-
return nil, &BuildError{Reason: ErrChartReference, Err: fmt.Errorf("unsupported remote type %T", b.remote)}
85+
res, result, err := b.downloadFromRepository(b.remote, remoteRef, opts)
86+
if err != nil {
87+
return nil, &BuildError{Reason: ErrChartPull, Err: err}
88+
}
89+
if res == nil {
90+
return result, nil
11191
}
11292

11393
requiresPackaging := len(opts.GetValuesFiles()) != 0 || opts.VersionMetadata != ""
@@ -152,66 +132,31 @@ func (b *remoteChartBuilder) Build(_ context.Context, ref Reference, p string, o
152132
return result, nil
153133
}
154134

155-
func (b *remoteChartBuilder) downloadFromOCIRepository(remote *repository.OCIChartRepository, remoteRef RemoteReference, buildResult *Build, opts BuildOptions) (*bytes.Buffer, error) {
156-
cv, err := remote.Get(remoteRef.Name, remoteRef.Version)
157-
if err != nil {
158-
err = fmt.Errorf("failed to get chart version for remote reference: %w", err)
159-
return nil, &BuildError{Reason: ErrChartPull, Err: err}
160-
}
161-
162-
result, shouldReturn, err := generateBuildResult(cv, opts)
163-
if err != nil {
164-
return nil, err
165-
}
166-
167-
if shouldReturn {
168-
*buildResult = *result
169-
return nil, nil
170-
}
171-
172-
// Download the package for the resolved version
173-
res, err := remote.DownloadChart(cv)
174-
if err != nil {
175-
err = fmt.Errorf("failed to download chart for remote reference: %w", err)
176-
return nil, &BuildError{Reason: ErrChartPull, Err: err}
177-
}
178-
179-
*buildResult = *result
180-
181-
return res, nil
182-
}
183-
184-
func (b *remoteChartBuilder) downloadFromRepository(remote *repository.ChartRepository, remoteRef RemoteReference, buildResult *Build, opts BuildOptions) (*bytes.Buffer, error) {
185-
if err := remote.StrategicallyLoadIndex(); err != nil {
186-
err = fmt.Errorf("could not load repository index for remote chart reference: %w", err)
187-
return nil, &BuildError{Reason: ErrChartPull, Err: err}
188-
}
189-
135+
func (b *remoteChartBuilder) downloadFromRepository(remote Repository, remoteRef RemoteReference, opts BuildOptions) (*bytes.Buffer, *Build, error) {
190136
// Get the current version for the RemoteReference
191-
cv, err := remote.Get(remoteRef.Name, remoteRef.Version)
137+
cv, err := remote.GetChartVersion(remoteRef.Name, remoteRef.Version)
192138
if err != nil {
193139
err = fmt.Errorf("failed to get chart version for remote reference: %w", err)
194-
return nil, &BuildError{Reason: ErrChartReference, Err: err}
140+
return nil, nil, &BuildError{Reason: ErrChartReference, Err: err}
195141
}
196142

197143
result, shouldReturn, err := generateBuildResult(cv, opts)
198144
if err != nil {
199-
return nil, err
145+
return nil, nil, err
200146
}
201-
*buildResult = *result
202147

203148
if shouldReturn {
204-
return nil, nil
149+
return nil, result, nil
205150
}
206151

207152
// Download the package for the resolved version
208153
res, err := remote.DownloadChart(cv)
209154
if err != nil {
210155
err = fmt.Errorf("failed to download chart for remote reference: %w", err)
211-
return nil, &BuildError{Reason: ErrChartPull, Err: err}
156+
return nil, nil, &BuildError{Reason: ErrChartPull, Err: err}
212157
}
213158

214-
return res, nil
159+
return res, result, nil
215160
}
216161

217162
// generateBuildResult returns a Build object generated from the given chart version and build options. It also returns

internal/helm/chart/dependency_manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func (dm *DependencyManager) addRemoteDependency(chart *chartWithLock, dep *helm
240240
return fmt.Errorf("failed to load index for '%s': %w", dep.Name, err)
241241
}
242242

243-
ver, err := repo.Get(dep.Name, dep.Version)
243+
ver, err := repo.GetChartVersion(dep.Name, dep.Version)
244244
if err != nil {
245245
return err
246246
}

internal/helm/repository/chart_repository.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,15 @@ func newChartRepository() *ChartRepository {
150150
}
151151
}
152152

153-
// Get returns the repo.ChartVersion for the given name, the version is expected
153+
// GetChartVersion returns the repo.ChartVersion for the given name, the version is expected
154154
// to be a semver.Constraints compatible string. If version is empty, the latest
155155
// stable version will be returned and prerelease versions will be ignored.
156-
func (r *ChartRepository) Get(name, ver string) (*repo.ChartVersion, error) {
156+
func (r *ChartRepository) GetChartVersion(name, ver string) (*repo.ChartVersion, error) {
157+
// See if we already have the index in cache or try to load it.
158+
if err := r.StrategicallyLoadIndex(); err != nil {
159+
return nil, err
160+
}
161+
157162
r.RLock()
158163
defer r.RUnlock()
159164

@@ -471,6 +476,22 @@ func (r *ChartRepository) Unload() {
471476
r.Index = nil
472477
}
473478

479+
// Clear cache the index in memory before unloading it.
480+
// It cleans up temporary files and directories created by the repository.
481+
func (r *ChartRepository) Clear() (errs []error) {
482+
if err := r.CacheIndexInMemory(); err != nil {
483+
errs = append(errs, err)
484+
}
485+
486+
r.Unload()
487+
488+
if err := r.RemoveCache(); err != nil {
489+
errs = append(errs, err)
490+
}
491+
492+
return
493+
}
494+
474495
// SetMemCache sets the cache to use for this repository.
475496
func (r *ChartRepository) SetMemCache(key string, c *cache.Cache, ttl time.Duration, rec RecordMetricsFunc) {
476497
r.IndexKey = key

internal/helm/repository/chart_repository_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ func TestChartRepository_Get(t *testing.T) {
181181
t.Run(tt.name, func(t *testing.T) {
182182
g := NewWithT(t)
183183

184-
cv, err := r.Get(tt.chartName, tt.chartVersion)
184+
cv, err := r.GetChartVersion(tt.chartName, tt.chartVersion)
185185
if tt.wantErr != "" {
186186
g.Expect(err).To(HaveOccurred())
187187
g.Expect(err.Error()).To(ContainSubstring(tt.wantErr))

internal/helm/repository/oci_chart_repository.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ func NewOCIChartRepository(repositoryURL string, chartRepoOpts ...OCIChartReposi
115115
return r, nil
116116
}
117117

118-
// Get returns the repo.ChartVersion for the given name, the version is expected
118+
// GetChartVersion returns the repo.ChartVersion for the given name, the version is expected
119119
// to be a semver.Constraints compatible string. If version is empty, the latest
120120
// stable version will be returned and prerelease versions will be ignored.
121121
// adapted from https://github.com/helm/helm/blob/49819b4ef782e80b0c7f78c30bd76b51ebb56dc8/pkg/downloader/chart_downloader.go#L162
122-
func (r *OCIChartRepository) Get(name, ver string) (*repo.ChartVersion, error) {
122+
func (r *OCIChartRepository) GetChartVersion(name, ver string) (*repo.ChartVersion, error) {
123123
// Find chart versions matching the given name.
124124
// Either in an index file or from a registry.
125125
cpURL := r.URL

internal/helm/repository/oci_chart_repository_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ func TestOCIChartRepository_Get(t *testing.T) {
183183
g.Expect(r).ToNot(BeNil())
184184

185185
chart := "podinfo"
186-
cv, err := r.Get(chart, tc.version)
186+
cv, err := r.GetChartVersion(chart, tc.version)
187187
if tc.expectedErr != "" {
188188
g.Expect(err).To(HaveOccurred())
189189
g.Expect(err.Error()).To(Equal(tc.expectedErr))

0 commit comments

Comments
 (0)