updater

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: May 17, 2026 License: MPL-2.0 Imports: 25 Imported by: 0

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

View Source
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):

  1. No state file or unreadable
  2. Unknown schema
  3. Dev build (version.Version == "dev")
  4. state.NewVersion != version.Version ← prevents false triggers
  5. status != "pending"

If attempts reaches 3 and .old is valid, the rollback is executed and os.Exit(0) is called 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

func RunSmokeTest(dataDir string) error

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

func (u *Updater) Run(ctx context.Context)

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.

func (*Updater) Status

func (u *Updater) Status() map[string]any

Status returns fields for a2al_status / GET /update/status. Safe to call on a nil receiver (returns update_enabled:false).

func (*Updater) TriggerNow

func (u *Updater) TriggerNow(ctx context.Context) error

TriggerNow runs an immediate check and applies any available update, ignoring the rollout window. Used by POST /update/apply.

Jump to

Keyboard shortcuts

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