apt lists phased updates as upgradable while an upgrade defers them until
Ubuntu selects the host, so a freshly patched server kept reporting pending
updates. The agent now flags them; the server stores the flag and leaves them
out of patch run counts, and the server page shows them in their own section.
shared/ is extracted to gitea.hostxtra.co.uk/vantage/vantage-shared and
pinned at v0.1.0 by server, agent, admin, sitesvc and vantagectl. The
replace directives and the ./shared entry in go.work are gone.
Every Go build now needs a credential for the private module: CI writes a
netrc per job from REGISTRY_USER + RELEASE_TOKEN and sets GOPRIVATE, and
the four Go Dockerfiles take it as a BuildKit secret rather than a build
arg, which would survive in the builder layer's history. RELEASE_TOKEN
needs read access to the vantage org.
admin, sitesvc and vantagectl now build from their own directory; only
server still needs the repository root, for default_steps/. The rebuild
triggers in server-deploy.yml lose their shared/ patterns, since a
service now moves when its own go.mod pin does.
trivy-db, oras-go, the three version comparators and robfig/cron were
recorded as indirect with an incomplete go.sum, which builds locally
against a warm module cache but fails in CI with "updates to go.mod
needed". trivy-db pulls testify into the build graph, and its hashes
were missing entirely.
Completes tasks 10-15 and fixes what was outstanding:
- vulndb.Pull implemented with oras-go, streaming the ~50MB layer and
staging both files before replacing either, so a failed pull leaves the
previous database intact rather than a half-written one.
- db.go: Vulnerability.Severity is a string, not trivy Severity, so the
int conversion did not compile. Severity now resolves vendor (highest
when vendors disagree) then NVD then unknown, and CVSS is read too.
- findings.go: added sweepFixedFindings plus the fleet query, severity
counts, rescan flag and accept/unaccept the API needs.
- vulnrules.go: added rule CRUD and the digest builder. ResolveTargets
returns []models.Server, not []string, so filterByServers was wrong.
- api/vulnerabilities.go was an empty file while handlers.go registered
twelve routes against it; written, grouped by CVE.
- shared/mail: added the missing sender. The templates were orphaned and
the HTML one was a copy of the text one, defining "subject" (which
html/template would escape) and emitting no markup. render.go parses
every template in init(), so a bad one panics server, admin and sitesvc
at boot — go build never runs init(), which is why nothing complained.
- notify: digests dispatch through their own path so SMTP gets the digest
template rather than arriving dressed as a monitor alert.
go build inside the Docker image runs outside the workspace, so server/go.sum
needed the hyperboloide/lk entry that GOWORK resolution was supplying locally.
Caught by the image build, not by go build.