105 lines
3.2 KiB
Python
Executable file
105 lines
3.2 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# because nixos-rebuild --target-host is too flaky
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
with open(os.path.expanduser("~/var/addresses.json"), "rt") as f:
|
|
opts = json.loads(f.read())
|
|
|
|
|
|
def main():
|
|
args = sys.argv
|
|
cfg = args[1]
|
|
if "@" in cfg:
|
|
cfg, addr = cfg.split("@")
|
|
else:
|
|
addr = opts["addresses"][cfg]
|
|
build_host = opts["build_host"].get(cfg)
|
|
act = args[2]
|
|
assert act in ["boot", "switch", "test", "build"]
|
|
args = args[3:]
|
|
args.extend(
|
|
[
|
|
"--option",
|
|
"extra-builtins-file",
|
|
os.path.dirname(__file__) + "/extra-builtins.nix",
|
|
]
|
|
)
|
|
attr_path = f".#nixosConfigurations.{cfg}.config.system.build.toplevel"
|
|
copy_args = []
|
|
do_copy = True
|
|
if build_host is not None:
|
|
build_host = addr if cfg == build_host else opts["addresses"][build_host]
|
|
cmd = ["nix", "eval", "--json", attr_path + ".drvPath"] + args
|
|
ret = subprocess.run(cmd, check=True, encoding="utf-8", stdout=subprocess.PIPE)
|
|
drv = json.loads(ret.stdout)
|
|
print('copying', drv, 'to build host')
|
|
cmd = [
|
|
"nix",
|
|
"copy",
|
|
drv,
|
|
"--derivation",
|
|
"--to",
|
|
"ssh-ng://root@" + build_host,
|
|
] + args
|
|
subprocess.run(cmd, check=True)
|
|
print('building', drv)
|
|
cmd = ["nix", "build", f"'{drv}^*'", "--no-link", "--json"] + args
|
|
ret = subprocess.run(
|
|
["ssh", "root@" + build_host],
|
|
input=" ".join(cmd) + "\n",
|
|
check=True,
|
|
encoding="utf-8",
|
|
stdout=subprocess.PIPE,
|
|
)
|
|
if cfg == build_host:
|
|
do_copy = False
|
|
else:
|
|
copy_args.extend(["--from", "ssh-ng://root@" + build_host])
|
|
else:
|
|
print('building', attr_path)
|
|
cmd = ["nix", "build", attr_path, "--no-link", "--json"] + args
|
|
ret = subprocess.run(cmd, check=True, encoding="utf-8", stdout=subprocess.PIPE)
|
|
ret = json.loads(ret.stdout)[0]["outputs"]["out"]
|
|
print('output', ret)
|
|
cmds = []
|
|
if act in ["build"]:
|
|
return
|
|
if act in ["boot", "switch"]:
|
|
cmds.append(["nix-env", "-p", "/nix/var/nix/profiles/system", "--set", ret])
|
|
cmds.append(
|
|
["env", "NIXOS_INSTALL_BOOTLOADER=", ret + "/bin/switch-to-configuration", act]
|
|
)
|
|
if addr is None:
|
|
for cmd in cmds:
|
|
print('running', *cmd)
|
|
cmd = ["sudo", "-A"] + cmd
|
|
subprocess.run(cmd, check=True)
|
|
else:
|
|
if do_copy:
|
|
print('copying', ret, 'to', addr)
|
|
print(*(["nix", "copy", ret, "--no-check-sigs", "--to", "ssh-ng://root@" + addr] + copy_args + args))
|
|
subprocess.run(
|
|
["nix", "copy", ret, "--no-check-sigs", "--to", "ssh-ng://root@" + addr]
|
|
+ copy_args
|
|
+ args,
|
|
check=True,
|
|
)
|
|
print('running', *cmd)
|
|
subprocess.run(
|
|
["ssh", "root@" + addr],
|
|
input="\n".join(" ".join(cmd) for cmd in cmds) + "\n",
|
|
check=True,
|
|
encoding="utf-8",
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
main()
|
|
except subprocess.CalledProcessError:
|
|
sys.exit(1)
|