feat(storage): add verified offline MinIO migration pilot
This commit is contained in:
51
scripts/storage/pilot.py
Normal file
51
scripts/storage/pilot.py
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Entry point shipped inside a verified, self-contained storage pilot bundle."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def checksum(path):
|
||||
h = hashlib.sha256()
|
||||
with path.open("rb") as f:
|
||||
for block in iter(lambda: f.read(1024 * 1024), b""):
|
||||
h.update(block)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("command", choices=["load-images", "plan", "migrate", "activate", "resume-start", "rollback", "status"])
|
||||
parser.add_argument("--directory", default="/opt/fedeo")
|
||||
parser.add_argument("--writers-exclusive", action="store_true")
|
||||
args = parser.parse_args()
|
||||
manifest = json.loads((ROOT / "bundle.json").read_text())
|
||||
for name, expected in manifest["sha256"].items():
|
||||
# The large image archive is checked when loading, not on every status call.
|
||||
if name == "images.tar" and args.command != "load-images":
|
||||
continue
|
||||
path = ROOT / name
|
||||
if path.resolve().is_relative_to(ROOT) and checksum(path) == expected:
|
||||
continue
|
||||
raise SystemExit("Paket-Prüfsumme stimmt nicht: " + name)
|
||||
if args.command == "load-images":
|
||||
subprocess.run(["docker", "image", "load", "-i", str(ROOT / "images.tar")], check=True)
|
||||
for image in (manifest["toolsImage"], manifest["seaweedImage"]):
|
||||
subprocess.run(["docker", "image", "inspect", image], check=True, stdout=subprocess.DEVNULL)
|
||||
print("Offline-Images geprüft und geladen. Nächster Schritt: plan.")
|
||||
return
|
||||
command = [sys.executable, str(ROOT / "scripts/selfhost-storage-migrate.py"), args.command, "--directory", args.directory]
|
||||
if args.command == "plan":
|
||||
command += ["--tools-image", manifest["toolsImage"]]
|
||||
if args.writers_exclusive:
|
||||
command += ["--writers-exclusive"]
|
||||
raise SystemExit(subprocess.run(command).returncode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user