Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6e757d8
vesuvius: netboot prospit
mehbark Oct 23, 2025
3fcba78
corrected netboot configuration to avoid interface leakage and correc…
mikhail729 Nov 6, 2025
10ebb8f
corrected dhcp interface
mikhail729 Nov 6, 2025
eb25e22
hosts/vesuvius: change DNS domain from hephaestus to bastille
mehbark Nov 11, 2025
56bf0e8
hosts/common: refactor to remove k3s-ports.nix
mehbark Nov 11, 2025
7128fff
hosts/prospit: set k3s role
mehbark Nov 11, 2025
4dc169a
hosts/vesuvius: become the k3s cluster init
mehbark Nov 11, 2025
194b9cb
hosts/common/k3s: refactor to take role and clusterInit args
mehbark Nov 11, 2025
3845c0b
hosts/prospit: be adopted by bastille
mehbark Nov 11, 2025
3a8573f
hosts/bastille: fix root password warning
mehbark Nov 11, 2025
6041f78
hosts/bastille: automatically set hostname based on mac address
mehbark Nov 11, 2025
95545c0
hosts/bastille: add some actual names to auto-hostname
mehbark Nov 11, 2025
5364e33
fix(common/k3s): use cluster routing IP for vesuvius
kurisufriend Nov 26, 2025
946ab79
Merge branch 'main' into vesuvius-dnsmasq-netboot
kurisufriend Dec 9, 2025
86cf66c
Merge branch 'main' into vesuvius-dnsmasq-netboot
kurisufriend Dec 9, 2025
4e48b2b
!!breaking!! vesuvius/zfs: bind mount dataset /forge/nix to /nix, kee…
kurisufriend Jan 11, 2026
ba8cc98
hosts/vesuvius: opened port 53 for dns
mikhail729 Jan 22, 2026
77c1bbc
flake: bump
kurisufriend Jan 23, 2026
a3db521
feat(hosts/vesuvius): working freeIPA client
kurisufriend Jan 23, 2026
790c86e
refactor(hosts/vesuvius): use roles/common stuff
kurisufriend Jan 23, 2026
d220159
feat(common/nfs): mount dirtycow stuff
kurisufriend Jan 23, 2026
a0c8787
feat(hosts/vesuvius): include dirtycow mounts
kurisufriend Jan 23, 2026
946dbc4
hosts/vesuvius: added dhcp-host entries for netboot nodes
mikhail729 Jan 23, 2026
59c9833
hosts/bastille: disabled eno1 on lenovo nodes and removed auto-hostna…
mikhail729 Jan 23, 2026
4e8cf0e
fix(vesuvius/ipa): let "admins" group use passwordless sudo
kurisufriend Jan 30, 2026
7725870
docs(vesuvius/ipa): rm old comment about keytab
kurisufriend Jan 30, 2026
6a7feeb
hosts/vesuvius: added nfs share and port for kubernetes storage
mikhail729 Feb 2, 2026
fae7140
hosts/vesuvius: added static dnsmasq domain for vesuvius
mikhail729 Feb 2, 2026
5d8d2b2
hosts/{vesuvius,bastille}: opened ports for kubernetes intercluster c…
mikhail729 Feb 3, 2026
9f7669d
hosts/{bastille,common,vesuvius}: attempted k3s internal network ip a…
mikhail729 Feb 5, 2026
831d454
hosts/vesuvius: added static ipv4 route from enp1s0f1 to shellshock n…
mikhail729 Feb 5, 2026
bb565f0
hosts/common: fixed k3s command line parameters
mikhail729 Feb 5, 2026
c378e77
hosts/{vesuvius, common}: added public addresses and nftables firewall
mikhail729 Feb 7, 2026
2c1f7ac
hosts/vesuvius: added caddy container as the kubernetes cluster rever…
mikhail729 Feb 8, 2026
b1a0450
kube-manifests/ephemeral: removed ephemeral.vtluug.org as host since …
mikhail729 Feb 8, 2026
b96cfa4
hosts/vesuvius: changed caddy to use wildcard domains to the cluster
mikhail729 Feb 8, 2026
b1475ad
feat(vesuvius/caddy): dns acme validation w/ gandi api key
kurisufriend Feb 8, 2026
e6240b6
fix(vesuvius/caddy): move gandi secret
kurisufriend Feb 8, 2026
caf8f6d
fix(vesuvius/caddy): add gandi plugin
kurisufriend Feb 8, 2026
40e2d03
hosts/vesuvius: format caddy.nix
mikhail729 Feb 8, 2026
d6dd9d9
fix(vesuvius/caddy): gandi plugin hash
kurisufriend Feb 8, 2026
f9c6da0
Merge branch 'vesuvius-dnsmasq-netboot' of github.com:vtluug/construc…
kurisufriend Feb 8, 2026
1366ffb
hosts/vesuvius: fixed caddy proxy to bastille
mikhail729 Feb 8, 2026
1922943
flake.nix: removed depreciated arguments in favor of their replacements
mikhail729 Feb 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@

NIX_SSHOPTS="-o ForwardAgent=yes -J acidburn.vtluug.org" \
${pkgs.nixos-rebuild}/bin/nixos-rebuild switch \
--fast --flake ".#$TARGET_HOST_NAME" \
--use-remote-sudo \
--flake ".#$TARGET_HOST_NAME" \
--no-reexec \
--sudo \
--target-host "papatux@$TARGET_HOST_ADDRESS" \
--build-host "papatux@$TARGET_HOST_ADDRESS"
'';
Expand Down
34 changes: 18 additions & 16 deletions hosts/bastille/blade-names.nix
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# keep-sorted start
[
"backbiter"
"damocles"
"durendal"
"eyelander"
"excalibur"
"gram"
"gryffindor"
"kusanagi"
"narsil"
"oathbringer"
"riptide"
"sting"
]
# keep-sorted end
{
# TODO: prospit's a special case and won't remain here forever
"d8:9e:f3:3e:f9:41" = "prospit";

"40:f2:e9:c6:65:5f" = "backbiter";
"40:f2:e9:c6:69:43" = "damocles";
"40:f2:e9:c6:69:67" = "durendal";
"40:f2:e9:c6:74:59" = "eyelander";
"40:f2:e9:c6:75:f1" = "excalibur";
"40:f2:e9:c6:76:21" = "gram";

"unassigned-0" = "gryffindor";
"unassigned-1" = "kusanagi";
"unassigned-2" = "narsil";
"unassigned-3" = "oathbringer";
"unassigned-4" = "riptide";
"unassigned-5" = "sting";
}
36 changes: 36 additions & 0 deletions hosts/bastille/blade.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{ modulesPath, pkgs, lib, ... }: {
imports = [
./eno1-imm-disable.nix
(import ../common/k3s.nix { inherit lib; })
../common/nix.nix
../common/sshd.nix
../common/users-local.nix
(modulesPath + "/installer/netboot/netboot-minimal.nix")
];

# Get hostname from DHCP request
networking.hostName = "";

# Open kubernetes' ports for flannel and API server
networking.firewall = {
allowedTCPPorts = [
6443
10250
];
allowedUDPPorts = [
8472
];
};


# when making the ISO, the initialHashedPassword is set to "" for some reason
# we already set a hashed password, so null this
users.users.root.initialHashedPassword = lib.mkForce null;

environment.systemPackages = [
pkgs.fastfetch
pkgs.git
];

system.stateVersion = "25.11";
}
30 changes: 30 additions & 0 deletions hosts/bastille/eno1-imm-disable.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{ pkgs, lib, ... }:
let
eno1-imm-disable = pkgs.writeShellApplication {
name = "eno1-imm-disable";

runtimeInputs = [
pkgs.iproute2
];

text = ''
if grep "Lenovo NeXtScale nx360 M5" /sys/devices/virtual/dmi/id/product_name; then
ip link set down eno1
fi
'';
};
in {
systemd.services."eno1-imm-disable" = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];

unitConfig = {
Description = "Disable eno1 on Lenovo NeXtScale nodes to avoid issues with using the imm interface";
};

serviceConfig = {
Type = "oneshot";
ExecStart = "${lib.getExe eno1-imm-disable}";
};
};
}
39 changes: 39 additions & 0 deletions hosts/common/k3s.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
lib,
role ? "agent",
clusterInit ? false,
serverAddr ? "10.98.3.2",
flannelIface ? "enp1s0f1",
}:
{
networking.firewall.allowedTCPPorts = [
6443
];

networking.firewall.allowedUDPPorts = [
8472
];

services.k3s = {
inherit role clusterInit;

enable = true;
serverAddr = lib.mkIf (role != "server") "https://${serverAddr}:6443";
nodeIP = lib.mkIf (role == "server") serverAddr;

extraFlags = [
"--token=\"garbage secret\""
]
++ lib.optionals (role == "server") [
"--kubelet-arg=node-ip=${serverAddr}"
"--flannel-iface=${flannelIface}"
"--advertise-address=${serverAddr}"
"--bind-address=${serverAddr}"
"--write-kubeconfig-mode=0640"
"--write-kubeconfig-group=wheel"
];
extraKubeletConfig = lib.mkIf (role == "server") {
address = serverAddr;
};
};
}
20 changes: 20 additions & 0 deletions hosts/common/nfs.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ config, pkgs, ... }:
let
mkNfs = {path, options ? [ "vers=4.0" "soft" "nodev" "nosuid" ]}: {
device = "${path}";
fsType = "nfs";
inherit options;
};
in
{
environment.systemPackages = [ pkgs.nfs-utils ];

fileSystems."/nfs/cistern/share" = mkNfs {path = "10.98.0.7:/cistern/nfs/share";};
fileSystems."/nfs/cistern/files" = mkNfs {path = "10.98.0.7:/cistern/nfs/files";};
fileSystems."/nfs/cistern/home" = mkNfs {
path = "10.98.0.7:/cistern/nfs/home";
options = [ "vers=4.0" "soft" "nodev" "nosuid" ];
};
fileSystems."/nfs/cistern/libvirt" = mkNfs {path = "10.98.0.7:/cistern/nfs/libvirt";};
fileSystems."/nfs/cistern/docker/data" = mkNfs {path = "10.98.0.7:/cistern/nfs/docker/data";};
}
10 changes: 10 additions & 0 deletions hosts/vesuvius/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,13 @@ Giant storage server + future LHCPISCSIPXEIDK thing maybe?
## Storage
We currently have one (manually created) RAID-Z2 pool mounted at `/forge` with `8` drives of `12 Tb` each.
We have capacity for `48`(!) drives, but still only paper (and tape) caddies.

```
# for the nix store
zfs create -o mountpoint=legacy \
-o compression=zstd \
-o xattr=sa \
-o acltype=posixacl \
-o atime=off \
forge/nix
```
81 changes: 81 additions & 0 deletions hosts/vesuvius/caddy.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
config,
pkgs,
lib,
...
}:
let
gandi-key-path = "/secrets/gandi.env";
in
{
age.secrets."gandi.env".file = ../../secrets/vesuvius/gandi.env.age;

containers.caddy-proxy = {
autoStart = true;
ephemeral = true;
macvlans = [ "eno0" ];
privateNetwork = false;
bindMounts = {
"${gandi-key-path}" = {
hostPath = config.age.secrets."gandi.env".path;
};
};
config =
{
config,
lib,
pkgs,
...
}:
{
networking.interfaces.mv-eno0 = {
useDHCP = true;
ipv4.addresses = [
{
address = "128.173.89.163";
prefixLength = 24;
}
];
ipv6.addresses = [
{
address = "2607:b400:6:cc80:0:aff:fe62:f";
prefixLength = 64;
}
];
};

# Force container to get DNS settings from network
networking.useHostResolvConf = false;

services.caddy = {
enable = true;
virtualHosts."*.vtluug.org".extraConfig = ''
reverse_proxy svc.bastille.vtluug.org:80 {
header_up Host {labels.2}.svc.bastille.vtluug.org
}
'';
package = pkgs.caddy.withPlugins {
plugins = [ "github.com/caddy-dns/gandi@v1.1.0" ];
hash = "sha256-5mjD0CY7f5+sRtV1rXysj8PvId2gQaWiXlIaTg2Lv8A=";
};
globalConfig = ''
acme_dns gandi {env.GANDI_AUTH_TOKEN}
'';
};
systemd.services.caddy.serviceConfig.EnvironmentFile = [ "${gandi-key-path}" ];

networking.firewall = {
allowedTCPPorts = [
80
443
];
allowedUDPPorts = [
80
443
];
};

system.stateVersion = "26.05";
};
};
}
Loading