Skip to content

Commit 22aa98e

Browse files
authored
Merge pull request #1407 from afbjorklund/download-description
Show a user-readable description of the download
2 parents 9491b7f + ce34ce1 commit 22aa98e

File tree

5 files changed

+45
-36
lines changed

5 files changed

+45
-36
lines changed

pkg/downloader/downloader.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type Result struct {
3838

3939
type options struct {
4040
cacheDir string // default: empty (disables caching)
41+
description string // default: url
4142
expectedDigest digest.Digest
4243
}
4344

@@ -64,6 +65,14 @@ func WithCacheDir(cacheDir string) Opt {
6465
}
6566
}
6667

68+
// WithDecription adds a user description of the download.
69+
func WithDescription(description string) Opt {
70+
return func(o *options) error {
71+
o.description = description
72+
return nil
73+
}
74+
}
75+
6776
// WithExpectedDigest is used to validate the downloaded file against the expected digest.
6877
//
6978
// The digest is not verified in the following cases:
@@ -134,7 +143,7 @@ func Download(local, remote string, opts ...Opt) (*Result, error) {
134143
}
135144

136145
if IsLocal(remote) {
137-
if err := copyLocal(localPath, remote, o.expectedDigest); err != nil {
146+
if err := copyLocal(localPath, remote, o.description, o.expectedDigest); err != nil {
138147
return nil, err
139148
}
140149
res := &Result{
@@ -145,7 +154,7 @@ func Download(local, remote string, opts ...Opt) (*Result, error) {
145154
}
146155

147156
if o.cacheDir == "" {
148-
if err := downloadHTTP(localPath, remote, o.expectedDigest); err != nil {
157+
if err := downloadHTTP(localPath, remote, o.description, o.expectedDigest); err != nil {
149158
return nil, err
150159
}
151160
res := &Result{
@@ -174,11 +183,11 @@ func Download(local, remote string, opts ...Opt) (*Result, error) {
174183
if o.expectedDigest.String() != shadDigestS {
175184
return nil, fmt.Errorf("expected digest %q does not match the cached digest %q", o.expectedDigest.String(), shadDigestS)
176185
}
177-
if err := copyLocal(localPath, shadData, ""); err != nil {
186+
if err := copyLocal(localPath, shadData, "", ""); err != nil {
178187
return nil, err
179188
}
180189
} else {
181-
if err := copyLocal(localPath, shadData, o.expectedDigest); err != nil {
190+
if err := copyLocal(localPath, shadData, o.description, o.expectedDigest); err != nil {
182191
return nil, err
183192
}
184193
}
@@ -199,11 +208,11 @@ func Download(local, remote string, opts ...Opt) (*Result, error) {
199208
if err := os.WriteFile(shadURL, []byte(remote), 0644); err != nil {
200209
return nil, err
201210
}
202-
if err := downloadHTTP(shadData, remote, o.expectedDigest); err != nil {
211+
if err := downloadHTTP(shadData, remote, o.description, o.expectedDigest); err != nil {
203212
return nil, err
204213
}
205214
// no need to pass the digest to copyLocal(), as we already verified the digest
206-
if err := copyLocal(localPath, shadData, ""); err != nil {
215+
if err := copyLocal(localPath, shadData, "", ""); err != nil {
207216
return nil, err
208217
}
209218
if shadDigest != "" && o.expectedDigest != "" {
@@ -244,7 +253,7 @@ func canonicalLocalPath(s string) (string, error) {
244253
return localpathutil.Expand(s)
245254
}
246255

247-
func copyLocal(dst, src string, expectedDigest digest.Digest) error {
256+
func copyLocal(dst, src string, description string, expectedDigest digest.Digest) error {
248257
srcPath, err := canonicalLocalPath(src)
249258
if err != nil {
250259
return err
@@ -262,6 +271,9 @@ func copyLocal(dst, src string, expectedDigest digest.Digest) error {
262271
if err != nil {
263272
return err
264273
}
274+
if description != "" {
275+
// TODO: progress bar for copy
276+
}
265277
return fs.CopyFile(dstPath, srcPath)
266278
}
267279

@@ -316,7 +328,7 @@ func createBar(size int64) (*pb.ProgressBar, error) {
316328
return bar, nil
317329
}
318330

319-
func downloadHTTP(localPath, url string, expectedDigest digest.Digest) error {
331+
func downloadHTTP(localPath, url string, description string, expectedDigest digest.Digest) error {
320332
if localPath == "" {
321333
return fmt.Errorf("downloadHTTP: got empty localPath")
322334
}
@@ -357,6 +369,12 @@ func downloadHTTP(localPath, url string, expectedDigest digest.Digest) error {
357369
}
358370
multiWriter := io.MultiWriter(writers...)
359371

372+
if !HideProgress {
373+
if description == "" {
374+
description = url
375+
}
376+
fmt.Printf("Downloading %s\n", description)
377+
}
360378
bar.Start()
361379
if _, err := io.Copy(multiWriter, bar.NewProxyReader(resp.Body)); err != nil {
362380
return err

pkg/fileutils/download.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,27 @@ package fileutils
22

33
import (
44
"fmt"
5+
"path"
56

67
"github.com/lima-vm/lima/pkg/downloader"
78
"github.com/lima-vm/lima/pkg/limayaml"
89
"github.com/sirupsen/logrus"
910
)
1011

11-
func DownloadFile(dest string, f limayaml.File, description string, expectedArch limayaml.Arch) error {
12+
// DownloadFile downloads a file to the cache, optionally copying it to the destination. Returns path in cache.
13+
func DownloadFile(dest string, f limayaml.File, description string, expectedArch limayaml.Arch) (string, error) {
1214
if f.Arch != expectedArch {
13-
return fmt.Errorf("unsupported arch: %q", f.Arch)
15+
return "", fmt.Errorf("unsupported arch: %q", f.Arch)
1416
}
15-
logrus.WithField("digest", f.Digest).Infof("Attempting to download %s from %q", description, f.Location)
17+
fields := logrus.Fields{"location": f.Location, "arch": f.Arch, "digest": f.Digest}
18+
logrus.WithFields(fields).Infof("Attempting to download %s", description)
1619
res, err := downloader.Download(dest, f.Location,
1720
downloader.WithCache(),
21+
downloader.WithDescription(fmt.Sprintf("%s (%s)", description, path.Base(f.Location))),
1822
downloader.WithExpectedDigest(f.Digest),
1923
)
2024
if err != nil {
21-
return fmt.Errorf("failed to download %q: %w", f.Location, err)
25+
return "", fmt.Errorf("failed to download %q: %w", f.Location, err)
2226
}
2327
logrus.Debugf("res.ValidatedDigest=%v", res.ValidatedDigest)
2428
switch res.Status {
@@ -29,5 +33,5 @@ func DownloadFile(dest string, f limayaml.File, description string, expectedArch
2933
default:
3034
logrus.Warnf("Unexpected result from downloader.Download(): %+v", res)
3135
}
32-
return nil
36+
return res.CachePath, nil
3337
}

pkg/qemu/qemu.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ func EnsureDisk(cfg Config) error {
5050
var ensuredBaseDisk bool
5151
errs := make([]error, len(cfg.LimaYAML.Images))
5252
for i, f := range cfg.LimaYAML.Images {
53-
if err := fileutils.DownloadFile(baseDisk, f.File, "the image", *cfg.LimaYAML.Arch); err != nil {
53+
if _, err := fileutils.DownloadFile(baseDisk, f.File, "the image", *cfg.LimaYAML.Arch); err != nil {
5454
errs[i] = err
5555
continue
5656
}
5757
if f.Kernel != nil {
58-
if err := fileutils.DownloadFile(kernel, f.Kernel.File, "the kernel", *cfg.LimaYAML.Arch); err != nil {
58+
if _, err := fileutils.DownloadFile(kernel, f.Kernel.File, "the kernel", *cfg.LimaYAML.Arch); err != nil {
5959
errs[i] = err
6060
continue
6161
}
@@ -67,7 +67,7 @@ func EnsureDisk(cfg Config) error {
6767
}
6868
}
6969
if f.Initrd != nil {
70-
if err := fileutils.DownloadFile(initrd, *f.Initrd, "the initrd", *cfg.LimaYAML.Arch); err != nil {
70+
if _, err := fileutils.DownloadFile(initrd, *f.Initrd, "the initrd", *cfg.LimaYAML.Arch); err != nil {
7171
errs[i] = err
7272
continue
7373
}

pkg/start/start.go

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/lima-vm/lima/pkg/driverutil"
1717

1818
"github.com/lima-vm/lima/pkg/downloader"
19+
"github.com/lima-vm/lima/pkg/fileutils"
1920
hostagentevents "github.com/lima-vm/lima/pkg/hostagent/events"
2021
"github.com/lima-vm/lima/pkg/limayaml"
2122
"github.com/lima-vm/lima/pkg/store"
@@ -37,33 +38,19 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML) (string, error) {
3738
}
3839

3940
errs := make([]error, len(y.Containerd.Archives))
40-
for i := range y.Containerd.Archives {
41-
f := &y.Containerd.Archives[i]
42-
if f.Arch != *y.Arch {
43-
errs[i] = fmt.Errorf("unsupported arch: %q", f.Arch)
44-
continue
45-
}
46-
logrus.WithField("digest", f.Digest).Infof("Attempting to download the nerdctl archive from %q", f.Location)
47-
res, err := downloader.Download("", f.Location, downloader.WithCache(), downloader.WithExpectedDigest(f.Digest))
41+
for i, f := range y.Containerd.Archives {
42+
path, err := fileutils.DownloadFile("", f, "the nerdctl archive", *y.Arch)
4843
if err != nil {
49-
errs[i] = fmt.Errorf("failed to download %q: %w", f.Location, err)
44+
errs[i] = err
5045
continue
5146
}
52-
switch res.Status {
53-
case downloader.StatusDownloaded:
54-
logrus.Infof("Downloaded the nerdctl archive from %q", f.Location)
55-
case downloader.StatusUsedCache:
56-
logrus.Infof("Using cache %q", res.CachePath)
57-
default:
58-
logrus.Warnf("Unexpected result from downloader.Download(): %+v", res)
59-
}
60-
if res.CachePath == "" {
47+
if path == "" {
6148
if downloader.IsLocal(f.Location) {
6249
return f.Location, nil
6350
}
6451
return "", fmt.Errorf("cache did not contain %q", f.Location)
6552
}
66-
return res.CachePath, nil
53+
return path, nil
6754
}
6855

6956
return "", fmt.Errorf("failed to download the nerdctl archive, attempted %d candidates, errors=%v",

pkg/vz/disk.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func EnsureDisk(driver *driver.BaseDriver) error {
2929
var ensuredBaseDisk bool
3030
errs := make([]error, len(driver.Yaml.Images))
3131
for i, f := range driver.Yaml.Images {
32-
if err := fileutils.DownloadFile(baseDisk, f.File, "the image", *driver.Yaml.Arch); err != nil {
32+
if _, err := fileutils.DownloadFile(baseDisk, f.File, "the image", *driver.Yaml.Arch); err != nil {
3333
errs[i] = err
3434
continue
3535
}

0 commit comments

Comments
 (0)