Skip to content

Commit 5a8acb4

Browse files
committed
Support ansible provision mode for remote playbook
Signed-off-by: Anders F Björklund <[email protected]>
1 parent 13f1a58 commit 5a8acb4

File tree

6 files changed

+78
-2
lines changed

6 files changed

+78
-2
lines changed

pkg/cidata/cidata.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
334334
})
335335
case limayaml.ProvisionModeBoot:
336336
continue
337+
case limayaml.ProvisionModeAnsible:
338+
continue
337339
default:
338340
return fmt.Errorf("unknown provision mode %q", f.Mode)
339341
}

pkg/limayaml/limayaml.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,14 @@ const (
180180
ProvisionModeUser ProvisionMode = "user"
181181
ProvisionModeBoot ProvisionMode = "boot"
182182
ProvisionModeDependency ProvisionMode = "dependency"
183+
ProvisionModeAnsible ProvisionMode = "ansible"
183184
)
184185

185186
type Provision struct {
186187
Mode ProvisionMode `yaml:"mode" json:"mode"` // default: "system"
187188
SkipDefaultDependencyResolution *bool `yaml:"skipDefaultDependencyResolution,omitempty" json:"skipDefaultDependencyResolution,omitempty"`
188189
Script string `yaml:"script" json:"script"`
190+
Playbook string `yaml:"playbook,omitempty" json:"playbook,omitempty"`
189191
}
190192

191193
type Containerd struct {

pkg/limayaml/validate.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,10 @@ func Validate(y LimaYAML, warn bool) error {
183183
i, ProvisionModeDependency)
184184
}
185185
case ProvisionModeDependency:
186+
case ProvisionModeAnsible:
186187
default:
187-
return fmt.Errorf("field `provision[%d].mode` must one of %q, %q, %q, or %q",
188-
i, ProvisionModeSystem, ProvisionModeUser, ProvisionModeBoot, ProvisionModeDependency)
188+
return fmt.Errorf("field `provision[%d].mode` must one of %q, %q, %q, %q, or %q",
189+
i, ProvisionModeSystem, ProvisionModeUser, ProvisionModeBoot, ProvisionModeDependency, ProvisionModeAnsible)
189190
}
190191
if strings.Contains(p.Script, "LIMA_CIDATA") {
191192
logrus.Warn("provisioning scripts should not reference the LIMA_CIDATA variables")

pkg/start/ansible.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package start
2+
3+
import (
4+
"context"
5+
"os"
6+
"os/exec"
7+
"path/filepath"
8+
9+
"github.com/goccy/go-yaml"
10+
"github.com/lima-vm/lima/pkg/limayaml"
11+
"github.com/lima-vm/lima/pkg/store"
12+
"github.com/lima-vm/lima/pkg/store/filenames"
13+
"github.com/sirupsen/logrus"
14+
)
15+
16+
func runAnsibleProvision(ctx context.Context, inst *store.Instance) error {
17+
y, err := inst.LoadYAML()
18+
if err != nil {
19+
return err
20+
}
21+
for _, f := range y.Provision {
22+
if f.Mode == limayaml.ProvisionModeAnsible {
23+
logrus.Infof("Waiting for ansible playbook %q", f.Playbook)
24+
if err := runAnsiblePlaybook(ctx, inst, f.Playbook); err != nil {
25+
return err
26+
}
27+
}
28+
}
29+
return nil
30+
}
31+
32+
func runAnsiblePlaybook(ctx context.Context, inst *store.Instance, playbook string) error {
33+
inventory, err := createInventory(inst)
34+
if err != nil {
35+
return err
36+
}
37+
logrus.Debugf("ansible-playbook -i %q %q", inventory, playbook)
38+
args := []string{"-i", inventory, playbook}
39+
cmd := exec.CommandContext(ctx, "ansible-playbook", args...)
40+
cmd.Stdout = os.Stdout
41+
cmd.Stderr = os.Stderr
42+
return cmd.Run()
43+
}
44+
45+
func createInventory(inst *store.Instance) (string, error) {
46+
vars := map[string]interface{}{
47+
"ansible_connection": "ssh",
48+
"ansible_host": "lima-" + inst.Name,
49+
"ansible_ssh_common_args": "-F " + inst.SSHConfigFile,
50+
}
51+
hosts := map[string]interface{}{
52+
inst.Name: vars,
53+
}
54+
group := "lima"
55+
data := map[string]interface{}{
56+
group: map[string]interface{}{
57+
"hosts": hosts,
58+
},
59+
}
60+
bytes, err := yaml.Marshal(data)
61+
if err != nil {
62+
return "", err
63+
}
64+
inventory := filepath.Join(inst.Dir, filenames.InventoryYAML)
65+
return inventory, os.WriteFile(inventory, bytes, 0o644)
66+
}

pkg/start/start.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ func watchHostAgentEvents(ctx context.Context, inst *store.Instance, haStdoutPat
291291
return true
292292
}
293293

294+
if xerr := runAnsibleProvision(ctx, inst); xerr != nil {
295+
err = xerr
296+
return true
297+
}
294298
if *inst.Config.Plain {
295299
logrus.Infof("READY. Run `ssh -F %q lima-%s` to open the shell.", inst.SSHConfigFile, inst.Name)
296300
} else {

pkg/store/filenames/filenames.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const (
5656
VzIdentifier = "vz-identifier"
5757
VzEfi = "vz-efi" // efi variable store
5858
QemuEfiCodeFD = "qemu-efi-code.fd" // efi code; not always created
59+
InventoryYAML = "inventory.yaml" // ansible inventory
5960

6061
// SocketDir is the default location for forwarded sockets with a relative paths in HostSocket
6162
SocketDir = "sock"

0 commit comments

Comments
 (0)