# Transport Packaging Scripts Эти скрипты реализуют MVP для `manual + pinned` доставки transport-бинарей в режиме `runtime_mode=exec`. ## Файлы - `manifest.example.json` — шаблон pinned-манифеста (заполнить реальными версиями/URL/checksum). - `manifest.production.json` — pinned production-манифест с зафиксированными версиями и checksum. - `source_policy.example.json` — шаблон trusted-source/signature policy. - `source_policy.production.json` — production policy с trusted URL-prefix и режимами подписи. - `update.sh` — ручной update (скачивание, checksum verify, атомарный switch symlink, history). - `auto_update.sh` — opt-in обёртка над `update.sh` (interval gate + lock + jitter). - `rollback.sh` — откат на предыдущую версию из history. - `systemd/transport-packaging-auto-update.{service,timer}` — шаблоны для systemd расписания. ## Быстрый старт 1. Выберите манифест: - production: `scripts/transport-packaging/manifest.production.json`; - кастомный: скопируйте `manifest.example.json` и заполните значения. 2. Для кастомного манифеста заполните: - `enabled=true` для нужных компонентов; - `version`, `url`, `sha256` для каждой target-платформы. 3. Выполните update: ```bash ./scripts/transport-packaging/update.sh \ --manifest /path/to/manifest.json \ --source-policy ./scripts/transport-packaging/source_policy.production.json \ --component singbox,dnstt \ --target linux-amd64 ``` 4. При проблеме откатите: ```bash ./scripts/transport-packaging/rollback.sh \ --bin-root /opt/selective-vpn/bin \ --component singbox,dnstt ``` ## Поведение update.sh - Поддерживает `packaging_profile=system|bundled` в API-контракте. - Для `bundled` активный бинарь переключается symlink в `bin_root`. - История обновлений: `BIN_ROOT/.packaging/.history`. - Fail-fast валидация checksum (`sha256sum`) обязательна. - Trusted source policy: - `--source-policy` ограничивает допустимые URL (`https`, host/prefix allowlist). - для `manifest.production.json` policy подхватывается автоматически из `source_policy.production.json`. - Signature policy: - настраивается через `policy.signature.default_mode` и `components..signature_mode` (`off|optional|required`); - поддержан `signature.type=openssl-sha256` (detached signature); - для `required` нужны поля `signature.url` + `signature.public_key_path` (и опционально `signature.sha256`). - Staged rollout / canary: - `target.rollout.stage`: `stable|canary` (default `stable`); - `target.rollout.percent`: `0..100` (default `100`); - runtime-флаги: `--rollout-stage`, `--cohort-id`, `--force-rollout`, `--canary`. ## Auto-update opt-in - По умолчанию выключен (`--enabled false`). - Скрипт `auto_update.sh`: - запускает `update.sh` только при `enabled=true`; - защищён lock'ом (`flock`) от параллельных запусков; - поддерживает интервал запуска (`--min-interval-sec`) и jitter (`--jitter-sec`); - хранит state в `.../.packaging/auto-update` (`last_run_epoch`, `last_success_epoch`, `last_error`). Пример ручного запуска: ```bash ./scripts/transport-packaging/auto_update.sh \ --enabled true \ --manifest ./scripts/transport-packaging/manifest.production.json \ --source-policy ./scripts/transport-packaging/source_policy.production.json \ --component singbox,phoenix \ --min-interval-sec 21600 \ --jitter-sec 300 ``` Шаблон systemd: 1. Скопировать `systemd/transport-packaging-auto-update.service` и `.timer` в `/etc/systemd/system/`. 2. Скопировать `systemd/transport-packaging-auto-update.env.example` в `/etc/selective-vpn/transport-packaging-auto-update.env`. 3. Включить timer: ```bash sudo systemctl daemon-reload sudo systemctl enable --now transport-packaging-auto-update.timer ``` ## Примеры rollout ```bash # Установить только stable targets ./scripts/transport-packaging/update.sh \ --manifest ./scripts/transport-packaging/manifest.production.json \ --rollout-stage stable # Установить только canary targets для конкретного cohort ./scripts/transport-packaging/update.sh \ --manifest /path/to/manifest-with-canary.json \ --rollout-stage canary \ --cohort-id 5 ``` ## Ограничения MVP - Обновление запускается вручную (без авто-таймера). - Нет фонового scheduler/каналов обновления. - В `manifest.production.json` компонент `dnstt` выключен по умолчанию (`enabled=false`), т.к. текущий источник prebuilt-бинарей не является официальным release upstream.