Count a unit as found only when the machine runs it or starts it at boot, so a packaged unit nothing ran is not held (hq ADR 0103, found by the adoption bed)

This commit is contained in:
2026-09-22 18:47:48 +02:00
parent bde5e3461c
commit 60bb3d895c
2 changed files with 33 additions and 4 deletions
+10 -3
View File
@@ -95,9 +95,16 @@ func lookBefore(ctx context.Context, sys system.System, d *declaration.Declarati
if known.Recorded(string(declaration.TypeService), res.Unit) {
continue
}
// A unit the service manager cannot find is not there; one it can read is, whatever
// state it is in.
if _, err := sys.ServiceState(ctx, run, res.Unit); err == nil {
// Found is what the machine runs: a unit that is running or starts at boot. A unit
// file a package merely ships — a template instance nothing ever started, say the
// private network's own wg-quick@mesh0 — is not a predecessor's service, and holding
// it kept the private network from ever coming up (found by the adoption bed).
state, err := sys.ServiceState(ctx, run, res.Unit)
if err != nil {
continue
}
boot, _ := sys.ServiceBoot(ctx, run, res.Unit)
if state == "running" || boot == "enabled" {
seen["unit:"+res.Unit] = true
}
case *declaration.Container:
+23 -1
View File
@@ -570,7 +570,8 @@ func TestAFoundServiceOfAnUntakenModuleIsNeitherStartedNorEnabledNorRestarted(t
dir := t.TempDir()
conf := filepath.Join(dir, "hello.conf")
m := &machine{containers: map[string]*fakeContainer{},
units: map[string]*fakeUnit{"hello.service": {active: "inactive", enabled: "disabled"}}}
// The predecessor's unit: stopped just now, but it starts at boot, so it is the machine's.
units: map[string]*fakeUnit{"hello.service": {active: "inactive", enabled: "enabled"}}}
report, state := applyAdopted(t, adopted(t, untaken("hello-web.conf", "hello-web.unit"),
`{"id":"hello-web.conf","type":"file","path":"`+conf+`","content":"x\n"},
{"id":"hello-web.unit","type":"service","unit":"hello.service","state":"running","boot":"enabled",
@@ -610,6 +611,27 @@ func TestAHeldServiceIsStillReloadedButNeverRestarted(t *testing.T) {
}
}
func TestAUnitAPackageOnlyShipsIsNotFound(t *testing.T) {
// The adoption bed found this: the private network's wg-quick@mesh0 is an instance of a unit
// the tunnel package ships. Nothing had ever run it, yet it was held as a predecessor's, and
// the private network never came up. Found is what the machine runs.
dir := t.TempDir()
m := &machine{containers: map[string]*fakeContainer{},
units: map[string]*fakeUnit{"wg-quick@mesh0.service": {active: "inactive", enabled: "disabled"}}}
report, state := applyAdopted(t, adopted(t, untaken("mesh-wireguard.overlay-up"),
`{"id":"mesh-wireguard.overlay-up","type":"service","unit":"wg-quick@mesh0.service","state":"running","boot":"enabled"}`),
store.State{}, m, dir)
if o := outcomeOf(report, "mesh-wireguard.overlay-up"); o.Action == "held" {
t.Fatalf("a unit nothing runs was held as a predecessor's: %+v", o)
}
if !m.did("systemctl start wg-quick@mesh0.service") || !m.did("systemctl enable wg-quick@mesh0.service") {
t.Errorf("the unit was not started and enabled: %v", m.asked)
}
if len(state.Held) != 0 {
t.Errorf("held: %+v", state.Held)
}
}
func TestAServiceWhoseUnitIsNotThereIsAppliedAsUsual(t *testing.T) {
// No unit before the apply: nothing of a predecessor's to hold.
dir := t.TempDir()