Files
docker-migrate/dry_run.py
Stitch505 97b3623915 bugfix: comprehensive stability audit and fixes
- discover/docker.py: handle comma-separated compose_file in labels
- discover/network.py: replace os.getlogin() with robust user detection
- target.py: add lsb_release fallback via hostnamectl, guard None compose_file,
  use container name (not cached CID) for docker logs
- main.py: call reset_state(mode='target') before target mode,
  improve EOF handling info message
- source.py: remove redundant set_stage('DONE') inside transfer_offer
- transfer.py: fix stage naming for resume after transfer
- add dry_run.py for local logic validation
2026-05-22 20:58:37 +04:00

137 lines
4.4 KiB
Python
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.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
dry_run.py — Локальная проверка логики без Docker/SSH
"""
import sys
import os
# Добавляем корень проекта
_PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
if _PROJECT_ROOT not in sys.path:
sys.path.insert(0, _PROJECT_ROOT)
errors = []
def check(msg, ok):
if not ok:
errors.append(msg)
print(f" FAIL: {msg}")
else:
print(f" OK: {msg}")
print("=== DRY-RUN: Проверка импортов ===")
try:
from core import state
check("state модуль импортируется", True)
except Exception as e:
check(f"state импорт: {e}", False)
try:
from core.fsm import FSM
check("FSM класс доступен", True)
except Exception as e:
check(f"FSM импорт: {e}", False)
try:
from core.color import menu, prompt
check("color модуль доступен", True)
except Exception as e:
check(f"color импорт: {e}", False)
try:
from discover.docker import discover_docker, get_container_pid
check("discover.docker доступен", True)
except Exception as e:
check(f"discover.docker: {e}", False)
try:
from discover.nginx import discover_nginx
check("discover.nginx доступен", True)
except Exception as e:
check(f"discover.nginx: {e}", False)
try:
from transfer.transfer import do_transfer
check("transfer.transfer доступен", True)
except Exception as e:
check(f"transfer.transfer: {e}", False)
try:
from transfer.ssh import list_private_keys
check("transfer.ssh доступен", True)
except Exception as e:
check(f"transfer.ssh: {e}", False)
try:
from manifest.manifest import build_manifest, save_manifest
check("manifest доступен", True)
except Exception as e:
check(f"manifest: {e}", False)
print("\n=== DRY-RUN: Проверка FSM ===")
# Проверим что SOURCE_STEPS содержит все нужные шаги
fsm_s = FSM(mode="source")
check("SOURCE_STEPS содержит TRANSFER", "TRANSFER" in fsm_s.steps)
check("SOURCE_STEPS содержит DONE", "DONE" in fsm_s.steps)
fsm_t = FSM(mode="target")
check("TARGET_STEPS содержит DONE", "DONE" in fsm_t.steps)
print("\n=== DRY-RUN: Проверка state.json ===")
state.load_state()
check("State загружается без ошибок", True)
state.set_stage("INIT", mode=None)
check("State сохраняется", True)
print("\n=== DRY-RUN: Проверка reset_state ===")
state.mark_completed("SOURCE_DISCOVER")
state.set_stage("SOURCE_PACK", archive_path="/tmp/test.tar.gz")
state.reset_state(mode="source")
st = state.load_state()
check("reset_state очищает completed_steps", len(st.get("completed_steps", [])) == 0)
check("reset_stage после reset = INIT", st.get("stage") == "INIT")
print("\n=== DRY-RUN: Проверка manifest ===")
manifest = build_manifest(
docker_data={"container_name":"test","image":"img","status":"running","compose_file":"/tmp/compose.yml","env_file":None,"mounts":[],"ports":{},"networks":[],"host_config":{},"labels":{}},
nginx_data=[],
sidecars=[],
host_network={},
systemd_units=[],
cron_jobs=[],
extra_hints=[],
)
check("Manifest содержит service.name", manifest["service"]["name"] == "test")
check("Manifest содержит docker.compose_file", manifest["docker"]["compose_file"] == "/tmp/compose.yml")
print("\n=== DRY-RUN: Проверка transfer без host ===")
st = state.load_state()
state.save_state({**st, "archive_path":None, "target_host":None, "target_user":None, "target_port":22})
try:
do_transfer()
check("do_transfer без archive_path — бросил RuntimeError", False)
except RuntimeError as e:
check("do_transfer без archive_path — RuntimeError", "Архив не найден" in str(e))
except Exception as e:
check(f"do_transfer без archive_path — неожиданная ошибка: {e}", False)
# Проверка ssh key discovery (без файловой системы)
try:
keys = list_private_keys()
check("list_private_keys не падает", True)
except Exception as e:
check(f"list_private_keys: {e}", False)
print("\n=== DRY-RUN: ИТОГ ===")
if errors:
print(f"FAIL: {len(errors)} проверок не прошло:")
for e in errors:
print(f" - {e}")
sys.exit(1)
else:
print("Все проверки прошли успешно!")
sys.exit(0)