feat: add nix server provision
This commit is contained in:
1350
pkgs/helpers/cli.py
Normal file
1350
pkgs/helpers/cli.py
Normal file
File diff suppressed because it is too large
Load Diff
32
pkgs/helpers/default.nix
Normal file
32
pkgs/helpers/default.nix
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
lib,
|
||||
writeShellApplication,
|
||||
python3,
|
||||
openbao,
|
||||
openssh,
|
||||
gitMinimal,
|
||||
nix,
|
||||
}:
|
||||
writeShellApplication {
|
||||
name = "nodeiwest";
|
||||
|
||||
runtimeInputs = [
|
||||
python3
|
||||
openbao
|
||||
openssh
|
||||
gitMinimal
|
||||
nix
|
||||
];
|
||||
|
||||
text = ''
|
||||
export NODEIWEST_HELPER_TEMPLATES=${./templates}
|
||||
exec ${python3}/bin/python ${./cli.py} "$@"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Safe VPS provisioning helper for the NodeiWest NixOS flake";
|
||||
license = licenses.mit;
|
||||
mainProgram = "nodeiwest";
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
}
|
||||
23
pkgs/helpers/templates/configuration.nix.tmpl
Normal file
23
pkgs/helpers/templates/configuration.nix.tmpl
Normal file
@@ -0,0 +1,23 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
# Generated by nodeiwest host init.
|
||||
imports = [
|
||||
./disko.nix
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
networking.hostName = "@@HOST_NAME@@";
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
time.timeZone = "@@TIMEZONE@@";
|
||||
|
||||
@@BOOT_LOADER_BLOCK@@
|
||||
|
||||
nodeiwest.ssh.userCAPublicKeys = @@SSH_CA_KEYS@@;
|
||||
|
||||
nodeiwest.tailscale.openbao = {
|
||||
enable = @@TAILSCALE_OPENBAO_ENABLE@@;
|
||||
};
|
||||
|
||||
system.stateVersion = "@@STATE_VERSION@@";
|
||||
}
|
||||
41
pkgs/helpers/templates/disko-bios-ext4.nix
Normal file
41
pkgs/helpers/templates/disko-bios-ext4.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Generated by nodeiwest host init.
|
||||
# Replace the disk only if the provider exposes a different primary device.
|
||||
disko.devices = {
|
||||
disk.main = {
|
||||
type = "disk";
|
||||
device = lib.mkDefault "@@DISK_DEVICE@@";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
BIOS = {
|
||||
priority = 1;
|
||||
name = "BIOS";
|
||||
start = "1MiB";
|
||||
end = "2MiB";
|
||||
type = "EF02";
|
||||
};
|
||||
swap = {
|
||||
size = "@@SWAP_SIZE@@";
|
||||
content = {
|
||||
type = "swap";
|
||||
resumeDevice = true;
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
47
pkgs/helpers/templates/disko-uefi-ext4.nix
Normal file
47
pkgs/helpers/templates/disko-uefi-ext4.nix
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Generated by nodeiwest host init.
|
||||
# Replace the disk only if the provider exposes a different primary device.
|
||||
disko.devices = {
|
||||
disk.main = {
|
||||
type = "disk";
|
||||
device = lib.mkDefault "@@DISK_DEVICE@@";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
ESP = {
|
||||
priority = 1;
|
||||
name = "ESP";
|
||||
start = "1MiB";
|
||||
end = "512MiB";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "umask=0077" ];
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "@@SWAP_SIZE@@";
|
||||
content = {
|
||||
type = "swap";
|
||||
resumeDevice = true;
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{ ... }:
|
||||
{
|
||||
# Placeholder generated by nodeiwest host init.
|
||||
# nixos-anywhere will replace this with the generated hardware config.
|
||||
}
|
||||
3
pkgs/helpers/templates/openbao-policy.hcl.tmpl
Normal file
3
pkgs/helpers/templates/openbao-policy.hcl.tmpl
Normal file
@@ -0,0 +1,3 @@
|
||||
path "@@POLICY_PATH@@" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
50
pkgs/helpers/tests/test_cli.py
Normal file
50
pkgs/helpers/tests/test_cli.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[3]
|
||||
CLI_PATH = REPO_ROOT / "pkgs" / "helpers" / "cli.py"
|
||||
|
||||
spec = importlib.util.spec_from_file_location("nodeiwest_cli", CLI_PATH)
|
||||
cli = importlib.util.module_from_spec(spec)
|
||||
assert spec.loader is not None
|
||||
sys.modules[spec.name] = cli
|
||||
spec.loader.exec_module(cli)
|
||||
|
||||
|
||||
class HelperCliTests(unittest.TestCase):
|
||||
def test_disk_from_device_supports_sd_and_nvme(self) -> None:
|
||||
self.assertEqual(cli.disk_from_device("/dev/sda2"), "/dev/sda")
|
||||
self.assertEqual(cli.disk_from_device("/dev/nvme0n1p2"), "/dev/nvme0n1")
|
||||
|
||||
def test_lookup_colmena_target_host_reads_existing_inventory(self) -> None:
|
||||
flake_text = (REPO_ROOT / "flake.nix").read_text()
|
||||
self.assertEqual(cli.lookup_colmena_target_host(flake_text, "vps1"), "100.101.167.118")
|
||||
|
||||
def test_parse_existing_vps1_configuration(self) -> None:
|
||||
configuration = cli.parse_existing_configuration(REPO_ROOT / "hosts" / "vps1" / "configuration.nix")
|
||||
self.assertEqual(configuration.host_name, "vps1")
|
||||
self.assertEqual(configuration.boot_mode, "uefi")
|
||||
self.assertTrue(configuration.tailscale_openbao)
|
||||
self.assertEqual(configuration.state_version, "25.05")
|
||||
self.assertTrue(configuration.user_ca_public_keys)
|
||||
|
||||
def test_parse_existing_vps1_disko(self) -> None:
|
||||
disko = cli.parse_existing_disko(REPO_ROOT / "hosts" / "vps1" / "disko.nix")
|
||||
self.assertEqual(disko.disk_device, "/dev/sda")
|
||||
self.assertEqual(disko.boot_mode, "uefi")
|
||||
self.assertEqual(disko.swap_size, "4GiB")
|
||||
|
||||
def test_render_bios_disko_uses_bios_partition(self) -> None:
|
||||
rendered = cli.render_disko(boot_mode="bios", disk_device="/dev/vda", swap_size="8GiB")
|
||||
self.assertIn('type = "EF02";', rendered)
|
||||
self.assertIn('device = lib.mkDefault "/dev/vda";', rendered)
|
||||
self.assertIn('size = "8GiB";', rendered)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user