Documentation
¶
Overview ¶
Package updater checks GitHub Releases for a newer Extension Guard build, downloads and integrity-checks the binaries, and swaps them into place.
The swap is deliberately cooperative. Because the guard runs as a self-healing service (watchdog + SCM recovery), the live binaries cannot simply be overwritten - the service holds guard.exe open and the watchdog fights any restart. Windows won't overwrite or delete a running .exe, but it *will* let you rename one (even the caller's own image), so SwapFiles moves each old binary aside and drops the new one in its place; the caller (cmd/guard's "update" command) pauses the watchdog via the "updating" sentinel, stops the service, swaps, then restarts so the new image loads. See guardsvc for the watchdog stand-down.
Integrity today rests on a SHA-256 manifest served over HTTPS from the release. That catches corruption and casual tampering, but it is NOT a substitute for Authenticode code signing: a compromised release could publish a matching hash. Signing is a hard prerequisite before enabling silent auto-apply in the wild (see docs/pc-version.md) - which is why the service defaults to "notify" rather than "apply".
Index ¶
Constants ¶
This section is empty.
Variables ¶
var (
Repo = "codepurse/extension-guard"
)
Repo is the GitHub "owner/name" the updater queries; apiBase is the API root. Both are vars so tests can point them at a local server.
Functions ¶
func CleanupOld ¶
func CleanupOld(dir string)
CleanupOld removes leftover "<name>.old" binaries in dir.
func Compare ¶
Compare returns -1, 0, or 1 as a is less than, equal to, or greater than b, comparing dotted numeric versions ("1.10.0" > "1.9.0"). A leading "v" and any pre-release/build suffix ("-rc1", "+meta") are ignored. The sentinel "dev" (an un-stamped local build) parses to 0.0.0, so a dev build sorts below every real release.
func SwapFiles ¶
SwapFiles replaces each live binary in dir with its staged "<name>.new" counterpart (staged maps asset name -> staged path, as returned by Release.Stage).
On Unix a running binary can be replaced by rename - the open image keeps executing from the now-unlinked inode - so this is a straight atomic rename with the same move-aside-and-rollback safety net as the Windows path. The ".old" files are removed immediately, since Unix has no objection to unlinking a busy binary.
Types ¶
type Manifest ¶
type Manifest struct {
Version string `json:"version"`
Notes string `json:"notes"`
Files []FileHash `json:"files"`
}
Manifest is the manifest.json asset attached to each release. Version mirrors the release tag without a leading "v"; Files lists the SHA-256 of every binary the updater may download.
type Release ¶
Release is the resolved "latest release" the updater acts on.
func CheckLatest ¶
CheckLatest fetches the latest published release and resolves its binaries and expected hashes from the attached manifest.json. It does NOT download the binaries - callers decide whether the version warrants that.
func (Release) Stage ¶
Stage downloads the named assets into dir as "<name>.new", verifying each against its manifest SHA-256. It returns the staged paths keyed by asset name. On any failure it removes whatever it staged, so a partial download is never left behind. dir should be the install directory so the later rename-in-place swap stays on one volume (a cross-volume rename would fail).