-
Notifications
You must be signed in to change notification settings - Fork 0
1.12 Step | GenerateConfig
Generates
odoo<N>.conffrom the template, reversibly. It lives insrc/steps/generate_config.rs. A port ofgenerate_configfromlib/config.sh. The template is embedded in the binary (include_str!): no dependency on external files at runtime.Two novelties compared with the earlier steps: the first undo that restores instead of removing, and the care taken so that the master password is never world-readable.
Until now, the undo of a Preexisting step was a no-op (not ours, we do not touch it). Here it is
different: run overwrites a pre-existing odoo.conf, so the undo has to restore the original.
| Phase | Behaviour |
|---|---|
| snapshot | does the file already exist? → Preexisting/Untracked
|
| run | if Preexisting, back it up to odoo<N>.conf.bak.<timestamp> before overwriting (the path is saved in the snapshot); then render and write |
| undo |
CreatedByUs → rm -f (we created it); Preexisting → restore the backup over the destination file |
In the
Preexistingcase the undo does NOT leave the overwritten file and does NOT delete it: it puts exactly the customer's original back in place, from the backup. It is the first undo that restores rather than destroys.
A test proves it with a round trip on a real disk: after the undo, the file is byte-for-byte the original.
The file contains admin_passwd (and db_password). It must never pass through a file readable by
other users, not for an instant. The pattern (faithful to Bash, confirmed in analysis):
1. render → write to a PRIVATE temp (mode 0600, owned by root) ← password never readable by others
2. move → move the temp to its destination (same filesystem, atomic)
3. chown odoo:odoo
4. chmod 0640 ← readable only by odoo and root
The plaintext password enters only render_config (the Secret's single expose()) and from there
the file's contents; it is never logged nor printed in the summary. The mock in the tests records the
write as “private” without capturing its contents.
-
${VAR}placeholders are substituted with the Context's values (version, port, db_user/name, addons_path, data_dir, limits, proxy_mode, logfile, …). Thedata_diris no longer a plain template value: the formula lives ingenerate_config::data_dirand the same function is used by 1.12b SetupDataDir to create that directory reversibly. Two identicalformat!s in two files would be the premise of a rollback cleaning the wrong directory. -
Empty directives →
False: everykey =left without a value becomeskey = False(Odoo rejects empty values). So emptydb_host,db_port,db_passwordandlogfileend up asFalserather than dangling. -
Validation after rendering: the
[options]section is present,addons_pathandhttp_porthave values, and no${...}placeholder is left. Otherwise → error, and no incoherent file.
render_config, normalize_empty_directives and validate_rendered are pure functions, tested
separately.
- The temp file is written in the same directory as the destination, so
moveis an atomic rename on one filesystem. - Best-effort undo: if the backup is missing, it logs a warning and carries on without destroying anything.
- Final permissions
0640 odoo:odoo. - Tests:
CreatedByUs(generates 640, undo removes),Preexisting(the undo restores the backup), rendering (empty→False, no leftovers), validation (leftover placeholder or missing section → error).
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: