Skip to content

Commit eaf0ea7

Browse files
committed
add "additionalArchives" config option
Signed-off-by: Justin Alvarez <[email protected]>
1 parent f26b412 commit eaf0ea7

File tree

6 files changed

+79
-16
lines changed

6 files changed

+79
-16
lines changed

cmd/limactl/hostagent.go

+8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func newHostagentCommand() *cobra.Command {
2828
hostagentCommand.Flags().StringP("pidfile", "p", "", "write pid to file")
2929
hostagentCommand.Flags().String("socket", "", "hostagent socket")
3030
hostagentCommand.Flags().String("nerdctl-archive", "", "local file path (not URL) of nerdctl-full-VERSION-linux-GOARCH.tar.gz")
31+
hostagentCommand.Flags().String("additional-archive", "", "local file path (not URL) of an arbitrary archive to add to CIDATA")
3132
return hostagentCommand
3233
}
3334

@@ -70,6 +71,13 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
7071
if nerdctlArchive != "" {
7172
opts = append(opts, hostagent.WithNerdctlArchive(nerdctlArchive))
7273
}
74+
additionalArchive, err := cmd.Flags().GetString("additional-archive")
75+
if err != nil {
76+
return err
77+
}
78+
if additionalArchive != "" {
79+
opts = append(opts, hostagent.WithAdditionalArchive(additionalArchive))
80+
}
7381
ha, err := hostagent.New(instName, stdout, sigintCh, opts...)
7482
if err != nil {
7583
return err

examples/default.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,19 @@ containerd:
214214
# vim was not installed in the guest. Make sure the package system is working correctly.
215215
# Also see "/var/log/cloud-init-output.log" in the guest.
216216

217+
# Adds an additional archive which matches the system architecture to the CIDATA image which is mounted on boot.
218+
# The additional archive will be available on the CIDATA disk at /additional.tgz.
219+
# Useful for provisioning scripts that run before mounts (like `mode: dependency`) in case they need any file resources.
220+
# See pkg/cidata/cidata.TEMPLATE.d/boot/40-install-containerd.sh for an example of how to use an archive
221+
# from a provisioning script.
222+
# additionalArchives:
223+
# - location: "~/additional.amd64.tar.gz"
224+
# arch: "x86_64"
225+
# digest: "sha256:..."
226+
# - location: "~/additional.aarch64.tar.gz"
227+
# arch: "aarch64"
228+
# digest: "sha256:..."
229+
217230
# ===================================================================== #
218231
# FURTHER ADVANCED CONFIGURATION
219232
# ===================================================================== #

pkg/cidata/cidata.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func setupEnv(y *limayaml.LimaYAML) (map[string]string, error) {
105105
return env, nil
106106
}
107107

108-
func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string) error {
108+
func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive, additionalArchive string) error {
109109
if err := limayaml.Validate(*y, false); err != nil {
110110
return err
111111
}
@@ -304,6 +304,19 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
304304
})
305305
}
306306

307+
if additionalArchive != "" {
308+
additionaltgzR, err := os.Open(additionalArchive)
309+
if err != nil {
310+
return err
311+
}
312+
defer additionaltgzR.Close()
313+
layout = append(layout, iso9660util.Entry{
314+
// ISO9660 requires len(Path) <= 30
315+
Path: "additional.tgz",
316+
Reader: additionaltgzR,
317+
})
318+
}
319+
307320
return iso9660util.Write(filepath.Join(instDir, filenames.CIDataISO), "cidata", layout)
308321
}
309322

pkg/hostagent/hostagent.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ type HostAgent struct {
5353
}
5454

5555
type options struct {
56-
nerdctlArchive string // local path, not URL
56+
nerdctlArchive string // local path, not URL
57+
additionalArchive string // local path, not URL
5758
}
5859

5960
type Opt func(*options) error
@@ -65,6 +66,13 @@ func WithNerdctlArchive(s string) Opt {
6566
}
6667
}
6768

69+
func WithAdditionalArchive(s string) Opt {
70+
return func(o *options) error {
71+
o.additionalArchive = s
72+
return nil
73+
}
74+
}
75+
6876
// New creates the HostAgent.
6977
//
7078
// stdout is for emitting JSON lines of Events.
@@ -103,7 +111,7 @@ func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt
103111
}
104112
}
105113

106-
if err := cidata.GenerateISO9660(inst.Dir, instName, y, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive); err != nil {
114+
if err := cidata.GenerateISO9660(inst.Dir, instName, y, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive, o.additionalArchive); err != nil {
107115
return nil, err
108116
}
109117

pkg/limayaml/limayaml.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ type LimaYAML struct {
3131
DNS []net.IP `yaml:"dns,omitempty" json:"dns,omitempty"`
3232
HostResolver HostResolver `yaml:"hostResolver,omitempty" json:"hostResolver,omitempty"`
3333
// `useHostResolver` was deprecated in Lima v0.8.1, removed in Lima v0.14.0. Use `hostResolver.enabled` instead.
34-
PropagateProxyEnv *bool `yaml:"propagateProxyEnv,omitempty" json:"propagateProxyEnv,omitempty"`
35-
CACertificates CACertificates `yaml:"caCerts,omitempty" json:"caCerts,omitempty"`
36-
Rosetta Rosetta `yaml:"rosetta,omitempty" json:"rosetta,omitempty"`
34+
PropagateProxyEnv *bool `yaml:"propagateProxyEnv,omitempty" json:"propagateProxyEnv,omitempty"`
35+
CACertificates CACertificates `yaml:"caCerts,omitempty" json:"caCerts,omitempty"`
36+
Rosetta Rosetta `yaml:"rosetta,omitempty" json:"rosetta,omitempty"`
37+
AdditionalArchives []File `yaml:"additionalArchives,omitempty" json:"additionalArchives,omitempty"`
3738
}
3839

3940
type Arch = string

pkg/start/start.go

+30-10
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,35 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML) (string, error) {
3636
return "", nil
3737
}
3838

39-
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 {
39+
location, errs := downloadAndCacheArchiveForArch(y.Containerd.Archives, *y.Arch, "nerdctl")
40+
if location == "" {
41+
return "", fmt.Errorf("failed to download the nerdctl archive, attempted %d candidates, errors=%v",
42+
len(y.Containerd.Archives), errs)
43+
}
44+
45+
return location, nil
46+
}
47+
48+
// downloadAndCacheArchiveForArch iterates through a slice of File and tries to download the provided
49+
// file which matches the supplied arch.
50+
// The downloader caches remote downloads to disk, and then returns a file path to the archive.
51+
func downloadAndCacheArchiveForArch(files []limayaml.File, arch limayaml.Arch, archiveType string) (string, []error) {
52+
errs := make([]error, len(files))
53+
for i := range files {
54+
f := &files[i]
55+
if f.Arch != arch {
4356
errs[i] = fmt.Errorf("unsupported arch: %q", f.Arch)
4457
continue
4558
}
46-
logrus.WithField("digest", f.Digest).Infof("Attempting to download the nerdctl archive from %q", f.Location)
59+
logrus.WithField("digest", f.Digest).Infof("Attempting to download the %s archive from %q", archiveType, f.Location)
4760
res, err := downloader.Download("", f.Location, downloader.WithCache(), downloader.WithExpectedDigest(f.Digest))
4861
if err != nil {
4962
errs[i] = fmt.Errorf("failed to download %q: %w", f.Location, err)
5063
continue
5164
}
5265
switch res.Status {
5366
case downloader.StatusDownloaded:
54-
logrus.Infof("Downloaded the nerdctl archive from %q", f.Location)
67+
logrus.Infof("Downloaded the %s archive from %q", archiveType, f.Location)
5568
case downloader.StatusUsedCache:
5669
logrus.Infof("Using cache %q", res.CachePath)
5770
default:
@@ -61,13 +74,11 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML) (string, error) {
6174
if downloader.IsLocal(f.Location) {
6275
return f.Location, nil
6376
}
64-
return "", fmt.Errorf("cache did not contain %q", f.Location)
77+
errs[i] = fmt.Errorf("cache did not contain %q", f.Location)
6578
}
6679
return res.CachePath, nil
6780
}
68-
69-
return "", fmt.Errorf("failed to download the nerdctl archive, attempted %d candidates, errors=%v",
70-
len(y.Containerd.Archives), errs)
81+
return "", errs
7182
}
7283

7384
func Start(ctx context.Context, inst *store.Instance) error {
@@ -134,6 +145,15 @@ func Start(ctx context.Context, inst *store.Instance) error {
134145
if nerdctlArchiveCache != "" {
135146
args = append(args, "--nerdctl-archive", nerdctlArchiveCache)
136147
}
148+
if len(y.AdditionalArchives) > 0 {
149+
location, errs := downloadAndCacheArchiveForArch(y.AdditionalArchives, *y.Arch, "additionalArchive")
150+
if location == "" {
151+
return fmt.Errorf("failed to download the additionalArchive archive, attempted %d candidates, errors=%v",
152+
len(y.AdditionalArchives), errs)
153+
}
154+
args = append(args, "--additional-archive", location)
155+
}
156+
137157
args = append(args, inst.Name)
138158
haCmd := exec.CommandContext(ctx, self, args...)
139159

0 commit comments

Comments
 (0)