fix(R-1220): an unreadable app.yaml counts as installed — its folders are never kept data
liveDriveBinds(drives): an app whose app.yaml exists but does not parse binds every folder its compose names on every drive (fail closed); WARN per app. Red-proved (the live folder was listed). Commit only.
This commit is contained in:
@@ -217,10 +217,31 @@ func readKeptMarker(dir string) *KeptMarker {
|
||||
}
|
||||
|
||||
// liveDriveBinds is every drive folder an INSTALLED app binds — never kept data.
|
||||
func (m *Manager) liveDriveBinds() []string {
|
||||
//
|
||||
// R-1220 — FAIL CLOSED ON AN UNREADABLE app.yaml. A parse error gives a nil AppConfig, so ScanStacks reads the app as
|
||||
// „not installed"; before this, its live folder was then listed as kept data and offered for deletion. An app whose
|
||||
// app.yaml EXISTS but cannot be read counts as installed: its HDD_PATH is unknown, so every folder its compose would bind
|
||||
// on ANY of the given drives is live. One WARN per app per listing names it. Pinned by
|
||||
// TestR1220_AnUnreadableAppYamlKeepsTheFolderLive.
|
||||
func (m *Manager) liveDriveBinds(drives []string) []string {
|
||||
var out []string
|
||||
for _, st := range m.GetStacks() {
|
||||
if st.ComposePath == "" {
|
||||
continue
|
||||
}
|
||||
if !st.Deployed || st.AppConfig == nil {
|
||||
if !st.Deployed && !appYAMLUnreadable(filepath.Dir(st.ComposePath)) {
|
||||
continue // not installed: no app.yaml, or one that reads as not deployed
|
||||
}
|
||||
m.logger.Printf("[WARN] [stacks] kept: %s has an app.yaml that cannot be read — it counts as INSTALLED, so its drive folders are never listed as kept data (R-1220)", st.Name)
|
||||
for _, d := range drives {
|
||||
if d = strings.TrimSpace(d); d == "" {
|
||||
continue
|
||||
}
|
||||
for _, p := range ParseComposeHDDMounts(st.ComposePath, filepath.Clean(d)) {
|
||||
out = append(out, filepath.Clean(p))
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
hdd := strings.TrimSpace(st.AppConfig.Env["HDD_PATH"])
|
||||
@@ -234,6 +255,15 @@ func (m *Manager) liveDriveBinds() []string {
|
||||
return out
|
||||
}
|
||||
|
||||
// appYAMLUnreadable is true when the stack folder holds an app.yaml that LoadAppConfig cannot turn into a config — the
|
||||
// R-1220 case. A missing app.yaml is false (a template that was never installed, or a removed app).
|
||||
func appYAMLUnreadable(stackDir string) bool {
|
||||
if _, err := os.Stat(filepath.Join(stackDir, "app.yaml")); err != nil {
|
||||
return false
|
||||
}
|
||||
return LoadAppConfig(stackDir) == nil
|
||||
}
|
||||
|
||||
func overlaps(a, b string) bool {
|
||||
sep := string(filepath.Separator)
|
||||
return a == b || strings.HasPrefix(a, b+sep) || strings.HasPrefix(b, a+sep)
|
||||
@@ -284,7 +314,7 @@ var sizeFn = getDirSizeBytes
|
||||
// ListKept lists every kept item on the given drive roots: the dated folders under <drive>/kept/<app>/,
|
||||
// and each <drive>/appdata/<x> that holds something and that no installed app binds. Sorted newest first.
|
||||
func (m *Manager) ListKept(drives []string) []KeptItem {
|
||||
live := m.liveDriveBinds()
|
||||
live := m.liveDriveBinds(drives)
|
||||
var out []KeptItem
|
||||
seen := map[string]bool{}
|
||||
for _, d := range drives {
|
||||
|
||||
Reference in New Issue
Block a user