updater

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package updater fetches release manifests, downloads matching binaries, verifies them by SHA256 checksum, and atomically swaps the running executable.

Design notes:

  • Version comparison uses golang.org/x/mod/semver (Go's curated semver) so "v0.10.0" is correctly newer than "v0.9.0" — the original spike used lexicographic string comparison and silently broke double-digit minor versions.
  • DownloadRelease writes to dest+".tmp", verifies the SHA256 checksum against the asset's manifest entry, then renames. A mismatch removes the tmp file and returns an error before any swap happens.
  • Asset.Checksum is REQUIRED (not omitempty in the JSON sense, and an empty value is rejected at download time as "untrusted binary"). The original spike had VerifyChecksum as a public function with no callers; this rewrite wires it in as a security-required step.
  • ApplyUpdate uses os.Rename + os.Rename rollback on Unix-like filesystems. Windows is not currently handled (the running EXE is locked); a future enhancement would write to a .new file and let the orchestrator swap on restart.
  • The current version is held in package var Version, settable at build time via: go build -ldflags "-X github.com/dd0wney/graphdb/pkg/updater.Version=v1.2.3" If unset, Version defaults to "dev" and every update check returns "update available" (intentional for dev builds).

Index

Constants

This section is empty.

Variables

View Source
var ErrNoAsset = errors.New("no asset for current OS/arch in release")

ErrNoAsset is returned when a release contains no asset matching the current runtime.GOOS / runtime.GOARCH.

View Source
var ErrNoChecksum = errors.New("asset has no checksum; refusing to download untrusted binary")

ErrNoChecksum is returned when a release asset has an empty checksum. Refusing to download in that case is a security policy: a manifest author who omits checksums is asking us to install an unverified binary.

View Source
var Version = "dev"

Version is the current build's semver string. Set via -ldflags:

go build -ldflags "-X github.com/dd0wney/graphdb/pkg/updater.Version=v1.2.3"

If unset (i.e., "dev"), every CheckForUpdates call reports an update available — intentional for development builds.

Functions

func ApplyUpdate

func ApplyUpdate(newBinaryPath string) error

ApplyUpdate atomically swaps the running executable with the binary at newBinaryPath. The current binary is moved to <exe>.old as a backup; if the second rename fails, the backup is restored. Successful swaps remove the backup.

On Unix-like filesystems both renames are atomic. Windows is not currently handled — the running EXE is locked there; callers on Windows will see a rename error. A future enhancement would write to a .new file and let the orchestrator perform the swap on restart.

func DownloadRelease

func DownloadRelease(ctx context.Context, release *Release, dest string) error

DownloadRelease downloads the asset matching runtime.GOOS/GOARCH from the given release, writing first to dest+".tmp", then verifying its SHA256 against the manifest checksum, then renaming to dest. On any failure the tmp file is removed and an error is returned — dest is never written unless the checksum verifies.

func IsNewer

func IsNewer(current, latest string) bool

IsNewer reports whether latest is a strictly higher semver than current. "dev" and "" current versions are always considered older (so every dev build sees updates).

func VerifyChecksum

func VerifyChecksum(path, expected string) error

VerifyChecksum SHA256-hashes the file at path and returns nil iff its hex digest matches expected (case-insensitive). Wired into DownloadRelease — this is not an opt-in helper, it's a required step.

Types

type Asset

type Asset struct {
	Name     string `json:"name"`
	OS       string `json:"os"`   // matches runtime.GOOS, e.g. "linux"
	Arch     string `json:"arch"` // matches runtime.GOARCH, e.g. "amd64"
	URL      string `json:"url"`
	Checksum string `json:"checksum"` // SHA256 hex digest (case-insensitive)
}

Asset represents a downloadable binary for a specific OS/arch. Checksum is required at download time; a release entry with an empty Checksum is rejected as untrusted.

type Release

type Release struct {
	Version     string    `json:"version"`      // semver, e.g. "v1.2.3"
	Channel     string    `json:"channel"`      // e.g. "stable", "beta"
	ReleaseDate time.Time `json:"release_date"` //nolint:tagliatelle // external manifest schema; keep snake_case
	Description string    `json:"description"`
	Assets      []Asset   `json:"assets"`
}

Release represents a single entry in the release manifest.

type UpdateStatus

type UpdateStatus struct {
	CurrentVersion  string   `json:"current_version"`          //nolint:tagliatelle // external API schema
	LatestVersion   string   `json:"latest_version"`           //nolint:tagliatelle
	UpdateAvailable bool     `json:"update_available"`         //nolint:tagliatelle
	LatestRelease   *Release `json:"latest_release,omitempty"` //nolint:tagliatelle
}

UpdateStatus is the result of a CheckForUpdates call.

func CheckForUpdates

func CheckForUpdates(ctx context.Context, manifestURL, channel string) (*UpdateStatus, error)

CheckForUpdates fetches the JSON manifest at manifestURL, picks the highest-semver release in the named channel (channel "" matches any), and returns whether it's newer than the running Version.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL