Hold a unit an administrator installed whatever its state, and a packaged unit only when the machine uses it (hq ADR 0103)
This commit is contained in:
@@ -29,6 +29,9 @@ type machine struct {
|
||||
|
||||
type fakeUnit struct {
|
||||
active, enabled string
|
||||
// fragment is where systemd loads the unit from; empty means /etc/systemd/system, where an
|
||||
// administrator installs one.
|
||||
fragment string
|
||||
}
|
||||
|
||||
// systemctl answers as systemd does for the units the machine has, and "not-found" for any other.
|
||||
@@ -41,8 +44,18 @@ func (m *machine) systemctl(args []string) (string, error) {
|
||||
switch args[0] {
|
||||
case "show":
|
||||
if !ok {
|
||||
if len(args) > 2 && strings.Contains(args[2], "FragmentPath") {
|
||||
return "FragmentPath=\n", nil
|
||||
}
|
||||
return "LoadState=not-found\nActiveState=inactive\nType=simple\n", nil
|
||||
}
|
||||
if len(args) > 2 && strings.Contains(args[2], "FragmentPath") {
|
||||
from := u.fragment
|
||||
if from == "" {
|
||||
from = "/etc/systemd/system/" + unit
|
||||
}
|
||||
return "FragmentPath=" + from + "\n", nil
|
||||
}
|
||||
return "LoadState=loaded\nActiveState=" + u.active + "\nType=simple\nRemainAfterExit=no\n", nil
|
||||
case "is-enabled":
|
||||
if !ok {
|
||||
@@ -617,7 +630,8 @@ func TestAUnitAPackageOnlyShipsIsNotFound(t *testing.T) {
|
||||
// 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"}}}
|
||||
units: map[string]*fakeUnit{"wg-quick@mesh0.service": {active: "inactive", enabled: "disabled",
|
||||
fragment: "/usr/lib/systemd/system/wg-quick@.service"}}}
|
||||
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)
|
||||
@@ -904,3 +918,43 @@ func TestAVolumeTheRuntimeCannotBeAskedAboutStopsTheContainer(t *testing.T) {
|
||||
t.Fatalf("a volume the runtime could not be asked about did not stop the container: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAUnitSomebodyInstalledIsHeldWhateverStateItIsIn(t *testing.T) {
|
||||
// A predecessor's unit under /etc, deliberately stopped and disabled: starting it would put
|
||||
// back a service somebody took down on purpose (novox/hq ADR 0103).
|
||||
dir := t.TempDir()
|
||||
m := &machine{containers: map[string]*fakeContainer{},
|
||||
units: map[string]*fakeUnit{"hello.service": {active: "inactive", enabled: "disabled",
|
||||
fragment: "/etc/systemd/system/hello.service"}}}
|
||||
report, state := applyAdopted(t, adopted(t, untaken("hello-web.unit"),
|
||||
`{"id":"hello-web.unit","type":"service","unit":"hello.service","state":"running","boot":"enabled"}`),
|
||||
store.State{}, m, dir)
|
||||
if o := outcomeOf(report, "hello-web.unit"); o.Action != "held" {
|
||||
t.Fatalf("a unit an administrator installed was not held: %+v", o)
|
||||
}
|
||||
if m.did("systemctl start") || m.did("systemctl enable") {
|
||||
t.Errorf("a unit somebody had stopped and disabled was started: %v", m.asked)
|
||||
}
|
||||
if _, ok := state.HeldAt("hello-web.unit"); !ok {
|
||||
t.Error("the hold was not recorded")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPackagedUnitTheMachineUsesIsStillHeld(t *testing.T) {
|
||||
// The predecessor's own service from a package, running: not the mesh's to restart.
|
||||
dir := t.TempDir()
|
||||
conf := filepath.Join(dir, "hello.conf")
|
||||
m := &machine{containers: map[string]*fakeContainer{},
|
||||
units: map[string]*fakeUnit{"nginx.service": {active: "active", enabled: "enabled",
|
||||
fragment: "/usr/lib/systemd/system/nginx.service"}}}
|
||||
report, _ := 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":"nginx.service","state":"running","boot":"enabled",
|
||||
"restart-on":["hello-web.conf"]}`), store.State{}, m, dir)
|
||||
if o := outcomeOf(report, "hello-web.unit"); o.Action != "held" {
|
||||
t.Fatalf("a packaged unit the machine runs was not held: %+v", o)
|
||||
}
|
||||
if m.did("systemctl stop") || m.did("systemctl restart") {
|
||||
t.Errorf("the predecessor's service was restarted: %v", m.asked)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user