81 lines
2.4 KiB
Python
81 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import hashlib
|
|
import json
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
MANIFEST = ROOT / "offline" / "manifest.json"
|
|
BASE_IMAGE = "redroid/redroid:13.0.0-latest"
|
|
|
|
|
|
def digest(path, algorithm):
|
|
hasher = hashlib.new(algorithm)
|
|
with path.open("rb") as handle:
|
|
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
|
hasher.update(chunk)
|
|
return hasher.hexdigest()
|
|
|
|
|
|
def runtime_available(runtime):
|
|
return shutil.which(runtime) is not None
|
|
|
|
|
|
def local_base_image_present():
|
|
for runtime in ("docker", "podman"):
|
|
if not runtime_available(runtime):
|
|
continue
|
|
result = subprocess.run(
|
|
[runtime, "image", "inspect", BASE_IMAGE],
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
check=False,
|
|
)
|
|
if result.returncode == 0:
|
|
return True, runtime
|
|
return False, ""
|
|
|
|
|
|
def main():
|
|
manifest = json.loads(MANIFEST.read_text(encoding="utf-8"))
|
|
failures = []
|
|
base_image_present, base_runtime = local_base_image_present()
|
|
for entry in manifest["artifacts"]:
|
|
path = ROOT / entry["relative_path"]
|
|
if path.name == "redroid-redroid-13.0.0-latest.tar" and base_image_present:
|
|
print("SKIP {} ({} already present locally)".format(entry["relative_path"], BASE_IMAGE))
|
|
continue
|
|
if not path.is_file():
|
|
if path.name == "redroid-redroid-13.0.0-latest.tar":
|
|
failures.append(
|
|
"{} missing (and {} not found in local {} storage)".format(
|
|
entry["relative_path"], BASE_IMAGE, base_runtime or "docker/podman"
|
|
)
|
|
)
|
|
continue
|
|
failures.append("{} missing".format(entry["relative_path"]))
|
|
continue
|
|
if path.stat().st_size != entry["size"]:
|
|
failures.append("{} size mismatch".format(entry["relative_path"]))
|
|
continue
|
|
sha256 = digest(path, "sha256")
|
|
if sha256 != entry["sha256"]:
|
|
failures.append("{} sha256 mismatch".format(entry["relative_path"]))
|
|
continue
|
|
print("OK {}".format(entry["relative_path"]))
|
|
|
|
if failures:
|
|
for item in failures:
|
|
print("FAIL {}".format(item))
|
|
sys.exit(1)
|
|
|
|
print("Offline bundle is complete.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|