From b58373ad2fc93b4f872ac29aaea08281d328cca4 Mon Sep 17 00:00:00 2001 From: Hein Date: Fri, 10 Apr 2026 09:38:45 +0200 Subject: [PATCH 1/2] feat(config): add restart options for unit configuration * include Restart, RestartSec, and RestartRetries fields * update service file generation to support restart settings * add tests for restart behavior in unit generation --- config/config.go | 3 +++ systemd/generator.go | 14 +++++++++-- systemd/generator_test.go | 49 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/config/config.go b/config/config.go index 5c99319..83d4223 100644 --- a/config/config.go +++ b/config/config.go @@ -20,6 +20,9 @@ type Unit struct { Delay string `yaml:"delay,omitempty"` // e.g. "5s" Enabled bool `yaml:"enabled"` DisabledReason string `yaml:"disabled_reason,omitempty"` + Restart bool `yaml:"restart,omitempty"` // enable Restart=on-failure + RestartSec int `yaml:"restart_sec,omitempty"` // seconds between restarts + RestartRetries int `yaml:"restart_retries,omitempty"` // max restart attempts (StartLimitBurst) } // Config is the root config structure. diff --git a/systemd/generator.go b/systemd/generator.go index 6a89c72..0650191 100644 --- a/systemd/generator.go +++ b/systemd/generator.go @@ -20,8 +20,13 @@ Requires={{.}}{{end}} Type=simple ExecStart={{.ExecStart}} ExecStop={{.ExecStop}} +{{- if .Unit.Restart}} Restart=on-failure -RestartSec=5 +RestartSec={{.Unit.RestartSec}} +{{- if gt .Unit.RestartRetries 0}} +StartLimitBurst={{.Unit.RestartRetries}} +{{- end}} +{{- end}} [Install] WantedBy=multi-user.target @@ -38,8 +43,13 @@ After=default.target Type=simple ExecStart={{.ExecStart}} ExecStop={{.ExecStop}} +{{- if .Unit.Restart}} Restart=on-failure -RestartSec=5 +RestartSec={{.Unit.RestartSec}} +{{- if gt .Unit.RestartRetries 0}} +StartLimitBurst={{.Unit.RestartRetries}} +{{- end}} +{{- end}} [Install] WantedBy=default.target diff --git a/systemd/generator_test.go b/systemd/generator_test.go index 89c50ef..493d7aa 100644 --- a/systemd/generator_test.go +++ b/systemd/generator_test.go @@ -50,7 +50,6 @@ func TestGenerate_SystemUnit(t *testing.T) { "WantedBy=multi-user.target", "ExecStart=/usr/bin/podman start -a nginx", "ExecStop=/usr/bin/podman stop nginx", - "Restart=on-failure", "Generated by unitdore", } @@ -66,6 +65,9 @@ func TestGenerate_SystemUnit(t *testing.T) { if strings.Contains(content, "Requires=") { t.Errorf("Generate() podman system unit should not contain Requires= (podman is daemonless):\n%s", content) } + if strings.Contains(content, "Restart=") { + t.Errorf("Generate() restart should be disabled by default:\n%s", content) + } } func TestGenerate_UserUnit(t *testing.T) { @@ -100,6 +102,51 @@ func TestGenerate_UserUnit(t *testing.T) { } } +func TestGenerate_WithRestart(t *testing.T) { + t.Run("restart with retries", func(t *testing.T) { + u := config.Unit{ + Name: "nginx", + Runtime: "podman", + Enabled: true, + Restart: true, + RestartSec: 5, + RestartRetries: 3, + } + content, err := Generate(u, "", "") + if err != nil { + t.Fatalf("Generate() error: %v", err) + } + for _, want := range []string{"Restart=on-failure", "RestartSec=5", "StartLimitBurst=3"} { + if !strings.Contains(content, want) { + t.Errorf("Generate() missing %q in output:\n%s", want, content) + } + } + }) + + t.Run("restart without retries", func(t *testing.T) { + u := config.Unit{ + Name: "nginx", + Runtime: "podman", + Enabled: true, + Restart: true, + RestartSec: 10, + } + content, err := Generate(u, "", "") + if err != nil { + t.Fatalf("Generate() error: %v", err) + } + if !strings.Contains(content, "Restart=on-failure") { + t.Errorf("Generate() missing Restart=on-failure:\n%s", content) + } + if !strings.Contains(content, "RestartSec=10") { + t.Errorf("Generate() missing RestartSec=10:\n%s", content) + } + if strings.Contains(content, "StartLimitBurst") { + t.Errorf("Generate() should not contain StartLimitBurst when retries=0:\n%s", content) + } + }) +} + func TestGenerate_CustomCommand(t *testing.T) { u := config.Unit{ Name: "custom", From 2efccc5d4f1933ba17894e9fffa3dfb0c27b51b5 Mon Sep 17 00:00:00 2001 From: Hein Date: Fri, 10 Apr 2026 09:38:59 +0200 Subject: [PATCH 2/2] chore(release): update package version to 0.0.8 --- cmd/root.go | 2 +- pkg/arch/PKGBUILD | 2 +- pkg/centos/unitdore.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index d77268a..f90dbf2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,7 +7,7 @@ import ( "github.com/spf13/cobra" ) -var version = "0.0.7" +var version = "0.0.8" var configPath string diff --git a/pkg/arch/PKGBUILD b/pkg/arch/PKGBUILD index a4c2e17..e299045 100644 --- a/pkg/arch/PKGBUILD +++ b/pkg/arch/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: Hein (Warky Devs) pkgname=unitdore -pkgver=0.0.7 +pkgver=0.0.8 pkgrel=1 pkgdesc="A door you open and close for container units — manage containers via systemd" arch=('x86_64' 'aarch64') diff --git a/pkg/centos/unitdore.spec b/pkg/centos/unitdore.spec index 53c4046..486cd43 100644 --- a/pkg/centos/unitdore.spec +++ b/pkg/centos/unitdore.spec @@ -1,5 +1,5 @@ Name: unitdore -Version: 0.0.7 +Version: 0.0.8 Release: 1%{?dist} Summary: Manage container units via systemd