kept second-drive copies (D25: R-1175, R-1181, R-1179); .fab import keeps the family gate (R-1191); stale restore temp (R-1188 c); the overcommit sentence made true (R-1192); escrow before the floor (R-1176); unreleased
gates / gates (push) Successful in 1m20s
gates / gates (push) Successful in 1m20s
This commit is contained in:
1 parent
8f5bea0148
commit
5929b8e345
34 files changed
+2152
-44
No files matched your search
@@ -1167,6 +1167,11 @@ func main() {
|
||||
// Hand it to the updater and reconcile — if the box is below the floor it auto-updates to
|
||||
// the floor (reusing the Phase 1 swap). This rides the existing report cycle; no new timer.
|
||||
// latest_version stays informational (the customer's opt-in button), NOT the auto-target.
|
||||
// SLICE 3: run the escrow auto-confirm on the same ACK. R-1176 (2026-10-21): it runs BEFORE SetFloor, because
|
||||
// the off-site apply-bridge's settle gate GOes the moment the floor is known — and a rebuilt box must already
|
||||
// have recorded „the hub holds the household's package" by then, or its mint guard (R-241) cannot stop a
|
||||
// fresh repository password. Pinned by TestR1176_EscrowIsRecordedBeforeTheFloorIsKnown.
|
||||
escrowConfirmer.Reconcile(resp.Escrow)
|
||||
if updater != nil {
|
||||
updater.SetFloor(resp.MinControllerVersion)
|
||||
updater.MaybeAutoUpdate()
|
||||
@@ -1196,9 +1201,6 @@ func main() {
|
||||
Logger: logger,
|
||||
}
|
||||
cr.Reconcile(resp.ConfigVersion)
|
||||
// SLICE 3: run the escrow auto-confirm on the same ACK (after the config refresh decision —
|
||||
// a refresh-restart re-enters here anyway on the next cycle).
|
||||
escrowConfirmer.Reconcile(resp.Escrow)
|
||||
// v0.111.0: operator log-tail requests ride the same ACK (pull pattern — the hub
|
||||
// never reaches in). The NEXT report cycle collects + ships the tails; the hub
|
||||
// clears its pending request on receipt. An empty list clears any stale local set.
|
||||
@@ -3380,6 +3382,9 @@ func (a *geoStackAdapter) GetDeployedHostnames() map[string]string {
|
||||
type exportAdapter struct {
|
||||
mgr *stacks.Manager
|
||||
encKey []byte
|
||||
// R-1191: whether the app had no record before the import (SaveEncryptedAppConfig → PrepareImportedApp).
|
||||
importFreshMu sync.Mutex
|
||||
importFresh map[string]bool
|
||||
}
|
||||
|
||||
func (a *exportAdapter) GetStackDir(name string) (string, bool) {
|
||||
@@ -3522,20 +3527,27 @@ func (a exportStopGuard) End() { a.g.End() }
|
||||
func (a exportStopGuard) ReleaseFailed(stacks ...string) { a.g.ReleaseFailed(stacks...) }
|
||||
|
||||
func (a *exportAdapter) SaveEncryptedAppConfig(stackDir string, env map[string]string) error {
|
||||
meta := stacks.LoadMetadata(stackDir)
|
||||
sensitiveVars := stacks.SensitiveEnvVars(&meta)
|
||||
cfg := &stacks.AppConfig{
|
||||
Deployed: true,
|
||||
DeployedAt: time.Now().Format(time.RFC3339),
|
||||
Env: env,
|
||||
// R-166 — a CUSTOMER-INTENT POINT, and the one that is not the API action switch. Importing
|
||||
// a `.fab` bundle is the customer installing that app on this box, and the import path starts
|
||||
// it (appexport/restore.go). Without this the app would come back from a restore with NO
|
||||
// recorded intent and fall to legacy boot behaviour — meaning a power cut days later would
|
||||
// strand it, which is exactly the failure this release exists to remove.
|
||||
DesiredState: stacks.DesiredStateRunning,
|
||||
// R-1191: the record the unit restore would build (locked fields, the prior record's life records, desired state
|
||||
// running — R-166), not a bare one; the gates follow in PrepareImportedApp, once the compose file is in place.
|
||||
fresh, err := a.mgr.SaveImportedAppConfig(stackDir, env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return stacks.SaveAppConfig(stackDir, cfg, a.encKey, sensitiveVars)
|
||||
a.importFreshMu.Lock()
|
||||
if a.importFresh == nil {
|
||||
a.importFresh = map[string]bool{}
|
||||
}
|
||||
a.importFresh[stackDir] = fresh
|
||||
a.importFreshMu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *exportAdapter) PrepareImportedApp(stackDir string, env map[string]string) error {
|
||||
a.importFreshMu.Lock()
|
||||
fresh := a.importFresh[stackDir]
|
||||
delete(a.importFresh, stackDir)
|
||||
a.importFreshMu.Unlock()
|
||||
return a.mgr.PrepareImportedApp(stackDir, env, fresh)
|
||||
}
|
||||
|
||||
func (a *exportAdapter) RefreshStacks() error {
|
||||
|
||||
Reference in new issue
Block a user