B2b: decommission orchestration + missing-storage indicator + re-enroll fix (v0.65.0)
agentapi.Decommission + handleStorageDecommission (migrate-all-or-none, Change 2): migrate-then-decommission via the migration done-hook, or decommission-anyway (stop apps, keep HDD_PATH). 'Hiányzó tárhely' badge on dashboard/stacks/app card when an app's drive is decommissioned/disconnected/absent. Change 4: registerStoragePath clears the decommissioned marker on re-enroll (ClearDecommissioned had no callers). Non-hollow tests incl. mutation-proven Change-4 companion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,8 +23,8 @@ type ContainerState string
|
||||
|
||||
const (
|
||||
StateRunning ContainerState = "running"
|
||||
StateStarting ContainerState = "starting" // running but health: starting
|
||||
StateUnhealthy ContainerState = "unhealthy" // running but health: unhealthy
|
||||
StateStarting ContainerState = "starting" // running but health: starting
|
||||
StateUnhealthy ContainerState = "unhealthy" // running but health: unhealthy
|
||||
StateStopped ContainerState = "stopped"
|
||||
StateRestarting ContainerState = "restarting"
|
||||
StateExited ContainerState = "exited"
|
||||
@@ -52,12 +52,12 @@ type HealthProbeResult struct {
|
||||
|
||||
// HealthCheckDetail holds the result of a single health check item.
|
||||
type HealthCheckDetail struct {
|
||||
Type string `json:"type"` // "http", "api", "tcp"
|
||||
Target string `json:"target"` // e.g. ":3456/api/v1/info"
|
||||
Type string `json:"type"` // "http", "api", "tcp"
|
||||
Target string `json:"target"` // e.g. ":3456/api/v1/info"
|
||||
Healthy bool `json:"healthy"`
|
||||
Status int `json:"status,omitempty"` // HTTP status code (for http/api)
|
||||
Latency string `json:"latency"` // e.g. "45ms"
|
||||
Error string `json:"error,omitempty"` // error message if unhealthy
|
||||
Status int `json:"status,omitempty"` // HTTP status code (for http/api)
|
||||
Latency string `json:"latency"` // e.g. "45ms"
|
||||
Error string `json:"error,omitempty"` // error message if unhealthy
|
||||
}
|
||||
|
||||
// Stack represents a docker compose stack on disk.
|
||||
@@ -66,14 +66,14 @@ type Stack struct {
|
||||
Meta Metadata `json:"meta"`
|
||||
ComposePath string `json:"compose_path"`
|
||||
State ContainerState `json:"state"`
|
||||
Deployed bool `json:"deployed"` // Has app.yaml with deployed=true
|
||||
Deployed bool `json:"deployed"` // Has app.yaml with deployed=true
|
||||
Protected bool `json:"protected"`
|
||||
Orphaned bool `json:"orphaned"` // Deployed but no catalog template
|
||||
Orphaned bool `json:"orphaned"` // Deployed but no catalog template
|
||||
Containers []ContainerInfo `json:"containers"`
|
||||
AppConfig *AppConfig `json:"app_config,omitempty"`
|
||||
Deploying bool `json:"deploying"` // compose up in progress
|
||||
DeployError string `json:"deploy_error,omitempty"` // last async deploy error
|
||||
HealthProbe *HealthProbeResult `json:"health_probe,omitempty"` // controller-side probe result
|
||||
Deploying bool `json:"deploying"` // compose up in progress
|
||||
DeployError string `json:"deploy_error,omitempty"` // last async deploy error
|
||||
HealthProbe *HealthProbeResult `json:"health_probe,omitempty"` // controller-side probe result
|
||||
LastUpdated time.Time `json:"last_updated"`
|
||||
}
|
||||
|
||||
@@ -93,8 +93,9 @@ type Manager struct {
|
||||
migJob *MigrationJob
|
||||
settings *settings.Settings
|
||||
sysDataPath string
|
||||
backupRunning func() bool // mutual exclusion with the backup orchestrator (Change 3)
|
||||
testSeams *migSeams // nil in production; tests inject fakes
|
||||
backupRunning func() bool // mutual exclusion with the backup orchestrator (Change 3)
|
||||
migDoneHook func(*MigrationJob) // fired on successful completion (decommission policy lives in caller)
|
||||
testSeams *migSeams // nil in production; tests inject fakes
|
||||
}
|
||||
|
||||
// NewManager creates a new stack manager.
|
||||
@@ -1105,4 +1106,4 @@ func (m *Manager) getCatalogTemplateSlugs() map[string]bool {
|
||||
m.logger.Printf("[DEBUG] [stacks] getCatalogTemplateSlugs: found %d template slugs in %s", len(slugs), cacheDir)
|
||||
}
|
||||
return slugs
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user