Closes DOCS-AUDIT §6.1 and §5.1. **The script could not run.** It read `APP` off `host.data` and then used `SERVICE_NAME` and `AUTOSTART` as if they were in scope, so the very first statement — `if AUTOSTART:` — raised `NameError`; `server` was used in the else branch but never imported. Three lines: import `server` alongside `systemd`, read the two names next to `APP`. The logic underneath was always right. `python3 -m py_compile` passes. **The README documented a different cube.** It was titled "TypeStack Install Cube" and described cloning a git repository, `yarn install`, `yarn build`, `docker compose up -d` and PM2 — none of which this cube does, and it listed parameters (`USER`, `REPO`, `ENV`, `NODE_PATH`) the manifest does not have, carrying someone's private repository URL and username as defaults. Rewritten from the manifest and the now-working script: the three parameters that exist, and the thing the old text obscured by describing a deploy pipeline — this cube does not create the unit file, it enables and starts one that is already installed. `SERVICE_NAME` is documented as what it is, a label that never reaches systemd, so getting it wrong is cosmetic rather than a cube managing the wrong unit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DCzYTAm9QUhvLNr2EpdagJ
autostart
Enable and start an existing systemd service
Purpose
Takes a systemd unit that is already installed on the host and decides whether
it runs: systemctl enable plus systemctl start, or neither.
It does not create the unit. Something else — a package, another cube, a
files.template — has to have put <APP>.service on the host first. This cube
is the switch, not the wiring.
What This Cube Does
With AUTOSTART=True (the default), two systemd.service operations against
<APP>: one setting enabled=True so the unit comes up on boot, one setting
running=True so it comes up now. Both are idempotent — a unit already enabled
and running is left alone.
With AUTOSTART=False, nothing is changed. The cube prints the two commands you
would run by hand and exits, which is the point of the flag: install now, decide
later.
Configuration
| Variable | Default | What it does |
|---|---|---|
APP |
(required) | the systemd unit name, without the .service suffix — flintstone for /etc/systemd/system/flintstone.service. This is what systemctl is actually pointed at. |
SERVICE_NAME |
Application |
a display name, used only in the operation labels pyinfra prints and in the AUTOSTART=False message. Changing it changes what you read, not what happens. |
AUTOSTART |
true |
whether to enable and start the unit at all. |
APP has no default, so nopy -D (--use-defaults) fails by name rather than
guessing. Supply it under env in .nopyrc.json, from a dependency, or at the
prompt.
Dependencies
None declared, and none implied beyond the unit file itself. systemd.service
is a pyinfra built-in; there is nothing to install.
Post-Installation
systemctl status <APP> # is it running?
systemctl is-enabled <APP> # will it come back after a reboot?
journalctl -u <APP> -f # follow its log
If the run fails with Unit <APP>.service could not be found, the unit was
never installed — see Purpose. systemctl daemon-reload is worth trying if the
file was written after systemd last read the directory.
Notes
- Enabling and starting are separate systemd concepts and this cube always does
both or neither. If you need one without the other, call
systemd.servicefrom your own deploy script. SERVICE_NAMEis deliberately not passed to systemd. The unit is identified byAPPalone, so a wrongSERVICE_NAMEis a cosmetic mistake rather than a cube that manages the wrong service.