Skip to content

Commit beaa734

Browse files
committed
Add Cached function for files already Download
This will return any files already in the cache, with valid digest, but not download any new ones. Signed-off-by: Anders F Björklund <[email protected]>
1 parent 50db1b7 commit beaa734

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

pkg/downloader/downloader.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,52 @@ func Download(local, remote string, opts ...Opt) (*Result, error) {
242242
return res, nil
243243
}
244244

245+
// Cached checks if the remote resource is in the cache.
246+
//
247+
// Download caches the remote resource if WithCache or WithCacheDir option is specified.
248+
// Local files are not cached.
249+
//
250+
// When the cache path already exists, Cached returns Result with StatusUsedCache.
251+
func Cached(remote string, opts ...Opt) (*Result, error) {
252+
var o options
253+
for _, f := range opts {
254+
if err := f(&o); err != nil {
255+
return nil, err
256+
}
257+
}
258+
if o.cacheDir == "" {
259+
return nil, fmt.Errorf("caching-only mode requires the cache directory to be specified")
260+
}
261+
if IsLocal(remote) {
262+
return nil, fmt.Errorf("local files are not cached")
263+
}
264+
265+
shad := cacheDirectoryPath(o.cacheDir, remote)
266+
shadData := filepath.Join(shad, "data")
267+
shadDigest, err := cacheDigestPath(shad, o.expectedDigest)
268+
if err != nil {
269+
return nil, err
270+
}
271+
if _, err := os.Stat(shadData); err != nil {
272+
return nil, err
273+
}
274+
if _, err := os.Stat(shadDigest); err != nil {
275+
if err := validateCachedDigest(shadDigest, o.expectedDigest); err != nil {
276+
return nil, err
277+
}
278+
} else {
279+
if err := validateLocalFileDigest(shadData, o.expectedDigest); err != nil {
280+
return nil, err
281+
}
282+
}
283+
res := &Result{
284+
Status: StatusUsedCache,
285+
CachePath: shadData,
286+
ValidatedDigest: o.expectedDigest != "",
287+
}
288+
return res, nil
289+
}
290+
245291
// cacheDirectoryPath returns the cache subdirectory path.
246292
// - "url" file contains the url
247293
// - "data" file contains the data

pkg/downloader/downloader_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os/exec"
66
"path/filepath"
77
"runtime"
8+
"strings"
89
"testing"
910

1011
"github.com/opencontainers/go-digest"
@@ -87,6 +88,24 @@ func TestDownloadRemote(t *testing.T) {
8788
assert.NilError(t, err)
8889
assert.Equal(t, StatusUsedCache, r.Status)
8990
})
91+
t.Run("cached", func(t *testing.T) {
92+
_, err := Cached(dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest))
93+
assert.ErrorContains(t, err, "cache directory to be specified")
94+
95+
cacheDir := filepath.Join(t.TempDir(), "cache")
96+
r, err := Download("", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
97+
assert.NilError(t, err)
98+
assert.Equal(t, StatusDownloaded, r.Status)
99+
100+
r, err = Cached(dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
101+
assert.NilError(t, err)
102+
assert.Equal(t, StatusUsedCache, r.Status)
103+
assert.Assert(t, strings.HasPrefix(r.CachePath, cacheDir), "expected %s to be in %s", r.CachePath, cacheDir)
104+
105+
wrongDigest := digest.Digest("sha256:8313944efb4f38570c689813f288058b674ea6c487017a5a4738dc674b65f9d9")
106+
_, err = Cached(dummyRemoteFileURL, WithExpectedDigest(wrongDigest), WithCacheDir(cacheDir))
107+
assert.ErrorContains(t, err, "expected digest")
108+
})
90109
}
91110

92111
func TestDownloadLocal(t *testing.T) {
@@ -129,6 +148,15 @@ func TestDownloadLocal(t *testing.T) {
129148
os.Remove(localTestFile)
130149
})
131150

151+
t.Run("cached", func(t *testing.T) {
152+
localFile := filepath.Join(t.TempDir(), "test-file")
153+
os.Create(localFile)
154+
testLocalFileURL := "file://" + localFile
155+
156+
cacheDir := filepath.Join(t.TempDir(), "cache")
157+
_, err := Cached(testLocalFileURL, WithCacheDir(cacheDir))
158+
assert.ErrorContains(t, err, "not cached")
159+
})
132160
}
133161

134162
func TestDownloadCompressed(t *testing.T) {

0 commit comments

Comments
 (0)