-
Notifications
You must be signed in to change notification settings - Fork 0
History
Historical note. Bash is mentioned here only — as the past, not as a usage guide.
The installer was originally written in Bash (installer.sh plus lib/*.sh modules, with a
check_install.sh verification suite). Those versions are archived at the tags:
The Bash version was idempotent (run it again and carry on) but not reversible (undo and clean up): if a step failed, it could leave the system in an intermediate state.
The current version is a complete rewrite in Rust, born to add what Bash lacked: transactional
rollback — either the installation succeeds, or the system goes back to exactly what it was. The
compiler guarantees that no error branch is ignored; every step has snapshot/run/undo, and the
rollback is proven by end-to-end tests.
The Bash files are no longer in the repository: they were removed when Rust became the source of truth. They remain recoverable from the git history and the tags above.
2.2.0 came out of a cold audit of the whole tree. There was a single theme: the promise “either it succeeds, or the system goes back to what it was” was not being kept in several places — and none of them showed up as an error.
The three things a user notices:
- Ctrl-C rolls back instead of killing the process. Before, the installation was left half-done.
-
An interrupted installation resumes, without losing track of what it had already created. And a
completed one is no longer overwritten: the uninstall manifest was the only thing making an
instance removable, and a second
sudo invokdestroyed it silently. -
/opt/odooreally disappears after a rollback. Before it always stayed: the lock and the log lived inside it and kept it occupied, so the undo meant to remove it could never fire.
Hence the three path moves (manifest to /var/lib, lock to /run, log to /var/log) and the renaming
of --enable-ssl to --open-https-port — a flag that promised TLS without providing it. The legacy
name and its .env key keep working.
If you are upgrading: the log has moved, and re-running the installer on an already-installed instance now fails on purpose (use
rollbackor--force). Instances installed with 2.1.0 remain uninstallable-by-command: the historical manifest path is still read.
Until then the installer spoke one language only. Fedora support was not added with an if next to
every command, but by extracting two boundaries — “which commands install a package, and what is it
called here” and “where do the files live, which concepts exist, who governs the firewall” — so that
the steps stopped knowing which distribution they run on.
Three things that only showed up by actually running it, and that are worth more than the list of translated package names:
- on Fedora the PostgreSQL cluster does not exist until you create it, so “install the package” is not enough: initialising is a mutation with an artifact of its own, and as such it has to be recorded and undoable;
-
SELinux denies the proxy to Odoo with a valid
nginx -tand a successful reload: the symptom is a 502 and nothing in the configuration explains it; - from Fedora 43 the system
python3is newer than Odoo's pins, and no build flag works around a wheel that does not exist. Hence the rule that the installer chooses the interpreter instead of taking whatever is there, installing one the pins cover and removing it on rollback.
The full account: Multi-distribution support.
If you are upgrading from 2.2.0: no flag changes and no existing installation needs redoing. On Ubuntu and Debian the behaviour is identical; the difference only shows on Fedora, where the installer used to stop and now goes all the way through.
The project used to be called odoo-installer. From 3.0.0 it is called Invok, with the short
alias vok — a /usr/bin/vok → /usr/bin/invok symlink created by the packages, not a second
program.
The rule that decided every single occurrence, and that is worth knowing because it explains what
changed and what did not: “Odoo” leaves the identifiers and stays in descriptive use. Out of the
name of the crate, the binary, the packages and the bookkeeping paths (/var/lib/invok/state.json,
/var/log/invok.log, /run/invok.lock). In, unchanged, all the artifacts that are Odoo's:
/opt/odoo, the odoo user and database, odoo.conf, odoo18.service, the odoo helper command. A
trademark is defended on identity, not on mention: taking “Odoo” out of the prose would cost
discoverability without reducing exposure.
If you are upgrading from a 2.x: your instances stay uninstallable-by-command. The manifest of an installation made with 2.4.0 lives in
/var/lib/odoo-installer/state.json, and that path is still read — together with the even older/opt/odoo/.installer-state.json. Dropping it would not leave “an instance to remove by hand”: it would leave an instance nobody can uninstall without guessing the names of its artifacts.
Up to 2.3.0 there was one route: clone and compile. From 3.0.0 there are four wrappers, and three of
them need no Rust — .tar.gz (static musl, any distro), .deb, .rpm, each with its own sha256,
plus cargo install invok for those who already have the toolchain.
Updates come from the Releases page, where every
version stays with its checksums: you update by downloading again. There is no apt/dnf repository
to add to the machine's sources.
Looking for how to use the current version: Home, Quick start, The rollback model.
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: