update

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package update is how a release build of raglit gets its next build: a manifest of downloads (URL, sha256 and size per os/arch) signed with minisign, an installer that verifies a download before anything runs it, and the daily check that stages a new build for the daemon to move to.

Copied from dun's internal/update (same key, same manifest format), which another module cannot import. Whether the two copies become one shared module is aw4 i_1m6kvp7g4e6dwrxx5bx0x0.

Nothing here knows a download location: those are in the manifest, and the manifest's own location is compiled into release builds only (cmd/raglit/release_on.go).

Index

Constants

View Source
const (
	MaxManifest = 1 << 20
	MaxSig      = 4 << 10
	MaxArchive  = 512 << 20
)

Limits on what is read from the network.

View Source
const Interval = 24 * time.Hour

Interval is how often the check runs at most.

View Source
const MaxBinary = 512 << 20

MaxBinary caps the binary read out of an archive.

View Source
const Schema = 1

Schema is the manifest format this build reads.

Variables

View Source
var ErrNoKey = errors.New("no minisign public key")

ErrNoKey: a key file with no key in it (release/minisign.pub's placeholder).

View Source
var ErrNotDue = errors.New("checked less than a day ago")

ErrNotDue: the last check was less than Interval ago.

Functions

func IsVerify

func IsVerify(err error) bool

IsVerify reports whether err is a failed check.

func Platform

func Platform(goos, goarch string) string

Platform is a files key: "linux_amd64".

func Sign

func Sign(priv ed25519.PrivateKey, id [8]byte, msg []byte, trusted string) string

Sign makes a prehashed ("ED") minisign signature of msg, as `minisign -S` does. For tests and for endorsing a next key by hand; release manifests are signed with the minisign CLI (make release).

func StateFile

func StateFile(home string) string

StateFile is the check's state in home.

func VerifyManifest

func VerifyManifest(body []byte, sig string, keys []PublicKey) (*Manifest, *PublicKey, error)

VerifyManifest checks body's signature with one of keys, then parses it. It returns the manifest, and the next key when key_next is present and endorsed by the key that signed the manifest.

Types

type Artifact

type Artifact struct {
	Version string          `json:"version"`
	Files   map[string]File `json:"files"`
}

type Endorsement

type Endorsement struct {
	Key       string `json:"key"`       // the base64 key line
	Signature string `json:"signature"` // a .minisig over Key's bytes
}

Endorsement is a key signed by another.

type Fetcher

type Fetcher struct {
	Client    *http.Client
	AllowHTTP bool
}

Fetcher downloads. AllowHTTP is for tests (httptest serves plain HTTP).

func (*Fetcher) Install

func (f *Fetcher) Install(ctx context.Context, file File, entry, dst string) (string, error)

Install downloads file, checks it, and puts the archive's binary named entry at dst (mode 0755). It returns dst.

func (*Fetcher) Small

func (f *Fetcher) Small(ctx context.Context, u string, max int64) ([]byte, error)

Small reads a small document (a manifest, a signature), at most max bytes.

type File

type File struct {
	URL    string `json:"url"`
	SHA256 string `json:"sha256"`
	Size   int64  `json:"size"`
}

type Manifest

type Manifest struct {
	Schema    int                 `json:"schema"`
	Version   string              `json:"version"`
	Published string              `json:"published"`
	Summary   string              `json:"summary,omitempty"`
	KeyNext   *Endorsement        `json:"key_next,omitempty"`
	Artifacts map[string]Artifact `json:"artifacts"`
}

func Latest

func Latest(ctx context.Context, f *Fetcher, url string, keys []PublicKey, home string) (*Manifest, error)

Latest fetches and verifies the newest release's manifest at url, with the keys this build trusts and any next key endorsed before (in StateFile), and installs nothing and records nothing: what a version check shows as "latest".

func ParseManifest

func ParseManifest(b []byte) (*Manifest, error)

ParseManifest reads and checks a manifest's shape. It does not verify a signature: VerifyManifest does.

func (*Manifest) File

func (m *Manifest) File(name, plat string) (Artifact, File, bool)

File is name's download for plat, if the manifest has one.

func (*Manifest) PublishedAt

func (m *Manifest) PublishedAt() time.Time

PublishedAt is the manifest's publication time (zero when unset).

type PublicKey

type PublicKey struct {
	ID  [8]byte
	Key ed25519.PublicKey
}

PublicKey is a minisign public key.

func ParseKeys

func ParseKeys(file string) ([]PublicKey, error)

ParseKeys reads a key file: comment lines, then one key line per key (more than one while a rotation overlaps). A file with none, or with a line that is not a key, is ErrNoKey.

func ParsePublicKey

func ParsePublicKey(line string) (PublicKey, error)

ParsePublicKey reads one key's base64 line.

func VerifyAny

func VerifyAny(msg []byte, sigText string, keys []PublicKey) (PublicKey, error)

VerifyAny checks sig with whichever of keys it names, and returns that key.

func (PublicKey) IDString

func (k PublicKey) IDString() string

IDString is the key id as minisign prints it.

func (PublicKey) Line

func (k PublicKey) Line() string

Line is the key's base64 line, as in a .pub file.

func (PublicKey) Verify

func (k PublicKey) Verify(msg []byte, sig *Signature) error

Verify checks sig over msg with k: the key id, the signature, and the global signature over the trusted comment.

type Result

type Result struct {
	Checked bool
	Staged  bool
	From    string
	To      string
	Summary string
}

Result is what a check did. Staged: a new build is at Exe.

type Signature

type Signature struct {
	Alg       string // "Ed" or "ED" (prehashed)
	KeyID     [8]byte
	Sig       []byte
	Trusted   string // the trusted comment, without its prefix
	GlobalSig []byte
}

Signature is a parsed .minisig file.

func ParseSignature

func ParseSignature(text string) (*Signature, error)

ParseSignature reads a .minisig file's four lines.

type State

type State struct {
	Checked   time.Time `json:"checked"`
	Version   string    `json:"version,omitempty"`   // the newest manifest's version seen
	Published string    `json:"published,omitempty"` // and its publication time
	Keys      []string  `json:"keys,omitempty"`      // next keys endorsed by a trusted one
	Staged    string    `json:"staged,omitempty"`    // the version last installed
	Error     string    `json:"error,omitempty"`     // what the last check ran into
}

State is what the check keeps between runs, in StateFile.

func LoadState

func LoadState(path string) State

LoadState reads the check's state ("" fields when there is none).

type Updater

type Updater struct {
	ManifestURL string
	Name        string      // the artifact in the manifest, and the file in its archive
	Keys        []PublicKey // the keys compiled into this build
	Current     string      // this build's version
	Exe         string      // this binary's file, which the new build replaces
	Home        string      // where StateFile lives
	Platform    string      // Platform(runtime.GOOS, runtime.GOARCH)
	Fetch       *Fetcher
	Now         func() time.Time
}

Updater is one release build's check.

func (*Updater) Run

func (u *Updater) Run(ctx context.Context) (res Result, err error)

Run checks once, unless the last check was less than Interval ago.

type VerifyError

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

VerifyError is a check that failed on what was downloaded — a signature, a checksum, an archive — as opposed to a network that did not answer. It is said to the person; an unreachable network is not.

func (*VerifyError) Error

func (e *VerifyError) Error() string

type Version

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

Version is a parsed vMAJOR.MINOR.PATCH[-pre][+build].

func ParseVersion

func ParseVersion(s string) (Version, error)

ParseVersion reads a release version; anything else ("dev", a git describe with a commit count) is an error.

func (Version) Compare

func (a Version) Compare(b Version) int

Compare is -1, 0 or 1. A pre-release is before its release; two pre-releases compare as strings (a simplification of semver's rule).

Jump to

Keyboard shortcuts

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