engine: resources, modules: virtualization: Add a seeds option

This makes it easier to configure the machine by giving it an automatic
initial setup of an mgmt client.
This commit is contained in:
James Shubin
2025-03-11 00:03:56 -04:00
parent 181aab9c81
commit 219d25b330
2 changed files with 44 additions and 3 deletions

View File

@@ -33,6 +33,7 @@ import (
"bytes"
"context"
"fmt"
"net/url"
"os"
"os/exec"
"path"
@@ -146,9 +147,13 @@ type VirtBuilderRes struct {
// additional packages to install which are needed to bootstrap mgmt.
// This defaults to true.
// TODO: This does not yet support multi or cross arch.
// FIXME: This doesn't kick off mgmt runs yet.
Bootstrap bool `lang:"bootstrap" yaml:"bootstrap"`
// Seeds is a list of default etcd client endpoints to connect to. If
// you specify this, you must also set Bootstrap to true. These should
// likely be http URL's like: http://127.0.0.1:2379 or similar.
Seeds []string `lang:"seeds" yaml:"seeds"`
// LogOutput logs the output of running this command to a file in the
// special $vardir directory. It defaults to true. Keep in mind that if
// you let virt-builder choose the password randomly, it will be output
@@ -305,6 +310,15 @@ func (obj *VirtBuilderRes) Validate() error {
}
}
for _, x := range obj.Seeds {
if x == "" {
return fmt.Errorf("empty seed")
}
if _, err := url.Parse(x); err != nil { // it's so rare this fails
return err
}
}
return nil
}
@@ -501,8 +515,24 @@ func (obj *VirtBuilderRes) CheckApply(ctx context.Context, apply bool) (bool, er
// TODO: bootstrap mgmt based on the deploy method this ran with
// TODO: --tmp-prefix ? --module-path ?
//args2 := []string{"--firstboot-command", VirtBuilderBinDir+"mgmt", "run", "lang", "?"}
//cmdArgs = append(cmdArgs, args2...)
// TODO: add an alternate handoff method to run a bolus of code?
if len(obj.Seeds) > 0 {
m := filepath.Join(VirtBuilderBinDir, filepath.Base(p)) // mgmt full path
setupSvc := []string{
m, // mgmt
"setup", // setup command
"svc", // TODO: pull from a const?
"--install",
//"--start", // we're in pre-boot env right now
"--enable", // start on first boot!
fmt.Sprintf("--binary-path=%s", m),
"--no-server", // TODO: hardcode this for now
fmt.Sprintf("--seeds=%s", strings.Join(obj.Seeds, ",")),
}
setupSvcCmd := strings.Join(setupSvc, " ")
args := []string{"--run-command", setupSvcCmd} // cmd must be a single string
cmdArgs = append(cmdArgs, args...)
}
}
cmd := exec.CommandContext(ctx, cmdName, cmdArgs...)
@@ -644,6 +674,15 @@ func (obj *VirtBuilderRes) Cmp(r engine.Res) error {
return fmt.Errorf("the Bootstrap value differs")
}
if len(obj.Seeds) != len(res.Seeds) {
return fmt.Errorf("the number of Seeds differs")
}
for i, x := range obj.Seeds {
if seed := res.Seeds[i]; x != seed {
return fmt.Errorf("the seed at index %d differs", i)
}
}
if obj.LogOutput != res.LogOutput {
return fmt.Errorf("the LogOutput value differs")
}

View File

@@ -97,6 +97,7 @@ class vm($name, $config) {
} else { # other distros TODO: add a switch or else if?
[]
}
$seeds = $config->seeds || []
virt:builder "${filename}" {
hostname => $name,
@@ -115,6 +116,7 @@ class vm($name, $config) {
},
],
root_password_selector => $root_password_selector,
seeds => $seeds,
# make sure key exists so that's it's available for injection!
Depend => File["/root/.ssh/id_rsa"],