# chj.disks – Disk Manager (správa disků vzdálených Linux serverů) Vestavěný plugin pro grafickou správu blokových zařízení vzdáleného Linux serveru přes existující SSH relaci Core, podobně jako GParted. Na serveru není potřeba grafické prostředí. Plugin je jen UI (vlastní okno a partition); veškerou logiku provádí Core služba `src/main/disks/diskService.js` s pevným skriptem `src/main/disks/remoteDisks.sh`. Neexistuje obecné spouštění příkazů ani obecný root exec. ## Architektura | Část | Soubor | Odpovědnost | |---|---|---| | Manifest / UI | `src/main/firstPartyPlugins/chj.disks/0.0.1/` (`manifest.json`, `ui/index.html`, `ui/index.js`, `ui/i18n.js`, `ui/styles.css`) | mapa disků, tabulka, kontextové menu, dialogy, fronta, kontrola plánu, monitor úloh, SMART; CS/DE/EN | | Inventura (model) | `src/main/disks/inventory.js` | graf zařízení ze sysfs (holders/slaves), obohacený o lsblk/blkid/sfdisk/LVM/cryptsetup; vrstvy disk → oddíl → LUKS → PV → VG → LV → FS; volné místo GPT/MBR | | Plánovač | `src/main/disks/planner.js` | validace a simulace fronty operací, generování whitelistovaných kroků, návrhy automatického rozšíření | | Core služba | `src/main/disks/diskService.js` | detekce platformy, inspect, plán (vázaný na identitu serveru, TTL 30 min, jednorázový), apply s novým ověřením, úlohy, SMART | | Vzdálený helper | `src/main/disks/remoteDisks.sh` | POSIX sh (dash/bash/BusyBox ash): inspect, smart, job-start/job-run/job-status/job-list, kroky | | IPC | `src/main/plugins/pluginRuntime.js`, `src/preload/pluginPreload.js` | `plugin:disks:inspect/smart/jobs/jobStatus` (`disks.read`), `plan/autoExpand/cancelPlan/apply` (`disks.manage`); Plugin API 1.6.0 | ## Bezpečnostní pravidla - Čtení běží bez roota (sysfs, lsblk, blkid cache, mountinfo, df); inventura bez roota je označena jako neúplná. Plné údaje (tabulky oddílů, LVM, LUKS, velikosti FS) a všechny změny jdou přes `PrivilegedExecutor` (root/sudo, heslo jen přes stdin; volitelně jen v paměti pro relaci kvůli sledování úloh). - Každá operace je validována v Core i znovu ve skriptu (zařízení, čísla, štítky `[A-Za-z0-9._-]`, přípojné body jen `/mnt` a `/media`). Řádky plánu nesmí obsahovat glob ani uvozovky. - Nikdy automaticky: odpojení systémových přípojných bodů, swapoff, zavření LUKS, deaktivace LVM, restart, instalace balíčků, `umount -f/-l`, `btrfs check --repair`. Spouštěcí oddíly (BIOS boot, ESP) disku s běžícím systémem nelze smazat ani formátovat. Úložiště hostitele Proxmox a disky hostů (`vm--disk-*`) jsou chráněné. - Před každou změnou: `verify-disk` (velikost + SHA-256 výpisu `sfdisk -d`), `verify-size` u LV/LUKS, záloha metadat tabulky oddílů do `/var/lib/chj-server-manager/disks/backups` (posledních 50). **Záloha tabulky není záloha dat.** - Apply znovu načte inventuru a plán musí vyjít krok za krokem stejně; jinak `DISKS_PLAN_STALE` bez jakékoli změny. Plán je jednorázový; ID úlohy na serveru nelze spustit podruhé (`DISKS_JOB_EXISTS`). ## Úlohy a výpadky SSH - `job-start` uloží plán a kopii helperu do `/var/lib/chj-server-manager/disks/jobs//` (0700) a spustí běh odděleně od SSH: `systemd-run` (transient unit `chj-disks-`), bez systemd `setsid` (Alpine/OpenRC). - Stav `state`, `step`, `log`, `error`, `pid`; po reconnectu UI načte stav a pokračování logu. `running` bez živého procesu = **unknown** (nikdy se nespouští znovu). Jediný globální zámek `/run/chj-disks.lock` brání souběžným diskovým úlohám na serveru (`DISKS_BUSY`). Běžící úlohu UI nepřerušuje. - Procenta se nezobrazují (nástroje nedávají spolehlivý průběh): krok k z n + neurčitý indikátor + skutečný log. - Pokud jádro nepřevezme novou geometrii oddílu (`blockdev --rereadpt`, jinak `partx`), úloha skončí stavem `pending-reboot` a další kroky neprovede. ## Podporované operace | Oblast | Stav | |---|---| | GPT/MBR tabulka, nový/smazaný oddíl (MBR jen primární), název (GPT), příznaky boot/legacy_boot a typové (esp, bios-boot, lvm, raid, swap, basic-data) | implementováno | | Formátování ext4, XFS, Btrfs, FAT32, NTFS, swap (podle nástrojů), štítky | implementováno | | ext4: zvětšení online/offline; zmenšení jen odpojené: e2fsck -f -p, minimum `resize2fs -P` + rezerva max(10 %, 128 MiB), FS → oddíl → `e2fsck -n` | implementováno, ověřeno na VM | | XFS: zvětšení jen připojené (`xfs_growfs`); zmenšení odmítnuto s vysvětlením (migrace dat) | implementováno, ověřeno | | Btrfs: zvětšení/zmenšení připojeného jednozařízeného FS s kontrolou alokace | implementováno, na VM neověřeno | | NTFS: `ntfsresize` s dry-run | implementováno, na VM neověřeno | | swap: změna oddílu jen u neaktivního swapu, `mkswap` se stejným UUID/štítkem | implementováno, na VM neověřeno | | LVM: PV resize, LV extend (+FS), LV reduce jen ext4 odpojené jako pokročilá operace; thin pool/thin volume jen zobrazení | implementováno; auto řetězec ověřen | | LUKS: resize mapování jen s klíčem v dm-crypt; klíč v keyringu (vyžaduje heslo) = odmítnuto; zmenšení nikdy | implementováno, ověřeno | | Automatické rozšíření (oddíl s volným místem za ním, FS menší než zařízení, PV, volné místo VG), přesun záložní GPT hlavičky | implementováno, ověřeno | | Kontrola FS (jen čtení / oprava), mount/unmount (dočasně, bez fstab) | implementováno | | SMART/NVMe (`smartctl -j`, `nvme smart-log`) | implementováno; na VM jen stav „nedostupné“ | | Přesun/kopírování oddílů, FAT resize, rozšířené/logické MBR oddíly, RAID/ZFS změny | záměrně vypnuto (jen zobrazení) | | Windows/jiné platformy | jen detekce a srozumitelné odmítnutí; žádné Linux nástroje se nespouštějí | ## Testy - `test/disksPlanner.test.js` (23): model, plánovač, návrhy a kontrakty služby (prázdný GPT, více oddílů, ext4 s/bez volného místa, online/offline ext4, XFS, LVM, LUKS+ext4, LUKS+LVM, systémový root, zvětšený virtuální disk, bez sudo, chybějící nástroje, stale plán, SMART nedostupný, souběh, Windows). - `test/disksVmIntegration.test.js` (CHJ_VM_*; destruktivní část jen s `CHJ_DISKS_WRITE=1`, výhradně loop obrazy `/var/tmp/chj-disks-test/chjtest-*.img` z `test/fixtures/disks/loopFixture.sh`, ověřované před každou změnou; Proxmox jen read-only). - `test/disksWindowsIntegration.test.js` (CHJ_DISKS_WINDOWS_*), `scripts/smokeDisksUi.js` (Electron UI).