Phase 5-7: README, Makefile, unit tests

- README.md: full usage docs
- Makefile: build/install/uninstall/test/lint/clean targets
- config/config_test.go: 7 tests (load, save, find, add, roundtrip, invalid yaml)
- runtime/runtime_test.go: 6 tests (get, available, ListRunning graceful degradation)
- systemd/generator_test.go: 7 tests (ServiceName, Generate system/user/custom/docker/unknown, buildExecCommands)
- fix: docker/podman ListRunning returns nil (not error) when daemon unavailable
- fix: invalid YAML test uses tab-indent which is genuinely unparseable
This commit is contained in:
2026-04-03 14:50:36 +02:00
parent 203e8e3f04
commit 5078558d01
7 changed files with 576 additions and 2 deletions

131
README.md Normal file
View File

@@ -0,0 +1,131 @@
# unitdore
> *A door you open and close for container units.*
Unitdore bridges your container runtime (Podman, Docker) and systemd. It discovers running containers, stores them in a config file, and generates + manages systemd `.service` units for each one.
## Install
```bash
make build
sudo make install
```
Or manually:
```bash
go build -o unitdore .
sudo cp unitdore /usr/local/bin/
```
## Usage
### Discover running containers
```bash
sudo unitdore syncup
```
Queries Podman and Docker for running containers, adds new ones to the config, and reconciles any that have disappeared (marking them disabled).
### Edit the config
```bash
sudo unitdore edit
```
Opens `/etc/unitdore/units.yaml` in `$EDITOR` (falls back to `vi`).
### Install systemd unit files
```bash
sudo unitdore install
```
Generates `.service` files for all enabled units and writes them to systemd. Use `--dry-run` to preview without writing.
```bash
sudo unitdore install --dry-run
```
### Enable and start units
```bash
sudo unitdore active
```
Runs `systemctl enable --now` for all installed, enabled units in startup order.
### Check status
```bash
sudo unitdore status
```
Prints a summary table:
```
NAME RUNTIME USER ENABLED INSTALLED STATE REASON
nginx podman root yes yes active
myapp docker hein yes yes active
oldthing podman hein no no — container not found
```
## Config file
**Location:** `/etc/unitdore/units.yaml`
```yaml
units:
- name: nginx
runtime: podman # podman | docker
user: "" # empty = root/system unit
command: "" # optional: override ExecStart entirely
order: 1 # startup order (lower = earlier)
delay: 0s # delay after previous order group
enabled: true
disabled_reason: "" # auto-set by syncup reconciliation
- name: myapp
runtime: docker
user: hein # rootless: generates user unit for this user
order: 2
delay: 5s
enabled: true
```
## Generated unit file (example)
```ini
# /etc/systemd/system/unitdore-nginx.service
# Generated by unitdore — do not edit manually
[Unit]
Description=Unitdore: nginx (podman)
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/podman start -a nginx
ExecStop=/usr/bin/podman stop nginx
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
For user units (rootless containers), files go to `~/.config/systemd/user/` and target `default.target`.
## Flags
```
--config string path to units config file (default "/etc/unitdore/units.yaml")
```
## Requirements
- Go 1.21+
- systemd
- Podman and/or Docker (only what you have installed is used)
- Root for system units; the relevant user for rootless units