updates

package
v0.0.11 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2024 License: MIT Imports: 15 Imported by: 2

Documentation

Overview

Package updates implements a mechanism for checking if software updates are available, and fetching a changelog.

Given a domain, the latest version of the software is queried in DNS from "_updates.<domain>" as a TXT record. If a new version is available, the changelog compared to a last known version can be retrieved. A changelog base URL and public key for signatures has to be specified explicitly.

Downloading or upgrading to the latest version is not part of this package.

Index

Constants

This section is empty.

Variables

View Source
var (
	MetricLookup         stub.HistogramVec                                                                                           = stub.HistogramVecIgnore{}
	MetricFetchChangelog stub.HistogramVec                                                                                           = stub.HistogramVecIgnore{}
	HTTPClientObserve    func(ctx context.Context, log *slog.Logger, pkg, method string, statusCode int, err error, start time.Time) = stub.HTTPClientObserveIgnore
)
View Source
var (
	// Lookup errors.
	ErrDNS             = errors.New("updates: dns error")
	ErrRecordSyntax    = errors.New("updates: dns record syntax")
	ErrNoRecord        = errors.New("updates: no dns record")
	ErrMultipleRecords = errors.New("updates: multiple dns records")
	ErrBadVersion      = errors.New("updates: malformed version")

	// Fetch changelog errors.
	ErrChangelogFetch = errors.New("updates: fetching changelog")
)

Functions

func Check

func Check(ctx context.Context, elog *slog.Logger, resolver dns.Resolver, domain dns.Domain, lastKnown Version, changelogBaseURL string, pubKey []byte) (rversion Version, rrecord *Record, changelog *Changelog, rerr error)

Check checks for an updated version through DNS and fetches a changelog if so.

Check looks up a TXT record at _updates.<domain>, and parses the record. If the latest version is more recent than lastKnown, an update is available, and Check will fetch the signed changes since lastKnown, verify the signatures, and return the changelog. The latest version and parsed DNS record is returned regardless of whether a new version was found. A non-nil changelog is only returned when a new version was found and a changelog could be fetched and verified.

func Lookup

func Lookup(ctx context.Context, elog *slog.Logger, resolver dns.Resolver, domain dns.Domain) (rversion Version, rrecord *Record, rerr error)

Lookup looks up the updates DNS TXT record at "_updates.<domain>" and returns the parsed form.

Types

type Change

type Change struct {
	PubKey []byte // Key used for signing.
	Sig    []byte // Signature over text, with ed25519.
	Text   string // Signed changelog entry, starts with header similar to email, with at least fields "version" and "date".
}

Change is a an entry in the changelog, a released version.

type Changelog

type Changelog struct {
	Changes []Change // Newest first.
}

Changelog is returned as JSON.

The changelog itself is not signed, only individual changes. The goal is to prevent a potential future different domain owner from notifying users about new versions.

func FetchChangelog

func FetchChangelog(ctx context.Context, elog *slog.Logger, baseURL string, base Version, pubKey []byte) (changelog *Changelog, rerr error)

FetchChangelog fetches the changelog compared against the base version, which can be the Version zero value.

The changelog is requested using HTTP GET from baseURL with optional "from" query string parameter.

Individual changes are verified using pubKey. If any signature is invalid, an error is returned.

A changelog can be maximum 1 MB.

type Record

type Record struct {
	Version string  // v=UPDATES0, required and must always be first.
	Latest  Version // l=<version>, required.
}

Record is an updates DNS record.

func ParseRecord

func ParseRecord(txt string) (record *Record, isupdates bool, err error)

ParseRecord parses an updates DNS TXT record as served at

type Version

type Version struct {
	Major int
	Minor int
	Patch int
}

Version is a specified version in an updates records.

func ParseVersion

func ParseVersion(s string) (Version, error)

ParseVersion parses a version as used in an updates records.

Rules:

  • Optionally start with "v"
  • A dash and anything after it is ignored, e.g. for non-release modifiers.
  • Remaining string must be three dot-separated numbers.

func (Version) After

func (v Version) After(ov Version) bool

After returns if v comes after ov.

func (Version) String

func (v Version) String() string

String returns a human-reasonable version, also for use in the updates record.

Jump to

Keyboard shortcuts

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