- 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
3.4 KiB
Project Overview
Unitdore is a Go CLI tool that bridges container runtimes (Podman, Docker) and systemd. It discovers running containers, stores them in a YAML config, and generates + manages systemd .service unit files for each one.
Agent Rules
Keep answers short. Question everything, never assume or guess. Ask if unsure.
You must use the AMCS MCP system tools. Set unitdore as the active project and always capture summaries of what was done as thoughts using the capture_thought tool. If AMCS is not available, write files to docs/llm/log/yyyymmdd_hh.md.
Tools to use
When writing Go: doc/tools/go-skill.md (if present), otherwise follow standard Go conventions.
Commands
make build # Compile binary: ./unitdore
make install # Install binary to /usr/bin, man page, create /etc/unitdore
make uninstall # Remove binary and man page
make test # go test ./... -v
make test-short # go test ./...
make lint # go vet ./...
make clean # Remove built binary
make release-version # Bump patch version, commit, tag, and push
Architecture
cmd/ # Cobra commands (edit, install, list, root, start, startall,
# status, stop, stopall, syncup, uninstall, update)
config/ # Config struct + YAML load/save (units.yaml)
runtime/ # Docker and Podman runtime abstraction
systemd/ # .service file generator and systemd manager
docs/ # generated-units.md (unit file examples), unitdore.1 (man page)
Key packages
config—UnitandConfigstructs;Load,Save,FindUnit,AddUnitruntime—ContainerRuntimeinterface;docker.go,podman.goimplementationssystemd—generator.gobuilds.servicefile content;manager.gocallssystemctl
Config file
Location: /etc/unitdore/units.yaml
prefix: "" # prepended to service file name (e.g. "prod-")
suffix: "" # appended to service file name (e.g. "-svc")
units:
- name: nginx
runtime: podman # podman | docker
user: "" # empty = system unit; set for rootless user unit
command: "" # override ExecStart entirely
order: 1 # startup order, lower = earlier; same = parallel
delay: 0s # delay after previous order group
enabled: true
disabled_reason: "" # auto-set by syncup reconciliation
restart: false # Restart=on-failure
restart_sec: 0 # RestartSec
restart_retries: 0 # StartLimitBurst
Generated service file locations
| Scenario | Path |
|---|---|
| System unit (root) | /etc/systemd/system/unitdore-<name>.service |
| User unit | /home/<user>/.config/systemd/user/unitdore-<name>.service |
With prefix prod- |
/etc/systemd/system/unitdore-prod-<name>.service |
With suffix -svc |
/etc/systemd/system/unitdore-<name>-svc.service |
Libraries
github.com/spf13/cobra— CLI frameworkgopkg.in/yaml.v3— config parsing
Testing
Tests exist in:
config/config_test.goruntime/runtime_test.gosystemd/generator_test.go
Always run make test before marking a task complete. Add tests for new behaviour in the same package as the code under test.
Additional documentation
docs/generated-units.md— full annotated examples of every generated unit file combinationdocs/unitdore.1— man page