controller v0.67.4: startup recreate also recovers exited/restarting drive-backed apps
recreateBootStaleApps recreates a present drive-backed app when boot-stale OR exited/restarting/unhealthy (the recency-only gate missed already-exited apps). Still skips healthy long-running + cleanly user-stopped apps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
## Changelog
|
||||
|
||||
### v0.67.4 — gate: startup recreate also recovers exited/restarting drive-backed apps (2026-06-15)
|
||||
|
||||
Refines v0.67.3's `recreateBootStaleApps`: recreate a present drive-backed app when it is boot-stale
|
||||
(recently started) OR currently `exited`/`restarting`/`unhealthy` (came up wrong on the empty bind and
|
||||
bailed) — the recency-only gate missed apps that had already exited. Still skips healthy long-running
|
||||
apps (no bounce on a controller-only restart) and cleanly user-stopped apps.
|
||||
|
||||
### v0.67.3 — gate: startup recreate of boot-stale drive-backed apps (2026-06-15)
|
||||
|
||||
Completes guest-reboot convergence (caught in the live migration). On a guest reboot docker auto-starts
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/agentapi"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
|
||||
)
|
||||
|
||||
// Intermediary-mount model (controller side). Post-migration a drive is visible in the guest ONLY at its
|
||||
@@ -249,10 +250,16 @@ func (s *Server) recreateBootStaleApps() {
|
||||
if hdd == "" || !strings.HasPrefix(hdd, StableParentDir+"/") || !presentStable[hdd] {
|
||||
continue
|
||||
}
|
||||
if !s.stackStartedRecently(st.Name, 5*time.Minute) {
|
||||
continue // long-running across a controller-only restart — don't bounce it
|
||||
// Recreate when the app is boot-stale or not cleanly running: recently-started (it likely came up
|
||||
// on the empty bind before the drive was re-propagated) OR currently exited/restarting/unhealthy
|
||||
// (came up wrong and bailed). SKIP a healthy long-running app (no bounce on a controller-only
|
||||
// restart) and a cleanly user-Stopped app (respect the user's intent).
|
||||
needs := s.stackStartedRecently(st.Name, 5*time.Minute) ||
|
||||
st.State == stacks.StateExited || st.State == stacks.StateRestarting || st.State == stacks.StateUnhealthy
|
||||
if !needs {
|
||||
continue
|
||||
}
|
||||
s.logger.Printf("[INFO] [gate] startup: recreating drive-backed app %s onto its (re-propagated) drive %s", st.Name, hdd)
|
||||
s.logger.Printf("[INFO] [gate] startup: recreating drive-backed app %s (state=%s) onto its drive %s", st.Name, st.State, hdd)
|
||||
_ = s.stackMgr.StopStack(st.Name)
|
||||
if serr := s.stackMgr.StartStack(st.Name); serr != nil {
|
||||
s.logger.Printf("[WARN] [gate] startup recreate %s: %v", st.Name, serr)
|
||||
|
||||
Reference in New Issue
Block a user