init: docker-migrate universal migration tool

This commit is contained in:
2026-05-22 19:58:09 +04:00
commit ddb2ae9501
34 changed files with 2431 additions and 0 deletions
View File
Binary file not shown.
+90
View File
@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
"""
transfer.py — Адаптивный перенос архива (scp/rsync/fallback)
"""
import os
import json
from core.color import info, success, warn, error as cerror, prompt, confirm, step
from core import state
from core.runner import run, exists
def do_transfer():
st = state.load_state()
archive_path = st.get("archive_path")
if not archive_path or not os.path.isfile(archive_path):
raise RuntimeError("Архив не найден. Сначала выполните сборку (Source → Pack).")
host = st.get("target_host")
user = st.get("target_user")
port = st.get("target_port", 22)
step(5, "ПЕРЕНОС АРХИВА")
info(f"Target: {user}@{host}:{port}")
# Определяем размер
size = os.path.getsize(archive_path)
size_mb = size / 1024 / 1024
info(f"Размер архива: {size_mb:.2f} MB")
# Определяем путь назначения
remote_dir = "/tmp/docker-migrate-incoming"
remote_path = os.path.join(remote_dir, os.path.basename(archive_path))
# Копируем bootstrap (migrate + core/) чтобы target мог запуститься
# Найдём корень проекта
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
tar_script = os.path.join(project_root, "tar_project.sh")
# Выбираем метод
if size_mb < 50 and exists("scp"):
method = "scp"
elif size_mb >= 50 and exists("rsync"):
method = "rsync"
else:
if exists("rsync"):
method = "rsync"
elif exists("scp"):
method = "scp"
else:
raise RuntimeError("Ни rsync, ни scp не найдены. Установите один из них.")
info(f"Выбран метод переноса: {method}")
ssh_opts = f"-p {port}"
if exists("ssh"):
# Проверим доступность
info("Проверяем SSH-соединение ...")
check = run(f"ssh {ssh_opts} -o ConnectTimeout=10 -o BatchMode=yes {user}@{host} 'echo ok'", check=False)
if check.returncode != 0:
warn("SSH (batch mode) не прошёл — возможно, нужен пароль.")
else:
success("SSH доступ подтверждён")
if method == "scp":
info("Копируем архив через scp ...")
run(f"scp {ssh_opts} {archive_path} {user}@{host}:{remote_path}", check=False)
else:
info("Копируем архив через rsync ...")
run(f"rsync -avz --progress -e 'ssh {ssh_opts}' {archive_path} {user}@{host}:{remote_path}", check=False)
success(f"Архив передан на {host}:{remote_path}")
# Распаковка на target во временную директорию
info("Распаковываем архив на target ...")
run(f"ssh {ssh_opts} {user}@{host} 'mkdir -p {remote_dir} \u0026\u0026 tar xzf {remote_path} -C {remote_dir}'", check=False)
# Сохраняем remote_dir в state для target
state.set_stage("TRANSFER_DONE", target_remote_dir=remote_dir)
# Предлагаем сразу запустить target-режим удалённо
if confirm("Сразу запустить восстановление на новом сервере (remote target mode)", default="y"):
info("Запускаем target-mode удалённо ...")
# Передаём скрипт на target
project_local = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
run(f"scp {ssh_opts} -r {project_local} {user}@{host}:/opt/docker-migrate-tool", check=False)
# Запуск target как remote python
run(f"ssh {ssh_opts} {user}@{host} 'cd /opt/docker-migrate-tool && python3 core/main.py --mode=target --remote-dir={remote_dir}'", check=False)
else:
success(f"Архив передан. Запустите на target: python3 core/main.py --mode=target --remote-dir={remote_dir}")