Documentation
¶
Overview ¶
Package promote runs an environment promotion as an injected transaction.
Index ¶
- Constants
- Variables
- func AcquireRecordLock(ctx context.Context, projectRoot string) (context.Context, func(), error)
- func CheckDBRestoreCompletion(rec *Record) error
- func ManifestHash(raw []byte) string
- func MarkDBRestoreDone(root string, rec *Record) error
- func RecordApplied(st *State, res deploy.ApplyResult)
- func RestoreDatabase(ctx context.Context, r deploy.Remote, remotePath, tag, backup string, ...) error
- func RollbackRecord(ctx context.Context, projectRoot string, rec *Record, ...) error
- func SaveAttempt(root string, rec Record) error
- func SaveRecord(projectRoot string, rec Record) error
- func TargetArchitecture(ctx context.Context, configured string, run Runner) (string, error)
- func UndoApplied(ctx context.Context, st *State, remotes map[string]deploy.Remote, ...) error
- func ValidateTiers(source, target string, sourceTier, targetTier controlplane.Tier) error
- type DeployIdentity
- type DigestRow
- type Engine
- type Image
- type ManifestIdentity
- type Observer
- type Record
- type Result
- type Runner
- type SavedManifest
- type SourceImage
- type State
- type Step
- type StepResult
Constants ¶
const AttemptFile = ".nself/state/promote-attempt.json"
const RecordFile = ".nself/state/promote.json"
RecordFile is the local promotion rollback authority.
Variables ¶
var StepNames = []string{
"resolve", "confirm", "verify", "preflight", "source-health", "capture",
"build", "compare", "snapshot", "save", "apply", "migrate", "health", "record",
}
StepNames is the only accepted promotion execution order.
Functions ¶
func AcquireRecordLock ¶
AcquireRecordLock holds the deployment operation lock for the entire rollback.
func CheckDBRestoreCompletion ¶
CheckDBRestoreCompletion refuses recovery while a restore outcome is uncertain.
func ManifestHash ¶
ManifestHash binds recovery to the exact shipped compose manifest bytes.
func MarkDBRestoreDone ¶
MarkDBRestoreDone records the operator's explicit host verification.
func RecordApplied ¶
func RecordApplied(st *State, res deploy.ApplyResult)
RecordApplied remembers only hosts whose artifact tree was changed.
func RestoreDatabase ¶
func RestoreDatabase(ctx context.Context, r deploy.Remote, remotePath, tag, backup string, phase, restored *string, checkpoint func() error) error
RestoreDatabase checkpoints intent before running the remote restore.
func RollbackRecord ¶
func RollbackRecord(ctx context.Context, projectRoot string, rec *Record, remotes map[string]deploy.Remote, remotePaths map[string]string) error
RollbackRecord re-applies every saved stack before restoring the migrated DB.
func SaveAttempt ¶
SaveAttempt persists provisional evidence without replacing promote.json.
func SaveRecord ¶
SaveRecord atomically writes promote.json with private permissions.
func TargetArchitecture ¶
TargetArchitecture normalizes an inventory value or probes the target when absent.
func UndoApplied ¶
func UndoApplied(ctx context.Context, st *State, remotes map[string]deploy.Remote, paths map[string]string) error
UndoApplied restores files and reapplies the previous stack, without a DB undo.
func ValidateTiers ¶
func ValidateTiers(source, target string, sourceTier, targetTier controlplane.Tier) error
ValidateTiers rejects downward promotions and identical environments.
Types ¶
type DeployIdentity ¶
type DeployIdentity struct {
StartedAt time.Time `json:"started_at"`
PreDeployTar string `json:"pre_deploy_tar,omitempty"`
PreDeployTars map[string]string `json:"pre_deploy_tars,omitempty"`
}
DeployIdentity records the deploy.json identity written by promotion apply.
type DigestRow ¶
type DigestRow struct {
Service string `json:"service"`
Source string `json:"source"`
Target string `json:"target"`
Status string `json:"status"`
Detail string `json:"detail,omitempty"`
}
DigestRow records the per-platform release identity comparison.
func CompareDigests ¶
func CompareDigests(ctx context.Context, source []SourceImage, target []Image, targetArch string, tier controlplane.Tier, lookup archguard.Lookup, warn func(string)) ([]DigestRow, error)
CompareDigests proves that source and target resolve to equal platform manifests.
Purpose: reject drift and production build-context ambiguity before snapshot. Inputs: captured source identities, target image declarations, arch, tier and lookup. Outputs: deterministic comparison rows and E490 when identity is not proven. Constraints: build-context services warn below prod and fail closed on prod.
type Engine ¶
type Engine struct {
Steps []Step
Observer Observer
Verify func(context.Context, *State) error
Now func() time.Time
}
Engine executes the canonical promotion transaction.
Purpose: enforce ordering, observability, and rollback invariants. Inputs: canonical Steps, optional Observer/Verify/clock, and mutable State. Outputs: a Result plus the triggering structured error on failure. Constraints: execution is pure orchestration; all I/O lives in injected hooks.
func (Engine) Plan ¶
func (e Engine) Plan() []StepResult
Plan returns the deterministic canonical plan without executing a step.
type Image ¶
Image identifies one generated compose service and whether it has a build context.
func ReadComposeImages ¶
ReadComposeImages reads and merges service image declarations from compose files.
Purpose: give capture and compare one deterministic view of compose fragments. Inputs: compose files in merge order; later service declarations override earlier ones. Outputs: service/image/build rows sorted by service name. Constraints: files are read only; an empty image is retained for build-context checks.
func ResolvedArtifactImages ¶
func ResolvedArtifactImages(ctx context.Context, local, host Runner, set deploy.ArtifactSet) ([]Image, error)
ResolvedArtifactImages resolves exactly the staged compose and environment set. Host-owned env files are read privately and removed after interpolation.
type ManifestIdentity ¶
ManifestIdentity authorizes a prior manifest, including a first deploy's absence.
func ReadManifestIdentity ¶
func ReadManifestIdentity(ctx context.Context, r deploy.Remote, rp string) (ManifestIdentity, error)
Purpose: Read prior artifact identity without conflating absent and empty files. Inputs: Validated remote path. Outputs: Manifest presence and exact byte hash. Constraints: File reads only; command failures never authorize manifest absence.
type Observer ¶
type Observer interface {
Start(step string)
Done(step string, d time.Duration)
Failed(step string, err error)
Skipped(step, reason string)
Rollback(step string, err error)
}
Observer receives synchronous promotion lifecycle events.
type Record ¶
type Record struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Source string `json:"source"`
Target string `json:"target"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
Status string `json:"status"`
SnapshotTag string `json:"snapshot_tag,omitempty"`
BackupID string `json:"backup_id,omitempty"`
BackupHost string `json:"backup_host,omitempty"`
PreDeployTar map[string]string `json:"pre_deploy_tar,omitempty"`
Changed map[string][]string `json:"changed,omitempty"`
Absent map[string][]string `json:"absent,omitempty"`
Digests []DigestRow `json:"digests,omitempty"`
SavedManifest SavedManifest `json:"saved_manifest"`
DBRestoredAt string `json:"db_restored_at,omitempty"`
MigrateStarted bool `json:"migrate_started"`
ApplyStarted bool `json:"apply_started"`
DeployIdentity *DeployIdentity `json:"deploy_identity,omitempty"`
RemotePaths map[string]string `json:"remote_paths,omitempty"`
AppliedManifestHash map[string]string `json:"applied_manifest_hash,omitempty"`
PriorManifestIdentity map[string]ManifestIdentity `json:"prior_manifest_identity,omitempty"`
FilesRestored map[string]bool `json:"files_restored,omitempty"`
RecoveryPhase string `json:"recovery_phase,omitempty"`
}
Record describes one completed promotion and everything its rollback may touch.
func LoadAttempt ¶
LoadAttempt reads isolated attempt history, including interrupted apply.
func LoadLatestRecord ¶
LoadLatestRecord returns a target record only when no different deploy supersedes it.
func LoadRecord ¶
LoadRecord reads promote.json; a missing record returns nil, nil.
type Result ¶
type Result struct {
Status string `json:"status"`
Source string `json:"source"`
Target string `json:"target"`
Steps []StepResult `json:"steps"`
Digests []DigestRow `json:"digests,omitempty"`
SnapshotTag string `json:"snapshot_tag,omitempty"`
BackupID string `json:"backup_id,omitempty"`
FailedStep string `json:"failed_step,omitempty"`
DryRun bool `json:"dry_run,omitempty"`
}
Result is the complete promotion outcome returned to human and JSON callers.
type SavedManifest ¶
type SavedManifest struct {
Host string `json:"host"`
ComposeFiles []string `json:"compose_files,omitempty"`
EnvFiles []string `json:"env_files,omitempty"`
}
SavedManifest is the target's compose and env-file manifest before apply.
type SourceImage ¶
SourceImage is the per-platform identity captured from a running source.
func CaptureManifestSource ¶
func CaptureManifestSource(ctx context.Context, run Runner, raw []byte, lookup archguard.Lookup) ([]SourceImage, error)
CaptureManifestSource inspects the captured listing using the source's resolved declarations.
func CaptureSource ¶
func CaptureSource(ctx context.Context, run Runner, services []Image, lookup archguard.Lookup) ([]SourceImage, error)
CaptureSource reads running compose images and inspects their platform identities.
Purpose: derive release identity from what the source host actually runs. Inputs: an injected command runner, generated service declarations, optional registry lookup. Outputs: one source image identity per declared service, sorted by service. Constraints: commands contain only shell-quoted image references; no process is started here.
type State ¶
type State struct {
Source string
Target string
SourceTier controlplane.Tier
TargetTier controlplane.Tier
SnapshotTag string
BackupID string
BackupHost string
DBRestoredAt string
MigrateStarted bool
ApplyStarted bool
PriorManifestIdentity map[string]ManifestIdentity
FilesRestored map[string]bool
RecoveryPhase string
RecoveryCheckpoint func(*State) error
Digests []DigestRow
PreDeployTar map[string]string
PreDeployChanged map[string][]string
PreDeployAbsent map[string][]string
RemotePaths map[string]string
AppliedManifestHash map[string]string
Values map[string]any
DryRun bool
}
State is the mutable data shared by promotion steps.
Purpose: carry resolved promotion inputs and rollback evidence between steps. Inputs: command wiring initializes environment and tier fields; steps fill evidence. Outputs: Engine.Run copies public outcome fields into Result. Constraints: Values is opaque wiring state; this package does not interpret it.
type Step ¶
type Step struct {
Name string
Run func(context.Context, *State) error
Undo func(context.Context, *State) error
}
Step is one promotion action and its compensating action.
func HealthStep ¶
HealthStep checks the target primary and is reused after rollback.
func MigrateStep ¶
MigrateStep runs target migrations. Engine marks MigrateStarted first.
func SnapshotStep ¶
SnapshotStep creates a verified target backup and restores it on undo.
type StepResult ¶
type StepResult struct {
Name string `json:"name"`
Status string `json:"status"`
Detail string `json:"detail,omitempty"`
}
StepResult is one deterministic plan or execution result row.