Skip to content

Commit 0b75217

Browse files
committed
storage: only store relative path in artifact
As the storage base directory is determined during runtime, and artifacts may live longer than that if they are e.g. stored in a persistent volume but the mount path configuration changes.
1 parent f8c4bd3 commit 0b75217

File tree

4 files changed

+55
-34
lines changed

4 files changed

+55
-34
lines changed

api/v1alpha1/source.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package v1alpha1
22

3-
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3+
import (
4+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5+
)
46

57
// Source interface must be supported by all API types.
68
// +k8s:deepcopy-gen=false

controllers/helmchart_controller.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ func (r *HelmChartReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, opts
188188

189189
func (r *HelmChartReconciler) reconcileFromHelmRepository(ctx context.Context,
190190
repository sourcev1.HelmRepository, chart sourcev1.HelmChart) (sourcev1.HelmChart, error) {
191-
cv, err := helm.GetDownloadableChartVersionFromIndex(repository.Status.Artifact.Path, chart.Spec.Chart, chart.Spec.Version)
191+
cv, err := helm.GetDownloadableChartVersionFromIndex(r.Storage.LocalPath(*repository.GetArtifact()),
192+
chart.Spec.Chart, chart.Spec.Version)
192193
if err != nil {
193194
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPullFailedReason, err.Error()), err
194195
}
@@ -333,7 +334,7 @@ func (r *HelmChartReconciler) reconcileFromGitRepository(ctx context.Context,
333334
defer os.RemoveAll(tmpDir)
334335

335336
// open file
336-
f, err := os.Open(repository.GetArtifact().Path)
337+
f, err := os.Open(r.Storage.LocalPath(*repository.GetArtifact()))
337338
if err != nil {
338339
err = fmt.Errorf("artifact open error: %w", err)
339340
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
@@ -384,7 +385,7 @@ func (r *HelmChartReconciler) reconcileFromGitRepository(ctx context.Context,
384385

385386
// package chart
386387
pkg := action.NewPackage()
387-
pkg.Destination = filepath.Dir(artifact.Path)
388+
pkg.Destination = filepath.Dir(r.Storage.LocalPath(artifact))
388389
_, err = pkg.Run(chartPath, nil)
389390
if err != nil {
390391
err = fmt.Errorf("chart package error: %w", err)

controllers/storage.go

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func NewStorage(basePath string, hostname string, timeout time.Duration) (*Stora
6969
}, nil
7070
}
7171

72-
// ArtifactFor returns an artifact for the given Kubernetes object
72+
// ArtifactFor returns an artifact for the v1alpha1.Source.
7373
func (s *Storage) ArtifactFor(kind string, metadata metav1.Object, fileName, revision string) sourcev1.Artifact {
7474
path := sourcev1.ArtifactPath(kind, metadata.GetNamespace(), metadata.GetName(), fileName)
7575
localPath := filepath.Join(s.BasePath, path)
@@ -83,29 +83,30 @@ func (s *Storage) ArtifactFor(kind string, metadata metav1.Object, fileName, rev
8383
}
8484
}
8585

86-
// MkdirAll calls os.MkdirAll for the given artifact base dir
86+
// MkdirAll calls os.MkdirAll for the given v1alpha1.Artifact base dir.
8787
func (s *Storage) MkdirAll(artifact sourcev1.Artifact) error {
88-
dir := filepath.Dir(artifact.Path)
88+
dir := filepath.Dir(s.LocalPath(artifact))
8989
return os.MkdirAll(dir, 0777)
9090
}
9191

92-
// RemoveAll calls os.RemoveAll for the given artifact base dir
92+
// RemoveAll calls os.RemoveAll for the given v1alpha1.Artifact base dir.
9393
func (s *Storage) RemoveAll(artifact sourcev1.Artifact) error {
94-
dir := filepath.Dir(artifact.Path)
94+
dir := filepath.Dir(s.LocalPath(artifact))
9595
return os.RemoveAll(dir)
9696
}
9797

9898
// RemoveAllButCurrent removes all files for the given artifact base dir excluding the current one
9999
func (s *Storage) RemoveAllButCurrent(artifact sourcev1.Artifact) error {
100-
dir := filepath.Dir(artifact.Path)
100+
localPath := s.LocalPath(artifact)
101+
dir := filepath.Dir(localPath)
101102
var errors []string
102103
_ = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
103104
if err != nil {
104105
errors = append(errors, err.Error())
105106
return nil
106107
}
107108

108-
if path != artifact.Path && !info.IsDir() && info.Mode()&os.ModeSymlink != os.ModeSymlink {
109+
if path != localPath && !info.IsDir() && info.Mode()&os.ModeSymlink != os.ModeSymlink {
109110
if err := os.Remove(path); err != nil {
110111
errors = append(errors, info.Name())
111112
}
@@ -122,7 +123,7 @@ func (s *Storage) RemoveAllButCurrent(artifact sourcev1.Artifact) error {
122123
// ArtifactExist returns a boolean indicating whether the artifact exists in storage and is a
123124
// regular file.
124125
func (s *Storage) ArtifactExist(artifact sourcev1.Artifact) bool {
125-
fi, err := os.Lstat(artifact.Path)
126+
fi, err := os.Lstat(s.LocalPath(artifact))
126127
if err != nil {
127128
return false
128129
}
@@ -143,7 +144,7 @@ func (s *Storage) Archive(artifact sourcev1.Artifact, dir string, spec sourcev1.
143144

144145
matcher := gitignore.NewMatcher(ps)
145146

146-
gzFile, err := os.Create(artifact.Path)
147+
gzFile, err := os.Create(s.LocalPath(artifact))
147148
if err != nil {
148149
return err
149150
}
@@ -204,28 +205,30 @@ func (s *Storage) Archive(artifact sourcev1.Artifact, dir string, spec sourcev1.
204205

205206
// WriteFile writes the given bytes to the artifact path if the checksum differs
206207
func (s *Storage) WriteFile(artifact sourcev1.Artifact, data []byte) error {
208+
localPath := s.LocalPath(artifact)
207209
sum := s.Checksum(data)
208-
if file, err := os.Stat(artifact.Path); !os.IsNotExist(err) && !file.IsDir() {
209-
if fb, err := ioutil.ReadFile(artifact.Path); err == nil && sum == s.Checksum(fb) {
210+
if file, err := os.Stat(localPath); !os.IsNotExist(err) && !file.IsDir() {
211+
if fb, err := ioutil.ReadFile(localPath); err == nil && sum == s.Checksum(fb) {
210212
return nil
211213
}
212214
}
213215

214-
return ioutil.WriteFile(artifact.Path, data, 0644)
216+
return ioutil.WriteFile(localPath, data, 0644)
215217
}
216218

217219
// Symlink creates or updates a symbolic link for the given artifact
218-
// and returns the URL for the symlink
220+
// and returns the URL for the symlink.
219221
func (s *Storage) Symlink(artifact sourcev1.Artifact, linkName string) (string, error) {
220-
dir := filepath.Dir(artifact.Path)
222+
localPath := s.LocalPath(artifact)
223+
dir := filepath.Dir(localPath)
221224
link := filepath.Join(dir, linkName)
222225
tmpLink := link + ".tmp"
223226

224227
if err := os.Remove(tmpLink); err != nil && !os.IsNotExist(err) {
225228
return "", err
226229
}
227230

228-
if err := os.Symlink(artifact.Path, tmpLink); err != nil {
231+
if err := os.Symlink(localPath, tmpLink); err != nil {
229232
return "", err
230233
}
231234

@@ -245,11 +248,20 @@ func (s *Storage) Checksum(b []byte) string {
245248

246249
// Lock creates a file lock for the given artifact
247250
func (s *Storage) Lock(artifact sourcev1.Artifact) (unlock func(), err error) {
248-
lockFile := artifact.Path + ".lock"
251+
lockFile := s.LocalPath(artifact) + ".lock"
249252
mutex := lockedfile.MutexAt(lockFile)
250253
return mutex.Lock()
251254
}
252255

256+
// LocalPath returns the local path of the given artifact (that is: relative to
257+
// the Storage.BasePath).
258+
func (s *Storage) LocalPath(artifact sourcev1.Artifact) string {
259+
if artifact.Path == "" {
260+
return ""
261+
}
262+
return filepath.Join(s.BasePath, artifact.Path)
263+
}
264+
253265
func getPatterns(reader io.Reader, path []string) []gitignore.Pattern {
254266
var ps []gitignore.Pattern
255267
scanner := bufio.NewScanner(reader)

controllers/storage_test.go

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ func walkTar(tarFile string, match string) (bool, error) {
113113
return false, nil
114114
}
115115

116-
func testPatterns(t *testing.T, artifact sourcev1.Artifact, table ignoreMap) {
116+
func testPatterns(t *testing.T, dir string, artifact sourcev1.Artifact, table ignoreMap) {
117117
for name, expected := range table {
118-
res, err := walkTar(artifact.Path, name)
118+
res, err := walkTar(filepath.Join(dir, artifact.Path), name)
119119
if err != nil {
120120
t.Fatalf("while reading tarball: %v", err)
121121
}
@@ -130,13 +130,7 @@ func testPatterns(t *testing.T, artifact sourcev1.Artifact, table ignoreMap) {
130130
}
131131
}
132132

133-
func createArchive(t *testing.T, filenames []string, sourceIgnore string, spec sourcev1.GitRepositorySpec) sourcev1.Artifact {
134-
dir, err := createStoragePath()
135-
if err != nil {
136-
t.Fatal(err)
137-
}
138-
t.Cleanup(cleanupStoragePath(dir))
139-
133+
func createArchive(t *testing.T, dir string, filenames []string, sourceIgnore string, spec sourcev1.GitRepositorySpec) sourcev1.Artifact {
140134
storage, err := NewStorage(dir, "hostname", time.Minute)
141135
if err != nil {
142136
t.Fatalf("Error while bootstrapping storage: %v", err)
@@ -197,7 +191,13 @@ func TestArchiveBasic(t *testing.T) {
197191
".gitignore": false,
198192
}
199193

200-
testPatterns(t, createArchive(t, []string{"README.md", ".gitignore"}, "", sourcev1.GitRepositorySpec{}), table)
194+
dir, err := createStoragePath()
195+
if err != nil {
196+
t.Fatal(err)
197+
}
198+
t.Cleanup(cleanupStoragePath(dir))
199+
200+
testPatterns(t, dir, createArchive(t, dir, []string{"README.md", ".gitignore"}, "", sourcev1.GitRepositorySpec{}), table)
201201
}
202202

203203
func TestArchiveIgnore(t *testing.T) {
@@ -221,8 +221,14 @@ func TestArchiveIgnore(t *testing.T) {
221221
table[item] = false
222222
}
223223

224+
dir, err := createStoragePath()
225+
if err != nil {
226+
t.Fatal(err)
227+
}
228+
t.Cleanup(cleanupStoragePath(dir))
229+
224230
t.Run("automatically ignored files", func(t *testing.T) {
225-
testPatterns(t, createArchive(t, filenames, "", sourcev1.GitRepositorySpec{}), table)
231+
testPatterns(t, dir, createArchive(t, dir, filenames, "", sourcev1.GitRepositorySpec{}), table)
226232
})
227233

228234
table = ignoreMap{}
@@ -231,15 +237,15 @@ func TestArchiveIgnore(t *testing.T) {
231237
}
232238

233239
t.Run("only vcs ignored files", func(t *testing.T) {
234-
testPatterns(t, createArchive(t, filenames, "", sourcev1.GitRepositorySpec{Ignore: stringPtr("")}), table)
240+
testPatterns(t, dir, createArchive(t, dir, filenames, "", sourcev1.GitRepositorySpec{Ignore: stringPtr("")}), table)
235241
})
236242

237243
filenames = append(filenames, "test.txt")
238244
table["test.txt"] = false
239245
sourceIgnoreFile := "*.txt"
240246

241247
t.Run("sourceignore injected via CRD", func(t *testing.T) {
242-
testPatterns(t, createArchive(t, filenames, "", sourcev1.GitRepositorySpec{Ignore: stringPtr(sourceIgnoreFile)}), table)
248+
testPatterns(t, dir, createArchive(t, dir, filenames, "", sourcev1.GitRepositorySpec{Ignore: stringPtr(sourceIgnoreFile)}), table)
243249
})
244250

245251
table = ignoreMap{}
@@ -248,7 +254,7 @@ func TestArchiveIgnore(t *testing.T) {
248254
}
249255

250256
t.Run("sourceignore injected via filename", func(t *testing.T) {
251-
testPatterns(t, createArchive(t, filenames, sourceIgnoreFile, sourcev1.GitRepositorySpec{}), table)
257+
testPatterns(t, dir, createArchive(t, dir, filenames, sourceIgnoreFile, sourcev1.GitRepositorySpec{}), table)
252258
})
253259
}
254260

0 commit comments

Comments
 (0)