@@ -229,6 +229,20 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
229
229
return res , nil
230
230
}
231
231
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 ) {
232
246
shad := cacheDirectoryPath (o .cacheDir , remote )
233
247
shadData := filepath .Join (shad , "data" )
234
248
shadTime := filepath .Join (shad , "time" )
@@ -237,41 +251,53 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
237
251
if err != nil {
238
252
return nil , err
239
253
}
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 {
250
273
return nil , err
251
274
}
252
275
} 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
273
278
}
274
279
}
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 )
275
301
if err := os .MkdirAll (shad , 0o700 ); err != nil {
276
302
return nil , err
277
303
}
0 commit comments