// Package chain keeps the controller's chain on the bus alone (novox/hq ADR 0408, design 47): module, commit, build, // published artifact or package, rollout and assignment are one chain, a bucket each of the bus's key-value store, // each the only source of its kind, written by the controller that holds the lease by compare-and-set. // // **No key is removed.** A Backend has no delete and no purge (ADR 0408 §4): an assignment of a module taken off its // node is kept, saying so. **A value is never cut** (§6): one over the largest the bus holds is refused, and the key // stays as it was. **Each key keeps its earlier values** (§5), read back with History. package chain import ( "encoding/json" "time" ) // Ref names a build and the commit it was made from: one end of a change. type Ref struct { Build string `json:"build,omitempty"` Commit string `json:"commit,omitempty"` } // Package is a release a build published to the package registry. type Package struct { Name string `json:"name"` Version string `json:"version"` } // Published is what a build published: an artifact by its digest, or a package release by name and version. type Published struct { Artifact string `json:"artifact,omitempty"` Package *Package `json:"package,omitempty"` } // Artifact is one thing a build made. type Artifact struct { Name string `json:"name"` Kind string `json:"kind"` Reference string `json:"reference"` } // ReadRepository is a repository a build read source from besides the module's own. type ReadRepository struct { Repository string `json:"repository"` Ref string `json:"ref,omitempty"` Paths []string `json:"paths,omitempty"` Own bool `json:"own,omitempty"` } // Source is the build source a build read in one repository. type Source struct { Repository string `json:"repository,omitempty"` Ref string `json:"ref,omitempty"` Paths []string `json:"paths"` } // The states of a build record. A record in state asked is a request that no outcome has answered (issue 1091); one // without a state is an outcome. const BuildAsked = "asked" // Build is one attempt, whichever way it went, kept under its id. It names its module, its repository and commit, its // reuse key (novox/hq ADR 0350) and what it published (ADR 0408 §1). type Build struct { ID string `json:"id"` State string `json:"state,omitempty"` Repository string `json:"repository"` Ref string `json:"ref,omitempty"` Module string `json:"module,omitempty"` Commit string `json:"commit,omitempty"` On string `json:"on,omitempty"` Path string `json:"path,omitempty"` Manifest json.RawMessage `json:"manifest,omitempty"` Against []string `json:"against,omitempty"` Mirrored []string `json:"mirrored,omitempty"` Read []ReadRepository `json:"read,omitempty"` Sources []Source `json:"sources,omitempty"` SourceFingerprint string `json:"source-fingerprint,omitempty"` Failed string `json:"failed,omitempty"` Made []Artifact `json:"made,omitempty"` Asked time.Time `json:"asked,omitzero"` At time.Time `json:"at,omitzero"` ReuseKey string `json:"reuse-key,omitempty"` Published *Published `json:"published,omitempty"` } // Commit is one repository's commit a rollout carries. type Commit struct { Repository string `json:"repository"` Branch string `json:"branch,omitempty"` Commit string `json:"commit"` Merged time.Time `json:"merged,omitzero"` } // Change is one assignment a rollout changed: the build and commit it ran before and the ones it runs after. type Change struct { Node string `json:"node"` Module string `json:"module"` Before Ref `json:"before"` After Ref `json:"after"` } // Step is one tier sent to one machine. type Step struct { Tier int `json:"tier"` Node string `json:"node"` Sent *time.Time `json:"sent,omitempty"` Reported *time.Time `json:"reported,omitempty"` } // Links are the fields a rollout gains on the chain: the builds it carried, the machine steps it has taken and the // assignments it changed, each with the build before and after. The controller's plan embeds them, so the plan's own // fields and these are one value (ADR 0408 §1). type Links struct { Builds []string `json:"builds,omitempty"` Steps []Step `json:"steps,omitempty"` Changed []Change `json:"changed,omitempty"` } // Rollout is the controller's record of one batch's delivery, kept under the batch's id: the commit it fixed per // repository, its tiers, the builds it carried and the assignments it changed (ADR 0408 §1). The controller's plan // carries more (its modules, its times, its backups) beside these, under the same key. type Rollout struct { ID string `json:"id"` State string `json:"state,omitempty"` Commits []Commit `json:"commits,omitempty"` Tiers [][]string `json:"tiers,omitempty"` Links } // Assignment is one module on one node, kept under `.`. The first five fields are the ones its readers // have always read, with the names they have always had (novox/hq ADR 0408 §3); the rest name the chain: the build, the // artifact (by digest) or the package it runs, its commit, the rollout that put it there and since when. type Assignment struct { Node string `json:"node"` Module string `json:"module"` Assigned time.Time `json:"assigned,omitzero"` RequiredBy string `json:"required-by,omitempty"` Provisioning json.RawMessage `json:"provisioning,omitempty"` Build string `json:"build,omitempty"` Artifact string `json:"artifact,omitempty"` Package *Package `json:"package,omitempty"` Commit string `json:"commit,omitempty"` Rollout string `json:"rollout,omitempty"` Since time.Time `json:"since,omitzero"` } // Key is an assignment's key. func (a Assignment) Key() string { return a.Node + "." + a.Module }