Skip to content

Commit 344c010

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

File tree

6 files changed

+77
-2
lines changed

6 files changed

+77
-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
@@ -178,12 +178,14 @@ const (
178178
ProvisionModeUser ProvisionMode = "user"
179179
ProvisionModeBoot ProvisionMode = "boot"
180180
ProvisionModeDependency ProvisionMode = "dependency"
181+
ProvisionModeAnsible ProvisionMode = "ansible"
181182
)
182183

183184
type Provision struct {
184185
Mode ProvisionMode `yaml:"mode" json:"mode"` // default: "system"
185186
SkipDefaultDependencyResolution *bool `yaml:"skipDefaultDependencyResolution,omitempty" json:"skipDefaultDependencyResolution,omitempty"`
186187
Script string `yaml:"script" json:"script"`
188+
Playbook string `yaml:"playbook,omitempty" json:"playbook,omitempty"`
187189
}
188190

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

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)