377a522c53
CI / Test (store) (pull_request) Successful in 4s
CI / Lint (pull_request) Successful in 11s
CI / Test (rest) (pull_request) Successful in 20s
CI / Build (windows/amd64) (pull_request) Successful in 8s
CI / Build (linux/amd64) (pull_request) Successful in 8s
CI / Build (linux/arm64) (pull_request) Successful in 8s
CI / Test (server-http) (pull_request) Successful in 1m43s
e2e / Playwright vs docker-compose (pull_request) Successful in 1m18s
222 lines
10 KiB
Markdown
222 lines
10 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to this project are documented here.
|
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
and the project follows [Semantic Versioning](https://semver.org/).
|
|
|
|
## [Unreleased]
|
|
|
|
## [1.2.2] - 2026-08-22
|
|
|
|
### Added
|
|
|
|
- Added audited single-job and bulk recovery controls for jobs that are no
|
|
longer running on their agents but remain stuck server-side. Agents now
|
|
acknowledge unknown cancellation targets so orphaned jobs become terminal,
|
|
while host ownership checks prevent cross-host updates. ([#56])
|
|
|
|
### Fixed
|
|
|
|
- Source-group JSON create and update requests now accept encrypted pre- and
|
|
post-hooks, preserve hooks when their fields are omitted, allow explicit
|
|
clearing, and expose only boolean presence indicators. ([#54])
|
|
- Generic backup-job requests without paths are rejected before a broken job
|
|
is created. Configured run-now backups use the source-group endpoint. ([#55])
|
|
|
|
## [1.2.1] - 2026-08-22
|
|
|
|
### Fixed
|
|
|
|
- Made the Agent updates host-selection screen stable and responsive: removed
|
|
the redundant typed-count confirmation, corrected name/version/eligibility
|
|
filtering, and stopped replacing idle or terminal controls through polling.
|
|
Progress polling now runs only while a rollout is actively running. ([#50])
|
|
|
|
## [1.2.0] - 2026-08-22
|
|
|
|
### Added
|
|
|
|
- Fleet-wide agent updates are now discoverable from Settings and the
|
|
dashboard, with arbitrary host subsets, name/tag/version/eligibility
|
|
filtering, explicit exclusion reasons, server-side membership validation,
|
|
and a canary-first pause after the first verified reconnect. Halted rolls
|
|
expose retry and resume actions. ([#43])
|
|
- Running jobs with no recent persisted activity are detected server-side and
|
|
surfaced through deduplicated alerts. Kind-aware thresholds protect normal
|
|
long-running work, terminal jobs self-resolve, and Prometheus exports stuck
|
|
job count and oldest inactivity age. ([#41])
|
|
- Snapshot projections now retain host-level refresh timestamps—including
|
|
authoritative empty reports—expose a derived stale flag, refresh after
|
|
backup, forget, and prune, and support an explicit operator reconciliation
|
|
endpoint. ([#40])
|
|
|
|
### Fixed
|
|
|
|
- Raised the bounded WebSocket read limit on both peers so ordinary large
|
|
snapshot reports and restic events no longer disconnect otherwise healthy
|
|
agents. Regression coverage exercises payloads beyond the library's former
|
|
32 KiB default in both directions. ([#44])
|
|
- Fleet-update timeout verification now performs a final authoritative read of
|
|
the agent version delivered by the reconnect `hello`, avoiding a poll/deadline
|
|
race and reporting the last observed version when verification fails. ([#43])
|
|
|
|
### Changed
|
|
|
|
- CI runner images and release images use the anonymous-pull `public`
|
|
namespace at `docker.dcglab.co.uk`; registry authentication remains required
|
|
only for publishing.
|
|
|
|
## [1.1.1] - 2026-08-22
|
|
|
|
### Fixed
|
|
|
|
- Prevented agents from panicking when a WebSocket connection ends. The
|
|
WebSocket library transfers ownership of a successful upgrade stream to
|
|
the connection and leaves the HTTP response body nil; attempting to close
|
|
that body caused agents to restart and left forget jobs permanently stuck
|
|
in `running`. ([#37])
|
|
- Manual forget jobs now receive the same per-source-group retention policies
|
|
as scheduled forget jobs. The API also supports a validated `--dry-run`
|
|
option through the complete server-to-agent-to-restic path, and rejects
|
|
hosts without configured retention before creating a job. ([#36])
|
|
- Corrected the admin-credentials help text to reflect that forget uses normal
|
|
append-only credentials and blank admin credentials do not provide a
|
|
fallback for prune. ([#34])
|
|
|
|
## [1.1.0] - 2026-06-15
|
|
|
|
### Added
|
|
|
|
- **Always-On vs intermittent host mode.** A host can now be marked as
|
|
not always-on — for laptops/workstations that legitimately sleep,
|
|
travel, or shut down outside hours. An intermittent host no longer
|
|
raises "agent offline" alerts when it disappears; instead it shows a
|
|
calm "asleep" state in the UI ("asleep · last seen … · will catch up
|
|
on return") and is covered by a longer-horizon staleness alert (raised
|
|
only when it has an enabled schedule and no successful backup in 7
|
|
days). When such a host reconnects, the server waits a short settle
|
|
window and then automatically dispatches any scheduled backup whose
|
|
window elapsed while it was asleep. Toggle per host from the host
|
|
detail page (operator-band, audited as `host.mode_updated`). New and
|
|
existing hosts default to always-on, so current fleets are unaffected.
|
|
|
|
### Changed
|
|
|
|
- Host-detail header redesign: tags and presence are grouped into
|
|
labelled, boxed pills with click-to-edit; presence shows a `24x7` /
|
|
`Free` chip; the agent "out of date" indicator is simplified (the full
|
|
version detail remains in the Agent-update panel and on hover).
|
|
- Relative timestamps ("2h ago") now tick client-side, so a tab left
|
|
open no longer shows a stale value as wall-clock time moves on.
|
|
- Release and CI container images are now published to and pulled from
|
|
the zot OCI registry (`docker.dcglab.co.uk`).
|
|
|
|
## [1.0.1] - 2026-05-09
|
|
|
|
### Fixed
|
|
|
|
- Build version is now single-sourced from `internal/version`, and the
|
|
server Dockerfile's ldflags were corrected so docker-built binaries
|
|
report their real version. Previously `internal/version.Version` stayed
|
|
at its "dev" default in docker images, which made every host look
|
|
permanently out-of-date to the update logic.
|
|
|
|
## [1.0.0] - 2026-05-09
|
|
|
|
First tagged release. Six development phases brought the project from
|
|
empty repo to a self-hostable, multi-tenant restic backup orchestrator
|
|
with a web UI, JSON API, and self-updating agent fleet.
|
|
|
|
### Phase 1 — MVP: enrolment, visibility, on-demand backup
|
|
|
|
- HTTP server, SQLite store with migrations, AEAD-encrypted
|
|
credentials at rest, Argon2id password hashing, session cookies.
|
|
- WebSocket transport between server and agents (heartbeat, hello,
|
|
schedule fan-out, job log streaming).
|
|
- Agent install path for Linux (systemd unit + `install.sh`); one-time
|
|
enrolment tokens with embedded repo credentials.
|
|
- Run-now backup execution end-to-end, snapshot listing.
|
|
- Server-side encrypted repo creds pushed to the agent on hello.
|
|
|
|
### Phase 2 — Scheduling, retention, repo operations
|
|
|
|
- Source groups (paths + excludes + pre/post hooks + bandwidth caps)
|
|
decoupled from schedules; a schedule fires a source group.
|
|
- Cron-style schedules with retention policies, server-driven
|
|
reconciliation push and ack.
|
|
- `restic forget`, `prune`, `check`, `unlock` automation; periodic
|
|
maintenance ticker with per-host stagger.
|
|
- Pending-runs queue with backpressure (`max_concurrent_jobs` per
|
|
host).
|
|
- Repo stats panel on the host detail page (size, last-check, last-
|
|
prune, stale-lock banner).
|
|
- Auto-init of repos on first onboard with credential-failure surface
|
|
on the host detail page.
|
|
- Announce-and-approve enrolment path for hosts that don't have a
|
|
pre-minted token (Ed25519 fingerprint, operator approves).
|
|
- Windows agent: SCM service integration + `install.ps1` installer.
|
|
- Cross-platform alt-enrolment (announce flow on Windows).
|
|
|
|
### Phase 3 — Restore, alerts, audit
|
|
|
|
- Restore wizard: pick a snapshot, pick paths, pick a target
|
|
(in-place / new directory), live progress.
|
|
- Snapshot diff against parent.
|
|
- Alert engine: per-source-group dedup, severity tiers, ack / resolve.
|
|
- Live-refresh alerts table with severity cues.
|
|
- Audit log UI with filters, sort, CSV export, payload-detail modal.
|
|
|
|
### Phase 4 — RBAC, OIDC, host tags
|
|
|
|
- Role-based access control: viewer / operator / admin.
|
|
- User management UI (invite, role change, disable, password reset).
|
|
- Generic OIDC SSO with JIT user provisioning + role mapping.
|
|
- Per-host tags with chip-row filter on the dashboard.
|
|
|
|
### Phase 5 — OSS readiness
|
|
|
|
- mdBook-rendered docs site at `docs/book/`.
|
|
- Contributor onboarding (CONTRIBUTING.md, security policy, license).
|
|
- Docker-only release pipeline + reference deployment compose file.
|
|
- Playwright e2e harness covering the smoke runbook.
|
|
|
|
### Phase 6 — Update delivery + observability
|
|
|
|
- Agent self-update: server-side channel pin per host, signed binary
|
|
fetch via the WS transport, atomic swap with rollback on failure.
|
|
- Fleet-wide update orchestration with per-host stagger and an admin
|
|
pause switch.
|
|
- Prometheus `/metrics` endpoint + Grafana dashboard JSON.
|
|
- Repo size trend per host (90-day rolling) on the host detail page.
|
|
|
|
### Cross-cutting
|
|
|
|
- Live dashboard with column sort, filters, free-text host search,
|
|
background-tab-aware live refresh (5s cadence).
|
|
- Pure-Go binary with embedded UI, no Node/CGO at runtime.
|
|
- Reproducible `-trimpath -ldflags="-s -w"` builds for
|
|
linux/amd64, linux/arm64, windows/amd64.
|
|
- Sharded CI (server-http / store / rest), pre-commit hooks (gofumpt,
|
|
go vet, golangci-lint).
|
|
- Threat model published (`docs/threat-model.md`).
|
|
|
|
[Unreleased]: https://gitea.dcglab.co.uk/steve/restic-manager/compare/v1.2.2...HEAD
|
|
[1.2.2]: https://gitea.dcglab.co.uk/steve/restic-manager/compare/v1.2.1...v1.2.2
|
|
[1.2.1]: https://gitea.dcglab.co.uk/steve/restic-manager/compare/v1.2.0...v1.2.1
|
|
[1.2.0]: https://gitea.dcglab.co.uk/steve/restic-manager/compare/v1.1.1...v1.2.0
|
|
[1.1.1]: https://gitea.dcglab.co.uk/steve/restic-manager/compare/v1.1.0...v1.1.1
|
|
[1.1.0]: https://gitea.dcglab.co.uk/steve/restic-manager/releases/tag/v1.1.0
|
|
[1.0.0]: https://gitea.dcglab.co.uk/steve/restic-manager/releases/tag/v1.0.0
|
|
|
|
[#37]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/37
|
|
[#36]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/36
|
|
[#34]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/34
|
|
[#40]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/40
|
|
[#41]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/41
|
|
[#43]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/43
|
|
[#44]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/44
|
|
[#50]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/50
|
|
[#54]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/54
|
|
[#55]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/55
|
|
[#56]: https://gitea.dcglab.co.uk/steve/restic-manager/issues/56
|