90 lines
2.8 KiB
Python
90 lines
2.8 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import argparse
|
||
|
import hashlib
|
||
|
from pathlib import Path
|
||
|
import requests
|
||
|
import subprocess
|
||
|
import sys
|
||
|
|
||
|
def get_hydra_store_path(url):
|
||
|
"""
|
||
|
Accepts an url to a hydra build.
|
||
|
Can be:
|
||
|
https://hydra.clerie.de/job/nixfiles/nixfiles/iso/latest-finished
|
||
|
Or:
|
||
|
https://hydra.clerie.de/build/917
|
||
|
"""
|
||
|
|
||
|
r = requests.get(url, headers={"Accept": "application/json"})
|
||
|
r.raise_for_status()
|
||
|
|
||
|
return Path(r.json()["buildoutputs"]["out"]["path"])
|
||
|
|
||
|
|
||
|
def cli():
|
||
|
parser = argparse.ArgumentParser(
|
||
|
prog="update-from-hydra",
|
||
|
description="Fetch the latest build of a Hydra job and set it as a specified symlink",
|
||
|
)
|
||
|
parser.add_argument("hydra_url")
|
||
|
parser.add_argument("update_path")
|
||
|
parser.add_argument("cache_store_uri")
|
||
|
args = parser.parse_args()
|
||
|
hydra_url = args.hydra_url
|
||
|
update_path = Path(args.update_path).absolute()
|
||
|
cache_store_uri = args.cache_store_uri
|
||
|
|
||
|
print("Update url:", hydra_url)
|
||
|
print("Path to update:", update_path)
|
||
|
|
||
|
current_store_path = None
|
||
|
|
||
|
if update_path.exists():
|
||
|
if not update_path.is_symlink():
|
||
|
print("Path to update is not a symlink")
|
||
|
exit(1)
|
||
|
|
||
|
current_store_path = update_path.readlink()
|
||
|
print("Current store path:", current_store_path)
|
||
|
else:
|
||
|
print("No current store path, update path does not exist")
|
||
|
|
||
|
print("Look up Hydra build metadata")
|
||
|
hydra_store_path = get_hydra_store_path(hydra_url)
|
||
|
print("Store path in hydra:", hydra_store_path)
|
||
|
|
||
|
if current_store_path == hydra_store_path:
|
||
|
print("Current store path is up to date")
|
||
|
exit()
|
||
|
|
||
|
print("Downloading new store paths")
|
||
|
subprocess.run(["nix", "copy", "--from", cache_store_uri, hydra_store_path])
|
||
|
print("Finished downloading")
|
||
|
|
||
|
print("Updating path to update")
|
||
|
update_path.parent.mkdir(parents=True, exist_ok=True)
|
||
|
tmp_update_path = update_path.parent / ( update_path.name + ".new")
|
||
|
print("Creating temporary symlink:", tmp_update_path)
|
||
|
tmp_update_path.symlink_to(hydra_store_path)
|
||
|
print("Rename symlink to:", update_path)
|
||
|
tmp_update_path.rename(update_path)
|
||
|
|
||
|
print("Adding to gcroot")
|
||
|
try:
|
||
|
gcroots_dir = Path("/nix/var/nix/gcroots/update-from-hydra")
|
||
|
update_dir_hash = hashlib.sha256(bytes(update_path)).hexdigest()
|
||
|
gcroots_dir.mkdir(parents=True, exist_ok=True)
|
||
|
gcroots_symlink = gcroots_dir / update_dir_hash
|
||
|
tmp_gcroots_symlink = gcroots_dir / (update_dir_hash + ".new")
|
||
|
print("Creating temporary symlink:", tmp_gcroots_symlink)
|
||
|
tmp_gcroots_symlink.symlink_to(update_path)
|
||
|
print("Rename symlink to:", gcroots_symlink)
|
||
|
tmp_gcroots_symlink.rename(gcroots_symlink)
|
||
|
except PermissionError:
|
||
|
print("Unable to create garbage collector root")
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
cli()
|