svcopts_other_test.go
Rama main · réplica de lectura del repositorio original.
//go:build !windows
package main
import (
"strings"
"testing"
"text/template"
)
// The self-install systemd unit tracks packaging/pingularity.service: read flags
// from /etc/default/pingularity via $PINGULARITY_OPTS, restart 5s after a crash,
// bound the restart loop, and apply the root-compatible hardening directives. Full
// de-rooting parity is deliberately out of scope - this unit installs as root, so
// it omits User=/ambient CAP_NET_RAW/StateDirectory and uses ProtectSystem=full not
// =strict (see svcopts_other.go). This renders the custom template with the same
// fields kardianos feeds it and checks the result, and doubles as a parse guard so
// a malformed template fails here rather than at `pingularity install`.
func TestSystemdScript(t *testing.T) {
// Stand-ins for kardianos's unexported cmd/cmdEscape funcs; identity is fine
// for a path with no spaces or quotes.
funcs := template.FuncMap{
"cmd": func(s string) string { return s },
"cmdEscape": func(s string) string { return s },
}
tmpl, err := template.New("").Funcs(funcs).Parse(systemdScript)
if err != nil {
t.Fatalf("systemdScript failed to parse: %v", err)
}
data := struct {
Description string
Path string
Name string
Dependencies []string
Arguments []string
WorkingDirectory string
ReloadSignal string
Restart string
}{
Description: "Internet connectivity monitor with a built-in web dashboard.",
Path: "/usr/local/bin/pingularity",
Name: "pingularity",
Dependencies: []string{"After=network-online.target", "Wants=network-online.target"},
Arguments: []string{"run"},
ReloadSignal: "HUP",
Restart: "always",
}
var b strings.Builder
if err := tmpl.Execute(&b, data); err != nil {
t.Fatalf("systemdScript failed to render: %v", err)
}
out := b.String()
mustContain := []string{
"EnvironmentFile=-/etc/default/pingularity",
"$PINGULARITY_OPTS",
"RestartSec=5",
"StartLimitBurst=5",
"Restart=always",
`ExecReload=/bin/kill -HUP "$MAINPID"`,
// Root-compatible hardening: these must survive on a root-run unit and
// stay in sync with the subset carried over from packaging/pingularity.service.
"NoNewPrivileges=yes",
"ProtectSystem=full",
"ProtectHome=yes",
"PrivateTmp=yes",
"ProtectKernelTunables=yes",
"RestrictSUIDSGID=yes",
"LockPersonality=yes",
}
for _, want := range mustContain {
if !strings.Contains(out, want) {
t.Errorf("rendered unit missing %q\n---\n%s", want, out)
}
}
mustNotContain := []string{
"/etc/sysconfig", // the RPM-ism the stock kardianos template uses
"RestartSec=120", // the stock 2-minute restart delay
// A root daemon writes its DB under /var; strict would make that tree
// read-only, so the root-run unit must use ProtectSystem=full, not strict.
"ProtectSystem=strict",
}
for _, bad := range mustNotContain {
if strings.Contains(out, bad) {
t.Errorf("rendered unit still contains %q\n---\n%s", bad, out)
}
}
}