feat: podman-compose stack units and root/user execution scopes
- syncup: podman first, docker only as fallback (podman wins on name clash;
existing docker units found in podman switch to podman)
- syncup: group podman-compose containers into one `kind: stack` unit per
project (project, working_dir, compose_files, compose_bin from labels);
disable existing member units ("part of stack <project>")
- generator: compose mode (podman-compose up/stop, WorkingDirectory) with
pod start/stop fallback when compose binary/dir/files are missing
- reconcile: stacks disabled with "stack not found" when neither compose
files nor pod exist
- root: scan root + rootless users listed in `users:` (podman only)
- non-root: config ~/.config/unitdore/units.yaml, own user units only
- sysuser package: runuser with XDG_RUNTIME_DIR/DBUS env, home/linger lookup
- install: warn when linger is not enabled for user units
- testdata/stack: podman-compose test stack and captured podman ps fixture
- docs: README, generated-units, man page, AGENTS, PLAN
This commit is contained in:
@@ -277,6 +277,59 @@ units:
|
||||
|
||||
---
|
||||
|
||||
## Stack Unit (podman-compose, compose mode)
|
||||
|
||||
Used when `compose_bin`, `working_dir` and all `compose_files` exist.
|
||||
|
||||
```yaml
|
||||
- name: shop
|
||||
kind: stack
|
||||
runtime: podman
|
||||
project: shop
|
||||
working_dir: /srv/shop
|
||||
compose_files: [compose.yaml]
|
||||
compose_bin: /usr/bin/podman-compose
|
||||
enabled: true
|
||||
```
|
||||
|
||||
```ini
|
||||
# /etc/systemd/system/unitdore-shop.service
|
||||
# Generated by unitdore — do not edit manually
|
||||
|
||||
[Unit]
|
||||
Description=Unitdore: shop (podman-compose stack)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/srv/shop
|
||||
ExecStart=/usr/bin/podman-compose -p shop -f compose.yaml up
|
||||
ExecStop=-/usr/bin/podman-compose -p shop -f compose.yaml stop
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stack Unit (pod fallback)
|
||||
|
||||
Used when the compose binary, working dir or a compose file is missing. Requires pod `pod_<project>`.
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Unitdore: shop (podman pod)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/podman pod start pod_shop
|
||||
ExecStop=-/usr/bin/podman pod stop pod_shop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: Service File Locations
|
||||
|
||||
| Scenario | Path |
|
||||
|
||||
+29
-4
@@ -9,18 +9,26 @@ unitdore \- manage container units via systemd
|
||||
.SH DESCRIPTION
|
||||
.B unitdore
|
||||
bridges your container runtime (Podman, Docker) and systemd.
|
||||
It discovers running containers, stores them in a config file, and generates
|
||||
and manages systemd \fI.service\fR units for each one.
|
||||
It discovers running containers and podman\-compose stacks, stores them in a
|
||||
config file, and generates and manages systemd \fI.service\fR units for each one.
|
||||
.PP
|
||||
As root: system units, plus user units for users listed in \fBusers:\fR.
|
||||
As a normal user: own config (\fI~/.config/unitdore/units.yaml\fR) and user units only.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-\-config " " \fIpath\fR
|
||||
Path to the units config file. Default: \fI/etc/unitdore/units.yaml\fR
|
||||
(non\-root: \fI~/.config/unitdore/units.yaml\fR)
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
.B syncup
|
||||
Query all available runtimes for running containers and add any new ones to
|
||||
the config. Reconciles existing entries: if a configured unit's container no
|
||||
longer exists it is marked disabled with a reason.
|
||||
Podman is queried first; Docker only for names Podman does not have.
|
||||
podman\-compose containers become one \fBkind: stack\fR unit per project;
|
||||
existing member units are disabled. As root, rootless Podman containers of
|
||||
each user in \fBusers:\fR are also discovered.
|
||||
.TP
|
||||
.B install
|
||||
Generate \fI.service\fR files for all enabled units and write them to the
|
||||
@@ -74,7 +82,7 @@ Open the units config file in \fB$EDITOR\fR. Falls back to \fBnvim\fR,
|
||||
.nf
|
||||
prefix: "" # prepended to all service names, e.g. "prod-"
|
||||
suffix: "" # appended to all service names, e.g. "-svc"
|
||||
service_user: "" # User= in [Service]; defaults to current OS user
|
||||
users: [] # root only: rootless users scanned by syncup
|
||||
|
||||
units:
|
||||
- name: nginx
|
||||
@@ -85,7 +93,19 @@ units:
|
||||
delay: 0s # delay after previous order group
|
||||
enabled: true
|
||||
disabled_reason: "" # auto-set by syncup reconciliation
|
||||
|
||||
- name: shop # compose project name
|
||||
kind: stack # container (default) | stack
|
||||
runtime: podman
|
||||
project: shop
|
||||
working_dir: /srv/shop
|
||||
compose_files: [compose.yaml]
|
||||
compose_bin: /usr/bin/podman-compose
|
||||
.fi
|
||||
.PP
|
||||
Stack units run \fBpodman\-compose up\fR/\fBstop\fR when compose_bin,
|
||||
working_dir and compose_files exist; otherwise \fBpodman pod start\fR/\fBstop
|
||||
pod_\fR\fIproject\fR.
|
||||
.SH GENERATED SERVICE FILES
|
||||
System units are written to \fI/etc/systemd/system/\fR and user units to
|
||||
\fI~/.config/systemd/user/\fR.
|
||||
@@ -127,13 +147,18 @@ sudo unitdore update nginx \-\-order 2
|
||||
.I /etc/unitdore/units.yaml
|
||||
Default configuration file.
|
||||
.TP
|
||||
.I ~/.config/unitdore/units.yaml
|
||||
Configuration file when run as a normal user.
|
||||
.TP
|
||||
.I /etc/systemd/system/unitdore-*.service
|
||||
Generated system unit files.
|
||||
.TP
|
||||
.I ~/.config/systemd/user/unitdore-*.service
|
||||
Generated rootless user unit files.
|
||||
.SH REQUIREMENTS
|
||||
systemd; Podman and/or Docker (only installed runtimes are used).
|
||||
systemd; Podman and/or Docker (only installed runtimes are used);
|
||||
podman\-compose for compose\-mode stacks.
|
||||
User units need linger to start at boot: \fBloginctl enable\-linger\fR \fIuser\fR.
|
||||
Root is required for system units; the relevant user for rootless units.
|
||||
.SH SEE ALSO
|
||||
.BR systemctl (1),
|
||||
|
||||
Reference in New Issue
Block a user