package apply import ( "context" "fmt" "strings" "testing" "github.com/novox/mesh-host/internal/store" ) // Defends novox/hq ADR 0177: a unit in the operator account's own service manager is applied // through that manager — `systemctl --user --machine=@` — and never as a system unit of // the same name; its record remembers the scope so removal goes the same way. // accountManager is a user's service manager whose one unit starts when asked, recording the // commands and refusing any that reach it outside the account's scope. func accountManager(account string, commands *[]string) Runner { active, enabled := false, false return func(_ context.Context, name string, args ...string) (string, error) { line := name + " " + strings.Join(args, " ") *commands = append(*commands, line) if name == "systemctl" && !strings.HasPrefix(line, "systemctl --user --machine="+account+"@ ") { return "", fmt.Errorf("a system-scope command reached the account's manager: %s", line) } switch { case strings.Contains(line, " start "): active = true return "", nil case strings.Contains(line, " stop "): active = false return "", nil case strings.Contains(line, " enable "): enabled = true return "", nil case strings.Contains(line, " disable "): enabled = false return "", nil case strings.Contains(line, "is-enabled"): if enabled { return "enabled", nil } return "disabled", nil case strings.Contains(line, "show") && strings.Contains(line, "ActiveState"): if active { return "LoadState=loaded\nActiveState=active\nSubState=running", nil } return "LoadState=loaded\nActiveState=inactive\nSubState=dead", nil } return "", nil } } func TestAUserScopedUnitIsAppliedThroughTheAccountsManager(t *testing.T) { var commands []string decl := `{"declaration":1,"resources":[ {"id":"i3.watcher","type":"service","unit":"i3-reload-watcher.service","state":"running","boot":"enabled","scope":"user","user":"ops"} ]}` report, known, err := Apply(context.Background(), archHost(t), parse(t, decl), store.State{}, store.OriginDeclared, accountManager("ops", &commands), nil, nil) if err != nil { t.Fatalf("apply: %v\n%s", err, strings.Join(commands, "\n")) } if !report.Changed() { t.Fatal("a unit that was stopped and is now running changed nothing") } var started, enabled bool for _, c := range commands { if c == "systemctl --user --machine=ops@ start i3-reload-watcher.service" { started = true } if c == "systemctl --user --machine=ops@ enable i3-reload-watcher.service" { enabled = true } } if !started || !enabled { t.Fatalf("the unit was not started and enabled in the account's manager:\n%s", strings.Join(commands, "\n")) } recorded, ok := known.At("service", "i3-reload-watcher.service") if !ok || recorded.Scope != "user" || recorded.User != "ops" { t.Fatalf("the record does not say whose manager the unit is in: %+v", recorded) } } func TestASystemUnitIsUntouchedByTheScope(t *testing.T) { var commands []string decl := `{"declaration":1,"resources":[ {"id":"x.daemon","type":"service","unit":"sshd.service","state":"running","boot":"enabled"} ]}` if _, _, err := Apply(context.Background(), archHost(t), parse(t, decl), store.State{}, store.OriginDeclared, unitIn(true, &commands), nil, nil); err != nil { t.Fatal(err) } for _, c := range commands { if strings.Contains(c, "--user") || strings.Contains(c, "--machine") { t.Fatalf("a system unit was addressed to an account's manager: %s", c) } } }