From 331d9c09c76e7b514cbf7951916f51efef46c11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io> Date: Sun, 24 Oct 2021 01:04:22 +0200 Subject: [PATCH] tasks: automate nixos-install --- tasks.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/tasks.py b/tasks.py index e3d4f55..8620ccb 100644 --- a/tasks.py +++ b/tasks.py @@ -3,8 +3,10 @@ from invoke import task import sys -from typing import List +from typing import List, Any from deploy_nixos import DeployHost, DeployGroup +import subprocess +import json def deploy_nixos(hosts: List[DeployHost]) -> None: @@ -22,8 +24,87 @@ def deploy_nixos(hosts: List[DeployHost]) -> None: g.run_function(deploy) +def sfdisk_json(host: DeployHost, dev: str) -> List[Any]: + out = host.run(f"sfdisk --json {dev}", stdout=subprocess.PIPE) + data = json.loads(out.stdout) + return data["partitiontable"]["partitions"] -def get_hosts(hosts: str): + +def _format_disks(host: DeployHost, devices: List[str]) -> None: + assert len(devices) == 1 or len(devices) == 2, "we only support single devices or mirror raids at the moment" + # format disk with as follow: + # - partition 1 will be the boot partition, needed for legacy (BIOS) boot + # - partition 2 is for boot partition + # - partition 3 takes up the rest of the space and is for the system + for device in devices: + host.run(f"sgdisk -Z -n 1:2048:4095 -n 2:4096:+2G -N 3 -t 1:ef02 -t 2:8304 -t 3:8304 {device}") + + # create mdadm raid for /boot with ext4 + if len(devices) == 2: + boot_parts = [] + root_parts = [] + for dev in devices: + # use partuuids as they are more stable than device names + partitions = sfdisk_json(host, dev) + boot_parts.append(partitions[1]["node"]) + root_parts.append(f"/dev/disk/by-partuuid/{partitions[2]['uuid'].lower()}") + + host.run(f"mdadm --create --verbose /dev/md127 --raid-devices=2 --level=1 {' '.join(boot_parts)}") + host.run(f"zpool create zroot -O acltype=posixacl -O xattr=sa -O compression=lz4 mirror {' '.join(root_parts)}") + boot = "/dev/md127" + else: + partitions = sfdisk_json(host, devices[0]) + boot = partitions[1]["node"] + uuid = partitions[2]["uuid"].lower() + root_part = f"/dev/disk/by-partuuid/{uuid}" + host.run(f"zpool create zroot -O acltype=posixacl -O xattr=sa -O compression=lz4 -O atime=off {root_part}") + + host.run(f"partprobe") + host.run(f"mkfs.ext4 -F {boot}") + + # setup zfs dataset + host.run(f"zfs create -o mountpoint=none zroot/root") + host.run(f"zfs create -o mountpoint=legacy zroot/root/nixos") + host.run(f"zfs create -o mountpoint=legacy zroot/root/home") + + ## and finally mount + host.run(f"mount -t zfs zroot/root/nixos /mnt") + host.run(f"mkdir /mnt/home /mnt/boot") + host.run(f"mount -t zfs zroot/root/home /mnt/home") + host.run(f"mount -t ext4 /dev/md127 /mnt/boot") + + +@task +def format_disks(c, hosts = "", disks = ""): + """ + Format disks with zfs + """ + _format_disks(get_hosts(hosts)[0], disks.split(",")) + + +@task +def setup_secret(c, hosts = ""): + """ + Setup SSH key and print age key for sops-nix + """ + for h in get_hosts(hosts): + h.run("install -m600 -D /etc/ssh/ssh_host_ed25519_key /mnt/etc/ssh/ssh_host_ed25519_key") + print(h.host) + h.run("nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'") + + +@task +def nixos_install(c, hosts = ""): + """ + Run NixOS install + """ + for h in get_hosts(hosts): + h.run("nix-shell -p git --run 'git clone https://github.com/nix-community/infra && cd infra && nix-shell'") + hostname = h.host.replace('.nix-community.org', '') + h.run(f"cd /root/infra && nixos-install --system $(nix-build -A {hostname}-system)") + + +def get_hosts(hosts: str) -> List[DeployHost]: if hosts == "": return [DeployHost(f"build{n + 1}.nix-community.org") for n in range(4)]