Repository: lima-vm/lima
Pull request #2130 (2024-01-11 17:47:10)

Enable noctx linter and fix up issues
This PR enables [`noctx`](https://github.com/sonatard/noctx) linter in golangci-lint's config. The linter requires the usage of HTTP requests with context for cancelation long-running requests. 


Patch:
diff --git a/.golangci.yml b/.golangci.yml
index 19eab934..366ba4ca 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -64,7 +64,7 @@ linters:
   # - maligned
   # - nestif
   # - nlreturn
-  # - noctx
+  - noctx
   - nolintlint
   # - rowserrcheck
   # - scopelint
diff --git a/cmd/limactl/start.go b/cmd/limactl/start.go
index e8614acc..1eb0b561 100644
--- a/cmd/limactl/start.go
+++ b/cmd/limactl/start.go
@@ -146,7 +146,11 @@ func loadOrCreateInstance(cmd *cobra.Command, args []string, createOnly bool) (*
 			}
 		}
 		logrus.Debugf("interpreting argument %q as a http url for instance %q", arg, st.instName)
-		resp, err := http.Get(arg)
+		req, err := http.NewRequestWithContext(cmd.Context(), http.MethodGet, arg, http.NoBody)
+		if err != nil {
+			return nil, err
+		}
+		resp, err := http.DefaultClient.Do(req)
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/downloader/downloader.go b/pkg/downloader/downloader.go
index 609263fb..016698d6 100644
--- a/pkg/downloader/downloader.go
+++ b/pkg/downloader/downloader.go
@@ -2,6 +2,7 @@ package downloader
 
 import (
 	"bytes"
+	"context"
 	"crypto/sha256"
 	"errors"
 	"fmt"
@@ -15,6 +16,7 @@ import (
 
 	"github.com/cheggaaa/pb/v3"
 	"github.com/containerd/continuity/fs"
+	"github.com/lima-vm/lima/pkg/httpclientutil"
 	"github.com/lima-vm/lima/pkg/localpathutil"
 	"github.com/lima-vm/lima/pkg/progressbar"
 	"github.com/opencontainers/go-digest"
@@ -125,7 +127,7 @@ func WithExpectedDigest(expectedDigest digest.Digest) Opt {
 // (So, the local path cannot be set to /dev/null for "caching only" mode.)
 //
 // The local path can be an empty string for "caching only" mode.
-func Download(local, remote string, opts ...Opt) (*Result, error) {
+func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result, error) {
 	var o options
 	for _, f := range opts {
 		if err := f(&o); err != nil {
@@ -173,7 +175,7 @@ func Download(local, remote string, opts ...Opt) (*Result, error) {
 	}
 
 	if o.cacheDir == "" {
-		if err := downloadHTTP(localPath, remote, o.description, o.expectedDigest); err != nil {
+		if err := downloadHTTP(ctx, localPath, remote, o.description, o.expectedDigest); err != nil {
 			return nil, err
 		}
 		res := &Result{
@@ -222,7 +224,7 @@ func Download(local, remote string, opts ...Opt) (*Result, error) {
 	if err := os.WriteFile(shadURL, []byte(remote), 0o644); err != nil {
 		return nil, err
 	}
-	if err := downloadHTTP(shadData, remote, o.description, o.expectedDigest); err != nil {
+	if err := downloadHTTP(ctx, shadData, remote, o.description, o.expectedDigest); err != nil {
 		return nil, err
 	}
 	// no need to pass the digest to copyLocal(), as we already verified the digest
@@ -472,7 +474,7 @@ func validateLocalFileDigest(localPath string, expectedDigest digest.Digest) err
 	return nil
 }
 
-func downloadHTTP(localPath, url, description string, expectedDigest digest.Digest) error {
+func downloadHTTP(ctx context.Context, localPath, url, description string, expectedDigest digest.Digest) error {
 	if localPath == "" {
 		return fmt.Errorf("downloadHTTP: got empty localPath")
 	}
@@ -487,14 +489,11 @@ func downloadHTTP(localPath, url, description string, expectedDigest digest.Dige
 	}
 	defer fileWriter.Close()
 
-	resp, err := http.Get(url)
+	resp, err := httpclientutil.Get(ctx, http.DefaultClient, url)
 	if err != nil {
 		return err
 	}
 	defer resp.Body.Close()
-	if resp.StatusCode != http.StatusOK {
-		return fmt.Errorf("expected HTTP status %d, got %s", http.StatusOK, resp.Status)
-	}
 	bar, err := progressbar.New(resp.ContentLength)
 	if err != nil {
 		return err
diff --git a/pkg/driver/driver.go b/pkg/driver/driver.go
index d6049c7f..086ca6e8 100644
--- a/pkg/driver/driver.go
+++ b/pkg/driver/driver.go
@@ -26,7 +26,7 @@ type Driver interface {
 	Initialize(_ context.Context) error
 
 	// CreateDisk returns error if the current driver fails in creating disk
-	CreateDisk() error
+	CreateDisk(_ context.Context) error
 
 	// Start is used for booting the vm using driver instance
 	// It returns a chan error on successful boot
@@ -90,7 +90,7 @@ func (d *BaseDriver) Initialize(_ context.Context) error {
 	return nil
 }
 
-func (d *BaseDriver) CreateDisk() error {
+func (d *BaseDriver) CreateDisk(_ context.Context) error {
 	return nil
 }
 
diff --git a/pkg/fileutils/download.go b/pkg/fileutils/download.go
index 07a9ece0..97bf6d30 100644
--- a/pkg/fileutils/download.go
+++ b/pkg/fileutils/download.go
@@ -1,6 +1,7 @@
 package fileutils
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"path"
@@ -14,13 +15,13 @@ import (
 var ErrSkipped = errors.New("skipped to download")
 
 // DownloadFile downloads a file to the cache, optionally copying it to the destination. Returns path in cache.
-func DownloadFile(dest string, f limayaml.File, decompress bool, description string, expectedArch limayaml.Arch) (string, error) {
+func DownloadFile(ctx context.Context, dest string, f limayaml.File, decompress bool, description string, expectedArch limayaml.Arch) (string, error) {
 	if f.Arch != expectedArch {
 		return "", fmt.Errorf("%w: %q: unsupported arch: %q", ErrSkipped, f.Location, f.Arch)
 	}
 	fields := logrus.Fields{"location": f.Location, "arch": f.Arch, "digest": f.Digest}
 	logrus.WithFields(fields).Infof("Attempting to download %s", description)
-	res, err := downloader.Download(dest, f.Location,
+	res, err := downloader.Download(ctx, dest, f.Location,
 		downloader.WithCache(),
 		downloader.WithDecompress(decompress),
 		downloader.WithDescription(fmt.Sprintf("%s (%s)", description, path.Base(f.Location))),
diff --git a/pkg/networks/reconcile/reconcile.go b/pkg/networks/reconcile/reconcile.go
index 5f069326..47b20c69 100644
--- a/pkg/networks/reconcile/reconcile.go
+++ b/pkg/networks/reconcile/reconcile.go
@@ -54,7 +54,7 @@ func Reconcile(ctx context.Context, newInst string) error {
 		if activeNetwork[name] {
 			err = startNetwork(ctx, &config, name)
 		} else {
-			err = stopNetwork(&config, name)
+			err = stopNetwork(ctx, &config, name)
 		}
 		if err != nil {
 			return err
@@ -218,7 +218,7 @@ func startNetwork(ctx context.Context, config *networks.YAML, name string) error
 	return nil
 }
 
-func stopNetwork(config *networks.YAML, name string) error {
+func stopNetwork(ctx context.Context, config *networks.YAML, name string) error {
 	logrus.Debugf("Make sure %q network is stopped", name)
 	// Handle usernet first without sudo requirements
 	isUsernet, err := config.Usernet(name)
@@ -226,7 +226,7 @@ func stopNetwork(config *networks.YAML, name string) error {
 		return err
 	}
 	if isUsernet {
-		if err := usernet.Stop(name); err != nil {
+		if err := usernet.Stop(ctx, name); err != nil {
 			return fmt.Errorf("failed to stop usernet %q: %w", name, err)
 		}
 		return nil
diff --git a/pkg/networks/usernet/client.go b/pkg/networks/usernet/client.go
index 1036bd44..695c9ca1 100644
--- a/pkg/networks/usernet/client.go
+++ b/pkg/networks/usernet/client.go
@@ -12,6 +12,7 @@ import (
 	gvproxyclient "github.com/containers/gvisor-tap-vsock/pkg/client"
 	"github.com/containers/gvisor-tap-vsock/pkg/types"
 	"github.com/lima-vm/lima/pkg/driver"
+	"github.com/lima-vm/lima/pkg/httpclientutil"
 	"github.com/lima-vm/lima/pkg/limayaml"
 	"github.com/lima-vm/lima/pkg/networks/usernet/dnshosts"
 )
@@ -25,9 +26,9 @@ type Client struct {
 	subnet   net.IP
 }
 
-func (c *Client) ConfigureDriver(driver *driver.BaseDriver) error {
+func (c *Client) ConfigureDriver(ctx context.Context, driver *driver.BaseDriver) error {
 	macAddress := limayaml.MACAddress(driver.Instance.Dir)
-	ipAddress, err := c.ResolveIPAddress(macAddress)
+	ipAddress, err := c.ResolveIPAddress(ctx, macAddress)
 	if err != nil {
 		return err
 	}
@@ -72,7 +73,7 @@ func (c *Client) ResolveAndForwardSSH(ipAddr string, sshPort int) error {
 	return nil
 }
 
-func (c *Client) ResolveIPAddress(vmMacAddr string) (string, error) {
+func (c *Client) ResolveIPAddress(ctx context.Context, vmMacAddr string) (string, error) {
 	timeout := time.After(2 * time.Minute)
 	ticker := time.NewTicker(500 * time.Millisecond)
 	for {
@@ -80,7 +81,7 @@ func (c *Client) ResolveIPAddress(vmMacAddr string) (string, error) {
 		case <-timeout:
 			return "", errors.New("usernet unable to resolve IP for SSH forwarding")
 		case <-ticker.C:
-			leases, err := c.Leases()
+			leases, err := c.Leases(ctx)
 			if err != nil {
 				return "", err
 			}
@@ -94,15 +95,13 @@ func (c *Client) ResolveIPAddress(vmMacAddr string) (string, error) {
 	}
 }
 
-func (c *Client) Leases() (map[string]string, error) {
-	res, err := c.client.Get(fmt.Sprintf("%s%s", c.base, "/services/dhcp/leases"))
+func (c *Client) Leases(ctx context.Context) (map[string]string, error) {
+	u := fmt.Sprintf("%s%s", c.base, "/services/dhcp/leases")
+	res, err := httpclientutil.Get(ctx, c.client, u)
 	if err != nil {
 		return nil, err
 	}
 	defer res.Body.Close()
-	if res.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("unexpected status: %d", res.StatusCode)
-	}
 	dec := json.NewDecoder(res.Body)
 	var leases map[string]string
 	if err := dec.Decode(&leases); err != nil {
diff --git a/pkg/networks/usernet/recoincile.go b/pkg/networks/usernet/recoincile.go
index d3fef01d..0dca3ba7 100644
--- a/pkg/networks/usernet/recoincile.go
+++ b/pkg/networks/usernet/recoincile.go
@@ -121,7 +121,7 @@ func Start(ctx context.Context, name string) error {
 
 // Stop stops running instance a usernet network with the given name.
 // The name parameter must point to a valid network configuration name under <LIMA_HOME>/_config/networks.yaml with `mode: user-v2`
-func Stop(name string) error {
+func Stop(ctx context.Context, name string) error {
 	logrus.Debugf("Make sure usernet network is stopped")
 	pidFile, err := PIDFile(name)
 	if err != nil {
@@ -132,7 +132,7 @@ func Stop(name string) error {
 	if pid != 0 {
 		logrus.Debugf("Stopping usernet daemon")
 
-		err = writeLeases(name)
+		err = writeLeases(ctx, name)
 		if err != nil {
 			return err
 		}
@@ -190,9 +190,9 @@ func readLeases(name string) (map[string]string, error) {
 	return leases, err
 }
 
-func writeLeases(nwName string) error {
+func writeLeases(ctx context.Context, nwName string) error {
 	client := NewClientByName(nwName)
-	leases, err := client.Leases()
+	leases, err := client.Leases(ctx)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/qemu/qemu.go b/pkg/qemu/qemu.go
index bd33df46..0c7710a2 100644
--- a/pkg/qemu/qemu.go
+++ b/pkg/qemu/qemu.go
@@ -2,6 +2,7 @@ package qemu
 
 import (
 	"bytes"
+	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -48,7 +49,7 @@ const (
 )
 
 // EnsureDisk also ensures the kernel and the initrd
-func EnsureDisk(cfg Config) error {
+func EnsureDisk(ctx context.Context, cfg Config) error {
 	diffDisk := filepath.Join(cfg.InstanceDir, filenames.DiffDisk)
 	if _, err := os.Stat(diffDisk); err == nil || !errors.Is(err, os.ErrNotExist) {
 		// disk is already ensured
@@ -63,12 +64,12 @@ func EnsureDisk(cfg Config) error {
 		var ensuredBaseDisk bool
 		errs := make([]error, len(cfg.LimaYAML.Images))
 		for i, f := range cfg.LimaYAML.Images {
-			if _, err := fileutils.DownloadFile(baseDisk, f.File, true, "the image", *cfg.LimaYAML.Arch); err != nil {
+			if _, err := fileutils.DownloadFile(ctx, baseDisk, f.File, true, "the image", *cfg.LimaYAML.Arch); err != nil {
 				errs[i] = err
 				continue
 			}
 			if f.Kernel != nil {
-				if _, err := fileutils.DownloadFile(kernel, f.Kernel.File, false, "the kernel", *cfg.LimaYAML.Arch); err != nil {
+				if _, err := fileutils.DownloadFile(ctx, kernel, f.Kernel.File, false, "the kernel", *cfg.LimaYAML.Arch); err != nil {
 					errs[i] = err
 					continue
 				}
@@ -80,7 +81,7 @@ func EnsureDisk(cfg Config) error {
 				}
 			}
 			if f.Initrd != nil {
-				if _, err := fileutils.DownloadFile(initrd, *f.Initrd, false, "the initrd", *cfg.LimaYAML.Arch); err != nil {
+				if _, err := fileutils.DownloadFile(ctx, initrd, *f.Initrd, false, "the initrd", *cfg.LimaYAML.Arch); err != nil {
 					errs[i] = err
 					continue
 				}
@@ -462,7 +463,7 @@ func qemuMachine(arch limayaml.Arch) string {
 	return "virt"
 }
 
-func Cmdline(cfg Config) (exe string, args []string, err error) {
+func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err error) {
 	y := cfg.LimaYAML
 	exe, args, err = Exe(*y.Arch)
 	if err != nil {
@@ -578,7 +579,7 @@ func Cmdline(cfg Config) (exe string, args []string, err error) {
 				switch f.VMType {
 				case "", limayaml.QEMU:
 					if f.Arch == *y.Arch {
-						if _, err = fileutils.DownloadFile(downloadedFirmware, f.File, true, "UEFI code "+f.Location, *y.Arch); err != nil {
+						if _, err = fileutils.DownloadFile(ctx, downloadedFirmware, f.File, true, "UEFI code "+f.Location, *y.Arch); err != nil {
 							logrus.WithError(err).Warnf("failed to download %q", f.Location)
 							continue loop
 						}
diff --git a/pkg/qemu/qemu_driver.go b/pkg/qemu/qemu_driver.go
index c500721e..d4306a92 100644
--- a/pkg/qemu/qemu_driver.go
+++ b/pkg/qemu/qemu_driver.go
@@ -50,13 +50,13 @@ func (l *LimaQemuDriver) Validate() error {
 	return nil
 }
 
-func (l *LimaQemuDriver) CreateDisk() error {
+func (l *LimaQemuDriver) CreateDisk(ctx context.Context) error {
 	qCfg := Config{
 		Name:        l.Instance.Name,
 		InstanceDir: l.Instance.Dir,
 		LimaYAML:    l.Yaml,
 	}
-	return EnsureDisk(qCfg)
+	return EnsureDisk(ctx, qCfg)
 }
 
 func (l *LimaQemuDriver) Start(ctx context.Context) (chan error, error) {
@@ -73,7 +73,7 @@ func (l *LimaQemuDriver) Start(ctx context.Context) (chan error, error) {
 		LimaYAML:     l.Yaml,
 		SSHLocalPort: l.SSHLocalPort,
 	}
-	qExe, qArgs, err := Cmdline(qCfg)
+	qExe, qArgs, err := Cmdline(ctx, qCfg)
 	if err != nil {
 		return nil, err
 	}
@@ -191,7 +191,7 @@ func (l *LimaQemuDriver) Start(ctx context.Context) (chan error, error) {
 	go func() {
 		if usernetIndex := limayaml.FirstUsernetIndex(l.Yaml); usernetIndex != -1 {
 			client := usernet.NewClientByName(l.Yaml.Networks[usernetIndex].Lima)
-			err := client.ConfigureDriver(l.BaseDriver)
+			err := client.ConfigureDriver(ctx, l.BaseDriver)
 			if err != nil {
 				l.qWaitCh <- err
 			}
diff --git a/pkg/start/start.go b/pkg/start/start.go
index 0cc4fdd7..33c8a7c8 100644
--- a/pkg/start/start.go
+++ b/pkg/start/start.go
@@ -38,7 +38,7 @@ const DefaultWatchHostAgentEventsTimeout = 10 * time.Minute
 // ensureNerdctlArchiveCache prefetches the nerdctl-full-VERSION-GOOS-GOARCH.tar.gz archive
 // into the cache before launching the hostagent process, so that we can show the progress in tty.
 // https://github.com/lima-vm/lima/issues/326
-func ensureNerdctlArchiveCache(y *limayaml.LimaYAML, created bool) (string, error) {
+func ensureNerdctlArchiveCache(ctx context.Context, y *limayaml.LimaYAML, created bool) (string, error) {
 	if !*y.Containerd.System && !*y.Containerd.User {
 		// nerdctl archive is not needed
 		return "", nil
@@ -53,7 +53,7 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML, created bool) (string, erro
 				return path, nil
 			}
 		}
-		path, err := fileutils.DownloadFile("", f, false, "the nerdctl archive", *y.Arch)
+		path, err := fileutils.DownloadFile(ctx, "", f, false, "the nerdctl archive", *y.Arch)
 		if err != nil {
 			errs[i] = err
 			continue
@@ -101,10 +101,10 @@ func Prepare(ctx context.Context, inst *store.Instance) (*Prepared, error) {
 	if _, err := os.Stat(baseDisk); err == nil {
 		created = true
 	}
-	if err := limaDriver.CreateDisk(); err != nil {
+	if err := limaDriver.CreateDisk(ctx); err != nil {
 		return nil, err
 	}
-	nerdctlArchiveCache, err := ensureNerdctlArchiveCache(y, created)
+	nerdctlArchiveCache, err := ensureNerdctlArchiveCache(ctx, y, created)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/vz/disk.go b/pkg/vz/disk.go
index c4b9f01f..0ee62d38 100644
--- a/pkg/vz/disk.go
+++ b/pkg/vz/disk.go
@@ -1,6 +1,7 @@
 package vz
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"os"
@@ -14,7 +15,7 @@ import (
 	"github.com/lima-vm/lima/pkg/store/filenames"
 )
 
-func EnsureDisk(driver *driver.BaseDriver) error {
+func EnsureDisk(ctx context.Context, driver *driver.BaseDriver) error {
 	diffDisk := filepath.Join(driver.Instance.Dir, filenames.DiffDisk)
 	if _, err := os.Stat(diffDisk); err == nil || !errors.Is(err, os.ErrNotExist) {
 		// disk is already ensured
@@ -26,7 +27,7 @@ func EnsureDisk(driver *driver.BaseDriver) error {
 		var ensuredBaseDisk bool
 		errs := make([]error, len(driver.Yaml.Images))
 		for i, f := range driver.Yaml.Images {
-			if _, err := fileutils.DownloadFile(baseDisk, f.File, true, "the image", *driver.Yaml.Arch); err != nil {
+			if _, err := fileutils.DownloadFile(ctx, baseDisk, f.File, true, "the image", *driver.Yaml.Arch); err != nil {
 				errs[i] = err
 				continue
 			}
diff --git a/pkg/vz/vm_darwin.go b/pkg/vz/vm_darwin.go
index 0b1e20dc..8d686678 100644
--- a/pkg/vz/vm_darwin.go
+++ b/pkg/vz/vm_darwin.go
@@ -102,7 +102,7 @@ func startVM(ctx context.Context, driver *driver.BaseDriver) (*virtualMachineWra
 					filesToRemove[pidFile] = struct{}{}
 					logrus.Info("[VZ] - vm state change: running")
 
-					err := usernetClient.ConfigureDriver(driver)
+					err := usernetClient.ConfigureDriver(ctx, driver)
 					if err != nil {
 						errCh <- err
 					}
diff --git a/pkg/vz/vz_driver_darwin.go b/pkg/vz/vz_driver_darwin.go
index ce496d6b..d4aea761 100644
--- a/pkg/vz/vz_driver_darwin.go
+++ b/pkg/vz/vz_driver_darwin.go
@@ -147,8 +147,8 @@ func (l *LimaVzDriver) Initialize(_ context.Context) error {
 	return err
 }
 
-func (l *LimaVzDriver) CreateDisk() error {
-	return EnsureDisk(l.BaseDriver)
+func (l *LimaVzDriver) CreateDisk(ctx context.Context) error {
+	return EnsureDisk(ctx, l.BaseDriver)
 }
 
 func (l *LimaVzDriver) Start(ctx context.Context) (chan error, error) {
diff --git a/pkg/vz/vz_driver_others.go b/pkg/vz/vz_driver_others.go
index 67ccd9fd..b8e414e1 100644
--- a/pkg/vz/vz_driver_others.go
+++ b/pkg/vz/vz_driver_others.go
@@ -27,7 +27,7 @@ func (l *LimaVzDriver) Validate() error {
 	return ErrUnsupported
 }
 
-func (l *LimaVzDriver) CreateDisk() error {
+func (l *LimaVzDriver) CreateDisk(_ context.Context) error {
 	return ErrUnsupported
 }
 
diff --git a/pkg/wsl2/fs.go b/pkg/wsl2/fs.go
index 7500985e..93c08fef 100644
--- a/pkg/wsl2/fs.go
+++ b/pkg/wsl2/fs.go
@@ -1,6 +1,7 @@
 package wsl2
 
 import (
+	"context"
 	"errors"
 	"os"
 	"path/filepath"
@@ -12,13 +13,13 @@ import (
 )
 
 // EnsureFs downloads the root fs.
-func EnsureFs(driver *driver.BaseDriver) error {
+func EnsureFs(ctx context.Context, driver *driver.BaseDriver) error {
 	baseDisk := filepath.Join(driver.Instance.Dir, filenames.BaseDisk)
 	if _, err := os.Stat(baseDisk); errors.Is(err, os.ErrNotExist) {
 		var ensuredBaseDisk bool
 		errs := make([]error, len(driver.Yaml.Images))
 		for i, f := range driver.Yaml.Images {
-			if _, err := fileutils.DownloadFile(baseDisk, f.File, true, "the image", *driver.Yaml.Arch); err != nil {
+			if _, err := fileutils.DownloadFile(ctx, baseDisk, f.File, true, "the image", *driver.Yaml.Arch); err != nil {
 				errs[i] = err
 				continue
 			}
diff --git a/pkg/wsl2/wsl_driver_others.go b/pkg/wsl2/wsl_driver_others.go
index 5e348406..7a116e5e 100644
--- a/pkg/wsl2/wsl_driver_others.go
+++ b/pkg/wsl2/wsl_driver_others.go
@@ -27,7 +27,7 @@ func (l *LimaWslDriver) Validate() error {
 	return ErrUnsupported
 }
 
-func (l *LimaWslDriver) CreateDisk() error {
+func (l *LimaWslDriver) CreateDisk(_ context.Context) error {
 	return ErrUnsupported
 }
 
diff --git a/pkg/wsl2/wsl_driver_windows.go b/pkg/wsl2/wsl_driver_windows.go
index 8d508e70..13b2c4b9 100644
--- a/pkg/wsl2/wsl_driver_windows.go
+++ b/pkg/wsl2/wsl_driver_windows.go
@@ -114,7 +114,7 @@ func (l *LimaWslDriver) Start(ctx context.Context) (chan error, error) {
 	distroName := "lima-" + l.Instance.Name
 
 	if status == store.StatusUninitialized {
-		if err := EnsureFs(l.BaseDriver); err != nil {
+		if err := EnsureFs(ctx, l.BaseDriver); err != nil {
 			return nil, err
 		}
 		if err := initVM(ctx, l.BaseDriver.Instance.Dir, distroName); err != nil {


Test patch:
diff --git a/pkg/downloader/downloader_test.go b/pkg/downloader/downloader_test.go
index 1ff29266..1ac66bb9 100644
--- a/pkg/downloader/downloader_test.go
+++ b/pkg/downloader/downloader_test.go
@@ -1,6 +1,7 @@
 package downloader
 
 import (
+	"context"
 	"net/http"
 	"net/http/httptest"
 	"os"
@@ -28,26 +29,26 @@ func TestDownloadRemote(t *testing.T) {
 	t.Run("without cache", func(t *testing.T) {
 		t.Run("without digest", func(t *testing.T) {
 			localPath := filepath.Join(t.TempDir(), t.Name())
-			r, err := Download(localPath, dummyRemoteFileURL)
+			r, err := Download(context.Background(), localPath, dummyRemoteFileURL)
 			assert.NilError(t, err)
 			assert.Equal(t, StatusDownloaded, r.Status)
 
 			// download again, make sure StatusSkippedIsReturned
-			r, err = Download(localPath, dummyRemoteFileURL)
+			r, err = Download(context.Background(), localPath, dummyRemoteFileURL)
 			assert.NilError(t, err)
 			assert.Equal(t, StatusSkipped, r.Status)
 		})
 		t.Run("with digest", func(t *testing.T) {
 			wrongDigest := digest.Digest("sha256:8313944efb4f38570c689813f288058b674ea6c487017a5a4738dc674b65f9d9")
 			localPath := filepath.Join(t.TempDir(), t.Name())
-			_, err := Download(localPath, dummyRemoteFileURL, WithExpectedDigest(wrongDigest))
+			_, err := Download(context.Background(), localPath, dummyRemoteFileURL, WithExpectedDigest(wrongDigest))
 			assert.ErrorContains(t, err, "expected digest")
 
-			r, err := Download(localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest))
+			r, err := Download(context.Background(), localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest))
 			assert.NilError(t, err)
 			assert.Equal(t, StatusDownloaded, r.Status)
 
-			r, err = Download(localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest))
+			r, err = Download(context.Background(), localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest))
 			assert.NilError(t, err)
 			assert.Equal(t, StatusSkipped, r.Status)
 		})
@@ -55,34 +56,34 @@ func TestDownloadRemote(t *testing.T) {
 	t.Run("with cache", func(t *testing.T) {
 		cacheDir := filepath.Join(t.TempDir(), "cache")
 		localPath := filepath.Join(t.TempDir(), t.Name())
-		r, err := Download(localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
+		r, err := Download(context.Background(), localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusDownloaded, r.Status)
 
-		r, err = Download(localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
+		r, err = Download(context.Background(), localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusSkipped, r.Status)
 
 		localPath2 := localPath + "-2"
-		r, err = Download(localPath2, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
+		r, err = Download(context.Background(), localPath2, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusUsedCache, r.Status)
 	})
 	t.Run("caching-only mode", func(t *testing.T) {
-		_, err := Download("", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest))
+		_, err := Download(context.Background(), "", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest))
 		assert.ErrorContains(t, err, "cache directory to be specified")
 
 		cacheDir := filepath.Join(t.TempDir(), "cache")
-		r, err := Download("", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
+		r, err := Download(context.Background(), "", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusDownloaded, r.Status)
 
-		r, err = Download("", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
+		r, err = Download(context.Background(), "", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusUsedCache, r.Status)
 
 		localPath := filepath.Join(t.TempDir(), t.Name())
-		r, err = Download(localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
+		r, err = Download(context.Background(), localPath, dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusUsedCache, r.Status)
 	})
@@ -91,7 +92,7 @@ func TestDownloadRemote(t *testing.T) {
 		assert.ErrorContains(t, err, "cache directory to be specified")
 
 		cacheDir := filepath.Join(t.TempDir(), "cache")
-		r, err := Download("", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
+		r, err := Download(context.Background(), "", dummyRemoteFileURL, WithExpectedDigest(dummyRemoteFileDigest), WithCacheDir(cacheDir))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusDownloaded, r.Status)
 
@@ -118,7 +119,7 @@ func TestDownloadLocal(t *testing.T) {
 		t.Cleanup(func() { _ = f.Close() })
 		testLocalFileURL := "file://" + localFile
 
-		r, err := Download(localPath, testLocalFileURL)
+		r, err := Download(context.Background(), localPath, testLocalFileURL)
 		assert.NilError(t, err)
 		assert.Equal(t, StatusDownloaded, r.Status)
 	})
@@ -132,10 +133,10 @@ func TestDownloadLocal(t *testing.T) {
 		testLocalFileURL := "file://" + localTestFile
 		wrongDigest := digest.Digest(emptyFileDigest)
 
-		_, err := Download(localPath, testLocalFileURL, WithExpectedDigest(wrongDigest))
+		_, err := Download(context.Background(), localPath, testLocalFileURL, WithExpectedDigest(wrongDigest))
 		assert.ErrorContains(t, err, "expected digest")
 
-		r, err := Download(localPath, testLocalFileURL, WithExpectedDigest(testDownloadLocalDigest))
+		r, err := Download(context.Background(), localPath, testLocalFileURL, WithExpectedDigest(testDownloadLocalDigest))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusDownloaded, r.Status)
 
@@ -170,7 +171,7 @@ func TestDownloadCompressed(t *testing.T) {
 		localFile += ".gz"
 		testLocalFileURL := "file://" + localFile
 
-		r, err := Download(localPath, testLocalFileURL, WithDecompress(true))
+		r, err := Download(context.Background(), localPath, testLocalFileURL, WithDecompress(true))
 		assert.NilError(t, err)
 		assert.Equal(t, StatusDownloaded, r.Status)