-
Notifications
You must be signed in to change notification settings - Fork 0
1.1 Step | PrepareOptRoot
The installer's first real step: it creates
/opt/odoo(thectx.odoo_homevalue) when missing, reversibly. It lives insrc/steps/prepare_opt_root.rs. It is the simplest possible mutation — a directory — chosen deliberately as the reference model for the steps that follow (user, packages, postgres…): all of them are richer variants of the samesnapshot → run → undoshape.It comes out of correction C4: the
mkdirthat Bash hid insidecheck_diskbecomes a step with anundohere. See 1. Checks and 0. Engine.
| Phase | Behaviour |
|---|---|
| snapshot |
ctx.odoo_home exists → PreState::Preexisting; otherwise it stays Untracked (run has not created it yet) |
| run |
Preexisting → no-op (not ours: neither owner nor permissions); Untracked → mkdir + 0755, then PreState::CreatedByUs. If the user already exists, the directory is handed over at once (chown + 0750). In dry_run it only logs |
| undo | acts only on CreatedByUs: removes the directory only if empty (rmdir, never rm -rf). Preexisting/Untracked → no-op |
All three PreStates are handled and tested. The post-run PreState is serialised
(snapshot_value) and persisted, so the rollback knows whether the directory is ours — including a
rollback run days later from the manifest, which rebuilds this step through rehydrate.
At this point the odoo user does not exist yet — it is created by the next step. So the directory
is created owned by root with 0755 permissions, and the chown odoo:odoo happens in the
user-creation step, which is the correct order. The dependency is documented in the code.
Only the missing level is created (create_dir, not create_dir_all). The rollback must restore
exactly what we added: if we also created /opt we would not remove it again, leaving a residue. The
parent (/opt) is assumed to exist on the system.
- Idempotent: if the directory is already gone → no-op.
- It removes only if empty. If it contains artifacts from later steps, those steps have their own
undos which run first (reverse order), so by the timePrepareOptRoot's undo runs the directory should be empty. If it is not → a warning, and it is not forced. Neverrm -rf. - A
Preexistingdirectory is never removed: it is not ours to destroy.
parse config
└─▶ preflight checks (non-mutating)
└─▶ Installer::execute([ PrepareOptRoot, … ]) ← first mutation, reversible
It is the first of the 25 steps, which means its undo is the last one to run in a rollback — the
reason its directory should be empty by then.
- An exemplary, deliberately minimal implementation: if the pattern is clean here, the complex steps copy it.
- No
.unwrap()/.expect(): every failure is aResult. - Round-trip tests:
CreatedByUs(creates → removes),Preexisting(survives the undo), non-empty directory (the undo does not force),dry_run(creates nothing,undois a no-op).
owned root is not the right state for the home: it is a waiting state, and it makes sense only
while the user does not exist. When the user is already there — a distro package, the leftover of a
manual setup, a company convention — there is nothing to wait for, and leaving it to root broke the
installation three steps later: CreateOdooUser sees a Preexisting user and returns immediately
without the chown (a deliberate choice: we do not touch what is not ours), and SetupCacheDir
then runs sudo -u odoo mkdir -p /opt/odoo/.cache on a root-owned directory → Permission denied,
with an error that says nothing about the cause.
The handover belongs here and not there because here is where the information is: this step knows
it created the directory itself. CreateOdooUser cannot know that — at its snapshot the home always
exists, because we just created it — so any attempt to infer it from there would be a check that in
production always answers the same way.
The opposite case — a pre-existing root-owned home with an already-existing user — stays out: that directory is not ours and does not get chowned. There the installation stops with an explicit precondition in CreateOdooUser.
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: