controller v0.68.0: storage lifecycle on intermediary model (H2/H3/M1/M3 + boot-id)
H2 decommission UI button (migrate / anyway); H3 one-click re-enroll of a
decommissioned drive; M1 default reassignment (auto-promote + block-if-none);
M3 migrate re-asserts 2775 setgid on userdata dirs; deterministic guest-reboot
recreate via agent boot_id (replaces the timed sample). Fixes the {path}/{where}
H1 JS bug. Non-hollow tests + companions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
package stacks
|
||||
|
||||
import "testing"
|
||||
|
||||
// TestIsUserdataDir pins which namespace-relative dirs the migrate merge-walk routes through the
|
||||
// 2775-setgid re-assert (EnsureUserdataDir) vs plain source-mode preservation. This is the M3 routing
|
||||
// decision: only the customer-facing `userdata` tree gets the convention ENFORCED on pre-existing target
|
||||
// dirs.
|
||||
//
|
||||
// COMPANION GUARD: the pre-fix merge-walk had NO userdata branch (everything went through
|
||||
// preserveDirOwnership, which copies the SOURCE mode) — equivalent to isUserdataDir always returning
|
||||
// false. The `userdata/...` → true cases below fail that impl, so a stale 755 target userdata dir would
|
||||
// keep its 755 instead of becoming 2775.
|
||||
func TestIsUserdataDir(t *testing.T) {
|
||||
yes := []string{"userdata", "userdata/import", "userdata/import/calibre", "userdata/media/movies"}
|
||||
no := []string{"appdata", "appdata/romm", "backups", "media", "userdataX", "", "."}
|
||||
for _, r := range yes {
|
||||
if !isUserdataDir(r) {
|
||||
t.Errorf("isUserdataDir(%q) = false, want true", r)
|
||||
}
|
||||
}
|
||||
for _, r := range no {
|
||||
if isUserdataDir(r) {
|
||||
t.Errorf("isUserdataDir(%q) = true, want false (only the userdata tree gets the setgid re-assert)", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user