Add vsock-backed SSH session reminders
Remind users when a VM is still running after hanger vm ssh exits instead of silently dropping them back to the host shell.\n\nAttach a Firecracker vsock device to each VM, persist the host vsock path/CID,\nadd a new guest-side banger-vsock-pingd responder to the runtime bundle and both\nimage-build paths, and expose a vm.ping RPC that the CLI and TUI call after SSH\nreturns. Doctor and start/build preflight now validate the helper plus\n/dev/vhost-vsock so the feature fails early and clearly.\n\nValidated with go mod tidy, bash -n customize.sh, git diff --check, make build,\nand GOCACHE=/tmp/banger-gocache go test ./... outside the sandbox because the\ndaemon tests need real Unix/UDP sockets. Rebuild the image/rootfs used for new\nVMs so the guest ping service is present.
This commit is contained in:
parent
4930d82cb9
commit
08ef706e3f
31 changed files with 912 additions and 75 deletions
|
|
@ -43,6 +43,11 @@ func TestNewDaemonLoggerEmitsJSONAtConfiguredLevel(t *testing.T) {
|
|||
|
||||
func TestStartVMLockedLogsBridgeFailure(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
origVsockHostDevicePath := vsockHostDevicePath
|
||||
vsockHostDevicePath = filepath.Join(t.TempDir(), "vhost-vsock")
|
||||
t.Cleanup(func() {
|
||||
vsockHostDevicePath = origVsockHostDevicePath
|
||||
})
|
||||
binDir := t.TempDir()
|
||||
for _, name := range []string{
|
||||
"sudo", "ip", "dmsetup", "losetup", "blockdev", "truncate", "pgrep", "ps",
|
||||
|
|
@ -54,9 +59,16 @@ func TestStartVMLockedLogsBridgeFailure(t *testing.T) {
|
|||
t.Setenv("PATH", binDir)
|
||||
|
||||
firecrackerBin := filepath.Join(t.TempDir(), "firecracker")
|
||||
vsockHelper := filepath.Join(t.TempDir(), "banger-vsock-pingd")
|
||||
if err := os.WriteFile(firecrackerBin, []byte("#!/bin/sh\nexit 0\n"), 0o755); err != nil {
|
||||
t.Fatalf("write firecracker: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(vsockHostDevicePath, []byte{}, 0o644); err != nil {
|
||||
t.Fatalf("write vsock host device: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(vsockHelper, []byte("#!/bin/sh\nexit 0\n"), 0o755); err != nil {
|
||||
t.Fatalf("write vsock helper: %v", err)
|
||||
}
|
||||
rootfsPath := filepath.Join(t.TempDir(), "rootfs.ext4")
|
||||
kernelPath := filepath.Join(t.TempDir(), "vmlinux")
|
||||
for _, path := range []string{rootfsPath, kernelPath} {
|
||||
|
|
@ -93,11 +105,12 @@ func TestStartVMLockedLogsBridgeFailure(t *testing.T) {
|
|||
d := &Daemon{
|
||||
layout: paths.Layout{RuntimeDir: filepath.Join(t.TempDir(), "runtime")},
|
||||
config: model.DaemonConfig{
|
||||
BridgeName: "br-fc",
|
||||
BridgeIP: model.DefaultBridgeIP,
|
||||
DefaultDNS: model.DefaultDNS,
|
||||
FirecrackerBin: firecrackerBin,
|
||||
StatsPollInterval: model.DefaultStatsPollInterval,
|
||||
BridgeName: "br-fc",
|
||||
BridgeIP: model.DefaultBridgeIP,
|
||||
DefaultDNS: model.DefaultDNS,
|
||||
FirecrackerBin: firecrackerBin,
|
||||
VSockPingHelperPath: vsockHelper,
|
||||
StatsPollInterval: model.DefaultStatsPollInterval,
|
||||
},
|
||||
runner: runner,
|
||||
logger: logger,
|
||||
|
|
@ -138,11 +151,15 @@ func TestBuildImagePreservesBuildLogOnFailure(t *testing.T) {
|
|||
packagesPath := filepath.Join(t.TempDir(), "packages.apt")
|
||||
sshKeyPath := filepath.Join(t.TempDir(), "id_ed25519")
|
||||
firecrackerBin := filepath.Join(t.TempDir(), "firecracker")
|
||||
vsockHelper := filepath.Join(t.TempDir(), "banger-vsock-pingd")
|
||||
for _, path := range []string{baseRootfs, kernelPath, packagesPath, sshKeyPath} {
|
||||
if err := os.WriteFile(path, []byte("artifact"), 0o644); err != nil {
|
||||
t.Fatalf("write %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
if err := os.WriteFile(vsockHelper, []byte("#!/bin/sh\nexit 0\n"), 0o755); err != nil {
|
||||
t.Fatalf("write %s: %v", vsockHelper, err)
|
||||
}
|
||||
if err := os.WriteFile(firecrackerBin, []byte("#!/bin/sh\nexit 0\n"), 0o755); err != nil {
|
||||
t.Fatalf("write %s: %v", firecrackerBin, err)
|
||||
}
|
||||
|
|
@ -169,6 +186,7 @@ func TestBuildImagePreservesBuildLogOnFailure(t *testing.T) {
|
|||
DefaultPackagesFile: packagesPath,
|
||||
SSHKeyPath: sshKeyPath,
|
||||
FirecrackerBin: firecrackerBin,
|
||||
VSockPingHelperPath: vsockHelper,
|
||||
},
|
||||
store: store,
|
||||
runner: runner,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue