update

package
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package update checks a signed update site for newer Gophenberg versions and keeps what each check found.

Index

Constants

View Source
const (
	// KeyListPath is where the key list sits on an update site.
	KeyListPath = "v1/keys.json"
	// TimestampPath is where the timestamp file sits on an update site.
	TimestampPath = "v1/timestamp.json"
	// SignatureSuffix ends the name of the file that signs another.
	SignatureSuffix = ".sig"
)
View Source
const DefaultAddress = "https://updates.gophenberg.org"

DefaultAddress is the official update site.

View Source
const MaxFileSize = 64 << 10

MaxFileSize is the most bytes a check reads of one file of the update site.

Variables

View Source
var ErrNoUpdate = errors.New("update: the update site offers no version newer than the one this site runs")

ErrNoUpdate says the update site offers this site no version newer than the one it runs.

View Source
var ErrNotStored = errors.New("update: the result of the check could not be stored")

ErrNotStored marks a check whose result the site setting store could not keep.

View Source
var ErrNotTaken = errors.New("update: the update site serves no update this site takes")

ErrNotTaken marks why Choose takes no update from the update site, as against a store it could not use.

Functions

func Bucket

func Bucket(siteID, release string) int

Bucket returns the share of sites, from 0 to 99, that a site falls in for version.

func Check

func Check(ctx context.Context, cfg Config, taken Serials) (*Found, Serials, error)

Check fetches and verifies the key list, the timestamp file and the index, refuses older serials, finds the update.

func IndexPath

func IndexPath(channel string) string

IndexPath returns where the index of channel sits on an update site.

func NeedsPostgreSQL

func NeedsPostgreSQL(major, needed int) bool

NeedsPostgreSQL reports whether a server of major runs an older PostgreSQL than needed, never on SQLite's 0.

func NewClient

func NewClient(timeout time.Duration) *http.Client

NewClient returns the client a check fetches with, giving up after timeout and following no redirect.

func ParseAddress

func ParseAddress(text string) (*url.URL, error)

ParseAddress returns the update site text names: https, or plain http on a loopback host, with no user or query.

func ParseRoots

func ParseRoots(text string) ([]*ecdsa.PublicKey, error)

ParseRoots returns the P-256 root keys a comma-separated list of Multikeys names, none for a blank text.

func Platform

func Platform() string

Platform returns the id of the archive built for the system and processor this binary runs on, like linux-amd64.

func Roots

func Roots() []*ecdsa.PublicKey

Roots returns the root keys built into this binary.

func SignIndex

func SignIndex(body []byte, key ed25519.PrivateKey) string

SignIndex returns the FAIR signature line of the exact bytes of an index under a release or standby key.

func SignKeyList

func SignKeyList(body []byte, root *ecdsa.PrivateKey) (string, error)

SignKeyList returns the line a root signs the exact bytes of a key list with: its Multikey, then its signature.

Types

type Artifact

type Artifact struct {
	ID          string `json:"id"`
	Platform    string `json:"platform"`
	ContentType string `json:"content-type"`
	URL         string `json:"url"`
	Checksum    string `json:"checksum"`
	Signature   string `json:"signature"`
}

Artifact is one archive a release record lists, with what an update needs to pick, fetch and check it.

type Artifacts

type Artifacts struct {
	Package []Artifact `json:"package"`
}

Artifacts holds the files of a release record by kind.

type Chosen

type Chosen struct {
	Found   Found
	Release Release
	Signers []ed25519.PublicKey
}

Chosen is the offer an update takes, read again from the signed index, with its release record and signing keys.

func Choose

func Choose(ctx context.Context, cfg Config, store Settings, named string) (Chosen, error)

Choose verifies the key list, timestamp file and index again, keeps their serials, returns the offer named or newest.

type Config

type Config struct {
	Address *url.URL
	Channel string
	Roots   []*ecdsa.PublicKey
	Client  *http.Client
	Site    Site
	Now     func() time.Time
}

Config is what a check needs: the update site, the channel, the trusted roots, the client and the site it is for.

type Found

type Found struct {
	Version         string   `json:"version"`
	MinimumVersion  string   `json:"minimum_version"`
	PostgreSQL      int      `json:"postgresql"`
	Kits            []string `json:"kits"`
	Notes           string   `json:"notes"`
	Auto            bool     `json:"auto"`
	LongJump        bool     `json:"long_jump"`
	NeedsPostgreSQL bool     `json:"needs_postgresql"`
}

Found is the update a check found for a site, with what taking it asks of the site.

type Index

type Index struct {
	Schema  int       `json:"schema"`
	Channel string    `json:"channel"`
	Serial  int64     `json:"serial"`
	Expires time.Time `json:"expires"`
	Offers  []Offer   `json:"offers"`
}

Index is the list of offers of one channel, signed by a release or standby key.

func (Index) UpdateFor

func (i Index) UpdateFor(site Site) *Found

UpdateFor returns the newest offer above the running version, not withdrawn, not refused and rolled out, or nil.

type KeyList

type KeyList struct {
	Schema  int         `json:"schema"`
	Serial  int64       `json:"serial"`
	Expires time.Time   `json:"expires"`
	Keys    []ListedKey `json:"keys"`
}

KeyList is the list of release keys a root signed, with its serial and expiry.

func ReadKeyList

func ReadKeyList(body, sigs []byte, roots []*ecdsa.PublicKey, now time.Time) (KeyList, error)

ReadKeyList returns the key list body holds once one trusted root signed it in sigs and it is still valid at now.

func (KeyList) ReadIndex

func (l KeyList) ReadIndex(body, sig []byte, channel string, now time.Time) (Index, error)

ReadIndex returns the index of channel body holds once a signer the list names signed it in sig, valid at now.

func (KeyList) ReadIndexOfAnyAge

func (l KeyList) ReadIndexOfAnyAge(body, sig []byte, channel string) (Index, error)

ReadIndexOfAnyAge returns the index of channel as ReadIndex does, but takes it whatever its expiry says.

func (KeyList) ReadTimestamp

func (l KeyList) ReadTimestamp(body, sig []byte, now time.Time) (Timestamp, error)

ReadTimestamp returns the timestamp file body holds once a timestamp key the list names signed it, valid at now.

func (KeyList) Signers

func (l KeyList) Signers() []ed25519.PublicKey

Signers returns the Ed25519 keys the list names as release or standby keys.

func (KeyList) TimestampKeys

func (l KeyList) TimestampKeys() []ed25519.PublicKey

TimestampKeys returns the Ed25519 keys the list names as timestamp keys.

type ListedKey

type ListedKey struct {
	Role     Role   `json:"role"`
	Multikey string `json:"multikey"`
}

ListedKey is one key the key list names, with what it may sign.

type Offer

type Offer struct {
	Rollout        int             `json:"rollout"`
	Auto           bool            `json:"auto"`
	Withdrawn      bool            `json:"withdrawn"`
	MinimumVersion string          `json:"minimum_version"`
	PostgreSQL     int             `json:"postgresql"`
	Kits           []string        `json:"kits"`
	Notes          string          `json:"notes"`
	Release        json.RawMessage `json:"release"`
}

Offer is one version a channel index offers, with what a site needs to take it.

func (Offer) Version

func (o Offer) Version() string

Version returns the version of the release an offer carries.

type RefusedError

type RefusedError struct {
	Version string
}

RefusedError refuses a version that failed its start check after an earlier update, never taken again on its own.

func (RefusedError) Error

func (e RefusedError) Error() string

Error says which version the site refused and why.

type Release

type Release struct {
	Version   string    `json:"version"`
	Artifacts Artifacts `json:"artifacts"`
}

Release is the release record an offer carries: the version and the archives it publishes.

func (Release) ArchiveFor

func (r Release) ArchiveFor(id string) (Artifact, error)

ArchiveFor returns the tar.gz archive the release record lists under id, refusing a platform it publishes none for.

type Result

type Result struct {
	CheckedAt *time.Time `json:"checked_at"`
	Offer     *Found     `json:"offer"`
	FailedAt  *time.Time `json:"failed_at"`
	Error     string     `json:"error"`
}

Result is what the checks found: the last good check, and the last failure since it.

func ResultOf

func ResultOf(ctx context.Context, store Settings) (Result, error)

ResultOf returns what the checks stored in store, an empty result before the first check.

func Run

func Run(ctx context.Context, cfg Config, store Settings) (Result, error)

Run checks the update site for the site, keeping its identity, the serials taken and the result in store.

type Role

type Role string

Role names what a listed key may sign.

const (
	// RoleRelease signs the channel indexes and the release files.
	RoleRelease Role = "release"
	// RoleStandby signs them in place of a release key that leaked.
	RoleStandby Role = "standby"
	// RoleTimestamp signs the timestamp file that keeps the indexes fresh.
	RoleTimestamp Role = "timestamp"
)

type Serials

type Serials struct {
	Keys  int64 `json:"keys"`
	Index int64 `json:"index"`
}

Serials are the serials of the last key list and index a site took.

type Settings

type Settings interface {
	Lookup(ctx context.Context, key string) (string, bool, error)
	Save(ctx context.Context, values map[string]string) error
	Update(ctx context.Context, keys []string, change func(held map[string]string) (map[string]string, error)) error
}

Settings is the site setting store a check keeps its state in, updating it as one write no other update overlaps.

type Site

type Site struct {
	ID          string
	Running     string
	ServerMajor int
	Refused     []string
}

Site is what the index is read for: the site's identity, running version, PostgreSQL major and refused versions.

func (Site) Lift

func (s Site) Lift(release string) Site

Lift returns the site taking the release named again, for a person who retries a version that failed before.

type Timestamp

type Timestamp struct {
	Schema  int              `json:"schema"`
	Expires time.Time        `json:"expires"`
	Keys    int64            `json:"keys"`
	Indexes map[string]int64 `json:"indexes"`
}

Timestamp is the timestamp file a timestamp key signed, naming the serials of the newest key list and indexes.

Jump to

Keyboard shortcuts

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