# Madagascar Cluster Projects

Acest director este punctul unic de lucru pentru proiectele cluster-level actuale si viitoare.

## Baza de referinta

Workflow-ul de install, uninstall si reinstall documentat aici este bazat pe implementarea cea mai completa existenta in `autoNAS`.

Referinte principale:
- `cluster/projects/autoNAS/README.md`
- `cluster/projects/autoNAS/DEVELOPMENT.md`
- `cluster/projects/autoNAS/scripts/install.sh`
- `cluster/projects/autoNAS/scripts/autonas-uninstall.sh`

Observatie importanta:
- `autoNAS` confirma workflow-ul corect de uninstall-inainte-de-reinstall si curatare a fisierelor orfane
- `autoNAS` nu este inca aliniat complet la noua regula de locatie pentru comenzi operator-facing, deoarece instaleaza in prezent in `/usr/local/bin`
- pentru proiectele noi, regula ramane `/usr/local/sbin`; `autoNAS` trebuie tratat ca precedent functional pentru workflow, nu ca standard final de layout

## Namespace de organizatie

Pentru claritate si evitarea coliziunilor intre proiecte, toate locatiile standard trebuie namespaced cu identificatorul de organizatie:

- `xdev`

Regula generala este:
- folosim `<project-name>` pentru identitatea proiectului
- folosim `xdev` in calea de instalare pentru fisiere interne, configuratie, date si documentatie

## Reguli generale

- Toate proiectele noi se creeaza sub `cluster/projects/<project-name>`.
- Proiectele se deschid si se mentin din `cluster`, pentru a reduce divergenta intre workspace-uri si duplicarea documentatiei sau scripturilor.
- Fiecare proiect trebuie sa aiba cel putin:
  - `README.md`
  - script de instalare
  - script de dezinstalare
  - instructiuni de operare si upgrade

## Locatii well-known obligatorii

Instalarile trebuie sa foloseasca locatii predictibile si stabile:

- executabile si scripturi operator-facing: `/usr/local/sbin`
- binare sau scripturi interne ale proiectului: `/usr/local/lib/xdev/<project-name>`
- documentatie instalata pe host: `/usr/local/share/doc/xdev/<project-name>`
- fisiere de configurare persistente: `/etc/xdev/<project-name>`
- environment defaults: `/etc/default/xdev-<project-name>`
- unitati systemd: `/etc/systemd/system`
- stare persistenta si date operationale: `/var/lib/xdev/<project-name>`
- cache temporar: `/var/cache/xdev/<project-name>` daca este necesar
- loguri dedicate pe disc, daca proiectul chiar le scrie in fisier: `/var/log/xdev/<project-name>`

Regula practica:
- daca un operator trebuie sa ruleze comanda direct, ea merge in `/usr/local/sbin`
- daca fisierul este suport intern pentru proiect, el merge in `/usr/local/lib/xdev/<project-name>`
- daca fisierul este documentatie instalata local pentru host, el merge in `/usr/local/share/doc/xdev/<project-name>`
- daca fisierul reprezinta configuratie editabila, el merge in `/etc/xdev/<project-name>` sau `/etc/default/xdev-<project-name>`
- daca fisierul reprezinta stare, baza locala, lock, snapshot sau alta data operationala, el merge in `/var/lib/xdev/<project-name>`

## Locatia standard pentru scripturile de dezinstalare

Locatia standard canonica pentru scriptul de dezinstalare instalat pe host este:

- `/usr/local/lib/xdev/<project-name>/uninstall.sh`

Motivatie:
- uninstall-ul este in primul rand parte din mecanismul intern de lifecycle al proiectului
- trebuie sa poata fi apelat de installer pentru cleanup automat inainte de reinstall
- trebuie versionat impreuna cu restul fisierelor interne ale proiectului
- evita aglomerarea inutila a `/usr/local/sbin` cu scripturi care nu sunt folosite frecvent in operare zilnica

Regula de naming:
- scriptul canonic instalat pe host se numeste `uninstall.sh`
- directorul proiectului da contextul complet: `/usr/local/lib/xdev/<project-name>/uninstall.sh`

Expunere optionala pentru operator:
- daca vrem o comanda manuala simpla si predictibila, se poate instala un wrapper sau symlink in:
  - `/usr/local/sbin/xdev-<project-name>-uninstall`
- acest wrapper trebuie sa apeleze scriptul canonic din `/usr/local/lib/xdev/<project-name>/uninstall.sh`
- wrapperul din `/usr/local/sbin` este optional; scriptul canonic din `/usr/local/lib/xdev/<project-name>/` este obligatoriu

## Instalare si dezinstalare

- Orice instalare trebuie sa fie insotita de un script de dezinstalare livrat de acelasi proiect.
- Scriptul de dezinstalare instalat pe host trebuie sa existe la `/usr/local/lib/xdev/<project-name>/uninstall.sh`.
- Scriptul de dezinstalare trebuie sa elimine toate fisierele instalate de proiect:
  - executabile
  - fisiere din `/usr/local/lib/xdev/<project-name>`
  - documentatie din `/usr/local/share/doc/xdev/<project-name>`
  - unitati systemd
  - fisiere de configurare generate de proiect, daca sunt gestionate exclusiv de el, din `/etc/xdev/<project-name>` sau `/etc/default/xdev-<project-name>`
  - directoare de stare, date sau cache create de proiect, daca nu contin date care trebuie pastrate explicit, din `/var/lib/xdev/<project-name>` sau `/var/cache/xdev/<project-name>`
- Scopul este prevenirea fisierelor orfane si a reinstalarilor peste artefacte ramase din versiuni anterioare.

## Regula de reinstall

- Toate reinstalarile se fac numai dupa dezinstalare completa.
- Dezinstalarea se face numai cu scriptul original de uninstall al proiectului, nu prin stergeri manuale partiale.
- Fluxul obligatoriu este:

```text
uninstall -> verificare curatare -> install
```

- Nu se face reinstall direct peste o instalare existenta, chiar daca pare functionala.
- Daca scriptul de uninstall lipseste, instalarea proiectului este incompleta si trebuie corectata inainte de orice upgrade sau reinstall.

## Cerinte pentru proiectele noi

Fiecare proiect nou trebuie sa includa explicit:

1. un `install` care foloseste locatiile well-known
2. un `uninstall` care inverseaza complet instalarea
3. un `README.md` cu:
   - layout-ul fisierelor instalate
   - comenzile de instalare
   - comenzile de dezinstalare
   - pasii de reinstall
   - locatia uninstall-ului instalat pe host: `/usr/local/lib/xdev/<project-name>/uninstall.sh`
   - locatiile pentru configuratie, documentatie si date
4. daca exista systemd:
   - `daemon-reload` la install si uninstall
   - enable/disable/stop clar definite
   - la deployment, serviciile si timer-ele care trebuie sa ramana active se pornesc cu `systemctl enable --now`, nu doar cu `enable`

## Aplicare la proiectele existente

Proiectele deja mutate sub `cluster/projects/` trebuie aliniate progresiv la aceste reguli.

Prioritati:
- confirmarea unui script de uninstall pentru fiecare proiect
- standardizarea instalarii in `/usr/local/sbin` si `/usr/local/lib/xdev/<project-name>`
- eliminarea reinstalarilor facute peste fisiere existente

## Lectii confirmate in autoNAS

Problemele deja identificate si rezolvate in `autoNAS`, care trebuie considerate reguli pentru proiectele viitoare:

- reinstalarile peste versiuni vechi lasa fisiere orfane daca nu exista cleanup explicit
- instalarea trebuie sa poata rula cleanup de versiune anterioara inainte de install
- uninstaller-ul trebuie instalat pe host pentru a permite cleanup corect la upgrade sau reinstall
- uninstall-ul trebuie sa curete agresiv fisierele istorice ramase din versiuni mai vechi
- config-ul utilizatorului trebuie pastrat cand contine date reale, nu sters orbeste
- serviciile systemd trebuie oprite, dezactivate, sterse si urmate de `daemon-reload`
- la deployment, un serviciu necesar in productie nu trebuie lasat doar `enabled`; se foloseste `enable --now` pentru a evita deploy-uri cu servicii instalate dar nepornite
- unele resurse necesita cleanup manual explicit daca pot contine date operationale, de exemplu exports NFS sau mount points active

Fluxul validat de `autoNAS` este:

```text
detect previous install -> run original uninstall -> clean orphan files -> install new version -> preserve user data where required
```

## Regula operationala

Cand se modifica un proiect existent sau se adauga unul nou, se actualizeaza si documentatia proiectului astfel incat procedura de:

- install
- uninstall
- reinstall

sa fie explicita, repetabila si fara artefacte ramase pe host.

## Deploy cluster-wide

Pentru rollout final pe cluster nu facem deploy nod cu nod manual daca proiectul este destinat cluster-wide.

Regula practica este:
- fiecare proiect trebuie sa pastreze si varianta pe un singur nod pentru development si testing
- pentru rollout cluster-wide se foloseste orchestratorul comun din radacina:
  - `cluster/scripts/deploy-project.sh <project-name>`

Sursa de adevar pentru noduri:
- `cluster/cluster-context/madagascar.json`

Exemple:

```bash
./scripts/deploy-project.sh pve-guests-state
./scripts/deploy-project.sh pve-net-hang-watchdog
./scripts/deploy-project.sh pve-backup-scheduler
./scripts/deploy-project.sh autoNAS
./scripts/deploy-project.sh pve-guests-state install --node ebony
```

Cerinta pentru proiecte:
- proiectele noi trebuie sa ofere fie `setup.sh`, fie `deploy.sh`
- `setup.sh` ramane entrypoint-ul standard pentru install/uninstall pe un singur nod
- orchestratorul comun decide nodurile pe baza `cluster-context/madagascar.json` si ruleaza proiectul pe toate tintele selectate
