-
Notifications
You must be signed in to change notification settings - Fork 0
1.14 Step | SetupSystemd
Installs and activates Odoo's systemd service: renders the unit from the template, installs it into
/etc/systemd/system/, thendaemon-reload,enable,start. It lives insrc/steps/setup_systemd.rs. A port oflib/systemd.sh+templates/odoo.service.tpl.A consolidation step: it reuses two already-proven patterns — the three independent PreStates of 1.6 SetupPostgres and the embedded template of 1.12 GenerateConfig.
struct SystemdSnapshot {
unit_file: PreState, // does /etc/systemd/system/odoo<N>.service already exist?
// (odoo-<instance>.service for a named instance: the
// name is what tells two installations apart, so the
// version stops being part of it)
enabled: PreState, // was the service already enabled?
active: PreState, // was the service already running?
}| Phase | Behaviour |
|---|---|
| snapshot | for each axis: already true before us → Preexisting; otherwise Untracked
|
| run | installs the unit (idempotent), daemon-reload, enable (if not already), start/restart, checks is-active
|
| undo | restores each CreatedByUs axis, in the order stop → disable → rm → reload
|
Rule D4: a service that was already running or enabled before us is left as it was; a pre-existing unit file is not removed.
stop (if active == CreatedByUs)
└─ disable (if enabled == CreatedByUs)
└─ rm the unit file (if unit_file == CreatedByUs)
└─ daemon-reload ← systemd forgets the removed unit
Stopping and disabling before removing the file keeps systemd from holding references to a unit that
has vanished. The final daemon-reload closes the loop. Every step is best-effort and idempotent.
The unit is rendered from the embedded template by substituting {{VAR}} placeholders (version, user,
install_dir, repo/venv). Validation: no {{...}} placeholder left.
The template's hardening is preserved and must not be watered down:
Under the “Security hardening” heading there was, for a long time, a single directive:
PermissionsStartOnly=true— deprecated since systemd 231 (2016) and ignored with a warning. Its job was to runExecStartPrecommands as root, and there are noExecStartPrecommands. It was a heading with no content: removed, and replaced with the directives that actually move the needle for a network-facing process.
| Directive | Value |
|---|---|
User / Group
|
odoo (the service is not root) |
NoNewPrivileges |
true |
PrivateTmp |
true |
RuntimeDirectory / RuntimeDirectoryMode
|
odoo / 0750
|
ProtectSystem |
full (/usr and /boot read-only; /opt stays writable) |
ProtectHome |
true |
PrivateDevices |
true |
ProtectKernelTunables / ProtectKernelModules / ProtectControlGroups
|
true |
RestrictSUIDSGID / LockPersonality
|
true |
RestrictAddressFamilies |
AF_UNIX AF_INET AF_INET6 |
Requires |
postgresql.service |
Restart |
on-failure |
StartLimitIntervalSec / StartLimitBurst
|
burst protection |
AF_UNIX is not optional in RestrictAddressFamilies: it is PostgreSQL's socket. Omitting it would
give a service that starts and cannot reach the database — a failure that would look like something
else entirely.
ProtectSystem=strict is deliberately excluded: it would require an exact list of ReadWritePaths
(install dir, filestore, cache, sessions), and getting one wrong breaks the service on a customer
machine. full covers /usr and /boot, which is the real gain for a process that already runs
unprivileged.
Installing the file: private temp → move → chmod 644 → chown root:root. Final is-active check,
with a journalctl -u odoo<N> hint if it did not come up.
-
No shared state: the three PreStates are local to the step. Unlike
1.13 InitializeOdooDatabase, no step-to-step channel is needed
here — no new
Arc<Atomic…>in the Context. Keeping shared state under control is what keeps the rollback traceable. -
render_unitandvalidate_unitare pure functions, tested separately. - Tests: all-absent (installs; the undo order
stop→disable→rm→reloadis verified), D4 on active (already running → restart in run, no stop in undo), D4 on enabled (already enabled → no disable), failed start → error, rendering (no leftovers, hardening present).
Start here
Key concepts
References
For developers
Technical detail — how it works inside
Steps:
- 1.1 PrepareOptRoot
- 1.2 CreateOdooUser
- 1.3 SetupLogDir
- 1.3b SetupCacheDir
- 1.4 AptPackages (delta)
- 1.5 InstallWkhtmltopdf
- 1.6 SetupPostgres
- 1.7 CreateDbRole
- 1.8 CreateDatabase
- 1.9 CloneOdooRepo
- 1.10 CreateVirtualenv
- 1.11 InstallPythonRequirements
- 1.12 GenerateConfig
- 1.12b SetupDataDir
- 1.13 InitializeOdooDatabase
- 1.14 SetupSystemd
- 1.15 Nginx (6 sub-steps)
- 1.16 WriteControlScript + PatchBashrc
Cross-cutting: