Documentation
¶
Overview ¶
Package selfupgrade defines the on-disk contracts for the daemon's binary self-upgrade protocol (epic #500): the self-upgrade.yaml state file and the .bak archived-binary naming convention.
self-upgrade.yaml is written by the OLD daemon immediately before it spawns the detached upgrade process — at step 0, before any binary swap begins. It is both a handoff record and a crash-diagnostic artifact:
- Crash diagnostics: if the detached upgrader dies mid-swap, the recover tool reads this file to learn what version was being installed, which step it had reached, and whether the .bak binaries are still present.
- PID tracking: ChildPID lets an operator/recovery tool check whether the detached process is still alive (kill -0).
- Recovery input: `solo-provisioner consensus node upgrade-recover` (#717) inspects this file to decide whether to restore a .bak binary and restart the daemon.
Because the file is written before the swap, a leftover Status of "in-progress" is itself the failure signal: a clean run always ends with "succeeded". On failure the detached process writes "failed" and leaves the .bak files intact.
Index ¶
- Constants
- Variables
- func BakDir(backupDir string) string
- func CLIBakName(operationID string) (string, error)
- func CLIBakPath(bakDir, operationID string) (string, error)
- func DaemonBakName(operationID string) (string, error)
- func DaemonBakPath(bakDir, operationID string) (string, error)
- func DefaultPath() string
- func Save(path string, s SelfUpgradeYAML) error
- type Binary
- type SelfUpgradeYAML
- type Status
Constants ¶
const CurrentSchemaVersion = 1
CurrentSchemaVersion is the schemaVersion written by this build. Increment it only when a breaking structural change is made to SelfUpgradeYAML, and add a corresponding sealed selfUpgradeV{N} struct + migration step.
Variables ¶
var ( // ErrNamespace groups self-upgrade state errors. ErrNamespace = errorx.NewNamespace("selfupgrade") // ErrState is returned when self-upgrade.yaml cannot be read or written. ErrState = ErrNamespace.NewType("state") )
Functions ¶
func BakDir ¶
BakDir returns the directory archived binaries live in, given the weaver backup directory (WeaverPaths.BackupDir): backupDir/solo-provisioner.
func CLIBakName ¶
CLIBakName returns the .bak filename for the CLI binary archived under operationID. It rejects an operationID that is not path-safe (sanity .ValidateOperationID) so the id can never introduce a path separator or ".." traversal sequence into the filename.
func CLIBakPath ¶
CLIBakPath returns the absolute .bak path for the CLI binary in bakDir (typically BakDir(WeaverPaths.BackupDir)). The operationID is validated, so a crafted id cannot escape bakDir.
func DaemonBakName ¶
DaemonBakName returns the .bak filename for the daemon binary archived under operationID, with the same validation as CLIBakName.
func DaemonBakPath ¶
DaemonBakPath returns the absolute .bak path for the daemon binary in bakDir (typically BakDir(WeaverPaths.BackupDir)), with the same validation as CLIBakPath.
func DefaultPath ¶
func DefaultPath() string
DefaultPath returns the HIP-authoritative self-upgrade.yaml path for the default weaver home (/opt/solo/weaver/daemon/self-upgrade.yaml).
func Save ¶
func Save(path string, s SelfUpgradeYAML) error
Save stamps SchemaVersion = CurrentSchemaVersion and atomically writes s to path (write-temp-then-rename so a crash mid-write never leaves a torn file), creating any missing parent directories.
Types ¶
type Binary ¶
type Binary string
Binary identifies which solo-provisioner binary a .bak archive belongs to.
func ParseBakName ¶
ParseBakName parses a .bak filename produced by CLIBakName/DaemonBakName, returning which binary it archives and the embedded operationId. It accepts a bare filename or a path (only the base name is parsed). The daemon prefix is tested before the CLI prefix because the daemon name contains the CLI name.
type SelfUpgradeYAML ¶
type SelfUpgradeYAML struct {
// SchemaVersion identifies the file format. Stamped to CurrentSchemaVersion by Save.
SchemaVersion int `yaml:"schemaVersion"`
// Timestamp is when the operation was initiated (RFC3339, UTC).
Timestamp time.Time `yaml:"timestamp"`
// OperationID ties this self-upgrade to the originating NetworkUpgradeExecute
// CR's spec.operationId. Also embedded in the .bak filenames (see bak.go).
OperationID string `yaml:"operationId"`
// Status is the lifecycle marker — the primary success/failure signal.
Status Status `yaml:"status"`
// ChildPID is the PID of the detached upgrade process, for liveness checks.
ChildPID int `yaml:"childPid,omitempty"`
// CurrentStep is the last step the detached upgrader began. Used to localise
// a crash during recovery diagnostics.
CurrentStep string `yaml:"currentStep,omitempty"`
// Version transition — the from/to versions of each binary being swapped.
FromCLIVersion string `yaml:"fromCliVersion,omitempty"`
ToCLIVersion string `yaml:"toCliVersion,omitempty"`
FromDaemonVersion string `yaml:"fromDaemonVersion,omitempty"`
ToDaemonVersion string `yaml:"toDaemonVersion,omitempty"`
// .bak references — absolute paths to the archived binaries the recover tool
// restores when an upgrade is rolled back. Empty when no archive was taken yet.
CLIBakPath string `yaml:"cliBakPath,omitempty"`
DaemonBakPath string `yaml:"daemonBakPath,omitempty"`
}
SelfUpgradeYAML is the current in-memory shape of self-upgrade.yaml. It lives at WeaverPaths.SelfUpgradeYAMLPath (/opt/solo/weaver/daemon/self-upgrade.yaml).
func Load ¶
func Load(path string) (SelfUpgradeYAML, error)
Load reads and strict-decodes self-upgrade.yaml at path, rejecting unknown fields and any schemaVersion the running build does not support.
type Status ¶
type Status string
Status is the lifecycle status recorded in self-upgrade.yaml.
const ( // StatusInProgress is written at step 0, before the binary swap begins. If it // survives to recovery time, the upgrade crashed mid-swap. StatusInProgress Status = "in-progress" // StatusSucceeded is written by the detached upgrader after a clean swap; the // .bak files are removed on success. StatusSucceeded Status = "succeeded" // StatusFailed is written by the detached upgrader on failure; the .bak files // are left intact for recovery. StatusFailed Status = "failed" )