raspberrypi #70
7 changed files with 248 additions and 166 deletions
17
flake.lock
17
flake.lock
|
@ -198,6 +198,22 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1708594753,
|
||||
"narHash": "sha256-c/gH7iXS/IYH9NrFOT+aJqTq+iEBkvAkpWuUHGU3+f0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "3f7d0bca003eac1a1a7f4659bbab9c8f8c2a0958",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "master",
|
||||
"repo": "nixos-hardware",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1702272962,
|
||||
|
@ -253,6 +269,7 @@
|
|||
"disko": "disko",
|
||||
"dns": "dns",
|
||||
"microvm": "microvm",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||
}
|
||||
|
|
33
flake.nix
33
flake.nix
|
@ -5,6 +5,7 @@
|
|||
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
deploy-rs.url = "github:serokell/deploy-rs";
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
|
@ -28,12 +29,12 @@
|
|||
};
|
||||
|
||||
outputs =
|
||||
{ self, nixpkgs, deploy-rs, disko, agenix, nixpkgs-unstable, dns, microvm, ... }:
|
||||
{ self, nixpkgs, deploy-rs, disko, agenix, nixpkgs-unstable, dns, microvm, nixos-hardware, ... }:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
controllerArch = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${controllerArch};
|
||||
lib = pkgs.lib;
|
||||
pkgs-unstable = nixpkgs-unstable.legacyPackages.${system};
|
||||
pkgs-unstable = nixpkgs-unstable.legacyPackages.${controllerArch};
|
||||
machines = import ./nixos/machines;
|
||||
physicalMachines = lib.filterAttrs (n: v: v.type == "physical") machines;
|
||||
mkNixosSystems = systemDef:
|
||||
|
@ -48,7 +49,7 @@
|
|||
physicalMachines;
|
||||
in
|
||||
{
|
||||
devShells.${system}.default = pkgs.mkShell {
|
||||
devShells.${controllerArch}.default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
libsecret
|
||||
# TODO: using nixos-anywhere from nixos-unstable produces buffer overflow.
|
||||
|
@ -65,11 +66,12 @@
|
|||
];
|
||||
};
|
||||
|
||||
formatter.${system} = pkgs.nixfmt;
|
||||
formatter.${controllerArch} = pkgs.nixfmt;
|
||||
|
||||
nixosConfigurations = mkNixosSystems (name: machine: {
|
||||
inherit system;
|
||||
specialArgs = { inherit machines machine dns microvm disko agenix; };
|
||||
system = machine.arch;
|
||||
|
||||
specialArgs = { inherit machines machine dns microvm disko agenix nixos-hardware; };
|
||||
modules = [
|
||||
./nixos
|
||||
{ networking.hostName = name; }
|
||||
|
@ -83,14 +85,25 @@
|
|||
nodes = mkDeployNodes (name: machine: {
|
||||
hostname = self.nixosConfigurations.${name}.config.networking.fqdn;
|
||||
profiles.system = {
|
||||
path = deploy-rs.lib.${system}.activate.nixos
|
||||
remoteBuild = machine.arch != controllerArch;
|
||||
path = deploy-rs.lib."${machine.arch}".activate.nixos
|
||||
self.nixosConfigurations.${name};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
# Deploy-rs' flake checks seem broken for architectures different from the deployment machine.
|
||||
# We skip these here.
|
||||
checks = builtins.mapAttrs
|
||||
(system: deployLib: deployLib.deployChecks self.deploy)
|
||||
(system: deployLib:
|
||||
deployLib.deployChecks (self.deploy // {
|
||||
nodes = (lib.attrsets.filterAttrs
|
||||
(name: node:
|
||||
machines.${name}.arch == controllerArch
|
||||
)
|
||||
self.deploy.nodes);
|
||||
})
|
||||
)
|
||||
deploy-rs.lib;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,26 @@
|
|||
# TODO: Create a nixos module system for this. (mkMerge)
|
||||
# That way, we don't have to specify isRaspberryPi on every machine... etc.
|
||||
{
|
||||
warwick = {
|
||||
type = "physical";
|
||||
arch = "aarch64-linux";
|
||||
isRaspberryPi = true;
|
||||
isHypervisor = false;
|
||||
isVirtualMachine = false;
|
||||
|
||||
nixosModule.lab = {
|
||||
storage = {
|
||||
osDisk = "/dev/sda";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
atlas = {
|
||||
type = "physical";
|
||||
arch = "x86_64-linux";
|
||||
isRaspberryPi = false;
|
||||
isHypervisor = true;
|
||||
isVirtualMachine = false;
|
||||
|
||||
nixosModule.lab = {
|
||||
storage = {
|
||||
|
@ -18,9 +38,12 @@
|
|||
|
||||
jefke = {
|
||||
type = "physical";
|
||||
arch = "x86_64-linux";
|
||||
isRaspberryPi = false;
|
||||
isHypervisor = true;
|
||||
isVirtualMachine = false;
|
||||
|
||||
nixosModule = {
|
||||
lab = {
|
||||
nixosModule.lab = {
|
||||
storage = {
|
||||
osDisk = "/dev/sda";
|
||||
dataPartition = "/dev/nvme0n1p1";
|
||||
|
@ -33,10 +56,13 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
lewis = {
|
||||
type = "physical";
|
||||
arch = "x86_64-linux";
|
||||
isRaspberryPi = false;
|
||||
isHypervisor = true;
|
||||
isVirtualMachine = false;
|
||||
|
||||
nixosModule.lab = {
|
||||
backups.enable = true;
|
||||
|
@ -59,18 +85,23 @@
|
|||
hermes = {
|
||||
type = "virtual";
|
||||
hypervisorName = "lewis";
|
||||
isRaspberryPi = false;
|
||||
isVirtualMachine = true;
|
||||
isHypervisor = false;
|
||||
|
||||
nixosModule = { config, ... }: {
|
||||
lab = {
|
||||
networking.dmz.services.enable = true;
|
||||
networking = {
|
||||
dmz.services.enable = true;
|
||||
staticNetworking = true;
|
||||
staticIPv4 = config.lab.networking.dmz.ipv4.services;
|
||||
staticIPv6 = config.lab.networking.dmz.ipv6.services;
|
||||
};
|
||||
|
||||
vm = {
|
||||
# TODO: would be cool to create a check that a mac address is only ever assigned to one VM.
|
||||
# TODO: idea: what if we generated these IDs by hashing the host name and reducing that to the amount of hosts possible?
|
||||
id = 7;
|
||||
staticNetworking = true;
|
||||
staticIPv4 = config.lab.networking.dmz.ipv4.services;
|
||||
staticIPv6 = config.lab.networking.dmz.ipv6.services;
|
||||
|
||||
shares = [{
|
||||
name = "dnsmasq";
|
||||
|
@ -84,6 +115,9 @@
|
|||
maestro = {
|
||||
type = "virtual";
|
||||
hypervisorName = "atlas";
|
||||
isRaspberryPi = false;
|
||||
isVirtualMachine = false;
|
||||
isHypervisor = false;
|
||||
|
||||
nixosModule = { config, ... }: {
|
||||
microvm.balloonMem = 7680;
|
||||
|
@ -101,6 +135,9 @@
|
|||
bancomart = {
|
||||
type = "virtual";
|
||||
hypervisorName = "jefke";
|
||||
isRaspberryPi = false;
|
||||
isVirtualMachine = false;
|
||||
isHypervisor = false;
|
||||
|
||||
nixosModule = {
|
||||
microvm.balloonMem = 7680;
|
||||
|
@ -115,6 +152,9 @@
|
|||
vpay = {
|
||||
type = "virtual";
|
||||
hypervisorName = "lewis";
|
||||
isRaspberryPi = false;
|
||||
isVirtualMachine = false;
|
||||
isHypervisor = false;
|
||||
|
||||
nixosModule = {
|
||||
microvm.balloonMem = 5120;
|
||||
|
|
|
@ -22,11 +22,26 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
mainNicNamePattern = lib.mkOption {
|
||||
default = "en*";
|
||||
staticNetworking = lib.mkOption {
|
||||
default = false;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether this machine has static networking configuration applied.
|
||||
Routing is prepopulated, but IP addresses have to be set.
|
||||
'';
|
||||
};
|
||||
|
||||
staticIPv4 = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Pattern to match the name of this machine's main NIC.
|
||||
Static IPv4 address for the machine.
|
||||
'';
|
||||
};
|
||||
|
||||
staticIPv6 = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Static IPv6 address for the machine.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
@ -43,10 +58,10 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
systemd.network = lib.mkIf (machine.type == "physical") {
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
|
||||
netdevs = {
|
||||
netdevs = lib.mkIf machine.isHypervisor {
|
||||
"20-vlandmz" = {
|
||||
vlanConfig.Id = 30;
|
||||
|
||||
|
@ -64,9 +79,10 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
networks = {
|
||||
networks = lib.attrsets.mergeAttrsList [
|
||||
(lib.optionalAttrs machine.isHypervisor {
|
||||
"30-main-nic" = {
|
||||
matchConfig.Name = cfg.mainNicNamePattern;
|
||||
matchConfig.Name = "en*";
|
||||
vlan = [ "vlandmz" ];
|
||||
|
||||
networkConfig = {
|
||||
|
@ -100,7 +116,52 @@ in {
|
|||
matchConfig.Name = "vm-*";
|
||||
networkConfig.Bridge = cfg.dmz.bridgeName;
|
||||
};
|
||||
})
|
||||
(lib.optionalAttrs machine.isVirtualMachine {
|
||||
"30-main-nic" = {
|
||||
matchConfig.Name = "en*";
|
||||
|
||||
networkConfig = {
|
||||
IPv6AcceptRA = ! cfg.staticNetworking;
|
||||
DHCP = lib.mkIf (! cfg.staticNetworking) "yes";
|
||||
|
||||
Address = lib.mkIf cfg.staticNetworking [
|
||||
"${cfg.staticIPv4}/${cfg.dmz.ipv4.prefixLength}"
|
||||
"${cfg.staticIPv6}/${cfg.dmz.ipv6.prefixLength}"
|
||||
];
|
||||
|
||||
DNS = lib.mkIf cfg.staticNetworking [
|
||||
cfg.dmz.ipv4.router
|
||||
cfg.dmz.ipv6.router
|
||||
];
|
||||
};
|
||||
|
||||
routes = lib.mkIf cfg.staticNetworking [
|
||||
{
|
||||
routeConfig = {
|
||||
Gateway = cfg.dmz.ipv4.router;
|
||||
Destination = "0.0.0.0/0";
|
||||
};
|
||||
}
|
||||
{
|
||||
routeConfig = {
|
||||
Gateway = cfg.dmz.ipv6.router;
|
||||
Destination = "::/0";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
(lib.optionalAttrs machine.isRaspberryPi {
|
||||
"30-main-nic" = {
|
||||
matchConfig.Name = "end*";
|
||||
networkConfig = {
|
||||
IPv6AcceptRA = true;
|
||||
DHCP = "yes";
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ in {
|
|||
};
|
||||
|
||||
dataPartition = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = null;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
Partition to be used for data storage on this machine.
|
||||
'';
|
||||
|
@ -25,11 +26,23 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (machine.type == "physical") {
|
||||
fileSystems.${cfg.dataMountPoint}.device = cfg.dataPartition;
|
||||
config = {
|
||||
fileSystems = lib.attrsets.mergeAttrsList [
|
||||
(lib.optionalAttrs machine.isHypervisor {
|
||||
"${cfg.dataMountPoint}".device = cfg.dataPartition;
|
||||
})
|
||||
(lib.optionalAttrs machine.isRaspberryPi {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-label/NIXOS_SD";
|
||||
fsType = "ext4";
|
||||
options = [ "noatime" ];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
# TODO: Rename this to 'osDisk'. Unfortunately, we would need to run nixos-anywhere again then.
|
||||
disko.devices.disk.vdb = {
|
||||
disko = lib.mkIf machine.isHypervisor {
|
||||
devices.disk.vdb = {
|
||||
device = cfg.osDisk;
|
||||
type = "disk";
|
||||
|
||||
|
@ -63,4 +76,5 @@ in {
|
|||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{ pkgs, config, lib, modulesPath, microvm, disko, agenix, machines, dns, ... }: {
|
||||
{ pkgs, config, lib, microvm, disko, agenix, machine, machines, dns, nixos-hardware, ... }: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
microvm.nixosModules.host
|
||||
];
|
||||
]
|
||||
++ lib.lists.optional (machine.isRaspberryPi) nixos-hardware.nixosModules.raspberry-pi-4;
|
||||
|
||||
config = {
|
||||
boot = {
|
||||
boot = lib.mkIf (machine.isHypervisor) {
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
extraModulePackages = [ ];
|
||||
|
||||
|
@ -30,10 +30,11 @@
|
|||
|
||||
nixpkgs = {
|
||||
config.allowUnfree = true;
|
||||
hostPlatform = "x86_64-linux";
|
||||
# TODO: do we need this?
|
||||
# hostPlatform = machine.arch;
|
||||
};
|
||||
|
||||
hardware.cpu.intel.updateMicrocode = config.hardware.enableRedistributableFirmware;
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkIf (machine.isHypervisor) config.hardware.enableRedistributableFirmware;
|
||||
|
||||
age.identityPaths = [ "/etc/age_ed25519" ];
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
imports = [ ./docker_swarm.nix ];
|
||||
|
||||
options.lab.vm = {
|
||||
# TODO: make global.
|
||||
baseMACAddress = lib.mkOption {
|
||||
default = "BA:DB:EE:F0:00:00";
|
||||
type = lib.types.str;
|
||||
|
@ -17,29 +18,6 @@
|
|||
'';
|
||||
};
|
||||
|
||||
staticNetworking = lib.mkOption {
|
||||
default = false;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether this VM has static networking configuration applied.
|
||||
Routing is prepopulated, but IP addresses have to be set.
|
||||
'';
|
||||
};
|
||||
|
||||
staticIPv4 = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Static IPv4 address for the VM.
|
||||
'';
|
||||
};
|
||||
|
||||
staticIPv6 = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Static IPv6 address for the VM.
|
||||
'';
|
||||
};
|
||||
|
||||
shares = lib.mkOption {
|
||||
default = [ ];
|
||||
description = ''
|
||||
|
@ -73,14 +51,18 @@
|
|||
mountPoint = "/etc/ssh/host_keys";
|
||||
}];
|
||||
|
||||
services.openssh = {
|
||||
services.openssh =
|
||||
let
|
||||
hostKeyPath = "/etc/ssh/host_keys/ssh_host_ed25519_key";
|
||||
in
|
||||
{
|
||||
hostKeys = [{
|
||||
path = "/etc/ssh/host_keys/ssh_host_ed25519_key";
|
||||
path = hostKeyPath;
|
||||
type = "ed25519";
|
||||
}];
|
||||
|
||||
extraConfig = ''
|
||||
HostKey /etc/ssh/host_keys/ssh_host_ed25519_key
|
||||
HostKey ${hostKeyPath}
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -108,51 +90,5 @@
|
|||
mac = pkgs.lib.net.mac.add config.lab.vm.id config.lab.vm.baseMACAddress;
|
||||
}];
|
||||
};
|
||||
|
||||
networking.useDHCP = false;
|
||||
|
||||
systemd.network =
|
||||
let
|
||||
cfg = config.lab.networking;
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
|
||||
networks = {
|
||||
"30-main-nic" = {
|
||||
matchConfig.Name = "en*";
|
||||
|
||||
networkConfig = {
|
||||
IPv6AcceptRA = ! config.lab.vm.staticNetworking;
|
||||
DHCP = lib.mkIf (! config.lab.vm.staticNetworking) "yes";
|
||||
|
||||
Address = lib.mkIf config.lab.vm.staticNetworking [
|
||||
"${ config.lab.vm.staticIPv4}/${cfg.dmz.ipv4.prefixLength}"
|
||||
"${config.lab.vm.staticIPv6}/${cfg.dmz.ipv6.prefixLength}"
|
||||
];
|
||||
|
||||
DNS = lib.mkIf config.lab.vm.staticNetworking [
|
||||
cfg.dmz.ipv4.router
|
||||
cfg.dmz.ipv6.router
|
||||
];
|
||||
};
|
||||
|
||||
routes = lib.mkIf config.lab.vm.staticNetworking [
|
||||
{
|
||||
routeConfig = {
|
||||
Gateway = cfg.dmz.ipv4.router;
|
||||
Destination = "0.0.0.0/0";
|
||||
};
|
||||
}
|
||||
{
|
||||
routeConfig = {
|
||||
Gateway = cfg.dmz.ipv6.router;
|
||||
Destination = "::/0";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue