Make installed banger self-contained
Fix the misleading make install path where banger and bangerd still depended on a repo checkout for Firecracker, guest artifacts, image builds, and the SSH key. Replace repo-root inference with an explicit runtime bundle model: resolve a runtime_dir from env/config/install layout, derive concrete artifact paths from it, and update the daemon, CLI, and image-build flow to use those paths. Keep repo_root only as an explicit compatibility alias instead of auto-detecting it. Teach customize.sh to run from a read-only bundled runtime tree while writing transient state under XDG/BANGER_STATE_DIR, and make make install copy the runtime assets into PREFIX/lib/banger so installed binaries stay usable outside the repo. Validate with go test ./..., make build, bash -n customize.sh, and make install DESTDIR=/tmp/banger-install PREFIX=/usr. An out-of-repo installed-binary smoke test was attempted, but this sandbox blocked bangerd from binding its Unix socket (setsockopt: operation not permitted).
This commit is contained in:
parent
375900cf65
commit
ce1be52047
13 changed files with 437 additions and 107 deletions
|
|
@ -131,6 +131,7 @@ func newVMCommand() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
|
||||
func newVMCreateCommand() *cobra.Command {
|
||||
var params api.VMCreateParams
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -372,6 +373,9 @@ func newImageBuildCommand() *cobra.Command {
|
|||
Short: "Build an image",
|
||||
Args: noArgsUsage("usage: banger image build"),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := absolutizeImageBuildPaths(¶ms); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := system.EnsureSudo(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -631,14 +635,28 @@ func sshCommandArgs(cfg model.DaemonConfig, guestIP string, extra []string) ([]s
|
|||
return nil, errors.New("vm has no guest IP")
|
||||
}
|
||||
args := []string{}
|
||||
if cfg.RepoRoot != "" {
|
||||
args = append(args, "-i", filepath.Join(cfg.RepoRoot, "id_ed25519"))
|
||||
if cfg.SSHKeyPath != "" {
|
||||
args = append(args, "-i", cfg.SSHKeyPath)
|
||||
}
|
||||
args = append(args, "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "root@"+guestIP)
|
||||
args = append(args, extra...)
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func absolutizeImageBuildPaths(params *api.ImageBuildParams) error {
|
||||
var err error
|
||||
for _, value := range []*string{¶ms.BaseRootfs, ¶ms.KernelPath, ¶ms.InitrdPath, ¶ms.ModulesDir} {
|
||||
if *value == "" || filepath.IsAbs(*value) {
|
||||
continue
|
||||
}
|
||||
*value, err = filepath.Abs(*value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printJSON(out anyWriter, v any) error {
|
||||
data, err := json.MarshalIndent(v, "", " ")
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"banger/internal/api"
|
||||
"banger/internal/model"
|
||||
)
|
||||
|
||||
|
|
@ -38,6 +39,7 @@ func TestVMCreateFlagsExist(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
func TestVMSetParamsFromFlags(t *testing.T) {
|
||||
params, err := vmSetParamsFromFlags("devbox", 4, 2048, "16G", true, false)
|
||||
if err != nil {
|
||||
|
|
@ -64,12 +66,12 @@ func TestVMSetParamsFromFlagsConflict(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSSHCommandArgs(t *testing.T) {
|
||||
args, err := sshCommandArgs(model.DaemonConfig{RepoRoot: "/repo"}, "172.16.0.2", []string{"--", "uname", "-a"})
|
||||
args, err := sshCommandArgs(model.DaemonConfig{SSHKeyPath: "/bundle/id_ed25519"}, "172.16.0.2", []string{"--", "uname", "-a"})
|
||||
if err != nil {
|
||||
t.Fatalf("sshCommandArgs: %v", err)
|
||||
}
|
||||
want := []string{
|
||||
"-i", "/repo/id_ed25519",
|
||||
"-i", "/bundle/id_ed25519",
|
||||
"-o", "StrictHostKeyChecking=no",
|
||||
"-o", "UserKnownHostsFile=/dev/null",
|
||||
"root@172.16.0.2",
|
||||
|
|
@ -127,3 +129,37 @@ func TestDaemonOutdated(t *testing.T) {
|
|||
t.Fatal("expected replaced daemon executable to be outdated")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAbsolutizeImageBuildPaths(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
prev, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("getwd: %v", err)
|
||||
}
|
||||
if err := os.Chdir(dir); err != nil {
|
||||
t.Fatalf("chdir: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_ = os.Chdir(prev)
|
||||
})
|
||||
|
||||
params := api.ImageBuildParams{
|
||||
BaseRootfs: "images/base.ext4",
|
||||
KernelPath: "/kernel",
|
||||
InitrdPath: "boot/initrd.img",
|
||||
ModulesDir: "modules",
|
||||
}
|
||||
if err := absolutizeImageBuildPaths(¶ms); err != nil {
|
||||
t.Fatalf("absolutizeImageBuildPaths: %v", err)
|
||||
}
|
||||
|
||||
want := api.ImageBuildParams{
|
||||
BaseRootfs: filepath.Join(dir, "images/base.ext4"),
|
||||
KernelPath: "/kernel",
|
||||
InitrdPath: filepath.Join(dir, "boot/initrd.img"),
|
||||
ModulesDir: filepath.Join(dir, "modules"),
|
||||
}
|
||||
if !reflect.DeepEqual(params, want) {
|
||||
t.Fatalf("params = %+v, want %+v", params, want)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue