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:
Thales Maciel 2026-03-18 20:14:51 -03:00
parent 4930d82cb9
commit 08ef706e3f
No known key found for this signature in database
GPG key ID: 33112E6833C34679
31 changed files with 912 additions and 75 deletions

View file

@ -2,12 +2,14 @@ package cli
import (
"context"
"errors"
"os"
"path/filepath"
"strings"
"testing"
"time"
"banger/internal/api"
"banger/internal/model"
"banger/internal/paths"
@ -236,6 +238,41 @@ func TestTUIStatusIncludesStageDurationsAfterInitialLoad(t *testing.T) {
}
}
func TestSSHDoneMsgShowsReminderWhenPingAlive(t *testing.T) {
origPing := vmPingFunc
t.Cleanup(func() {
vmPingFunc = origPing
})
vmPingFunc = func(ctx context.Context, socketPath, idOrName string) (api.VMPingResult, error) {
return api.VMPingResult{Name: "devbox", Alive: true}, nil
}
msg := sshDoneMsg(paths.Layout{SocketPath: "/tmp/bangerd.sock"}, actionRequest{id: "devbox", name: "devbox"}, "devbox", nil)
result, ok := msg.(actionResultMsg)
if !ok {
t.Fatalf("msg = %T, want actionResultMsg", msg)
}
if !strings.Contains(result.status, "devbox is still running") {
t.Fatalf("status = %q, want reminder", result.status)
}
}
func TestSSHDoneMsgShowsWarningWhenPingFails(t *testing.T) {
origPing := vmPingFunc
t.Cleanup(func() {
vmPingFunc = origPing
})
vmPingFunc = func(ctx context.Context, socketPath, idOrName string) (api.VMPingResult, error) {
return api.VMPingResult{}, errors.New("dial failed")
}
msg := sshDoneMsg(paths.Layout{SocketPath: "/tmp/bangerd.sock"}, actionRequest{id: "devbox", name: "devbox"}, "devbox", nil)
result := msg.(actionResultMsg)
if !strings.Contains(result.status, "failed to check whether devbox is still running") {
t.Fatalf("status = %q, want warning", result.status)
}
}
func TestAggregateRunningVMResources(t *testing.T) {
t.Parallel()