Documentation
¶
Overview ¶
Package upgrade replaces the running ephemerd binary with a specific published release and restarts the service into it.
The delivery model is "command, not bytes": a caller (the CLI or the control-plane Upgrade RPC) says "go to version vX.Y.Z" and the daemon downloads + checksum-verifies the release asset over its OWN outbound HTTPS — the same channel `install` and cloudflared already use. This is provider-agnostic and has no exec-channel size or timeout limit, unlike pushing an ~1 GB zip through a hypervisor guest-agent exec.
Safety is staged: nothing touches the live binary until the new one is downloaded, checksum-verified, and (when natively runnable) probed with `--version`. The old binary is kept alongside as `<name>.old` for rollback. Any failure before the final swap leaves the node running the old binary; only swap+restart is the point of no easy return, and it happens last.
Index ¶
- func AssetName(version, goos, goarch string) string
- func NormalizeVersion(v string) string
- func ParseChecksums(r io.Reader) (map[string]string, error)
- func Run(ctx context.Context, opts RunOptions, emit Emit) (retErr error)
- func SameVersion(a, b string) bool
- func ValidVersion(v string) bool
- type Drainer
- type Emit
- type Progress
- type RunOptions
- type State
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AssetName ¶
AssetName derives the release asset filename for a target/OS/arch, e.g. ephemerd_v0.1.7_windows_amd64.zip. Confirmed against the v0.1.6 release.
func NormalizeVersion ¶
NormalizeVersion trims and ensures a leading "v" so "0.1.7" and "v0.1.7" compare equal.
func ParseChecksums ¶
ParseChecksums parses a `sha256sum`-style checksums.txt into a filename→hex-digest map. Malformed lines are skipped; an empty result is an error.
func Run ¶
func Run(ctx context.Context, opts RunOptions, emit Emit) (retErr error)
Run executes the upgrade end to end, emitting Progress at each phase.
Sequence (reusing #132's cordon): preflight → cordon + wait for jobs to drain to idle → download → verify checksum → stage + probe → swap → restart. On success the final emitted Progress is StateRestarting and Run returns nil BEFORE the service actually restarts (the restart is scheduled detached, after restartDelay). The caller then polls Status until the reported version matches the target.
Any error before the swap emits StateFailed, re-uncordons the scheduler, and leaves the node running the old binary.
func SameVersion ¶
SameVersion reports whether two version strings denote the same release. A blank or "dev" build never equals a real target, so an unstamped daemon is always eligible to upgrade.
func ValidVersion ¶
ValidVersion reports whether v is a release tag (vX.Y.Z[-suffix]).
Types ¶
type Drainer ¶
type Drainer interface {
Cordon() int // stop claiming new jobs; returns the current active count
Uncordon() int // resume claiming (used to back out an aborted upgrade)
ActiveJobs() int // number of jobs currently running
}
Drainer is the slice of the scheduler the upgrade needs: stop claiming new jobs, report how many are still running so we can wait for idle, and resume claiming if we abort before the restart. The scheduler's existing Cordon/Uncordon (added in #132) satisfy this; ActiveJobs is a thin accessor over the running-job map.
type Emit ¶
type Emit func(Progress)
Emit receives progress updates. Implementations must not block for long; the RPC handler forwards each to a gRPC stream Send.
type Progress ¶
type Progress struct {
State State
Message string
CurrentVersion string
TargetVersion string
ActiveJobs int // populated during StateDraining
BytesDownloaded int64 // populated during StateDownloading
BytesTotal int64 // total asset size if the server reported it, else 0
}
Progress is one observable step of an upgrade.
type RunOptions ¶
type RunOptions struct {
TargetVersion string
CurrentVersion string
BaseURLOverride string // replaces the release base dir URL; for mirrors/tests
NoDrain bool
Force bool
DrainTimeout time.Duration
DrainPoll time.Duration
Drainer Drainer
Log *slog.Logger
// Test/override seams.
InstallPath string // default: resolved os.Executable()
StageDir string // default: <installdir>/.ephemerd-upgrade
HTTPClient *http.Client // default: http.DefaultClient (no timeout; ctx-governed)
GOOS string // default: runtime.GOOS
GOARCH string // default: runtime.GOARCH
Probe func(path string) (string, error) // default: probeVersion (runs `<path> --version`)
Restart func() error // default: triggerRestart (per-OS service restart)
RestartDelay time.Duration // default: restartDelay; delay before the detached restart fires
}
RunOptions configures a single upgrade. The exported override fields (InstallPath, Restart, Probe, GOOS, GOARCH, StageDir, HTTPClient) default to real behavior when zero and exist mainly so tests can inject seams.