Documentation
¶
Overview ¶
Package lifecyclesync makes the on-disk lifecycle ledger visible beyond the host. It watches the ledger for changes and is the runtime half of the server-lifecycle uplink capability, through which cloud starts operations and follows them.
Index ¶
Constants ¶
const ( Capability = uplink.CapabilityServerLifecycle Version1 uint = 1 // TypeRequest asks the runtime to start an operation. Cloud mints the id, // so a request repeated after a lost reply finds its record already there. TypeRequest = "lifecycle.request" // TypeReject answers a request the runtime would not record. TypeReject = "lifecycle.reject" // TypeSync is sent once per session: everything cloud should know about // this ledger before status updates start flowing. TypeSync = "lifecycle.sync" // TypeStatus carries one record each time it changes. TypeStatus = "lifecycle.status" )
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶
type Config struct {
// Watch names operations cloud still considers open. The sync reports each
// of them, as a record or as missing, so cloud can settle them.
Watch []string `json:"watch,omitempty"`
// Actions echoes the offered action set as cloud accepted it. Cloud keeps
// this config as the session's record of the capability and checks
// requests against it; the runtime has nothing to do with it here.
Actions []string `json:"actions,omitempty"`
}
Config is cloud's selection payload in the session welcome.
type Link ¶
type Link interface {
OfferCapabilityFunc(name string, versions []uint, provide uplink.CapabilityOfferFunc)
OnSession(func(context.Context, uplink.Session))
Handle(string, uplink.MessageHandler)
SendMessageBlocking(context.Context, string, any) error
}
Link is the part of *uplink.Client the reporter uses.
type Offer ¶
type Offer struct {
Actions []string `json:"actions"`
RuntimeInstanceID string `json:"runtime_instance_id"`
// InstallKind says how the server is supervised (systemd, container,
// unknown). Only a systemd install can be restarted or upgraded this way,
// and cloud is better placed to say so before a request than after.
InstallKind string `json:"install_kind,omitempty"`
}
Offer is the capability payload in the session hello.
type Reject ¶
Reject says why a request was not recorded. A request that was recorded but then failed is not rejected; its record says what happened.
type Reporter ¶
type Reporter struct {
// contains filtered or unexported fields
}
Reporter is the runtime half of the server-lifecycle capability: it offers the actions this host supports, starts operations cloud asks for, and streams the ledger back.
func NewReporter ¶
func NewReporter(log *slog.Logger, store *serverlifecycle.Store, launcher serverlifecycle.Launcher, watcher *Watcher, identity Identity) *Reporter
type Request ¶
type Request struct {
OperationID string `json:"operation_id"`
Action string `json:"action"`
TargetVersion string `json:"target_version,omitempty"`
ArtifactType string `json:"artifact_type,omitempty"`
NoRollback bool `json:"no_rollback,omitempty"`
ReadyTimeoutSeconds int `json:"ready_timeout_seconds,omitempty"`
// RequestedBy is recorded verbatim on the operation.
RequestedBy string `json:"requested_by,omitempty"`
}
Request is cloud asking for one operation.
type Status ¶
type Status struct {
RuntimeInstanceID string `json:"runtime_instance_id"`
Operation *serverlifecycle.Operation `json:"operation"`
}
Status is one record after a change.
type Subscription ¶
type Subscription struct {
// contains filtered or unexported fields
}
Subscription hands a subscriber every record the watcher sees change. It holds the latest state per operation rather than a queue of events, so a slow reader never loses a change: two updates to one record before it is read collapse into the newer one, and a terminal phase always survives.
func (*Subscription) Drain ¶
func (s *Subscription) Drain() []*serverlifecycle.Operation
Drain returns every changed record since the last Drain, oldest change first, and clears them.
func (*Subscription) Wake ¶
func (s *Subscription) Wake() <-chan struct{}
Wake is signalled when there is something to Drain.
type Sync ¶
type Sync struct {
RuntimeInstanceID string `json:"runtime_instance_id"`
Operations []*serverlifecycle.Operation `json:"operations"`
Missing []string `json:"missing,omitempty"`
}
Sync is the ledger as of session start: every operation still running, the most recent finished ones, and whichever watched ids exist. Watched ids that do not exist are listed as missing, which cloud reads as "this never reached the host".
type Watcher ¶
type Watcher struct {
// contains filtered or unexported fields
}
Watcher follows the file ledger and hands each changed record to its subscribers, which is how the uplink learns what to tell cloud. The files stay the source of truth; the watcher never writes them.
func NewWatcher ¶
func NewWatcher(log *slog.Logger, store *serverlifecycle.Store) *Watcher
func (*Watcher) Kick ¶
func (m *Watcher) Kick()
Kick asks for a pass now rather than at the next tick, for a caller that just wrote a record and wants it announced.
func (*Watcher) Run ¶
Run reads the ledger once, so later passes only announce changes, and then follows it until ctx ends.
func (*Watcher) Subscribe ¶
func (m *Watcher) Subscribe() (*Subscription, func())
Subscribe returns a subscription that sees every record change from now on, and a function to stop it. Delivery never blocks the watcher and never drops: the subscription keeps the latest state per record until read.