Ctrl K
ComunidadGuías…

svcopts_other_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
//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)
		}
	}
}