feat(cmd): add installall/uninstallall; fix startall/stopall and service lifecycle

- startall now uses systemctl start (not enable --now)
- stopall now uses systemctl stop (not disable --now)
- add installall command (bulk install with --dry-run support)
- add uninstallall command (bulk disable+remove in reverse order)
- fix docker ExecStart to use -a flag so the process stays attached
- prefix ExecStop with - so a stop-on-already-dead container does not fail the unit
This commit is contained in:
2026-07-05 15:12:18 +02:00
parent e6ef6e11d6
commit 029b9cee2e
9 changed files with 298 additions and 16 deletions
+3 -3
View File
@@ -19,7 +19,7 @@ Requires={{.}}{{end}}
[Service]
Type=simple
ExecStart={{.ExecStart}}
ExecStop={{.ExecStop}}
ExecStop={{if .ExecStop}}-{{.ExecStop}}{{end}}
{{- if .Unit.Restart}}
Restart=on-failure
RestartSec={{.Unit.RestartSec}}
@@ -42,7 +42,7 @@ After=default.target
[Service]
Type=simple
ExecStart={{.ExecStart}}
ExecStop={{.ExecStop}}
ExecStop={{if .ExecStop}}-{{.ExecStop}}{{end}}
{{- if .Unit.Restart}}
Restart=on-failure
RestartSec={{.Unit.RestartSec}}
@@ -117,7 +117,7 @@ func buildExecCommands(u config.Unit) (start, stop string) {
start = fmt.Sprintf("/usr/bin/podman start -a %s", u.Name)
stop = fmt.Sprintf("/usr/bin/podman stop %s", u.Name)
case "docker":
start = fmt.Sprintf("/usr/bin/docker start %s", u.Name)
start = fmt.Sprintf("/usr/bin/docker start -a %s", u.Name)
stop = fmt.Sprintf("/usr/bin/docker stop %s", u.Name)
default:
start = fmt.Sprintf("/usr/bin/%s start %s", u.Runtime, u.Name)
+6 -6
View File
@@ -49,7 +49,7 @@ func TestGenerate_SystemUnit(t *testing.T) {
"After=network.target",
"WantedBy=multi-user.target",
"ExecStart=/usr/bin/podman start -a nginx",
"ExecStop=/usr/bin/podman stop nginx",
"ExecStop=-/usr/bin/podman stop nginx",
"Generated by unitdore",
}
@@ -87,8 +87,8 @@ func TestGenerate_UserUnit(t *testing.T) {
checks := []string{
"After=default.target",
"WantedBy=default.target",
"ExecStart=/usr/bin/docker start myapp",
"ExecStop=/usr/bin/docker stop myapp",
"ExecStart=/usr/bin/docker start -a myapp",
"ExecStop=-/usr/bin/docker stop myapp",
}
for _, check := range checks {
@@ -178,8 +178,8 @@ func TestGenerate_DockerRuntime(t *testing.T) {
}
checks := []string{
"ExecStart=/usr/bin/docker start redis",
"ExecStop=/usr/bin/docker stop redis",
"ExecStart=/usr/bin/docker start -a redis",
"ExecStop=-/usr/bin/docker stop redis",
"After=network.target docker.service",
"Requires=docker.service",
}
@@ -240,7 +240,7 @@ func TestBuildExecCommands(t *testing.T) {
{
name: "docker",
unit: config.Unit{Name: "app", Runtime: "docker"},
wantStart: "/usr/bin/docker start app",
wantStart: "/usr/bin/docker start -a app",
wantStop: "/usr/bin/docker stop app",
},
{