-
Notifications
You must be signed in to change notification settings - Fork 0
1.11 Step | InstallPythonRequirements
Installa le dipendenze pip nel virtualenv. Vive in
src/steps/install_python_requirements.rs. Terzo e ultimo dei sotto-step dei sorgenti. Tutte le install come utente odoo, dalpipdel venv.La sua particolarità: non ha un undo proprio.
I pacchetti pip vivono dentro <install_dir>/sandbox (il venv). Se il venv è nostro, l'undo di
1.10 CreateVirtualenv (rm -rf sandbox) li rimuove tutti. Quindi:
undodi questo step → NO-OP documentato. Disinstallare i pacchetti uno a uno sarebbe ridondante e fragile: la rimozione del venv è l'undo corretto.
Un undo in meno da scrivere, per la ragione giusta. Se il venv era Preexisting, non tocchiamo comunque
i pacchetti di un venv altrui.
| Fase | Comportamento |
|---|---|
| snapshot | leggero: lo stato rilevante per il rollback è quello del venv (1.10), non un PreState per-pacchetto |
| run | legge requirements.txt (assente → errore), poi la sequenza pip qui sotto. dry_run → log |
| undo | NO-OP (vedi sopra) |
Cython 3 ha rimosso il tipo long di Python 2; gevent (richiesto da Odoo 18) usa ancora quel codice
nei .pyx. pip costruisce le wheel in un ambiente isolato che ignora il Cython del venv. La
soluzione (fedele al Bash) è una sequenza precisa:
1. pip install --upgrade pip wheel
2. pip install "Cython<3" # nel venv
3. pip install --no-build-isolation <gevent-spec> # usa il Cython<3 locale
4. pip install --prefer-binary -r <requirements senza gevent>
- Le righe di gevent e greenlet vengono passate a pip in un file di requirements, verbatim: vedi sotto, è la parte che ha richiesto due giri di CI per venire giusta.
- Il passaggio 4 usa un
requirementsfiltrato senza quelle righe, altrimenti pip le ricompilerebbe da sorgente nell'env isolato, ignorando il Cython<3.
Il requirements.txt di Odoo 18 non pinna una versione di gevent. Ne pinna quattro, una per
versione di Python, e altrettante di greenlet — con i marker d'ambiente, e annotate da Odoo stesso con
la release Ubuntu:
gevent==21.8.0 ; … python_version == '3.10' # (Jammy)
gevent==24.2.1 ; … python_version >= '3.12' and < '3.13' # (Noble)
greenlet==1.1.2 ; … python_version == '3.10' # (Jammy)
greenlet==3.0.3 ; … python_version >= '3.12' and < '3.13' # (Noble)
La prima versione di questo step prendeva la prima riga che iniziasse con gevent e ne buttava via
il marker. Su Ubuntu 22.04 è la riga giusta per coincidenza (Python 3.10 è la prima); su 24.04
sceglieva ancora Jammy, e la CI moriva così:
gevent → _greenlet_primitives.c:273: fatal error: longintrepr.h: No such file
greenlet → PyThreadState has no member 'recursion_limit'
longintrepr.h è stato reso privato in Python 3.12 e i campi di PyThreadState rinominati: gevent
21.8.0 e greenlet 1.1.x sono anteriori a 3.12 e non possono compilarci contro. Non era l'ambiente di
build: era la versione sbagliata.
Il marker si buttava via per un vincolo autoinflitto. È vero che
--no-build-isolationnon tollera un marker su argv — ma passando un file di requirements i marker restano, e a valutarli è pip: il software il cui mestiere è esattamente quello. Noi smettiamo di scegliere.
greenlet sta nel gruppo insieme a gevent perché installando gevent da solo pip risolveva greenlet
dalla metadata di gevent (greenlet>=1.1,<2) invece che dal pin di Odoo — ed è così che
greenlet 1.1.x finiva a compilare contro Python 3.12.
Effetto collaterale gradito: con la versione giusta, su Noble esiste la wheel precompilata
(gevent-24.2.1-cp312-manylinux…), quindi non si compila affatto e --no-build-isolation resta
inerte. Il workaround Cython<3 serve dove serve davvero — Jammy, dove per gevent 21.8.0 la wheel non
esiste.
Non è un residuo: è un fix reale. extract_gevent_spec e filter_out_gevent sono funzioni pure,
testate a parte; la sequenza pip è verificata in ordine.
pip mette la sua cache in $HOME/.cache, e l'$HOME dell'utente odoo è /opt/odoo — la directory
che l'installer, se la trova già esistente, marca Preexisting e non tocca mai. Risultato misurato
in CI: dopo un rollback completo, /opt/odoo/.cache restava lì. Cache rigenerabili, ma la promessa è
«il sistema torna esattamente com'era».
La correzione è preventiva, non una pulizia: ogni invocazione passa
--cache-dir <install_dir>/sandbox/.pip-cache, cioè dentro il venv, che l'undo di
1.10 CreateVirtualenv rimuove per intero con un rm -rf. Niente nasce
fuori dal perimetro, quindi non serve inseguire nulla con euristiche di cancellazione dentro la home del
cliente. E resta una cache: un secondo giro dell'installer la ritrova e non riscarica le wheel.
Perché non
<install_dir>/.pip-cache, un livello più su: l'undo di 1.9 CloneOdooRepo rimuoveinstall_dirsolo se vuota. Una cache lì la bloccherebbe — il residuo si sposterebbe di un livello invece di sparire.
Copre pip, non tutto. La prima installazione arrivata in fondo in CI ha mostrato che
/opt/odoo/.cacherinasce comunque: nella home dell'utenteodooscrivono ancheodoo-bine il servizio (fontconfig, e ilselfcheckdipipfino alla 23, che ignora--cache-dir). Inseguire i produttori è una battaglia che si perde; la copertura generale è 1.3b SetupCacheDir, che possiede la directory. Questo--cache-dirresta perché tiene comunque fuori dalla home le centinaia di MB di wheel.
- Tutte le install via
sudo -u odoo <venv>/bin/pip(privilegio minimo), con--cache-dirnel venv. - Snapshot serializza solo un flag "installato" per il riepilogo — non guida alcun undo.
- Test: undo no-op (nessuna disinstallazione, la rimozione pip è di 1.10), sequenza gevent/Cython in
ordine,
requirements.txtmancante → errore, estrazione/filtro gevent puri.
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: