Documentation
¶
Overview ¶
Package remotestate publishes one machine's WB fleet state to a shared store and reads every machine's state back. The store is pluggable; the snapshot format is not.
Index ¶
- Constants
- func Encode(s Snapshot) ([]byte, error)
- func EncodeClaim(c Claim) ([]byte, error)
- func ValidTaskName(task string) error
- type Claim
- type ClaimEntry
- type ClaimMode
- type ClaimOutcome
- type ClaimOutcomeKind
- type Config
- type Entry
- type Provider
- type PublishConfig
- type PublishResult
- type Redaction
- type ReleaseOutcome
- type ReleaseOutcomeKind
- type RepositoryInput
- type RepositoryState
- type Snapshot
- type UnconfiguredError
- type WorktreeState
Constants ¶
const ( StatusAttention = "attention" StatusError = "error" )
Status constants for RepositoryState.
const ClaimSchemaVersion = 1
ClaimSchemaVersion is the claim format this binary writes and the newest it can read.
const ConfigSnippet = `` /* 137-byte string literal not displayed */
ConfigSnippet is printed whenever the remote section is absent or incomplete, so the fix is copy-paste rather than documentation lookup.
const SchemaVersion = 1
SchemaVersion is the snapshot format this binary writes and the newest it can read.
Variables ¶
This section is empty.
Functions ¶
func EncodeClaim ¶ added in v0.45.0
EncodeClaim renders a claim as YAML.
func ValidTaskName ¶ added in v0.45.0
ValidTaskName enforces the machine-name rule on task names, which also keeps claims/<task>.yaml a safe path.
Types ¶
type Claim ¶ added in v0.45.0
type Claim struct {
SchemaVersion int `yaml:"schema_version" json:"schema_version"`
Task string `yaml:"task" json:"task"`
Login string `yaml:"login" json:"login"`
Machine string `yaml:"machine" json:"machine"`
ClaimedAt time.Time `yaml:"claimed_at" json:"claimed_at"`
Note string `yaml:"note,omitempty" json:"note,omitempty"`
}
Claim says one task is being worked on by one login/machine. The claim file's existence in the store IS the claim; releasing deletes it, so git history is the audit trail and no state field exists.
func DecodeClaim ¶ added in v0.45.0
DecodeClaim parses a claim, refusing formats newer than this binary knows.
type ClaimEntry ¶ added in v0.45.0
ClaimEntry is one claim as read from the store; Error is set when the file could not be decoded (Claim then carries only Task from the path).
type ClaimMode ¶ added in v0.45.0
type ClaimMode int
ClaimMode selects how an existing claim by someone else is treated.
const ( // ClaimNormal refuses to touch anyone else's claim. ClaimNormal ClaimMode = iota // ClaimTakeOverStale replaces another holder's claim; callers must have // established staleness first — the provider does not judge it. ClaimTakeOverStale // ClaimForce replaces anything, including an unreadable claim file. ClaimForce )
type ClaimOutcome ¶ added in v0.45.0
type ClaimOutcome struct {
Kind ClaimOutcomeKind `json:"kind"`
Current Claim `json:"current"`
Previous *Claim `json:"previous,omitempty"` // set on took_over
Location string `json:"location,omitempty"` // commit SHA / URL
}
ClaimOutcome reports a Claim call so commands own all messaging.
type ClaimOutcomeKind ¶ added in v0.45.0
type ClaimOutcomeKind string
ClaimOutcomeKind is what a Claim call did.
const ( ClaimAcquired ClaimOutcomeKind = "acquired" ClaimRefreshed ClaimOutcomeKind = "refreshed" // ClaimHeld means no write happened; Current is the other holder's claim. ClaimHeld ClaimOutcomeKind = "held" ClaimTookOver ClaimOutcomeKind = "took_over" )
type Config ¶
type Config struct {
Provider string `yaml:"provider"`
Repo string `yaml:"repo"`
Machine string `yaml:"machine"`
Publish PublishConfig `yaml:"publish"`
}
Config is the remote section of ~/.config/wb/wb.yaml.
func LoadConfig ¶
LoadConfig reads the remote section from path. A missing file or section is an UnconfiguredError; a present but invalid value is a plain error.
type Entry ¶
Entry is one machine as read from the store. Error is set when the stored snapshot could not be decoded; Snapshot then carries only Login/Machine.
type Provider ¶
type Provider interface {
// Publish overwrites the caller's own login/machine entry. It is
// self-contained: implementations refresh their own view of the store
// before writing, so callers never need a separate refresh step first.
Publish(ctx context.Context, snapshot Snapshot) (PublishResult, error)
// List returns every machine currently in the store, including the
// caller's own last-published entry, sorted by Key(). It is also
// self-contained, refreshing the store view itself before reading.
List(ctx context.Context) ([]Entry, error)
// Claim acquires or refreshes a claim on a task. It is self-contained:
// implementations refresh the store view before acting. The provider never
// judges staleness; ClaimTakeOverStale merely authorizes replacing another
// holder — commands establish staleness first.
//
// expectedHolder is the "<login>/<machine>" the caller judged stale and
// is authorizing replacement of; it is "" for ClaimNormal and
// ClaimForce, which do not need one. For ClaimTakeOverStale it is a
// precondition: a hub provider maps this to a conditional PUT keyed on
// the current holder, and a git-backed provider re-checks it against
// the freshly fetched store before writing. If the actual current
// holder no longer matches (they released and a third party claimed,
// or refreshed away their own staleness, between the caller's judgment
// and this call), the provider must not replace them — it reports an
// ordinary ClaimHeld naming the real current holder instead.
Claim(ctx context.Context, claim Claim, mode ClaimMode, expectedHolder string) (ClaimOutcome, error)
// Release removes a claim. It is self-contained, refreshing the store view
// before acting.
Release(ctx context.Context, task, login, machine string, force bool) (ReleaseOutcome, error)
// Claims returns every claim currently in the store, sorted by task name.
// It is self-contained, refreshing the store view itself before reading.
Claims(ctx context.Context) ([]ClaimEntry, error)
}
Provider is a shared store of machine snapshots. Implementations must be safe to call from several machines at once; the git provider relies on per-machine files plus rebase for that.
type PublishConfig ¶
type PublishConfig struct {
Unpushed Redaction `yaml:"unpushed"`
}
PublishConfig tunes what a snapshot contains.
type PublishResult ¶
type PublishResult struct {
Location string `json:"location"`
}
PublishResult says where a snapshot landed: a commit SHA for a git store, a URL for a hub.
type ReleaseOutcome ¶ added in v0.45.0
type ReleaseOutcome struct {
Kind ReleaseOutcomeKind `json:"kind"`
Current *Claim `json:"current,omitempty"`
Location string `json:"location,omitempty"`
}
ReleaseOutcome reports a Release call.
type ReleaseOutcomeKind ¶ added in v0.45.0
type ReleaseOutcomeKind string
ReleaseOutcomeKind is what a Release call did.
const ( Released ReleaseOutcomeKind = "released" // ReleaseNoop: no claim existed; releasing is idempotent. ReleaseNoop ReleaseOutcomeKind = "noop" // ReleaseHeldByOther: refused (force was false); Current names the holder. ReleaseHeldByOther ReleaseOutcomeKind = "held_by_other" )
type RepositoryInput ¶
type RepositoryInput struct {
Repository string
Path string
Status gitops.RepoStatus
Tracking gitops.TrackingState
Err error
}
RepositoryInput is the per-repository scan result Build consumes. Err set means the scan itself failed; Status and Tracking are then ignored.
type RepositoryState ¶
type RepositoryState struct {
Repository string `yaml:"repository" json:"repository"`
Path string `yaml:"path" json:"path"`
Status string `yaml:"status" json:"status"` // attention | error
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"`
Branch string `yaml:"branch,omitempty" json:"branch,omitempty"`
Upstream string `yaml:"upstream,omitempty" json:"upstream,omitempty"`
Ahead int `yaml:"ahead,omitempty" json:"ahead,omitempty"`
Behind int `yaml:"behind,omitempty" json:"behind,omitempty"`
Modified []string `yaml:"modified,omitempty" json:"modified,omitempty"`
Untracked []string `yaml:"untracked,omitempty" json:"untracked,omitempty"`
Conflicted []string `yaml:"conflicted,omitempty" json:"conflicted,omitempty"`
Unpushed []string `yaml:"unpushed,omitempty" json:"unpushed,omitempty"`
UnpushedBranches []gitops.UnpushedBranch `yaml:"unpushed_branches,omitempty" json:"unpushed_branches,omitempty"`
UnpushedCount int `yaml:"unpushed_count,omitempty" json:"unpushed_count,omitempty"`
Stashed []string `yaml:"stashed,omitempty" json:"stashed,omitempty"`
Error string `yaml:"error,omitempty" json:"error,omitempty"`
}
RepositoryState is one non-clean repository on the publishing machine.
type Snapshot ¶
type Snapshot struct {
SchemaVersion int `yaml:"schema_version" json:"schema_version"`
Login string `yaml:"login" json:"login"`
Machine string `yaml:"machine" json:"machine"`
PublishedAt time.Time `yaml:"published_at" json:"published_at"`
// LastSeenAt records the last time this machine acted through the store
// via a claim mutation (claim, refresh, release, take-over); it is
// stamped by the provider, never by Build. Zero means no claim activity
// has been recorded. See Heartbeat.
LastSeenAt time.Time `yaml:"last_seen_at,omitempty" json:"last_seen_at,omitempty"`
WBVersion string `yaml:"wb_version" json:"wb_version"`
ProjectsRoot string `yaml:"projects_root" json:"projects_root"`
RepositoriesScanned int `yaml:"repositories_scanned" json:"repositories_scanned"`
Repositories []RepositoryState `yaml:"repositories" json:"repositories"`
Worktrees []WorktreeState `yaml:"worktrees" json:"worktrees"`
}
Snapshot is one machine's published fleet state.
func Build ¶
func Build(identity Snapshot, repos []RepositoryInput, wts []worktrees.ListResult, redaction Redaction) Snapshot
Build assembles a snapshot. identity supplies Login, Machine, PublishedAt, WBVersion, and ProjectsRoot; everything else is derived here. Clean repositories are counted but not listed. Output is sorted by repository.
func (Snapshot) Heartbeat ¶ added in v0.54.0
Heartbeat is the effective liveness signal for staleness judgments: the later of PublishedAt (last full scan) and LastSeenAt (last claim-mutation activity through the store). This is the single definition of that max — callers must not compute it themselves.
type UnconfiguredError ¶
UnconfiguredError reports a missing or incomplete remote section. Commands map it to the usage exit code.
func (*UnconfiguredError) Error ¶
func (e *UnconfiguredError) Error() string
type WorktreeState ¶
type WorktreeState struct {
Task string `yaml:"task" json:"task"`
Repository string `yaml:"repository" json:"repository"`
Branch string `yaml:"branch" json:"branch"`
HeadSHA string `yaml:"head_sha" json:"head_sha"`
Dir string `yaml:"dir" json:"dir"`
// OwnerState is worktrees.ListResult.OwnerState: "active", "orphaned", or
// "unknown". Empty only if the underlying scan left it unset.
OwnerState string `yaml:"owner_state,omitempty" json:"owner_state,omitempty"`
}
WorktreeState is one WB task worktree on the publishing machine, whether or not its owning session is still alive.