Skip to content

1.2 Step | CreateOdooUser

Omisen edited this page Jul 26, 2026 · 5 revisions

Crea l'utente di sistema odoo (useradd --system), il suo gruppo dedicato, e rende odoo:odoo l'owner della home /opt/odoo. Reversibile. Vive in src/steps/create_odoo_user.rs. Segue il modello di 1.1 PrepareOptRoot su una risorsa più ricca (utente + gruppo + ownership).

Port di create_odoo_user / _verify_odoo_user_homedir di lib/system.sh.


Ciclo di vita

Fase Comportamento
snapshot rileva due cose indipendenti: (1) l'utente esiste già? → Preexisting/Untracked; (2) l'owner corrente di /opt/odoo prima del nostro chown (salvato per l'undo)
run Preexisting → skip useradd, nessun chown aggressivo; assente → useradd + chown odoo:odoo esplicito + chmod 0750, poi CreatedByUs. dry_run → solo log
undo solo CreatedByUs: userdel senza -r + groupdel (best-effort) + ripristino owner originale della home. Preexisting/Untracked → no-op

Argomenti di useradd (privilegio minimo, come nel Bash):

useradd --system --create-home --home-dir /opt/odoo --user-group --shell /bin/false odoo

--shell /bin/false → nessuna shell interattiva; --system → UID < 1000 senza password; --user-group → gruppo dedicato odoo.


Il coordinamento con PrepareOptRoot (il punto delicato)

È il primo caso in cui due step insistono sullo stesso artefatto (/opt/odoo). Uno lo crea (PrepareOptRoot), l'altro ne diventa owner (CreateOdooUser). La regola che scioglie il nodo:

Ogni step possiede la rimozione di ciò che ha creato.

Conseguenze concrete:

  • CreateOdooUser.undo esegue userdel senza -r: NON rimuove la home. Se usasse -r, cancellerebbe /opt/odoo, che è di competenza di PrepareOptRoot.
  • la home la rimuove PrepareOptRoot.undo, che gira dopo nell'ordine inverso (SetupLogDir → CreateOdooUser → PrepareOptRoot).
  • se la home era Preexisting (non nostra) e il nostro chown ne ha cambiato l'owner, undo ripristina l'owner originale salvato in snapshot — così non resta di proprietà di un utente che stiamo cancellando.

Regola invariante di CLAUDE.md: mai userdel -r su un utente Preexisting. Qui l'undo agisce solo su utenti CreatedByUs, e comunque senza -r. Un utente preesistente non viene mai toccato.

Questo schema — proprietà della rimozione + ordine inverso — è il modello per i casi futuri in cui due step condividono un artefatto (es. ruolo che possiede il DB in PostgreSQL).


Il confine testabile SystemOps

I comandi privilegiati (useradd/userdel/groupdel/chown/chmod) non sono chiamati direttamente: passano da un trait SystemOps memorizzato dentro lo step. Così il trait Step e il motore non cambiano.

Impl Uso
RealSystemOps produzione: useradd via Command, chown/mkdir via nix+std::fs
MockSystemOps (test) registra quale operazione verrebbe eseguita e con quali argomenti, senza root

I test verificano la logica di decisione (ramo PreState, argomenti esatti di useradd, userdel senza -r, ripristino owner) senza eseguire nulla e senza toccare il sistema.


Snapshot persistito

struct CreateUserSnapshot {
    user_prestate: PreState,               // Preexisting | Untracked | CreatedByUs
    home_original_owner: Option<OwnerId>,  // owner della home prima del nostro chown
}

Serializzato (snapshot_value) e persistito: al resume/rollback si sa se l'utente è nostro e a chi ripristinare la home.


Note di design

  • Non-aggressività sui preesistenti: se l'utente c'era già, niente useradd e niente chown — non è nostro da riconfigurare.
  • useradd non ri-chowna una home preesistente: il chown odoo:odoo è esplicito dopo la creazione (come _verify_odoo_user_homedir nel Bash).
  • Tutti i passi dell'undo sono best-effort: un fallimento logga warn e prosegue, senza bloccare la pulizia degli altri step.
  • Test: CreatedByUs (useradd+chown / userdel senza -r), Preexisting (mai toccato), ripristino owner su home preesistente, dry_run (nessuna operazione).

Clone this wiki locally