Skip to content

Commit

Permalink
add "additionalArchives" config option
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Alvarez <alvajus@amazon.com>
  • Loading branch information
pendo324 committed Apr 17, 2023
1 parent 261b4cd commit e007439
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 10 deletions.
8 changes: 8 additions & 0 deletions cmd/limactl/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func newHostagentCommand() *cobra.Command {
hostagentCommand.Flags().StringP("pidfile", "p", "", "write pid to file")
hostagentCommand.Flags().String("socket", "", "hostagent socket")
hostagentCommand.Flags().String("nerdctl-archive", "", "local file path (not URL) of nerdctl-full-VERSION-linux-GOARCH.tar.gz")
hostagentCommand.Flags().StringToString("additional-archive", map[string]string{}, "local file path (not URL) of an arbitrary archive to add to CIDATA")
return hostagentCommand
}

Expand Down Expand Up @@ -70,6 +71,13 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
if nerdctlArchive != "" {
opts = append(opts, hostagent.WithNerdctlArchive(nerdctlArchive))
}
additionalArchives, err := cmd.Flags().GetStringToString("additional-archive")
if err != nil {
return err
}
for archName, archLocation := range additionalArchives {
opts = append(opts, hostagent.WithAdditionalArchive(archName, archLocation))
}
ha, err := hostagent.New(instName, stdout, sigintCh, opts...)
if err != nil {
return err
Expand Down
14 changes: 14 additions & 0 deletions examples/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,20 @@ containerd:
# vim was not installed in the guest. Make sure the package system is working correctly.
# Also see "/var/log/cloud-init-output.log" in the guest.

# Adds an additional archive which matches the system architecture to the CIDATA image which is mounted on boot.
# The additional archive will be available on the CIDATA disk at /archive.tgz (depending on the key name).
# Useful for provisioning scripts that run before mounts (like `mode: dependency`) in case they need any file resources.
# See pkg/cidata/cidata.TEMPLATE.d/boot/40-install-containerd.sh for an example of how to use an archive
# from a provisioning script.
# additionalArchives:
# archive.tgz:
# - location: "/path/to/additional.x86_64.tar.gz"
# arch: "x86_64"
# digest: "sha256:..."
# - location: "/path/to/additional.aarch64.tar.gz"
# arch: "aarch64"
# digest: "sha256:..."

# ===================================================================== #
# FURTHER ADVANCED CONFIGURATION
# ===================================================================== #
Expand Down
15 changes: 14 additions & 1 deletion pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func setupEnv(y *limayaml.LimaYAML) (map[string]string, error) {
return env, nil
}

func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string) error {
func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, additionalArchives map[string]string) error {
if err := limayaml.Validate(*y, false); err != nil {
return err
}
Expand Down Expand Up @@ -304,6 +304,19 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
})
}

for archName, archLocation := range additionalArchives {
additionaltgzR, err := os.Open(archLocation)
if err != nil {
return err
}
defer additionaltgzR.Close()
layout = append(layout, iso9660util.Entry{
// ISO9660 requires len(Path) <= 30
Path: archName,
Reader: additionaltgzR,
})
}

return iso9660util.Write(filepath.Join(instDir, filenames.CIDataISO), "cidata", layout)
}

Expand Down
15 changes: 13 additions & 2 deletions pkg/hostagent/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ type HostAgent struct {
}

type options struct {
nerdctlArchive string // local path, not URL
nerdctlArchive string // local path, not URL
additionalArchives map[string]string // archive name => local path, not URL
}

type Opt func(*options) error
Expand All @@ -67,6 +68,16 @@ func WithNerdctlArchive(s string) Opt {
}
}

func WithAdditionalArchive(name string, location string) Opt {
return func(o *options) error {
if o.additionalArchives == nil {
o.additionalArchives = make(map[string]string)
}
o.additionalArchives[name] = location
return nil
}
}

// New creates the HostAgent.
//
// stdout is for emitting JSON lines of Events.
Expand Down Expand Up @@ -105,7 +116,7 @@ func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt
}
}

if err := cidata.GenerateISO9660(inst.Dir, instName, y, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive); err != nil {
if err := cidata.GenerateISO9660(inst.Dir, instName, y, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive, o.additionalArchives); err != nil {
return nil, err
}

Expand Down
7 changes: 4 additions & 3 deletions pkg/limayaml/limayaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ type LimaYAML struct {
DNS []net.IP `yaml:"dns,omitempty" json:"dns,omitempty"`
HostResolver HostResolver `yaml:"hostResolver,omitempty" json:"hostResolver,omitempty"`
// `useHostResolver` was deprecated in Lima v0.8.1, removed in Lima v0.14.0. Use `hostResolver.enabled` instead.
PropagateProxyEnv *bool `yaml:"propagateProxyEnv,omitempty" json:"propagateProxyEnv,omitempty"`
CACertificates CACertificates `yaml:"caCerts,omitempty" json:"caCerts,omitempty"`
Rosetta Rosetta `yaml:"rosetta,omitempty" json:"rosetta,omitempty"`
PropagateProxyEnv *bool `yaml:"propagateProxyEnv,omitempty" json:"propagateProxyEnv,omitempty"`
CACertificates CACertificates `yaml:"caCerts,omitempty" json:"caCerts,omitempty"`
Rosetta Rosetta `yaml:"rosetta,omitempty" json:"rosetta,omitempty"`
AdditionalArchives map[string][]File `yaml:"additionalArchives,omitempty" json:"additionalArchives,omitempty"`
}

type Arch = string
Expand Down
37 changes: 33 additions & 4 deletions pkg/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,27 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML) (string, error) {
return "", nil
}

errs := make([]error, len(y.Containerd.Archives))
for i, f := range y.Containerd.Archives {
path, err := fileutils.DownloadFile("", f, false, "the nerdctl archive", *y.Arch)
location, errs := downloadAndCacheArchiveForArch(y.Containerd.Archives, *y.Arch, "nerdctl")
if location == "" {
return "", fmt.Errorf("failed to download the nerdctl archive, attempted %d candidates, errors=%v",
len(y.Containerd.Archives), errs)
}

return location, nil
}

// downloadAndCacheArchiveForArch iterates through a slice of File and tries to download the provided
// file which matches the supplied arch.
// The downloader caches remote downloads to disk, and then returns a file path to the archive.
func downloadAndCacheArchiveForArch(files []limayaml.File, arch limayaml.Arch, archiveDescription string) (string, error) {
errs := make([]error, len(files))
for i := range files {
f := &files[i]
if f.Arch != arch {
errs[i] = fmt.Errorf("unsupported arch: %q", f.Arch)
continue
}
path, err := fileutils.DownloadFile("", *f, false, archiveDescription, arch)
if err != nil {
errs[i] = err
continue
Expand All @@ -48,7 +66,7 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML) (string, error) {
if downloader.IsLocal(f.Location) {
return f.Location, nil
}
return "", fmt.Errorf("cache did not contain %q", f.Location)
errs[i] = fmt.Errorf("cache did not contain %q", f.Location)
}
return path, nil
}
Expand Down Expand Up @@ -120,6 +138,17 @@ func Start(ctx context.Context, inst *store.Instance) error {
if nerdctlArchiveCache != "" {
args = append(args, "--nerdctl-archive", nerdctlArchiveCache)
}
if len(y.AdditionalArchives) > 0 {
for archName, archPath := range y.AdditionalArchives {
location, errs := downloadAndCacheArchiveForArch(archPath, *y.Arch, fmt.Sprintf("additional archive (%s)", archName))
if location == "" {
return fmt.Errorf("failed to download the additionalArchive archive (%s), attempted %d candidates, errors=%v",
archName, len(y.AdditionalArchives), errs)
}
args = append(args, "--additional-archive", fmt.Sprintf("%s=%s", archName, location))
}
}

args = append(args, inst.Name)
haCmd := exec.CommandContext(ctx, self, args...)

Expand Down
1 change: 1 addition & 0 deletions pkg/vz/vz_driver_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (l *LimaVzDriver) Validate() error {
"CACertificates",
"Rosetta",
"AdditionalDisks",
"AdditionalArchives",
); len(unknown) > 0 {
logrus.Warnf("Ignoring: vmType %s: %+v", *l.Yaml.VMType, unknown)
}
Expand Down

0 comments on commit e007439

Please sign in to comment.