95 lines
7.0 KiB
Markdown
95 lines
7.0 KiB
Markdown
# Phase 7: SSH deployment
|
||
|
||
Phase 7 завершена для подтверждённой NeoForge 1.21.1 / 21.1.252 комбинации.
|
||
Добавлены `mcpack deploy`, SSH worker и host deployment state. Подробный
|
||
контракт и подготовка/recovery — [deploy.md](deploy.md).
|
||
|
||
## Реальный host пользователя
|
||
|
||
2026-10-03 выполнен deployment на `crab@192.168.1.61:2228` (minipc):
|
||
|
||
- Отдельный root: `/home/crab/workspace/minecraft-lab/minecraft-lab-neoforge-spike`.
|
||
Базовый каталог для других сборок не используется как runtime.
|
||
- Подтверждены Docker 27.4.1, Node 26.10.0 через nvm, rsync, GNU tar и zstd.
|
||
Новые системные зависимости на remote host не устанавливались.
|
||
- Создан host `.env` с ранее принятой EULA, UID/GID 1000:1000, memory 2G,
|
||
port 25565, project minecraft-lab-neoforge-spike. Mode env=600, root=700.
|
||
- SSH key host закреплён в локальном known_hosts. Password authentication
|
||
использован для ControlMaster; пароль нигде не записан. Worker/rsync
|
||
используют BatchMode и StrictHostKeyChecking=yes.
|
||
- Clean release **0.0.4** построен в отдельном Git checkout, поскольку root
|
||
development release 0.0.4 имеет dirty=true и намеренно не допускается deploy.
|
||
Source repository пользователя не коммитился и immutable старый dist не менялся.
|
||
- Release manifest SHA256:
|
||
`4b9a060ecb74329c0c10ca8c24954f87f4b137dfb5240f844bb93208780a694f`.
|
||
- Первый deploy создал runtime без backup (first deploy), загрузил pinned
|
||
image/dependencies, запустил NeoForge и подтвердил status query + 10 s stability.
|
||
- Повторный deploy завершился healthy noop. Deployment state complete,
|
||
applied=false, noop=true; container StartedAt остаётся временем первого
|
||
запуска `2026-10-03T15:40:01.458777215Z`.
|
||
- Remote status query возвращает Minecraft 1.21.1. `online-mode=false` и
|
||
`enforce-secure-profile=false`; world принадлежит 1000:1000, Backpacks/Core
|
||
присутствуют, client-only Mouse Tweaks в server JAR нет.
|
||
- Сервер оставлен запущенным. Game port остаётся на remote IPv4 loopback;
|
||
инструкция SSH tunnel для клиента находится в deploy.md.
|
||
- Локальный primary Phase 0 сервер на 25565 не останавливался и остался healthy.
|
||
|
||
Свидетельства: `.tools/phase7-target-evidence/deploy-first.log`,
|
||
`deploy-noop.log`, `verification.txt`, `primary-server-status.txt`.
|
||
SSH config — `.tools/phase7-ssh-target/config`, только параметры соединения.
|
||
|
||
## Реальный изолированный SSH/rsync стенд
|
||
|
||
`scripts/verify-phase7.sh` создал loopback SSH server на 22227 с временными
|
||
ключами и новым Docker project minecraft-lab-phase7, port 25566. Полный
|
||
source snapshot помещён в отдельный Git clone, dependencies скопированы как
|
||
обычный ignored каталог (symlink node_modules делал worktree dirty).
|
||
|
||
Проверены реальные операции:
|
||
|
||
1. Clean build `0.0.4`, первая передача rsync и запуск healthy.
|
||
2. Повторная передача команды deploy той же версии: ID и StartedAt контейнера
|
||
совпали до/после, release не передавался повторно и restart не было.
|
||
3. Общий host lock заблокировал параллельный deploy до остановки сервера.
|
||
4. Clean build `0.0.5` с новым server override marker; update создал проверенный
|
||
backup исходного runtime/release, запустил target и обновил active/previous.
|
||
5. World/level.dat и persistent mod-state вне world сохранились; новый marker
|
||
применился после backup, unknown файлы не удалялись.
|
||
6. Ручное изменение managed config затем вызвало conflict/non-zero до stop/apply.
|
||
Изменённый файл сохранён, state failed/applied=false.
|
||
7. Test container/network и временный SSH daemon остановлены; snapshots,
|
||
оба releases/runtime/state/evidence сохранены.
|
||
|
||
Стенд: `.tools/phase7-check.6dbBak`, свидетельства в его `evidence/`:
|
||
`build-first.log`, `build-second.log`, `deploy-first.log`, `deploy-noop.log`,
|
||
`noop-container.txt`, `locked.log`, `deploy-second.log`, `update-assertions.txt`,
|
||
`manual-conflict.log`, `conflict-assertions.txt`, `primary-server-status.txt`.
|
||
|
||
## Автоматические проверки
|
||
|
||
`npm test`: 57 tests pass. Deployment tests используют controlled Compose/Docker
|
||
и проверяют first deploy, no-op, immutable version collision, backup-gated
|
||
update/world/mod-state, manual conflicts/diff, точный перенос ручной правки
|
||
в clean target, failure передачи/backup/startup, unresolved state, async lock
|
||
во время upload, dirty provenance, unsafe SSH arguments и CLI option scope.
|
||
|
||
При failure передачи source не останавливается. При failure backup target
|
||
не запускается. Failed startup оставляет target binding, source pointers,
|
||
verified snapshot и stopped state; старый pack не запускается автоматически.
|
||
Это unit fault injection, а не имитация сбоев на пользовательском live host.
|
||
Health failures с живым Docker проверены отдельно в Phase 6; tar failure и
|
||
restore — в Phase 5. Обычный SSH update выше подтверждает интеграцию gate.
|
||
|
||
## Границы
|
||
|
||
Первый реальный remote deploy и no-op проверены на host пользователя;
|
||
обновление и ручной conflict — на loopback стенде. Forge остаётся непроверенным.
|
||
Аккаунты отключены; LAN game port не открывался, используется tunnel.
|
||
Новый unknown существующий мир не принимается автоматически.
|
||
|
||
Failed/incomplete state блокирует следующий deploy до ручного recovery.
|
||
Указатели каждый atomic, общая пара не transaction; state содержит этап
|
||
committing и прежние значения. fsync, retention, off-host backup и автоматический
|
||
recovery не реализованы. Remote agents автоматически не удаляются.
|
||
Следующая Phase 8 — rollback с восстановлением snapshot и исходного release.
|