Skip to content

Commit d859a9d

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

File tree

7 files changed

+88
-13
lines changed

7 files changed

+88
-13
lines changed

cmd/limactl/hostagent.go

Lines changed: 8 additions & 0 deletions
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().StringToString("additional-archive", map[string]string{}, "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+
additionalArchives, err := cmd.Flags().GetStringToString("additional-archive")
75+
if err != nil {
76+
return err
77+
}
78+
for archName, archLocation := range additionalArchives {
79+
opts = append(opts, hostagent.WithAdditionalArchive(archName, archLocation))
80+
}
7381
ha, err := hostagent.New(instName, stdout, sigintCh, opts...)
7482
if err != nil {
7583
return err

examples/default.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,20 @@ containerd:
217217
# vim was not installed in the guest. Make sure the package system is working correctly.
218218
# Also see "/var/log/cloud-init-output.log" in the guest.
219219

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

pkg/cidata/cidata.go

Lines changed: 14 additions & 1 deletion
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 string, additionalArchives map[string]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+
for archName, archLocation := range additionalArchives {
308+
additionaltgzR, err := os.Open(archLocation)
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: archName,
316+
Reader: additionaltgzR,
317+
})
318+
}
319+
307320
return iso9660util.Write(filepath.Join(instDir, filenames.CIDataISO), "cidata", layout)
308321
}
309322

pkg/hostagent/hostagent.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ type HostAgent struct {
5555
}
5656

5757
type options struct {
58-
nerdctlArchive string // local path, not URL
58+
nerdctlArchive string // local path, not URL
59+
additionalArchives map[string]string // archive name => local path, not URL
5960
}
6061

6162
type Opt func(*options) error
@@ -67,6 +68,16 @@ func WithNerdctlArchive(s string) Opt {
6768
}
6869
}
6970

71+
func WithAdditionalArchive(name string, location string) Opt {
72+
return func(o *options) error {
73+
if o.additionalArchives == nil {
74+
o.additionalArchives = make(map[string]string)
75+
}
76+
o.additionalArchives[name] = location
77+
return nil
78+
}
79+
}
80+
7081
// New creates the HostAgent.
7182
//
7283
// stdout is for emitting JSON lines of Events.
@@ -105,7 +116,7 @@ func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt
105116
}
106117
}
107118

108-
if err := cidata.GenerateISO9660(inst.Dir, instName, y, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive); err != nil {
119+
if err := cidata.GenerateISO9660(inst.Dir, instName, y, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive, o.additionalArchives); err != nil {
109120
return nil, err
110121
}
111122

pkg/limayaml/limayaml.go

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

4041
type Arch = string

pkg/start/start.go

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,27 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML) (string, error) {
3737
return "", nil
3838
}
3939

40-
errs := make([]error, len(y.Containerd.Archives))
41-
for i, f := range y.Containerd.Archives {
42-
path, err := fileutils.DownloadFile("", f, false, "the nerdctl archive", *y.Arch)
40+
location, errs := downloadAndCacheArchiveForArch(y.Containerd.Archives, *y.Arch, "nerdctl")
41+
if location == "" {
42+
return "", fmt.Errorf("failed to download the nerdctl archive, attempted %d candidates, errors=%v",
43+
len(y.Containerd.Archives), errs)
44+
}
45+
46+
return location, nil
47+
}
48+
49+
// downloadAndCacheArchiveForArch iterates through a slice of File and tries to download the provided
50+
// file which matches the supplied arch.
51+
// The downloader caches remote downloads to disk, and then returns a file path to the archive.
52+
func downloadAndCacheArchiveForArch(files []limayaml.File, arch limayaml.Arch, archiveDescription string) (string, []error) {
53+
errs := make([]error, len(files))
54+
for i := range files {
55+
f := &files[i]
56+
if f.Arch != arch {
57+
errs[i] = fmt.Errorf("unsupported arch: %q", f.Arch)
58+
continue
59+
}
60+
path, err := fileutils.DownloadFile("", *f, false, archiveDescription, arch)
4361
if err != nil {
4462
errs[i] = err
4563
continue
@@ -48,13 +66,11 @@ func ensureNerdctlArchiveCache(y *limayaml.LimaYAML) (string, error) {
4866
if downloader.IsLocal(f.Location) {
4967
return f.Location, nil
5068
}
51-
return "", fmt.Errorf("cache did not contain %q", f.Location)
69+
errs[i] = fmt.Errorf("cache did not contain %q", f.Location)
5270
}
5371
return path, nil
5472
}
55-
56-
return "", fmt.Errorf("failed to download the nerdctl archive, attempted %d candidates, errors=%v",
57-
len(y.Containerd.Archives), errs)
73+
return "", errs
5874
}
5975

6076
func Start(ctx context.Context, inst *store.Instance) error {
@@ -121,6 +137,17 @@ func Start(ctx context.Context, inst *store.Instance) error {
121137
if nerdctlArchiveCache != "" {
122138
args = append(args, "--nerdctl-archive", nerdctlArchiveCache)
123139
}
140+
if len(y.AdditionalArchives) > 0 {
141+
for archName, archPath := range y.AdditionalArchives {
142+
location, errs := downloadAndCacheArchiveForArch(archPath, *y.Arch, fmt.Sprintf("additional archive (%s)", archName))
143+
if location == "" {
144+
return fmt.Errorf("failed to download the additionalArchive archive (%s), attempted %d candidates, errors=%v",
145+
archName, len(y.AdditionalArchives), errs)
146+
}
147+
args = append(args, "--additional-archive", fmt.Sprintf("%s=%s", archName, location))
148+
}
149+
}
150+
124151
args = append(args, inst.Name)
125152
haCmd := exec.CommandContext(ctx, self, args...)
126153

pkg/vz/vz_driver_darwin.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func (l *LimaVzDriver) Validate() error {
6565
"CACertificates",
6666
"Rosetta",
6767
"AdditionalDisks",
68+
"AdditionalArchives",
6869
); len(unknown) > 0 {
6970
logrus.Warnf("Ignoring: vmType %s: %+v", *l.Yaml.VMType, unknown)
7071
}

0 commit comments

Comments
 (0)