Documentation
¶
Overview ¶
Package state stores ar2's state in a container registry (GHCR).
The state doesn't belong in the aqua-registry-g2 repository: it changes on every run and would add a commit each time. GHCR is used the same way aqua-registry-updater uses it, as a small object store keyed by a tag.
Index ¶
- Constants
- Variables
- func Fingerprint(versions []string) string
- func NewRepository(reg *Registry, token string) (*remote.Repository, error)
- func Pull(ctx context.Context, repo *remote.Repository, dir, tag string) error
- func Push(ctx context.Context, repo *remote.Repository, dir, tag string) error
- func Store(ctx context.Context, reg *Registry, token string, s *State) error
- func Write(path string, s *State) error
- type Flags
- type Package
- type Registry
- type State
Constants ¶
const FileName = "state.json"
FileName is the name of the state file inside the OCI artifact.
const SchemaVersion = "0.1.0"
SchemaVersion is the current schema version of the state.
const Tag = "latest"
Tag is the tag the state artifact is pushed to.
Variables ¶
var ErrNotFound = errors.New("the container registry holds no state")
ErrNotFound is returned by Fetch when the container registry holds no state yet, which is what a repository looks like before 'ar2 init' has ever run.
Functions ¶
func Fingerprint ¶
Fingerprint reduces a sweep's versions to something worth storing for every package in the registry.
The versions themselves would be a few hundred kilobytes of state pushed on every run; what a sweep asks of them is only whether they are the same as last time.
func NewRepository ¶
func NewRepository(reg *Registry, token string) (*remote.Repository, error)
NewRepository creates a client for the remote OCI repository.
Types ¶
type Flags ¶
Flags are the settings locating the state in a container registry. Both 'ar2 init', which writes it, and 'ar2 run', which reads it, take these.
type Package ¶
type Package struct {
RepoOwner string `json:"repo_owner,omitempty"`
RepoName string `json:"repo_name,omitempty"`
// Stars orders the work: packages with more stars are processed first.
// It is not omitempty: a repository with 0 stars must stay distinguishable from
// one whose star count could not be read, so that the latter can be retried.
Stars int `json:"stars"`
// Versions fingerprints the newest versions the last sweep saw upstream.
//
// It is what an ETag would have been, over the one thing a sweep cares about.
// GitHub's own ETag for the release listing changes whenever an asset is
// downloaded, because the listing carries the count, so it says "something
// changed" for packages where nothing did — and does it most for the popular
// ones, which is exactly backwards.
Versions string `json:"versions,omitempty"`
// CaughtUp says the registry held every version of that sweep.
//
// It is recorded from asking the registry, never from having opened a pull
// request. A pull request that fails CI is never merged, and a package marked
// done for work that didn't land would never be looked at again. Versions are
// not removed from the registry, so what was true when it was written stays
// true.
CaughtUp bool `json:"caught_up,omitempty"`
// Round counts the runs that have reached this package.
//
// A run works through the packages in order and stops when its budget is spent,
// so the ones it never reached keep the lower count and come first next time.
// Without it the order is the same every run, and a package that takes a share
// and gets nowhere -- one whose asset can't be downloaded, say -- takes the same
// share of every run and holds up everything behind it for as long as it is
// broken.
//
// It counts turns rather than naming a round the whole registry is in, so that
// nothing has to decide when a round ended: a package that has had fewer turns
// than another is behind, and that is the whole rule. A package the registry has
// just gained starts from the largest count there is, which is the back of the
// order; starting from none would put it ahead of everything until it caught up.
Round int `json:"round,omitempty"`
// LastDeepCheck is when the package's whole history was last walked. Zero means
// never, which is what a package that hasn't been backfilled looks like.
//
// A sweep sees the newest versions, and anything published after the history is
// complete appears among them. A release dated in the past doesn't, so the
// history is walked again from time to time to find what the sweep structurally
// cannot.
LastDeepCheck time.Time `json:"last_deep_check,omitzero"`
}
Package is the state of a single package.
type Registry ¶
type Registry struct {
// Registry is the container registry host, e.g. "ghcr.io".
Registry string
// Repository is the OCI repository, e.g. "aquaproj/ar2".
Repository string
// Username is the user the token belongs to.
Username string
}
Registry describes where the state artifact lives.
type State ¶
type State struct {
// SchemaVersion allows the format to change without breaking an older ar2 that
// reads the state.
SchemaVersion string `json:"schema_version"`
UpdatedAt time.Time `json:"updated_at"`
// Packages is keyed by package name.
Packages map[string]*Package `json:"packages"`
// Renamed maps a name the registry has stopped holding to the one it holds now.
//
// A repository that is renamed makes the registry's name for the package the wrong
// one, and the package is moved: its branch is carried over and the catalogue is
// brought to the new name. What is left is aqua-registry, which still lists the old
// name until its own updater notices, and a run reading that would add the package
// back under the name it was just moved off.
//
// It is also what stops the same rename being done twice: the sweep asks about the
// repository a package records, so once that is the new one GitHub says nothing has
// changed.
Renamed map[string]string `json:"renamed,omitempty"`
}
State is ar2's state.
It holds only what is safe to cache. Which versions have been generated is not here: that is read from aqua-registry-g2 itself, because a version only counts once its pull request is merged, and a record of "already generated" would stop a version whose CI failed from ever being retried.
func Fetch ¶
Fetch pulls the state from the container registry and reads it. It returns ErrNotFound when there is none.
func (*State) Rename ¶ added in v0.0.20
Rename records that a package is held under another name now, and moves what is known about it.
The turn count comes along, so a renamed package neither loses its place in the order nor jumps to the front of it: it is the same package and has had the same turns.