Documentation
¶
Overview ¶
Package selfupdate turns a `go install` build of celeste into the official release binary of the same version, and backs `celeste update` (W5 rulings 25–30). It checks everything it downloads against the release signing key embedded in the binary and never installs a file that failed a check.
Index ¶
- Constants
- Variables
- func CheckManifest(manifest []byte, tag, archive string) ([32]byte, error)
- func CleanupOld(exe string)
- func Extract(archiveName string, data []byte, binary string) ([]byte, error)
- func FindChecksum(checksums []byte, name string) ([32]byte, error)
- func Newer(a, b string) bool
- func Reexec(exe string, argv, env []string) error
- func ValidTag(s string) bool
- func VerifyDist(dir, tag string, pubKey []byte) error
- func VerifySignature(pubKey, signed, armoredSig []byte) error
- type Kind
- type Platform
- type Throttle
- type Updater
Constants ¶
const ModulePath = "github.com/whykusanagi/celeste-cli"
ModulePath is the module whose go install builds upgrade to the official release; a fork's build (another path) is left alone.
const Repo = "https://github.com/whykusanagi/celeste-cli"
Repo is where official releases are published.
Variables ¶
var ( ErrNoAsset = errors.New("there is no official build for this platform") ErrBadArchive = errors.New("the release archive does not hold the expected binary") ErrTooLarge = errors.New("the download is larger than celeste allows") )
var ( ErrBadSignature = errors.New("the release signature does not verify with celeste's release key") ErrChecksum = errors.New("the download does not match the signed checksums") ErrManifest = errors.New("the signed release manifest does not describe this download") )
var ErrBadTag = errors.New("not a release tag")
ErrBadTag is a version string that is not a release tag.
var ErrHost = errors.New("the updater only talks HTTPS to GitHub")
ErrHost is a request to anything but HTTPS on an allowed host.
var Hosts = []string{"github.com", "objects.githubusercontent.com", "release-assets.githubusercontent.com"}
Hosts are the only hosts the updater talks to, over HTTPS only (ruling 26). GitHub redirects release downloads to release-assets.githubusercontent.com (objects.githubusercontent.com before 2025).
var Platforms = []Platform{
{"linux", "amd64", "celeste-linux-amd64.tar.gz", "celeste-linux-amd64"},
{"linux", "arm64", "celeste-linux-arm64.tar.gz", "celeste-linux-arm64"},
{"darwin", "amd64", "celeste-darwin-amd64.tar.gz", "celeste-darwin-amd64"},
{"darwin", "arm64", "celeste-darwin-arm64.tar.gz", "celeste-darwin-arm64"},
{"windows", "amd64", "celeste-windows-amd64.zip", "celeste-windows-amd64.exe"},
}
Platforms is every platform release.yml publishes. Renaming any of these breaks every installed updater; TestReleaseWorkflowKeepsTheUpdaterContract checks the workflow still produces them.
var ReleaseKey []byte
ReleaseKey is celeste's release signing key: a byte-identical copy of the repository's whykusanagi.asc (TestEmbeddedReleaseKeyMatchesTheRepositoryKey). Primary 940490EF09DA31322BF7FD83875849AB1D541C55; releases are signed by its subkey F4C254F6EE5D7F086C921DEBA6BB54DDC70EE8FB.
Functions ¶
func CheckManifest ¶
CheckManifest checks that a signed manifest.json describes tag and returns the SHA-256 it lists for archive. The caller requires that sum to equal checksums.txt's, which binds the download to its version (ruling 26): checksums.txt names no version, so an older release's signed checksums and archive copied into this release would otherwise pass. A missing, malformed or repeated entry is ErrManifest. Call it only on a manifest whose signature verified.
func CleanupOld ¶
func CleanupOld(exe string)
CleanupOld deletes the <exe>.old* files a Windows upgrade leaves behind. Best effort: one still running stays until the next start.
func Extract ¶
Extract returns the single regular-file entry named binary from a .tar.gz or .zip archive (by archiveName's extension), in memory. Every other entry is skipped and nothing is written to disk, so entry names can't escape anywhere.
func FindChecksum ¶
FindChecksum returns the SHA-256 that a sha256sum-format file lists for name (text "<hex> <name>" or binary "<hex> *<name>" lines). Call it only on a file whose signature verified. A name listed twice is an error.
func Newer ¶
Newer reports whether release tag a comes after b in semver order. A string that is not a ValidTag is never newer, and nothing is newer than it.
func Reexec ¶
Reexec replaces this process with exe, keeping argv and env (ruling 26). It returns only on failure.
func ValidTag ¶
ValidTag reports whether s is a release tag celeste will put in a URL: vMAJOR.MINOR.PATCH with an optional pre-release, not a Go pseudo-version.
func VerifyDist ¶
VerifyDist checks a local release directory exactly as the updater checks a download (ruling 30): both signatures with pubKey, the manifest's tag, and for every platform of the contract the archive's signed checksum and the binary inside it. release.yml runs it through the release binary, with its embedded key, before anything is published.
func VerifySignature ¶
VerifySignature checks an ASCII-armoured detached signature over signed with the armoured public key pubKey (ruling 26). It verifies as of the time the signature was made, so a release stays verifiable after the signing subkey expires; only the key's holder can date a signature. Every failure is ErrBadSignature: there is no outcome but nil or an error.
Types ¶
type Kind ¶
type Kind int
Kind is what sort of build a binary is (ruling 25).
const ( // Source is a checkout build, a pseudo-version or anything unrecognised: // the public persona, and the updater never touches the network. Source Kind = iota // Module is `go install …/cmd/celeste@vX.Y.Z` or @latest: no persona // key, a release tag, no VCS stamp. It upgrades itself. Module // Keyed is a local build that carries the persona key (make build with // ~/.celeste/persona.key): the full persona; it never downloads. Keyed // Official is a release binary: main.Channel == "release". Official )
type Platform ¶
type Platform struct{ GOOS, GOARCH, Archive, Binary string }
Platform is one entry of the release asset contract (ruling 30).
type Throttle ¶
Throttle remembers the last failed attempt, so an offline module build doesn't try on every run.
func DefaultThrottle ¶
DefaultThrottle keeps its record in ~/.celeste/cache/selfupdate.json.
type Updater ¶
type Updater struct {
Base string // the release repository, Repo
Hosts []string // allowed hosts, Hosts
Transport http.RoundTripper // nil: http.DefaultTransport's clone with ruling 26's timeouts
PublicKey []byte // the release key, ReleaseKey
GOOS string
GOARCH string
Exe string // the file to replace; "" = os.Executable() with symlinks resolved
Rename func(oldpath, newpath string) error
Now func() time.Time
}
Updater downloads, verifies and installs official release binaries. New returns the production one; tests replace fields.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package selfupdatetest builds signed fake releases for the updater's tests (W5 rulings 26, 30): a generated OpenPGP key with a signing subkey, like the real release key, and the release archives.
|
Package selfupdatetest builds signed fake releases for the updater's tests (W5 rulings 26, 30): a generated OpenPGP key with a signing subkey, like the real release key, and the release archives. |