Skip to content

Commit 8b90a0a

Browse files
committed
Split Download() to smaller functions
Extract getCache() to handle getting and file from the cache, and fetch() for fetching a file from the remote to the cache. This will allow locking around the code checking and updating the cache, and much easier to maintain and understand. Signed-off-by: Nir Soffer <[email protected]>
1 parent 92537e5 commit 8b90a0a

File tree

1 file changed

+56
-30
lines changed

1 file changed

+56
-30
lines changed

pkg/downloader/downloader.go

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,20 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
229229
return res, nil
230230
}
231231

232+
res, err := getCached(ctx, localPath, remote, o)
233+
if err != nil {
234+
return nil, err
235+
}
236+
if res != nil {
237+
return res, nil
238+
}
239+
return fetch(ctx, localPath, remote, o)
240+
}
241+
242+
// getCached tries to copy the file from the cache to local path. Return result,
243+
// nil if the file was copied, nil, nil if the file is not in the cache or the
244+
// cache needs update, or nil, error on fatal error.
245+
func getCached(ctx context.Context, localPath, remote string, o options) (*Result, error) {
232246
shad := cacheDirectoryPath(o.cacheDir, remote)
233247
shadData := filepath.Join(shad, "data")
234248
shadTime := filepath.Join(shad, "time")
@@ -237,41 +251,53 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
237251
if err != nil {
238252
return nil, err
239253
}
240-
if _, err := os.Stat(shadData); err == nil {
241-
logrus.Debugf("file %q is cached as %q", localPath, shadData)
242-
useCache := true
243-
if _, err := os.Stat(shadDigest); err == nil {
244-
logrus.Debugf("Comparing digest %q with the cached digest file %q, not computing the actual digest of %q",
245-
o.expectedDigest, shadDigest, shadData)
246-
if err := validateCachedDigest(shadDigest, o.expectedDigest); err != nil {
247-
return nil, err
248-
}
249-
if err := copyLocal(ctx, localPath, shadData, ext, o.decompress, "", ""); err != nil {
254+
if _, err := os.Stat(shadData); err != nil {
255+
return nil, nil
256+
}
257+
ext := path.Ext(remote)
258+
logrus.Debugf("file %q is cached as %q", localPath, shadData)
259+
if _, err := os.Stat(shadDigest); err == nil {
260+
logrus.Debugf("Comparing digest %q with the cached digest file %q, not computing the actual digest of %q",
261+
o.expectedDigest, shadDigest, shadData)
262+
if err := validateCachedDigest(shadDigest, o.expectedDigest); err != nil {
263+
return nil, err
264+
}
265+
if err := copyLocal(ctx, localPath, shadData, ext, o.decompress, "", ""); err != nil {
266+
return nil, err
267+
}
268+
} else {
269+
if match, lmCached, lmRemote, err := matchLastModified(ctx, shadTime, remote); err != nil {
270+
logrus.WithError(err).Info("Failed to retrieve last-modified for cached digest-less image; using cached image.")
271+
} else if match {
272+
if err := copyLocal(ctx, localPath, shadData, ext, o.decompress, o.description, o.expectedDigest); err != nil {
250273
return nil, err
251274
}
252275
} else {
253-
if match, lmCached, lmRemote, err := matchLastModified(ctx, shadTime, remote); err != nil {
254-
logrus.WithError(err).Info("Failed to retrieve last-modified for cached digest-less image; using cached image.")
255-
} else if match {
256-
if err := copyLocal(ctx, localPath, shadData, ext, o.decompress, o.description, o.expectedDigest); err != nil {
257-
return nil, err
258-
}
259-
} else {
260-
logrus.Infof("Re-downloading digest-less image: last-modified mismatch (cached: %q, remote: %q)", lmCached, lmRemote)
261-
useCache = false
262-
}
263-
}
264-
if useCache {
265-
res := &Result{
266-
Status: StatusUsedCache,
267-
CachePath: shadData,
268-
LastModified: readTime(shadTime),
269-
ContentType: readFile(shadType),
270-
ValidatedDigest: o.expectedDigest != "",
271-
}
272-
return res, nil
276+
logrus.Infof("Re-downloading digest-less image: last-modified mismatch (cached: %q, remote: %q)", lmCached, lmRemote)
277+
return nil, nil
273278
}
274279
}
280+
res := &Result{
281+
Status: StatusUsedCache,
282+
CachePath: shadData,
283+
LastModified: readTime(shadTime),
284+
ContentType: readFile(shadType),
285+
ValidatedDigest: o.expectedDigest != "",
286+
}
287+
return res, nil
288+
}
289+
290+
// fetch downloads remote to the cache and copy the cached file to local path.
291+
func fetch(ctx context.Context, localPath, remote string, o options) (*Result, error) {
292+
shad := cacheDirectoryPath(o.cacheDir, remote)
293+
shadData := filepath.Join(shad, "data")
294+
shadTime := filepath.Join(shad, "time")
295+
shadType := filepath.Join(shad, "type")
296+
shadDigest, err := cacheDigestPath(shad, o.expectedDigest)
297+
if err != nil {
298+
return nil, err
299+
}
300+
ext := path.Ext(remote)
275301
if err := os.MkdirAll(shad, 0o700); err != nil {
276302
return nil, err
277303
}

0 commit comments

Comments
 (0)