Documentation
¶
Overview ¶
Package updater implements a2ald self-update logic: periodic version checks, atomic binary replacement, startup-counter-based rollback, and retraction detection. See doc-local/a2ald 自动更新设计.md for the full design.
Index ¶
Constants ¶
const ( StatusPending = "pending" // binary replaced, health not yet confirmed StatusOK = "ok" // new binary confirmed healthy StatusRolledBack = "rolled_back" // rollback executed, old binary restored StatusRollbackFailed = "rollback_failed" // terminal: .old unavailable/corrupt, no rollback possible )
Status values stored in update_state.json.
Variables ¶
This section is empty.
Functions ¶
func CheckAndRollback ¶
func CheckAndRollback(dataDir string)
CheckAndRollback must be called at the very start of main(), before daemon.New() acquires the data-dir lock. It implements the startup-counter rollback described in the design doc.
Guard chain (any failure → return, normal startup):
- No state file or unreadable
- Unknown schema
- Dev build (version.Version == "dev")
- state.NewVersion != version.Version ← prevents false triggers
- status != "pending"
If attempts reaches 3 and .old is valid, the rollback is executed and checkRollbackExitFn(0) runs (production: os.Exit) so the service manager restarts with the old binary.
func IsPersistentService ¶
func IsPersistentService() bool
IsPersistentService reports whether a2ald is running under a service manager that will automatically restart it on failure.
Linux: systemd sets INVOCATION_ID (v232+) and JOURNAL_STREAM (v231+). macOS: launchd is PID 1 and does not set TERM for background agents. Other: always returns false.
func RunSmokeTest ¶
RunSmokeTest validates config parsing, keys, and data-dir writeability without starting the daemon or acquiring the data-dir lock. Called when a2ald is invoked as "__smoke-test --data-dir <path>" by the updater.
func WriteState ¶
func WriteState(dataDir string, s *UpdateState) error
WriteState atomically writes state via a temp file + rename.
Types ¶
type UpdateState ¶
type UpdateState struct {
Schema int `json:"schema"`
Status string `json:"status"`
OldVersion string `json:"old_version"`
NewVersion string `json:"new_version"`
OldChecksumSHA256 string `json:"old_checksum_sha256"`
ReplacedAt time.Time `json:"replaced_at"`
Attempts int `json:"attempts"`
LastAttemptAt time.Time `json:"last_attempt_at,omitempty"`
RolledBackAt time.Time `json:"rolled_back_at,omitempty"`
}
UpdateState is persisted as <data-dir>/update_state.json. It is written atomically before os.Exit(0) and read at startup.
func ReadState ¶
func ReadState(dataDir string) (*UpdateState, error)
ReadState reads update_state.json. Returns nil (no error) when file is absent.
type Updater ¶
type Updater struct {
// contains filtered or unexported fields
}
Updater manages periodic update checks, binary replacement, and the post-update health watchdog. It is created by daemon.New and started by daemon.Run via Run(ctx).
func New ¶
func New(dataDir, nodeIDHex string, auto, persistentService bool, networkReady func() bool, log *slog.Logger) *Updater
New creates an Updater. networkReady is called by the watchdog to confirm the new binary has established DHT connectivity. persistentService gates the automatic periodic check loop: when false, the loop is suppressed to avoid unrecoverable outages on manually-run daemons.
func (*Updater) Run ¶
Run starts the update subsystem:
- If update_state is "pending" for this binary, starts the health watchdog.
- If auto is true, starts the periodic check loop after initialDelay.
Blocks until ctx is cancelled.