feat(web): uninstall the agent on device delete, prompt when unreachable (VS-70) #90
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/VS-70-delete-device-uninstall-agent"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Implements server-orchestrated device delete (VS-70). Deleting a device now uninstalls the agent from the machine instead of only dropping the DB record and leaving the agent running + reconnecting.
Behavior
On
removedevices(the user control action), per node, after the existing UNINSTALL right check:uninstallaction and wait up to 10s for the agent's ack. The agent acks BEFORE it tears down (so the server can safely delete), then removes its own unit/binary and exits. Onokack -> delete the record. Resultok.uninstall-failed, record kept.agent-unreachable, record kept. The UI shows the "Delete anyway?" prompt and re-issues with top-levelforce: true.force: true: skip the uninstall, delete the record outright (the still-installed agent must be removed manually). Resultok.Result tokens are kebab-case to match the handler's existing
ok/no-nodes/no-db/not-authorized/db-error. These strings are the contract pinned in the VS-70 issue and consumed by the vervain-apps delete dialog (VAPP-55).How
The agent control channel had no request/response correlation: every server->agent send (
AgentRegistry::send_json) was fire-and-forget, and agent replies were fanned out to user sessions bydispatch_text, never matched to an outstanding request. Added the minimum needed:AgentRegistrygains apending_uninstall_acksmap keyed byrequestid.register_uninstall_ackreturns a oneshot receiver the delete path awaits with a timeout;resolve_uninstall_ack/cancel_uninstall_ackcomplete or drop it.agent.rs::dispatch_textintercepts the agent'suninstallreply, resolves the waiter by itsresponseid, and consumes the frame (it is a server-internal ack, not a user-facing frame).user_session.rs:RemoveDevicesgains aforceflag;remove_devicesgains the uninstall orchestration via arequest_agent_uninstallhelper; the in-memory agent registry entry is dropped after the record is deleted.This is additive: the existing fire-and-forget sends and
uninstall_agentspath are untouched.Dependencies
uninstallcontrol action, acks{"action":"uninstall","ok":true,"responseid":N}, then fully removes itself.agent-unreachableto show the force prompt and re-issues withforce: true. Can merge independently; the server tolerates a UI that never sendsforce(it just never force-deletes).Verification
In the compose dev image (
docker compose -f compose.dev.yml run --rm --no-deps app cargo ...):cargo fmt --checkclean.cargo clippy --all-targets -- -D warningsclean.cargo test --lib -p vervain-web-> 418 passed, 0 failed. New tests: registry ack round-trip / unknown-id / cancel (agent_state); andremove_devicesconnected-uninstall-then-delete, unreachable-blocks, reachable-but-failed (uninstall-failed), and forced DB-only delete (user_session).End-to-end confirmation (a real connected agent self-removing on delete) lands when this deploys to staging and the mokosh-server e2e / a manual delete exercises it.
#VS-70