remove vm session feature
Cuts the daemon-managed guest-session machinery (start/list/show/
logs/stop/kill/attach/send). The feature shipped aimed at agent-
orchestration workflows (programmatic stdin piping into a long-lived
guest process) that aren't driving any concrete user today, and the
~2.3K LOC of daemon surface area — attach bridge, FIFO keepalive,
controller registry, sessionstream framing, SQLite persistence — was
locking in an API we'd have to keep through v0.1.0.
Anything session-flavoured that people actually need today can be
done with `vm ssh + tmux` or `vm run -- cmd`.
Deleted:
- internal/cli/commands_vm_session.go
- internal/daemon/{guest_sessions,session_lifecycle,session_attach,session_stream,session_controller}.go
- internal/daemon/session/ (guest-session helpers package)
- internal/sessionstream/ (framing package)
- internal/daemon/guest_sessions_test.go
- internal/store/guest_session_test.go
- GuestSession* types from internal/{api,model}
- Store UpsertGuestSession/GetGuestSession/ListGuestSessionsByVM/DeleteGuestSession + scanner helpers
- guest.session.* RPC dispatch entries
- 5 CLI session tests, 2 completion tests, 2 printer tests
Extracted:
- ShellQuote + FormatStepError lifted to internal/daemon/workspace/util.go
(only non-session consumer); workspace package now self-contained
- internal/daemon/guest_ssh.go keeps guestSSHClient + dialGuest +
waitForGuestSSH — still used by workspace prepare/export
- internal/daemon/fake_firecracker_test.go preserves the test helper
that used to live in guest_sessions_test.go
Store schema: CREATE TABLE guest_sessions and its column migrations
removed. Existing dev DBs keep an orphan table (harmless, pre-v0.1.0).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c42fcbe012
commit
2b6437d1b4
34 changed files with 194 additions and 4031 deletions
|
|
@ -1918,34 +1918,9 @@ func (c *testVMRunGuestClient) StreamTarEntries(ctx context.Context, sourceDir s
|
|||
return nil
|
||||
}
|
||||
|
||||
func TestVMSessionSendCommandExists(t *testing.T) {
|
||||
root := NewBangerCommand()
|
||||
vm, _, err := root.Find([]string{"vm"})
|
||||
if err != nil {
|
||||
t.Fatalf("find vm: %v", err)
|
||||
}
|
||||
session, _, err := vm.Find([]string{"session"})
|
||||
if err != nil {
|
||||
t.Fatalf("find session: %v", err)
|
||||
}
|
||||
if _, _, err := session.Find([]string{"send"}); err != nil {
|
||||
t.Fatalf("find session send: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMSessionSendRejectsWrongArgCount(t *testing.T) {
|
||||
cmd := NewBangerCommand()
|
||||
cmd.SetArgs([]string{"vm", "session", "send", "only-one-arg"})
|
||||
err := cmd.Execute()
|
||||
if err == nil || !strings.Contains(err.Error(), "usage: banger vm session send") {
|
||||
t.Fatalf("Execute() error = %v, want send usage error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// stubEnsureDaemonForSend isolates XDG dirs and installs a daemon-ping
|
||||
// fake onto the caller's *deps so `ensureDaemon` short-circuits without
|
||||
// trying to spawn bangerd. `vm session send` uses this to avoid needing
|
||||
// a built binary on disk.
|
||||
// trying to spawn bangerd.
|
||||
func stubEnsureDaemonForSend(t *testing.T, d *deps) {
|
||||
t.Helper()
|
||||
t.Setenv("XDG_CONFIG_HOME", filepath.Join(t.TempDir(), "config"))
|
||||
|
|
@ -1956,98 +1931,6 @@ func stubEnsureDaemonForSend(t *testing.T, d *deps) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestVMSessionSendWithMessageFlag(t *testing.T) {
|
||||
d := defaultDeps()
|
||||
stubEnsureDaemonForSend(t, d)
|
||||
|
||||
var capturedParams api.GuestSessionSendParams
|
||||
d.guestSessionSend = func(_ context.Context, _ string, params api.GuestSessionSendParams) (api.GuestSessionSendResult, error) {
|
||||
capturedParams = params
|
||||
return api.GuestSessionSendResult{
|
||||
Session: model.GuestSession{ID: "sess-id", Name: "planner"},
|
||||
BytesWritten: len(params.Payload),
|
||||
}, nil
|
||||
}
|
||||
|
||||
cmd := d.newRootCommand()
|
||||
var out bytes.Buffer
|
||||
cmd.SetOut(&out)
|
||||
cmd.SetArgs([]string{"vm", "session", "send", "devbox", "planner", "--message", `{"type":"abort"}`})
|
||||
if err := cmd.Execute(); err != nil {
|
||||
t.Fatalf("Execute: %v", err)
|
||||
}
|
||||
|
||||
wantPayload := []byte(`{"type":"abort"}` + "\n")
|
||||
if string(capturedParams.Payload) != string(wantPayload) {
|
||||
t.Fatalf("payload = %q, want %q", capturedParams.Payload, wantPayload)
|
||||
}
|
||||
if capturedParams.VMIDOrName != "devbox" {
|
||||
t.Fatalf("VMIDOrName = %q, want %q", capturedParams.VMIDOrName, "devbox")
|
||||
}
|
||||
if capturedParams.SessionIDOrName != "planner" {
|
||||
t.Fatalf("SessionIDOrName = %q, want %q", capturedParams.SessionIDOrName, "planner")
|
||||
}
|
||||
if !strings.Contains(out.String(), "17") {
|
||||
t.Fatalf("output = %q, want bytes_written in output", out.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMSessionSendMessageAlreadyHasNewline(t *testing.T) {
|
||||
d := defaultDeps()
|
||||
stubEnsureDaemonForSend(t, d)
|
||||
|
||||
var capturedPayload []byte
|
||||
d.guestSessionSend = func(_ context.Context, _ string, params api.GuestSessionSendParams) (api.GuestSessionSendResult, error) {
|
||||
capturedPayload = params.Payload
|
||||
return api.GuestSessionSendResult{
|
||||
Session: model.GuestSession{Name: "s"},
|
||||
BytesWritten: len(params.Payload),
|
||||
}, nil
|
||||
}
|
||||
|
||||
cmd := d.newRootCommand()
|
||||
cmd.SetOut(io.Discard)
|
||||
cmd.SetArgs([]string{"vm", "session", "send", "devbox", "s", "--message", "{\"type\":\"abort\"}\n"})
|
||||
if err := cmd.Execute(); err != nil {
|
||||
t.Fatalf("Execute: %v", err)
|
||||
}
|
||||
|
||||
// Must not double-append newline.
|
||||
if capturedPayload[len(capturedPayload)-1] != '\n' {
|
||||
t.Fatalf("payload missing trailing newline: %q", capturedPayload)
|
||||
}
|
||||
if len(capturedPayload) > 0 && capturedPayload[len(capturedPayload)-2] == '\n' {
|
||||
t.Fatalf("payload has double trailing newline: %q", capturedPayload)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMSessionSendFromStdin(t *testing.T) {
|
||||
d := defaultDeps()
|
||||
stubEnsureDaemonForSend(t, d)
|
||||
|
||||
var capturedPayload []byte
|
||||
d.guestSessionSend = func(_ context.Context, _ string, params api.GuestSessionSendParams) (api.GuestSessionSendResult, error) {
|
||||
capturedPayload = params.Payload
|
||||
return api.GuestSessionSendResult{
|
||||
Session: model.GuestSession{Name: "planner"},
|
||||
BytesWritten: len(params.Payload),
|
||||
}, nil
|
||||
}
|
||||
|
||||
stdinPayload := `{"type":"steer","message":"Focus on src/"}` + "\n"
|
||||
cmd := d.newRootCommand()
|
||||
cmd.SetOut(io.Discard)
|
||||
cmd.SetIn(strings.NewReader(stdinPayload))
|
||||
cmd.SetArgs([]string{"vm", "session", "send", "devbox", "planner"})
|
||||
if err := cmd.Execute(); err != nil {
|
||||
t.Fatalf("Execute: %v", err)
|
||||
}
|
||||
|
||||
if string(capturedPayload) != stdinPayload {
|
||||
t.Fatalf("payload = %q, want %q", capturedPayload, stdinPayload)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMWorkspaceExportCommandExists(t *testing.T) {
|
||||
root := NewBangerCommand()
|
||||
vm, _, err := root.Find([]string{"vm"})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue