229 lines
7.6 KiB
Markdown
229 lines
7.6 KiB
Markdown
|
|
# Vault - Project Documentation
|
||
|
|
|
||
|
|
## About
|
||
|
|
|
||
|
|
Resilientní úložiště s redundantní strukturou. Program spravuje 2+ kontejnerů (disk image souborů), které obsahují:
|
||
|
|
- Souborovou strukturu přístupnou přes FUSE mount
|
||
|
|
- Metadata o lokacích ostatních kontejnerů
|
||
|
|
- Informace o verzích
|
||
|
|
- Synchronizované kopie stejného obsahu napříč všemi kontejnery
|
||
|
|
|
||
|
|
**Klíčový princip:** Aplikace běží jako tray daemon, mountuje vault jako běžnou složku. Uživatel pracuje se svým oblíbeným file managerem (Nautilus, Dolphin, Thunar). Aplikace na pozadí zajišťuje synchronizaci mezi replikami.
|
||
|
|
|
||
|
|
**Platforma:** Pouze Linux (FUSE mount). Windows/Mac možná později.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Specifikace
|
||
|
|
|
||
|
|
### Formát úložiště
|
||
|
|
- **Kontejner:** Raw disk image (.vault) se sparse alokací
|
||
|
|
- **Filesystem:** exFAT (cross-platform, bez 4GB limitu)
|
||
|
|
- **Přípona:** `.vault`
|
||
|
|
- **Velikost:** Uživatel zadá při vytvoření
|
||
|
|
- **Struktura uvnitř:**
|
||
|
|
```
|
||
|
|
myvault.vault (sparse soubor)
|
||
|
|
└── [exFAT filesystem]
|
||
|
|
├── .vault/
|
||
|
|
│ ├── manifest.json
|
||
|
|
│ └── lock # Lock soubor pro exkluzivní přístup
|
||
|
|
├── documents/
|
||
|
|
│ └── file.txt
|
||
|
|
└── photos/
|
||
|
|
└── image.jpg
|
||
|
|
```
|
||
|
|
|
||
|
|
### Mount
|
||
|
|
- **Metoda:** udisksctl (loop device + mount, bez root)
|
||
|
|
- **Mount point:** Automatický (udisksctl) nebo uživatelem zvolený
|
||
|
|
- **Exkluzivní přístup:** Lock soubor s fcntl - pouze jedna instance může mít vault otevřený
|
||
|
|
|
||
|
|
### Čitelnost bez aplikace (bez Vault app)
|
||
|
|
- `sudo mount -o loop myvault.vault /mnt/vault`
|
||
|
|
|
||
|
|
### Resize
|
||
|
|
- Při zaplnění: varování uživateli (notifikace při >90% využití)
|
||
|
|
- Uživatel rozhodne o zvětšení přes GUI dialog
|
||
|
|
|
||
|
|
### Umístění kontejnerů
|
||
|
|
- Kdekoli s RW přístupem (různé disky, síťová umístění, USB, cloud)
|
||
|
|
- Každý kontejner obsahuje metadata s cestami k ostatním kontejnerům
|
||
|
|
|
||
|
|
### Synchronizace
|
||
|
|
- **Úroveň:** Jednotlivé soubory (NE celé .vault obrazy)
|
||
|
|
- **Interní Python implementace** (bez rsync)
|
||
|
|
- **Hash** (SHA-256) pro detekci změn obsahu
|
||
|
|
- **Timestamp** pro určení master verze (novější vyhrává)
|
||
|
|
- Předpoklad: většinou budou všechny kontejnery dostupné → synchronní zápis
|
||
|
|
- Fallback: při nedostupnosti některého kontejneru se při reconnectu synchronizuje podle timestampu
|
||
|
|
- Chunked copy s progress callbackem pro velké soubory
|
||
|
|
- **Background sync:** Změny se detekují přes inotify/watchdog a propagují automaticky
|
||
|
|
|
||
|
|
**Jak sync funguje:**
|
||
|
|
1. Všechny repliky jsou mountnuté současně (každá do jiného temp mount pointu)
|
||
|
|
2. Uživatel vidí pouze hlavní mount point
|
||
|
|
3. Při změně souboru → soubor se zkopíruje do všech mountnutých replik
|
||
|
|
4. Při reconnect nedostupné repliky → porovnání manifestů → kopírování pouze změněných souborů
|
||
|
|
|
||
|
|
### GUI
|
||
|
|
- **Framework:** PySide6
|
||
|
|
- **Typ:** System tray aplikace (daemon)
|
||
|
|
- **Jazyk UI:** Čeština
|
||
|
|
- **Uživatel pracuje:** Se standardním file managerem OS
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## GUI - System Tray App
|
||
|
|
|
||
|
|
### Tray ikona - stavy
|
||
|
|
| Ikona | Stav |
|
||
|
|
|-------|------|
|
||
|
|
| Zelená | Vault otevřen, vše synchronizováno |
|
||
|
|
| Modrá | Synchronizace probíhá |
|
||
|
|
| Žlutá | Některé repliky nedostupné |
|
||
|
|
| Červená | Chyba (vault zaplněn, sync selhala, atd.) |
|
||
|
|
| Šedá | Žádný vault otevřen |
|
||
|
|
|
||
|
|
### Tray menu
|
||
|
|
```
|
||
|
|
My Vault (3/3 replik online) [status]
|
||
|
|
────────────────────────────────────
|
||
|
|
Otevřít složku [otevře mount point v file manageru]
|
||
|
|
────────────────────────────────────
|
||
|
|
Vytvořit nový vault...
|
||
|
|
Otevřít vault...
|
||
|
|
Zavřít vault
|
||
|
|
────────────────────────────────────
|
||
|
|
Přidat repliku...
|
||
|
|
Spravovat repliky...
|
||
|
|
────────────────────────────────────
|
||
|
|
Synchronizovat
|
||
|
|
Zvětšit vault...
|
||
|
|
────────────────────────────────────
|
||
|
|
Ukončit
|
||
|
|
```
|
||
|
|
|
||
|
|
### Dialogy
|
||
|
|
- **Nový vault:** Název, cesta, velikost (s quick buttony 1/5/10/50 GB)
|
||
|
|
- **Otevřít vault:** Výběr .vault souboru
|
||
|
|
- **Spravovat repliky:** Tabulka replik se statusem a tlačítkem pro odebrání
|
||
|
|
- **Zvětšit vault:** Aktuální využití, nová velikost
|
||
|
|
- **Sync progress:** Progress bar, aktuální soubor, log, cancel
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Architektura
|
||
|
|
|
||
|
|
```
|
||
|
|
Vault/
|
||
|
|
├── Vault.py # Entry point
|
||
|
|
├── pyproject.toml # Poetry konfigurace
|
||
|
|
├── src/
|
||
|
|
│ ├── core/ # Business logika (BEZ UI importů!)
|
||
|
|
│ │ ├── vault.py # Hlavní třída Vault - orchestrace
|
||
|
|
│ │ ├── container.py # Mount/unmount přes udisksctl
|
||
|
|
│ │ ├── image_manager.py # Vytváření/resize sparse .vault souborů
|
||
|
|
│ │ ├── lock.py # Exkluzivní přístup (fcntl)
|
||
|
|
│ │ ├── sync_manager.py # Synchronizace mezi replikami
|
||
|
|
│ │ ├── file_watcher.py # watchdog/inotify pro detekci změn
|
||
|
|
│ │ ├── file_sync.py # Kopírování souborů s progress callback
|
||
|
|
│ │ ├── manifest.py # Metadata - lokace, verze, soubory
|
||
|
|
│ │ └── file_entry.py # Reprezentace souboru (path, hash, timestamp)
|
||
|
|
│ └── ui/
|
||
|
|
│ ├── tray_app.py # System tray aplikace + menu
|
||
|
|
│ ├── notifications.py # System notifikace (notify-send)
|
||
|
|
│ └── dialogs/
|
||
|
|
│ ├── new_vault.py
|
||
|
|
│ ├── open_vault.py
|
||
|
|
│ ├── manage_replicas.py
|
||
|
|
│ ├── resize_vault.py
|
||
|
|
│ └── sync_progress.py
|
||
|
|
└── tests/
|
||
|
|
├── test_file_entry.py
|
||
|
|
├── test_manifest.py
|
||
|
|
├── test_lock.py
|
||
|
|
├── test_image_manager.py
|
||
|
|
├── test_container.py
|
||
|
|
├── test_file_watcher.py
|
||
|
|
├── test_file_sync.py
|
||
|
|
├── test_sync_manager.py
|
||
|
|
└── test_vault.py
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Metadata struktura (.vault/manifest.json)
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"vault_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
|
|
"vault_name": "My Vault",
|
||
|
|
"version": 1,
|
||
|
|
"created": "2026-01-28T10:30:00Z",
|
||
|
|
"last_modified": "2026-01-28T15:45:00Z",
|
||
|
|
"image_size_mb": 10240,
|
||
|
|
"locations": [
|
||
|
|
{
|
||
|
|
"path": "/mnt/disk1/myvault.vault",
|
||
|
|
"last_seen": "2026-01-28T15:45:00Z",
|
||
|
|
"status": "active"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"path": "/mnt/usb/myvault.vault",
|
||
|
|
"last_seen": "2026-01-28T15:45:00Z",
|
||
|
|
"status": "active"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"files": [
|
||
|
|
{
|
||
|
|
"path": "documents/file.txt",
|
||
|
|
"hash": "sha256:e3b0c44...",
|
||
|
|
"size": 1234,
|
||
|
|
"created": "2026-01-28T10:30:00Z",
|
||
|
|
"modified": "2026-01-28T14:20:00Z"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Závislosti
|
||
|
|
|
||
|
|
### Python (Poetry)
|
||
|
|
```
|
||
|
|
PySide6>=6.10.1 # GUI framework
|
||
|
|
pyfuse3>=3.4.2 # FUSE binding (nepoužito - udisksctl místo FUSE)
|
||
|
|
watchdog>=6.0.0 # File system events (inotify)
|
||
|
|
loguru>=0.7.3 # Logging
|
||
|
|
python-dotenv>=1.2.1 # Environment variables
|
||
|
|
|
||
|
|
# Dev
|
||
|
|
pytest>=9.0.2
|
||
|
|
pytest-cov>=7.0.0
|
||
|
|
ruff>=0.14.14
|
||
|
|
mypy>=1.19.1
|
||
|
|
```
|
||
|
|
|
||
|
|
### Systémové závislosti (Linux)
|
||
|
|
```bash
|
||
|
|
sudo apt install udisks2 exfatprogs
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Aktuální stav
|
||
|
|
|
||
|
|
**Fáze 1-5: Dokončeno**
|
||
|
|
|
||
|
|
- Kompletní core logika (vault, container, image_manager, manifest, file_entry, lock, sync_manager, file_watcher, file_sync)
|
||
|
|
- System tray GUI s menu, notifikacemi, dialogy
|
||
|
|
- Správa replik (přidání, odebrání, tabulka se statusy)
|
||
|
|
- Automatická detekce dostupnosti replik (30s polling) s auto-reconnect
|
||
|
|
- Resize vault přes GUI dialog
|
||
|
|
- Detekce zaplnění s varováním při >90%
|
||
|
|
- Graceful shutdown (SIGINT/SIGTERM)
|
||
|
|
- 130 testů, vše passing
|
||
|
|
- ruff + mypy clean
|