feat(integration-vm): golden image fetch + SHA512 verification
This commit is contained in:
parent
a8dc3c787a
commit
af76763c16
1 changed files with 39 additions and 3 deletions
|
|
@ -44,9 +44,6 @@ DEFAULT_VCPUS = 2
|
||||||
MIN_FREE_MIB = 4096
|
MIN_FREE_MIB = 4096
|
||||||
VALID_TIERS = ("internal", "le-staging", "le-prod-wildcard")
|
VALID_TIERS = ("internal", "le-staging", "le-prod-wildcard")
|
||||||
|
|
||||||
DISPATCH = {} # temporary; real dispatch added in a later task
|
|
||||||
|
|
||||||
|
|
||||||
def vm_name(host, suffix=None):
|
def vm_name(host, suffix=None):
|
||||||
suffix = suffix or uuid.uuid4().hex[:8]
|
suffix = suffix or uuid.uuid4().hex[:8]
|
||||||
return f"{NAME_PREFIX}{host}-{suffix}"
|
return f"{NAME_PREFIX}{host}-{suffix}"
|
||||||
|
|
@ -108,6 +105,45 @@ def render_run_hosts(name, ip, ansible_user, groups):
|
||||||
return "\n".join(lines) + "\n"
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def sh(cmd, check=True, capture=False, **kw):
|
||||||
|
"""Run a command (list form). Logs the command to stderr."""
|
||||||
|
print("+ " + " ".join(str(c) for c in cmd), file=sys.stderr)
|
||||||
|
return subprocess.run(cmd, check=check,
|
||||||
|
capture_output=capture, text=True, **kw)
|
||||||
|
|
||||||
|
|
||||||
|
def _expected_sha(sha_text, filename):
|
||||||
|
for line in sha_text.splitlines():
|
||||||
|
parts = line.split()
|
||||||
|
if len(parts) == 2 and parts[1].lstrip("*") == filename:
|
||||||
|
return parts[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_image():
|
||||||
|
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
img = CACHE_DIR / IMAGE_NAME
|
||||||
|
if img.exists():
|
||||||
|
return img
|
||||||
|
print(f"Downloading {IMAGE_URL} ...", file=sys.stderr)
|
||||||
|
tmp = img.with_suffix(".part")
|
||||||
|
urllib.request.urlretrieve(IMAGE_URL, tmp)
|
||||||
|
sha_text = urllib.request.urlopen(SHA_URL).read().decode()
|
||||||
|
want = _expected_sha(sha_text, IMAGE_NAME)
|
||||||
|
if not want:
|
||||||
|
tmp.unlink(missing_ok=True)
|
||||||
|
raise SystemExit(f"checksum for {IMAGE_NAME} not found at {SHA_URL}")
|
||||||
|
h = hashlib.sha512()
|
||||||
|
with open(tmp, "rb") as fh:
|
||||||
|
for chunk in iter(lambda: fh.read(1 << 20), b""):
|
||||||
|
h.update(chunk)
|
||||||
|
if h.hexdigest() != want:
|
||||||
|
tmp.unlink(missing_ok=True)
|
||||||
|
raise SystemExit("golden image SHA512 mismatch — refusing to use it")
|
||||||
|
tmp.rename(img)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
def main(argv=None):
|
def main(argv=None):
|
||||||
p = argparse.ArgumentParser(prog="integration-vm", description=__doc__)
|
p = argparse.ArgumentParser(prog="integration-vm", description=__doc__)
|
||||||
sub = p.add_subparsers(dest="cmd", required=True)
|
sub = p.add_subparsers(dest="cmd", required=True)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue