Files

77 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 📑 PRODUCT REQUIREMENTS DOCUMENT (PRD)## 1. Цели проекта
- Основная цель: Создать легковесную CLI-утилиту на Rust для централизованного деплоя хобби-проектов (Node.js, Rust) с локального ПК на слабую VPS по SSH.
- Зачем это нужно: Избежать дублирования скриптов деплоя в репозиториях, полностью разгрузить CPU слабой VPS (сборка только на ПК) и получить удовольствие от разработки пет-проекта.
## 2. Ключевые функции (Scope)
- Центральный конфиг: Все настройки всех проектов хранятся в одном локальном файле (deploy.toml).
- Локальное выполнение: Запуск команд сборки, тестов или линтеров на машине разработчика.
- Синхронизация файлов: Передача скомпилированных артефактов (папок dist, бинарников) на VPS.
- Удаленное выполнение: Запуск команд управления сервисами (pm2 restart, systemctl restart) на VPS через SSH.
- Безопасность: Использование существующего SSH-агента или приватного ключа (~/.ssh/id_rsa), никаких паролей в конфигах.
- Аварийная остановка (Fail-Fast): Если любой шаг (локальный или удаленный) падает с ошибкой, деплой немедленно прекращается.
## 3. Пользовательский сценарий (UX)
1. Разработчик находится в любой папке терминала.
2. Вводит команду: xboctploy my-node-app.
3. Утилита красиво (с логами и цветом) показывает прогресс:
- 🟢 [Local] running: npm run build... Success!
- 🔵 [SFTP] transferring dist/ to /var/www/node-app... Done!
- 🟡 [Remote] running: pm2 restart node-app... Success!
- 🎉 Deploy successful!
### Разрешение конфигурации
Утилита ищет deploy.toml по цепочке: сначала `./deploy.toml` в текущей папке,
если не найден — глобальный `~/.config/xboctploy/deploy.toml`. Локальный файл
приоритетен для простоты тестирования на конкретном проекте.
---
## 🏗️ ARCHITECTURE DECISION RECORD (ADR)## ADR-001: Выбор языка и формата конфигурации
- Решение: Разработка на Rust, формат конфигурации — TOML.
- Обоснование: Rust обеспечивает максимальную скорость запуска CLI и безопасность работы с памятью. TOML выбран как «родной» для экосистемы Rust формат (аналогично Cargo.toml), который проще читать и писать вручную, чем YAML, и он строго типизирован в отличие от JSON.
## ADR-002: Управление зависимостями (Крейты)
Для минимизации кодовой базы и сохранения легковесности утверждается следующий стек библиотек:
- clap (с feature-флагом derive) — для парсинга аргументов командной строки.
- serde + toml — для парсинга файла конфигурации в структуры Rust.
- ssh2-config + ssh2 (или async-ssh2-lite, если потребуется асинхронность) — для чтения системных настроек SSH (~/.ssh/config) и создания SSH/SFTP сессий.
- anyhow — для простой и понятной обработки ошибок без написания кастомных перечислений (enums).
## ADR-003: Модель выполнения (Синхронная vs Асинхронная)
- Решение: Использовать синхронную (блокирующую) модель выполнения.
- Обоснование: Деплой одного проекта происходит строго последовательно (Шаг 1 -> Шаг 2 -> Шаг 3). Асинхронность (tokio) усложнит код, увеличит размер бинарника и не даст преимуществ, так как параллельное выполнение шагов внутри одного деплоя не требуется.
## ADR-004: Механизм передачи файлов
- Решение: Использование протокола SFTP/SCP через встроенные возможности крейта ssh2.
- Обоснование: Отказ от вызова системного rsync через std::process::Command делает утилиту самодостаточной и независимой от того, установлен ли rsync на конкретной ОС (например, на Windows утилита отработает так же успешно, как на Linux).
## ADR-005: Стратегия обработки ошибок и идемпотентность
- Решение: Реализовать стратегию Fail-Fast с выводом stderr упавшей команды. Идемпотентность (как в Ansible) на первом этапе не реализуется.
- Обоснование: Для хобби-проекта проверка состояния системы перед каждым шагом (идемпотентность) избыточна и сильно усложнит архитектуру. Если команда упала, пользователь просто фиксит ошибку и запускает деплой заново.
## ADR-006: Замена ssh2 (libssh2) на russh в качестве SSH-транспорта
- Решение: Вместо крейта ssh2 (обёртка над libssh2) используется чисто Rust-овый russh (0.62.x, crypto-backend ring). Парсер ~/.ssh/config остаётся на ssh2-config (он не зависит от libssh2). Публичный API утилиты синхронный (ADR-003); tokio-runtime живёт внутри модуля ssh и наружу не торчит.
- Обоснование: libssh2 не поддерживает шифр `chacha20-poly1305@openssh.com`, а свежие OpenSSH-серверы (9.x/10.x, в т.ч. дефолтные Ubuntu) часто предлагают только его — подключение падает с Session(-5). Утилита обязана работать с любым стоковым сервером без правки sshd_config. russh умеет chacha20-poly1305, aes-gcm и современные KEX (включая post-quantum гибриды).
- Следствия: проверка host key реализована через TOFU поверх ~/.ssh/known_hosts средствами russh; ssh-agent (этап 6) доступен через встроенные agent-возможности russh; сборка не требует NASM/CMake (в отличие от aws-lc-rs дефолта russh 0.63, поэтому зафиксирован backend ring).
---
## 📈 План развития проекта (Roadmap)
- MVP: Парсинг TOML, последовательный запуск локальных std::process::Command, SSH-коннект по ключу, запуск удаленных команд.
- Files: Реализация копирования одиночных файлов и рекурсивного копирования папок по SFTP.
- UX: Добавление красивого вывода (библиотека indicatif для progress-bar или colored для цветных логов).
- Advanced: Поддержка переменных окружения (.env), интеграция с системным ssh-agent.