Documentation
¶
Overview ¶
Package selfupdate implements in-process binary self-update for the runner.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CanSelfUpdate ¶
CanSelfUpdate reports whether the runner can replace its own binary in place. The atomic swap copies the current binary to <dir>/.bak and renames the new one over the canonical path, so the executable's *directory* must be writable by the service user. A manual install that drops the binary in root-owned /usr/local/bin and runs as a non-root user cannot — and must not attempt to — self-update; the handler checks this before a doomed download ever begins, so such runners simply stay on their version instead of failing in a loop.
func ShouldSkipTarget ¶
ShouldSkipTarget reports whether an advertised target should be ignored because this host already rolled back from exactly that version.
Types ¶
type Marker ¶
type Marker struct {
TargetVersion string `json:"target_version"`
Attempts int `json:"attempts"`
RolledBack bool `json:"rolled_back"`
}
Marker persists across re-exec/restart to drive the probation/rollback state machine. A live marker means "an upgrade to TargetVersion is on probation"; it is deleted on commit (handshake) and carries RolledBack=true across the rollback re-exec so the restored old binary can report the outcome once.
type Outcome ¶
type Outcome struct {
InProbation bool // main should Commit() after first successful handshake
}
Outcome tells main what to do after CheckOnBoot.
type ProbationMgr ¶
type ProbationMgr struct {
ExePath string
CurrentVersion string
MaxAttempts int
// contains filtered or unexported fields
}
ProbationMgr runs the boot-time probation/rollback state machine driven by the persisted upgrade marker. reExec is an injectable seam so tests never actually exec; nil means real syscall.Exec.
func NewProbationMgr ¶
func NewProbationMgr(exePath, currentVersion string, maxAttempts int) *ProbationMgr
NewProbationMgr returns a ProbationMgr for the given canonical executable.
func (*ProbationMgr) CheckOnBoot ¶
func (p *ProbationMgr) CheckOnBoot() (Outcome, error)
CheckOnBoot inspects the marker at startup and advances the probation state machine: no marker -> normal; committed/stale -> cleanup; rolled_back -> report; matching target not yet committed -> probation (attempts++ then rollback past MaxAttempts).
func (*ProbationMgr) Commit ¶
func (p *ProbationMgr) Commit()
Commit is called by main after the first successful WS handshake during probation. It clears the marker, the .bak rollback copy, and any prior failed-version memory (we've successfully moved to a new version, so older failures are moot).
func (*ProbationMgr) RollbackNow ¶
func (p *ProbationMgr) RollbackNow()
RollbackNow restores the previous binary and re-execs into it. main calls this when the probation deadline elapses without a successful handshake (failure mode ②: the new binary boots but cannot complete the WS handshake — auth/url/ protocol regression). It is independent of the boot-attempt counter, which can never fire under the unlimited-reconnect (maxAttempts=0) config because the process never exits.
type StatusFunc ¶
type StatusFunc func(phase, errMsg string)
StatusFunc reports an upgrade phase (and optional error message) to the caller.
type Updater ¶
type Updater struct {
ExePath string
// contains filtered or unexported fields
}
Updater performs an in-process self-update: download, verify, extract, atomic swap, marker write, and re-exec. reExec is an injectable seam so tests never actually exec; nil means real syscall.Exec.
func NewUpdater ¶
NewUpdater returns an Updater bound to the given canonical executable path.
func (*Updater) Apply ¶
func (u *Updater) Apply(ctx context.Context, p protocol.UpgradePayload, status StatusFunc) error
Apply downloads the target artifact, verifies it, atomically swaps it into place, writes the probation marker, and re-execs. On any failure before the swap it leaves the running binary untouched; on a post-swap re-exec failure it rolls back inline.