controller v0.266.0: a failed install removes what it started (R-649, operator ruling)
gates / gates (push) Successful in 27s
gates / gates (push) Successful in 27s
compose down (volumes kept) before the record reads not deployed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -422,6 +422,17 @@ func (m *Manager) runComposeDeploy(name, stackDir string, env map[string]string,
|
||||
|
||||
if composeErr != nil {
|
||||
m.logger.Printf("[ERROR] [stacks] Stack %s deploy failed after %.1fs: %v", name, time.Since(start).Seconds(), composeErr)
|
||||
// R-649 (v0.266.0, operator ruling 2026-09-23): a failed install REMOVES what it started, so
|
||||
// „not installed" never stands over running containers (R-634's promise, for the deploy's OWN
|
||||
// failures — e.g. a dependency whose healthcheck never passes after its container started).
|
||||
// `down` WITHOUT -v: containers and the network go, named volumes stay — a reinstall of an app
|
||||
// removed with „keep my data" must find its data again. A failed `down` is logged and the record
|
||||
// still reads not-deployed; the household's Remove clears what is left (halfStateEvidence).
|
||||
if _, downErr := m.composeExecWithEnv(stackDir, env, "down"); downErr != nil {
|
||||
m.logger.Printf("[ERROR] [stacks] Stack %s: removing what the failed deploy started ALSO failed: %v — containers may remain; Remove clears them", name, downErr)
|
||||
} else {
|
||||
m.logger.Printf("[INFO] [stacks] Stack %s: the failed deploy's containers were removed (volumes kept) — R-649", name)
|
||||
}
|
||||
// Revert in-memory and disk state
|
||||
m.mu.Lock()
|
||||
if s, ok := m.stacks[name]; ok {
|
||||
|
||||
Reference in New Issue
Block a user