Documentation
¶
Overview ¶
Package selfupdate replaces the running binary with a newer release.
Fetch the release asset for this GOOS/GOARCH, verify its SHA-256 against the checksums the release ships, and rename it over the current executable. Nothing is executed before it is verified, and a failed verification leaves the running binary untouched.
On Unix the dashboard notices the replacement on its own: internal/selfreload watches the executable and re-execs into whatever is there now, so an update applied from another terminal takes effect without anyone quitting. Windows cannot exec over a running image, so the dashboard exits and asks for a restart instead.
One concern per file: release.go is the release API and everything off the network, checksum.go the verification of a fetched asset against the release checksums, install.go the filesystem half that puts a verified binary in place.
Index ¶
- Constants
- func Apply(ctx context.Context, rel *Release) (string, error)
- func AssetName(version string) string
- func ChecksumFor(listing, name string) (string, bool)
- func ChecksumListing(archive []byte) (string, error)
- func TrustedReleaseURL(raw string) bool
- func ValidateRepo(repo string) error
- type Release
Constants ¶
const DefaultRepo = "maci0/toktop"
DefaultRepo is the GitHub repository releases are fetched from.
const TokenEnv = "GITHUB_TOKEN"
TokenEnv is the optional environment variable authenticating the GitHub API calls `toktop update` makes, past the anonymous rate limit.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply downloads, verifies, and installs the release over the running executable. It returns the path that was replaced.
The new binary is written next to the current one (same filesystem, so the rename is atomic) and only renamed after its checksum matches. A failed verification leaves the running binary untouched. If the destination already matches the release checksum, the asset is not fetched or replaced.
func AssetName ¶
AssetName is the binary this platform needs from a release. It must match the names `make release` writes into dist/, or self-update finds nothing.
func ChecksumFor ¶
ChecksumFor finds one file's expected hash in a `sha256sum` style listing ("<hex> <name>", with an optional binary-mode asterisk).
func ChecksumListing ¶
ChecksumListing pulls checksums.txt out of the tar.gz the release ships it in. Entries are matched by base name, so a wrapper directory around the file does not matter; everything else in the archive is skipped.
func TrustedReleaseURL ¶ added in v0.16.0
TrustedReleaseURL reports whether raw is a GitHub URL over https. Every release download and redirect hop is held to it, and so is the release page `toktop update --check` prints for a shell expansion: that page is never fetched, but it is release data landing in the caller's shell.
A URL that survives that second job carries no byte a shell would read as anything but itself. url.Parse only refuses C0 and DEL, and the space it admits ends the word: a release page spelled "https://github.com/o/r/releases/tag/v1 x$(id)" parses, names a trusted host, and reaches the operator as two words with a command substitution in the second. Every character a release URL is built from is kept, and anything else is refused; none of the refused bytes appear in a real GitHub URL, so nothing legitimate stops working.
func ValidateRepo ¶ added in v0.6.0
ValidateRepo reports whether repo is a GitHub owner/name, the only shape interpolated into the releases API path. Anything else is path traversal, a query string, or log injection into the error that names the URL.
Types ¶
type Release ¶
type Release struct {
TagName string `json:"tag_name"`
HTMLURL string `json:"html_url"`
Assets []struct {
Name string `json:"name"`
URL string `json:"browser_download_url"`
} `json:"assets"`
}
Release is the subset of a GitHub release that matters here. The asset members are the only ones decoded: size and content_type are left out rather than carried unread, so a value spelled as a string or a float by some proxy cannot fail the whole decode and take the release down with it.
func Check ¶
Check queries the latest release. It is never called on the startup path: a version check must not stand between the user and the dashboard.