Documentation
¶
Overview ¶
Package advancedrollback runs the Advanced operation `rollback.coordinated`: it restores the OpenTofu state and payload of every local Terramate stack to one verified executor-state checkpoint, in reverse run order (ADR-0045 section 1 and section 3, docs/ARCHITECTURE.md "Coordinated rollback across stacks (Stage 1)").
The package owns the per-stack plan, its resumable journal and the `stackkit.rollback-result/v1` report. Checkpoint verification, lifecycle authority and the StackSpec restore stay with the command and internal/upgradelifecycle.
Index ¶
Constants ¶
const ( // ResultSchemaVersion identifies the rollback report // (schemas/stackkit-rollback-result-v1.schema.json). ResultSchemaVersion = "stackkit.rollback-result/v1" // JournalSchemaVersion identifies the per-checkpoint rollback journal. JournalSchemaVersion = "stackkit.rollback-journal/v1" // JournalDir holds one journal per target checkpoint. JournalDir = ".stackkit/advanced/rollbacks" )
const ( // ActionDestroyed: the stack is absent from the checkpoint's stack graph // (added after it). Its root is destroyed through OpenTofu, which runs the // wrapper's destroy-time `docker compose down` without volumes, and then // removed. ActionDestroyed = "destroyed" // ActionRestored: the root exists and differs from the checkpoint. Its // state, configuration and payload are restored and convergence is // forced with `tofu apply -replace` on the wrapper trigger. ActionRestored = "restored" // ActionRecreated: the checkpoint has the root but the workspace has no // applied root (the stack was removed after the checkpoint). Restored // and forced like a restored stack. ActionRecreated = "recreated" // ActionUnchanged: the root already equals the checkpoint, or the // checkpoint captured no root for a stack both graphs share. ActionUnchanged = "unchanged" )
Per-stack actions, decided once when the rollback is planned.
const ( StackConverged = "converged" StackFailed = "failed" StackPending = "pending" StackSkipped = "skipped" )
Per-stack statuses.
const ( StatusConverged = "converged" StatusFailed = "failed" )
Overall statuses.
const ( SealSealed = "sealed" SealUnsupported = "unsupported" SealFailed = "failed" SealNotAttempted = "not_attempted" )
Seal statuses.
Variables ¶
This section is empty.
Functions ¶
func JournalPath ¶
JournalPath is the workspace-relative journal of one target checkpoint.
func SaveJournal ¶
SaveJournal atomically replaces the journal of journal.TargetSnapshotID.
Types ¶
type Journal ¶
type Journal struct {
SchemaVersion string `json:"schemaVersion"`
RollbackID string `json:"rollbackId"`
TargetSnapshotID string `json:"targetSnapshotId"`
ChangeSetID string `json:"changeSetId,omitempty"`
LifecycleOperationID string `json:"lifecycleOperationId"`
Status string `json:"status"`
Steps []Step `json:"steps"`
Results map[string]StepResult `json:"results"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
Journal is the durable plan and progress of one rollback to one checkpoint. A second invocation for the same checkpoint resumes it and skips every step already converged.
func LoadJournal ¶
LoadJournal returns the journal of the rollback to snapshotID, if any.
func Prepare ¶
Prepare returns the unfinished journal of the rollback to the target checkpoint (resumed), or plans a new rollback and persists its journal before any runtime side effect. The plan is computed once: a resumed rollback executes the original plan, so a stack destroyed by the first invocation is never classified again.
func (Journal) InProgress ¶
InProgress reports whether the journal belongs to an unfinished rollback.
type Report ¶
type Report struct {
SchemaVersion string `json:"schemaVersion"`
RollbackID string `json:"rollbackId"`
TargetSnapshotID string `json:"targetSnapshotId"`
ChangeSetID string `json:"changeSetId,omitempty"`
LifecycleOperationID string `json:"lifecycleOperationId,omitempty"`
Resumed bool `json:"resumed"`
Order []string `json:"order"`
Stacks []StackReport `json:"stacks"`
// AuthorityRestored: the checkpoint's StackSpec and Inventory were
// restored through the executor-state recovery path.
AuthorityRestored bool `json:"authorityRestored"`
// PriorReleaseExecuted: the checkpoint's release differs from the
// running one, so its captured executable regenerated and verified.
PriorReleaseExecuted bool `json:"priorReleaseExecuted"`
// RuntimeVerified: the native verify of the restored plan passed.
RuntimeVerified bool `json:"runtimeVerified"`
// SealedSnapshotID is the executor-state checkpoint sealed after a
// converged rollback. SealStatus explains an absent one.
SealedSnapshotID string `json:"sealedSnapshotId,omitempty"`
SealStatus string `json:"sealStatus"`
SealDetail string `json:"sealDetail,omitempty"`
Status string `json:"status"`
}
Report is the `stackkit.rollback-result/v1` document.
type Request ¶
type Request struct {
WorkspaceRoot string
RollbackID string
TargetSnapshotID string
ChangeSetID string
LifecycleOperationID string
// Current are the local stacks of the current generation, Target those
// of the checkpoint, each in host run order.
Current []Stack
Target []Stack
// TargetRoots are the verified OpenTofu roots of the checkpoint.
TargetRoots []TargetRoot
Tools terramatehost.Tools
// Environment adds process environment for one stack's OpenTofu run,
// such as the Compose interpolation environment of a Core payload.
Environment func(Stack) ([]string, error)
Timeout time.Duration
// Event receives `stack` progress with the per-stack status.
Event func(phase, status string, attributes map[string]string)
Now func() time.Time
}
Request is one coordinated rollback of the local host to one verified checkpoint.
type RootFiles ¶
type RootFiles struct {
State []byte
Config []byte
Compose []byte
HasCompose bool
Environment []byte
HasEnvironment bool
}
RootFiles are the captured bytes of one OpenTofu root: the local-backend state and configuration inside the root, and the runtime Compose file and workload .env one level up when the root owns them.
type StackReport ¶
type StackReport struct {
StackID string `json:"stackId"`
Role string `json:"role"`
RuntimeRoot string `json:"runtimeRoot"`
Action string `json:"action"`
Status string `json:"status"`
PlanExitCode *int `json:"planExitCode,omitempty"`
DurationMS int64 `json:"durationMs"`
Detail string `json:"detail,omitempty"`
}
StackReport is one stack of the rollback report.
type Step ¶
type Step struct {
StackID string `json:"stackId"`
Role string `json:"role"`
RuntimeRoot string `json:"runtimeRoot"`
Action string `json:"action"`
}
Step is one planned per-stack action in execution order.
func Plan ¶
Plan decides one action per local stack. Stacks of the current graph run first in reverse run order, so every dependent is destroyed or restored before the stacks it runs after; stacks only the checkpoint has are recreated afterwards in run order, because they run after the restored cores.
type StepResult ¶
type StepResult struct {
Status string `json:"status"`
PlanExitCode *int `json:"planExitCode,omitempty"`
DurationMS int64 `json:"durationMs"`
Detail string `json:"detail,omitempty"`
// FilesRestored marks a restored or recreated root whose checkpoint
// files are written but whose forced apply has not converged yet.
FilesRestored bool `json:"filesRestored,omitempty"`
}
StepResult is the recorded outcome of one step.
type TargetRoot ¶
TargetRoot is one root of the target checkpoint.