Skip to content

Commit 0867002

Browse files
committed
Allow providing scripts as separate files
Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
1 parent e186a84 commit 0867002

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

examples/default.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ containerd:
208208
# Provisioning scripts need to be idempotent because they might be called
209209
# multiple times, e.g. when the host VM is being restarted.
210210
# The scripts can use the following template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}}
211+
# They can be provided inline (as field `script`), or in external files (as field `path`).
211212
# 🟢 Builtin default: null
212213
# provision:
213214
# # `system` is executed with root privileges
@@ -251,6 +252,7 @@ containerd:
251252
# Probe scripts to check readiness.
252253
# The scripts run in user mode. They must start with a '#!' line.
253254
# The scripts can use the following template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}}
255+
# They can be provided inline (as field `script`), or in external files (as field `path`).
254256
# 🟢 Builtin default: null
255257
# probes:
256258
# # Only `readiness` probes are supported right now.

pkg/cidata/cidata.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,11 +332,19 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS
332332
}
333333

334334
for i, f := range instConfig.Provision {
335+
script := f.Script
336+
if f.Path != "" {
337+
b, err := os.ReadFile(f.Path)
338+
if err != nil {
339+
return err
340+
}
341+
script = string(b)
342+
}
335343
switch f.Mode {
336344
case limayaml.ProvisionModeSystem, limayaml.ProvisionModeUser, limayaml.ProvisionModeDependency:
337345
layout = append(layout, iso9660util.Entry{
338346
Path: fmt.Sprintf("provision.%s/%08d", f.Mode, i),
339-
Reader: strings.NewReader(f.Script),
347+
Reader: strings.NewReader(script),
340348
})
341349
case limayaml.ProvisionModeBoot:
342350
continue
@@ -415,8 +423,16 @@ func getBootCmds(p []limayaml.Provision) ([]BootCmds, error) {
415423
if f.Mode != limayaml.ProvisionModeBoot {
416424
continue
417425
}
426+
script := f.Script
427+
if f.Path != "" {
428+
b, err := os.ReadFile(f.Path)
429+
if err != nil {
430+
return nil, err
431+
}
432+
script = string(b)
433+
}
418434
lines := []string{}
419-
for _, line := range strings.Split(f.Script, "\n") {
435+
for _, line := range strings.Split(script, "\n") {
420436
if line == "" {
421437
continue
422438
}

pkg/hostagent/requirements.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package hostagent
33
import (
44
"errors"
55
"fmt"
6+
"os"
67
"time"
78

89
"github.com/lima-vm/lima/pkg/limayaml"
@@ -201,10 +202,19 @@ Also see "/var/log/cloud-init-output.log" in the guest.
201202
})
202203
}
203204
for _, probe := range a.instConfig.Probes {
205+
script := probe.Script
206+
if probe.Path != "" {
207+
b, err := os.ReadFile(probe.Path)
208+
if err != nil {
209+
logrus.WithError(err).Errorf("failed to read script %q", probe.Path)
210+
continue
211+
}
212+
script = string(b)
213+
}
204214
if probe.Mode == limayaml.ProbeModeReadiness {
205215
req = append(req, requirement{
206216
description: probe.Description,
207-
script: probe.Script,
217+
script: script,
208218
debugHint: probe.Hint,
209219
})
210220
}

pkg/limayaml/limayaml.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ type Provision struct {
198198
Mode ProvisionMode `yaml:"mode" json:"mode"` // default: "system"
199199
SkipDefaultDependencyResolution *bool `yaml:"skipDefaultDependencyResolution,omitempty" json:"skipDefaultDependencyResolution,omitempty"`
200200
Script string `yaml:"script" json:"script"`
201+
Path string `yaml:"path,omitempty" json:"path,omitempty"`
201202
Playbook string `yaml:"playbook,omitempty" json:"playbook,omitempty"`
202203
}
203204

@@ -217,6 +218,7 @@ type Probe struct {
217218
Mode ProbeMode // default: "readiness"
218219
Description string
219220
Script string
221+
Path string `yaml:",omitempty" json:",omitempty"`
220222
Hint string
221223
}
222224

pkg/limayaml/validate.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@ func Validate(y *LimaYAML, warn bool) error {
208208
return fmt.Errorf("field `provision[%d].mode` must one of %q, %q, %q, %q, or %q",
209209
i, ProvisionModeSystem, ProvisionModeUser, ProvisionModeBoot, ProvisionModeDependency, ProvisionModeAnsible)
210210
}
211+
if p.Path != "" {
212+
if p.Script != "" {
213+
return fmt.Errorf("field `provision[%d].script must be empty if path is set", i)
214+
}
215+
if _, err := os.Stat(p.Path); err != nil {
216+
return fmt.Errorf("field `provision[%d].path` refers to an inaccessible path: %q: %w", i, p.Path, err)
217+
}
218+
}
211219
if strings.Contains(p.Script, "LIMA_CIDATA") {
212220
logrus.Warn("provisioning scripts should not reference the LIMA_CIDATA variables")
213221
}
@@ -232,6 +240,14 @@ func Validate(y *LimaYAML, warn bool) error {
232240
default:
233241
return fmt.Errorf("field `probe[%d].mode` can only be %q", i, ProbeModeReadiness)
234242
}
243+
if p.Path != "" {
244+
if p.Script != "" {
245+
return fmt.Errorf("field `probe[%d].script must be empty if path is set", i)
246+
}
247+
if _, err := os.Stat(p.Path); err != nil {
248+
return fmt.Errorf("field `probe[%d].path` refers to an inaccessible path: %q: %w", i, p.Path, err)
249+
}
250+
}
235251
}
236252
for i, rule := range y.PortForwards {
237253
field := fmt.Sprintf("portForwards[%d]", i)

0 commit comments

Comments
 (0)