7.0 KiB
Phase 7: SSH deployment
Phase 7 завершена для подтверждённой NeoForge 1.21.1 / 21.1.252 комбинации.
Добавлены mcpack deploy, SSH worker и host deployment state. Подробный
контракт и подготовка/recovery — 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).
Проверены реальные операции:
- Clean build
0.0.4, первая передача rsync и запуск healthy. - Повторная передача команды deploy той же версии: ID и StartedAt контейнера совпали до/после, release не передавался повторно и restart не было.
- Общий host lock заблокировал параллельный deploy до остановки сервера.
- Clean build
0.0.5с новым server override marker; update создал проверенный backup исходного runtime/release, запустил target и обновил active/previous. - World/level.dat и persistent mod-state вне world сохранились; новый marker применился после backup, unknown файлы не удалялись.
- Ручное изменение managed config затем вызвало conflict/non-zero до stop/apply. Изменённый файл сохранён, state failed/applied=false.
- 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.