init: docker-migrate universal migration tool
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
fsm.py — Конечный автомат (Finite State Machine) для миграции.
|
||||
Каждый mode (source/target) имеет свой pipeline steps.
|
||||
"""
|
||||
|
||||
from core import state
|
||||
from core.color import header, subheader, success, error as cerror, warn, info, step
|
||||
|
||||
|
||||
class FSM:
|
||||
SOURCE_STEPS = [
|
||||
"INIT",
|
||||
"SOURCE_DISCOVER",
|
||||
"SOURCE_MANIFEST_REVIEW",
|
||||
"SOURCE_PACK",
|
||||
"SOURCE_STOP_SERVICE",
|
||||
"TRANSFER",
|
||||
"DONE",
|
||||
]
|
||||
|
||||
TARGET_STEPS = [
|
||||
"INIT",
|
||||
"TARGET_PREFLIGHT",
|
||||
"TARGET_INSTALL",
|
||||
"TARGET_BACKUP",
|
||||
"TARGET_RESTORE",
|
||||
"TARGET_VERIFY",
|
||||
"DONE",
|
||||
]
|
||||
|
||||
def __init__(self, mode="source"):
|
||||
self.mode = mode
|
||||
self.steps = self.SOURCE_STEPS if mode == "source" else self.TARGET_STEPS
|
||||
|
||||
def _index(self, stage):
|
||||
try:
|
||||
return self.steps.index(stage)
|
||||
except ValueError:
|
||||
return -1
|
||||
|
||||
def resume_from(self, stage):
|
||||
idx = self._index(stage)
|
||||
if idx < 0:
|
||||
warn(f"Неизвестный stage '{stage}', начинаем с начала")
|
||||
idx = 0
|
||||
for s in self.steps[idx:]:
|
||||
if state.is_completed(s):
|
||||
info(f"Шаг {s} уже выполнен, пропускаем")
|
||||
continue
|
||||
self._run_step(s)
|
||||
|
||||
def _run_step(self, step_name):
|
||||
header(f"ШАГ: {step_name}")
|
||||
try:
|
||||
if self.mode == "source":
|
||||
self._source_step(step_name)
|
||||
else:
|
||||
self._target_step(step_name)
|
||||
state.mark_completed(step_name)
|
||||
state.set_stage(step_name)
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
cerror(f"Ошибка на шаге {step_name}: {msg}")
|
||||
state.set_error(step_name, "", msg, suggestion="Исправьте проблему и запустите: ./migrate --resume")
|
||||
raise
|
||||
|
||||
def _source_step(self, name):
|
||||
if name == "INIT":
|
||||
info("Инициализация source-режима")
|
||||
elif name == "SOURCE_DISCOVER":
|
||||
from source.source import do_discovery
|
||||
do_discovery()
|
||||
elif name == "SOURCE_MANIFEST_REVIEW":
|
||||
from source.source import do_manifest_review
|
||||
do_manifest_review()
|
||||
elif name == "SOURCE_PACK":
|
||||
from source.source import do_pack
|
||||
do_pack()
|
||||
elif name == "SOURCE_STOP_SERVICE":
|
||||
from source.source import do_stop_service
|
||||
do_stop_service()
|
||||
elif name == "TRANSFER":
|
||||
from transfer.transfer import do_transfer
|
||||
do_transfer()
|
||||
elif name == "DONE":
|
||||
success("Source-режим завершён")
|
||||
|
||||
def _target_step(self, name):
|
||||
if name == "INIT":
|
||||
info("Инициализация target-режима")
|
||||
elif name == "TARGET_PREFLIGHT":
|
||||
from target.target import do_preflight
|
||||
do_preflight()
|
||||
elif name == "TARGET_INSTALL":
|
||||
from target.target import do_install
|
||||
do_install()
|
||||
elif name == "TARGET_BACKUP":
|
||||
from target.target import do_backup_existing
|
||||
do_backup_existing()
|
||||
elif name == "TARGET_RESTORE":
|
||||
from target.target import do_restore
|
||||
do_restore()
|
||||
elif name == "TARGET_VERIFY":
|
||||
from target.target import do_verify
|
||||
do_verify()
|
||||
elif name == "DONE":
|
||||
success("Target-режим завершён")
|
||||
Reference in New Issue
Block a user