P2 completion (P2R-09/10/11/12/13/14, P2-16/17/18) #5
Reference in New Issue
Block a user
Delete Branch "p2-completion"
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?
Summary
Closes every remaining P2 item in tasks.md. 15 commits on this branch; full test suite green under
-race.--limit-upload/--limit-downloadon every restic invocation; host-wide viaconfig.update, per-job override via<details>disclosure on Run-nowLatestJobBySchedule+ cronNext()derivation, surfaced in dashboard row + schedules tabsvc.Handler+ SCMinstall/uninstall/start/stopsubcommands. Cross-compile verified; untested on Windows itselfinstall.ps1— pwsh installer mirroringinstall.sh, served from/install/Decisions made on the operator's behalf
<details>disclosure rather than modalinitjob (relies on restic's idempotent init); does not try to wipe S3/B2 bucketsTest plan
go vet ./... && go test ./... -race(green)GOOS=windows GOARCH=amd64 go build ./cmd/agent_diag/p2-completion-sweep/)-enroll-token, watch fingerprint print, accept from UI)P2R-13a. restic.Env gains LimitUploadKBps/LimitDownloadKBps which are emitted as global --limit-upload/--limit-download flags before the subcommand on every invocation. Agent dispatcher tracks host-wide caps received via config.update; server pushes them on hello and after PUT /api/hosts/{id}/bandwidth. Also extends api.CommandRunPayload with optional per-job overrides (BandwidthUpKBps/Down + PreHook/PostHook); the override consumers land in T2/T6.P2R-13b. POST /hosts/{id}/source-groups/{gid}/run accepts optional bandwidth_up_kbps / bandwidth_down_kbps form fields, plumbs them onto CommandRunPayload. Agent dispatcher already prefers per-job override over host-wide caps (T1). UI wraps the Run-now button in a form with a <details> 'Limit bandwidth for this run' disclosure containing two KB/s inputs.Latest 'init' job status surfaced under the host-detail vitals strip (succeeded/failed/running/queued, with link to the live job log on non-success). New POST /hosts/{id}/repo/reinit handler dispatches a fresh init job after the operator types the host name to confirm; audit row records 'host.repo_reinit'.Source-group edit form gains pre/post hook textareas with a service- user warning banner; bodies AEAD-encrypted on save (per-group AD). Repo page adds a 'Host-default hooks' panel above the danger zone with the same shape; saved via POST /hosts/{id}/repo/hooks.migration 0011 adds pending_hosts table (id, hostname, public_key, fingerprint, expiry). store/pending_hosts.go covers full CRUD plus hostname-collision count + expired-row sweeper. POST /api/agents/announce takes {hostname, os, arch, agent_version, restic_version, public_key (base64)}, returns {pending_id, fingerprint, hostname_collision}. Per-source-IP token-bucket rate limit (10/min) + global cap of 100 in-flight rows. Public key must be exactly 32 bytes (Ed25519).GET /ws/agent/pending?pending_id=… runs an Ed25519 nonce-sign handshake against the row's stored public key, then holds the connection open. POST /api/pending-hosts/{id}/accept (admin) mints a real Host row + bearer + AEAD-encrypted repo creds, pushes the bearer down the open WS, deletes the pending row, and writes a host.accept_pending audit entry. POST /api/pending-hosts/{id}/reject closes the socket with code 4001 and audit-logs host.reject_pending. In-memory pendingHub keyed by pending_id wires accept/reject to their live socket.