feat: order/delay in service files, enable cmd, --all on unit commands

- install/uninstall/start/stop/enable take <name> or --all; *all kept as shortcuts
- add enable (enable at boot + start); startall no longer enables
- order/delay resolved by config.ResolveOrder and written into systemd,
  OpenRC and runit service files (After=/sleep), so they apply at boot
- install --all stops and disables units before removing their files
- update regenerates all installed, enabled units and removes disabled ones
- edit creates the config dir; docs and man page updated
- tests: fake Init for cmd, ResolveOrder, backend ordering output
This commit is contained in:
2026-10-12 21:31:41 +02:00
parent d1d0889eb3
commit 91811b4fa1
28 changed files with 1394 additions and 503 deletions
+22 -2
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"strings"
"text/template"
"time"
"github.com/warkanum/unitdore/config"
"github.com/warkanum/unitdore/service"
@@ -14,7 +15,7 @@ const systemUnitTemplate = `# /etc/systemd/system/{{.ServiceName}}
[Unit]
Description=Unitdore: {{.Unit.Name}} ({{.Label}})
After=network.target{{with .RuntimeService}} {{.}}
After=network.target{{with .RuntimeService}} {{.}}{{end}}{{range .After}} {{.}}{{end}}{{with .RuntimeService}}
Requires={{.}}{{end}}
[Service]
@@ -25,6 +26,10 @@ RemainAfterExit=yes
{{- with .WorkingDir}}
WorkingDirectory={{.}}
{{- end}}
{{- with .DelaySec}}
ExecStartPre=/usr/bin/env sleep {{.}}
TimeoutStartSec={{$.StartTimeout}}
{{- end}}
ExecStart={{.ExecStart}}
ExecStop={{if .ExecStop}}-{{.ExecStop}}{{end}}
{{- if .Unit.Restart}}
@@ -44,7 +49,7 @@ const userUnitTemplate = `# ~/.config/systemd/user/{{.ServiceName}}
[Unit]
Description=Unitdore: {{.Unit.Name}} ({{.Label}})
After=default.target
After=default.target{{range .After}} {{.}}{{end}}
[Service]
Type={{.ServiceType}}
@@ -54,6 +59,10 @@ RemainAfterExit=yes
{{- with .WorkingDir}}
WorkingDirectory={{.}}
{{- end}}
{{- with .DelaySec}}
ExecStartPre=/usr/bin/env sleep {{.}}
TimeoutStartSec={{$.StartTimeout}}
{{- end}}
ExecStart={{.ExecStart}}
ExecStop={{if .ExecStop}}-{{.ExecStop}}{{end}}
{{- if .Unit.Restart}}
@@ -77,6 +86,9 @@ type templateData struct {
Label string // shown in Description
ServiceType string // simple | oneshot
WorkingDir string
After []string // service names of the previous order group
DelaySec int // ExecStartPre sleep, from unit delay
StartTimeout int // TimeoutStartSec when a delay is set
}
// ServiceName returns the systemd service name for a unit, with optional prefix/suffix.
@@ -102,6 +114,14 @@ func Generate(u config.Unit, prefix, suffix string) (string, error) {
WorkingDir: spec.WorkingDir,
}
for _, n := range u.After {
data.After = append(data.After, ServiceName(config.Unit{Name: n}, prefix, suffix))
}
if u.StartDelay > 0 {
data.DelaySec = int((u.StartDelay + time.Second - 1) / time.Second)
data.StartTimeout = data.DelaySec + 90
}
tmplStr := systemUnitTemplate
if u.User != "" {
tmplStr = userUnitTemplate