updater

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

README

updater

ci codecov

Auto-updater plugin for the Pilot Protocol daemon. Polls the GitHub releases endpoint hourly, hot-swaps the daemon, pilotctl, and gateway binaries when a newer SemVer tag appears, and exits so the supervisor restarts the new copy.

Install

import "github.com/pilot-protocol/updater"

Usage

u := updater.New(updater.Config{
    Repo:          "TeoSlayer/pilotprotocol",
    InstallDir:    "/home/user/.pilot/bin",
    Version:       "v1.10.5",
    CheckInterval: 1 * time.Hour,
})
u.Start()
Pinning a version

Set PinnedVersion to lock the updater to a specific release tag. When set, the updater fetches the exact release (via /releases/tags/{tag}), applies it if it differs from the current install, then idles — it will not chase the latest release. Clear PinnedVersion (set to "") to resume auto-updating.

u := updater.New(updater.Config{
    Repo:          "TeoSlayer/pilotprotocol",
    InstallDir:    "/home/user/.pilot/bin",
    PinnedVersion: "v1.10.5",  // stay on this version
})
u.Start()

The in-process Service adapter is used when embedding into the daemon; a standalone sidecar binary built from this package is also supported.

Layout

File What it does
updater.go Updater — GitHub release polling, download, SHA verify, atomic rename.
version.go SemVer parsing and comparison.
service.go *Servicecoreapi.Service adapter. Build tag !no_updater.
service_disabled.go Stub when build tag no_updater is set.

Build tags

Tag Effect
no_updater Compiles a stub whose Start is a no-op.

License

AGPL-3.0-or-later. See LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func VerifyChecksum

func VerifyChecksum(archivePath, archiveName, checksumsPath string) error

VerifyChecksum checks the SHA256 of archivePath against the checksums file.

Types

type Config

type Config struct {
	CheckInterval time.Duration
	Repo          string // "owner/repo"
	InstallDir    string
	Version       string // updater's own version (used for user-agent)

	// PinnedVersion locks the updater to a specific release tag
	// (e.g. "v1.10.5"). When set, the updater installs exactly that
	// version — regardless of whether it is newer, older, or already
	// current — and will not chase the latest release. An empty
	// string (default) preserves the existing "always follow latest"
	// behaviour. Set to an empty string to un-pin and resume
	// auto-updating to the latest stable.
	PinnedVersion string

	// SkipAttestation disables SLSA attestation verification of
	// checksums.txt. Intended for test environments where the test
	// repos do not have real attestations. Default (false) enables
	// verification in production.
	SkipAttestation bool

	// StatePath, when non-empty, points to a JSON control file
	// {"enabled": bool} that gates the AUTOMATIC update loop and is
	// re-read on every tick. When the file is absent or {"enabled":
	// false} the loop performs NO updates — so any deployment that sets
	// StatePath is OFF BY DEFAULT until explicitly enabled (e.g. via
	// `pilotctl update enable`). A manual one-shot RunOnce always runs,
	// ignoring this gate. An empty StatePath preserves the legacy
	// always-on loop behaviour for backward compatibility.
	StatePath string
}

Config holds the updater configuration.

type GitHubAsset

type GitHubAsset struct {
	Name               string `json:"name"`
	BrowserDownloadURL string `json:"browser_download_url"`
}

GitHubAsset represents a release asset.

type GitHubRelease

type GitHubRelease struct {
	TagName string        `json:"tag_name"`
	Assets  []GitHubAsset `json:"assets"`
}

GitHubRelease represents a subset of the GitHub release API response.

type Semver

type Semver struct {
	Major int
	Minor int
	Patch int
}

Semver represents a parsed semantic version.

func ParseSemver

func ParseSemver(s string) (Semver, error)

ParseSemver parses a version string like "v1.2.3" or "1.2.3" or "v1.2.3-dirty". It strips the "v" prefix and any suffix after a hyphen.

func (Semver) NewerThan

func (v Semver) NewerThan(other Semver) bool

NewerThan returns true if v is strictly newer than other.

func (Semver) String

func (v Semver) String() string

String returns the version as "vMAJOR.MINOR.PATCH".

type Service

type Service struct{}

Service is the L11 plugin lifecycle adapter for the updater. The daemon does not register this today — cmd/updater is a standalone binary that uses updater.New / *Updater.Start directly. The adapter exists so the plugin package conforms to the L10 Service contract and so the no_updater build tag has a meaningful counterpart (see service_disabled.go).

When this plugin is eventually wired into cmd/daemon's plugin runtime, this Service will own the *Updater lifecycle. Today its Start/Stop are no-ops; it is registered nowhere.

func NewService

func NewService() *Service

NewService returns a Service ready for daemon.RegisterPlugin (when cmd/daemon eventually starts registering it). Distinct from updater.New, which constructs the standalone *Updater used by cmd/updater.

func (*Service) Name

func (s *Service) Name() string

func (*Service) Order

func (s *Service) Order() int

func (*Service) Start

func (s *Service) Start(_ context.Context, _ coreapi.Deps) error

func (*Service) Stop

func (s *Service) Stop(_ context.Context) error

type Updater

type Updater struct {
	// contains filtered or unexported fields
}

Updater periodically checks GitHub Releases for new versions and optionally applies them.

func New

func New(cfg Config) *Updater

New creates a new Updater.

func (*Updater) RunOnce added in v0.2.2

func (u *Updater) RunOnce()

RunOnce runs the update check once synchronously and returns. Unlike Start, it does not enter a periodic loop — it performs a single check (checking the pinned version or latest release), applies the update if available, and returns. Useful for one-shot invocations from `pilotctl update` and similar CLI commands. It ALWAYS runs — the StatePath enabled-gate applies only to the automatic loop, so a manual `pilotctl update` works even when auto-update is disabled.

func (*Updater) Start

func (u *Updater) Start()

Start begins the periodic check loop.

func (*Updater) Stop

func (u *Updater) Stop()

Stop signals the check loop to stop and waits for it to finish.

Jump to

Keyboard shortcuts

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