Current deployed version (roko-backup.py) after refactoring from bash to Python. Generated via OpenCode (kimi-k2.7-code). Includes: - rclone streaming progress (log every 5% or 30s) - RotatingFileHandler (max 1MB, 5 backups) - LockFile for concurrent run prevention - Yandex Cloud upload with NO_PROXY bypass - Also includes comparison versions from mimo-v2.5-pro and kimi-k2.7-code
95 lines
4.7 KiB
Markdown
95 lines
4.7 KiB
Markdown
# Refactoring №2: roko-backup.py — улучшенная версия
|
||
|
||
## Исходный код
|
||
`/home/openclaw/.openclaw/scripts/roko-backup.py` (текущая версия — 8 классов, 380 строк)
|
||
|
||
## ✅ Сохранить
|
||
- Архитектуру (конвейер: Config → LockFile → Collector → Archiver → Uploader → Verifier → Cleaner → Reporter → BackupPipeline)
|
||
- Python 3.10+, только stdlib + rclone subprocess
|
||
- argparse (--config, --dry-run, --verbose)
|
||
- LockFile (защита от параллельных запусков)
|
||
- NO_PROXY для Yandex Cloud в subprocess env
|
||
- Exponential backoff (10s, 30s, 60s) на retry
|
||
|
||
## 🆕 Новый функционал
|
||
|
||
### 1. Streaming rclone progress
|
||
- Сейчас: `subprocess.run(capture_output=True)` — ждём завершения, потом показываем вывод
|
||
- Надо: `subprocess.Popen` с построчным чтением stderr в реальном времени
|
||
- rclone с `--progress` пишет progress строки в stderr
|
||
- **Формат вывода в логах:**
|
||
```
|
||
2026-07-07 10:30:15 INFO Upload: 15% (95 MiB / 622 MiB) @ 2.1 MiB/s
|
||
```
|
||
- Парсить `Transferred: ... MiB / ... MiB, ...%` из rclone stderr
|
||
- Не flood-ить лог — логировать прогресс раз в 30 секунд или при каждом новом проценте (кратном 5%)
|
||
- По завершении показать финальную статистику (скорость, время)
|
||
|
||
### 2. Ротация логов
|
||
- Лог-файл: `/home/openclaw/backups/roko-backup.log` (НА ДИСКЕ, не в /tmp!)
|
||
- Максимальный размер: 1 МБ (после этого ротация)
|
||
- Хранить: 5 последних ротированных логов (`roko-backup.log.1`, `.2`, ... `.5`)
|
||
- Использовать `logging.handlers.RotatingFileHandler` из stdlib
|
||
- При `--verbose` — дублировать в stdout тоже (для отладки вручную)
|
||
|
||
### 3. Улучшения кода
|
||
- **Type hints** полные, включая `collections.abc.Generator`, `ContextManager`
|
||
- **Меньше повторений** — RCLONE_ENV дублируется в Uploader/Verifier/Cleaner, вынести в конфиг или хелпер
|
||
- **Документация** — docstrings по PEP 257 на английском (краткие, по делу)
|
||
- **Error handling** — отдельный класс BackupError(Exception) вместо голых return 3
|
||
- **Cleanup гарантированный** — даже при падении архиватор должен подчищать staging
|
||
|
||
## Структура (сохраняем конвейер, улучшаем детали)
|
||
|
||
```python
|
||
class BackupError(Exception): ...
|
||
class LockError(BackupError): ...
|
||
|
||
@dataclass(frozen=True)
|
||
class Config:
|
||
# добавляем log_file: Path, max_log_size: int, max_log_backups: int
|
||
...
|
||
|
||
class LockFile(ContextManager): # добавить __enter__/__exit__
|
||
...
|
||
|
||
class Collector:
|
||
EXCLUDE_PATTERNS = (...) # можно сделать конфигурируемым в Config
|
||
...
|
||
|
||
class Archiver:
|
||
# архивирует через tarfile (не subprocess tar)
|
||
...
|
||
|
||
class Uploader:
|
||
# subprocess.Popen + streaming stderr для progress
|
||
UPLOAD_PROGRESS_INTERVAL = 30 # секунд между логами прогресса
|
||
PROGRESS_PERCENT_STEP = 5 # логировать каждые N процентов
|
||
...
|
||
|
||
class Verifier: ...
|
||
class Cleaner: ...
|
||
class Reporter: ...
|
||
class BackupPipeline: ...
|
||
|
||
def setup_logging(verbose, log_file, max_size, max_backups): ...
|
||
def main(): ...
|
||
```
|
||
|
||
## Требования к качеству
|
||
- `python3 -c "import ast; ast.parse(open('roko-backup.py').read())"` — OK
|
||
- `--dry-run --verbose` — работает, показывает все источники
|
||
- Без аргументов — полный цикл без ошибок
|
||
- `--config X` — работает
|
||
- `python3 -c "from roko_backup import Config, BackupPipeline"` — импортируемый модуль
|
||
|
||
## Файлы
|
||
- Пишем: `/home/openclaw/.openclaw/scripts/roko-backup.py` (перезаписать)
|
||
- Сохраняем: `roko-backup.py.bak` (текущая версия)
|
||
- README: обновить `/home/openclaw/.openclaw/scripts/README.md` (добавить про логи и streaming)
|
||
|
||
## Модели для OpenCode
|
||
- **Основная:** mimo-v2.5-pro (OpenCode Go)
|
||
- **Сравнение:** kimi-k2.7-code (OpenCode Go)
|
||
- **Запасные при зависании (до 3 попыток):** minimax-m3 (OpenCode Go), deepseek-v4-pro (OpenCode Go)
|