Skip to content

Commit

Permalink
vm: improve support for custom disk image
Browse files Browse the repository at this point in the history
Signed-off-by: Abiola Ibrahim <[email protected]>
  • Loading branch information
abiosoft committed Dec 16, 2024
1 parent 497803b commit c5c938a
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 16 deletions.
2 changes: 1 addition & 1 deletion cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func init() {
startCmd.Flags().StringVarP(&startCmdArgs.Arch, "arch", "a", defaultArch, "architecture (aarch64, x86_64)")
startCmd.Flags().BoolVarP(&startCmdArgs.Flags.Foreground, "foreground", "f", false, "Keep colima in the foreground")
startCmd.Flags().StringVar(&startCmdArgs.Hostname, "hostname", "", "custom hostname for the virtual machine")
startCmd.Flags().StringVarP(&startCmdArgs.DiskImage, "disk-image", "i", "", "local path or URL to a custom disk image")
startCmd.Flags().StringVarP(&startCmdArgs.DiskImage, "disk-image", "i", "", "file path to a custom disk image")

// host IP addresses
startCmd.Flags().BoolVar(&startCmdArgs.Network.HostAddresses, "network-host-addresses", false, "support port forwarding to specific host IP addresses")
Expand Down
7 changes: 7 additions & 0 deletions config/configmanager/configmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/abiosoft/colima/cli"
"github.com/abiosoft/colima/config"
Expand Down Expand Up @@ -77,6 +78,12 @@ func ValidateConfig(c config.Config) error {
}
}

if c.DiskImage != "" {
if strings.HasPrefix(c.DiskImage, "http://") || strings.HasPrefix(c.DiskImage, "https://") {
return fmt.Errorf("cannot use diskImage: remote URLs not supported, only local files can be specified")
}
}

return nil
}

Expand Down
4 changes: 2 additions & 2 deletions embedded/defaults/colima.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ sshPort: 0
mounts: []

# Specify a custom disk image for the virtual machine.
# When not specified, Colima downloads the disk image from Github at
# When not specified, Colima downloads an appropriate disk image from Github at
# https://github.com/abiosoft/colima-core/releases.
# A custom disk image (local disk path or URL) can be specified to override the behaviour.
# The file path to a custom disk image can be specified to override the behaviour.
#
# Default: ""
diskImage: ""
Expand Down
25 changes: 17 additions & 8 deletions environment/vm/lima/lima.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/abiosoft/colima/environment/vm/lima/limaconfig"
"github.com/abiosoft/colima/environment/vm/lima/limautil"
"github.com/abiosoft/colima/util"
"github.com/abiosoft/colima/util/downloader"
"github.com/abiosoft/colima/util/osutil"
"github.com/abiosoft/colima/util/yamlutil"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -274,25 +275,33 @@ func (l limaVM) Arch() environment.Arch {
func (l *limaVM) downloadDiskImage(ctx context.Context, conf config.Config) error {
log := l.Logger(ctx)

// use a previously cached image
if image, ok := limautil.ImageCached(l.limaConf.Arch, conf.Runtime); ok {
l.limaConf.Images = []limaconfig.File{image}
return nil
}

// use a user specified disk image
if conf.DiskImage != "" {
log.Infoln("using specified disk image ...")
if _, err := os.Stat(conf.DiskImage); err != nil {
return fmt.Errorf("invalid disk image: %w", err)
}

image, err := limautil.Image(l.limaConf.Arch, conf.Runtime)
if err != nil {
return fmt.Errorf("error getting disk image details: %w", err)
}
log.Warnf("disk image must be identical to '%s'", image.Location)

sha := downloader.SHA{Size: 512, Digest: image.Digest}
if err := sha.ValidateFile(l.host, conf.DiskImage); err != nil {
return fmt.Errorf("disk image must be downloaded from '%s', hash failure: %w", image.Location, err)
}

image.Location = conf.DiskImage
l.limaConf.Images = []limaconfig.File{image}
return nil
}

// use a previously cached image
if image, ok := limautil.ImageCached(l.limaConf.Arch, conf.Runtime); ok {
l.limaConf.Images = []limaconfig.File{image}
return nil
}

// download image
log.Infoln("downloading disk image ...")
image, err := limautil.DownloadImage(l.limaConf.Arch, conf.Runtime)
Expand Down
7 changes: 2 additions & 5 deletions util/downloader/sha.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ type SHA struct {
// ValidateFile validates the SHA of the file.
func (s SHA) ValidateFile(host hostActions, file string) error {
dir, filename := filepath.Split(file)
digest := strings.TrimPrefix(s.Digest, fmt.Sprintf("sha%d:", s.Size))

script := strings.NewReplacer(
"{dir}", dir,
"{digest}", s.Digest,
"{digest}", digest,
"{size}", strconv.Itoa(s.Size),
"{filename}", filename,
).Replace(
Expand All @@ -35,10 +36,6 @@ func (s SHA) validateDownload(host hostActions, url string, filename string) err
return fmt.Errorf("error validating SHA: one of Digest or URL must be set")
}

if s.Digest != "" {
s.Digest = strings.TrimPrefix(s.Digest, fmt.Sprintf("sha%d:", s.Size))
}

// fetch digest from URL if empty
if s.Digest == "" {
// retrieve the filename from the download url.
Expand Down

0 comments on commit c5c938a

Please sign in to comment.