Files
Roko a88b2604a1 Initial: Roko Backup Script v2 — Python rewrite with streaming progress & log rotation
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
2026-07-07 11:27:02 +07:00

4.7 KiB
Raw Permalink Blame History

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

Структура (сохраняем конвейер, улучшаем детали)

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)