infra/flake.nix

271 lines
9.7 KiB
Nix
Raw Normal View History

2024-06-23 04:41:53 +00:00
{
description = "Bagel cooking infrastructure";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
terranix.url = "github:terranix/terranix";
terranix.inputs.nixpkgs.follows = "nixpkgs";
2024-06-23 04:41:53 +00:00
2024-06-24 16:03:07 +00:00
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
2024-06-23 04:41:53 +00:00
colmena.url = "github:zhaofengli/colmena";
colmena.inputs.nixpkgs.follows = "nixpkgs";
2024-06-24 14:45:59 +00:00
hydra.url = "git+https://git.lix.systems/lix-project/hydra.git";
2024-06-24 14:45:59 +00:00
hydra.inputs.nixpkgs.follows = "nixpkgs";
2024-06-24 18:59:37 +00:00
nix-gerrit.url = "git+https://git.lix.systems/the-distro/nix-gerrit.git";
nix-gerrit.inputs.nixpkgs.follows = "nixpkgs";
gerrit-dashboard.url = "git+https://git.lix.systems/the-distro/gerrit-monitoring.git";
gerrit-dashboard.flake = false;
buildbot-nix.url = "git+https://git.lix.systems/lix-project/buildbot-nix.git?ref=refs/heads/faster-depinfo";
buildbot-nix.inputs.nixpkgs.follows = "nixpkgs";
channel-scripts.url = "git+https://git.lix.systems/the-distro/channel-scripts.git";
channel-scripts.inputs.nixpkgs.follows = "nixpkgs";
stateless-uptime-kuma.url = "git+https://git.dgnum.eu/DGNum/stateless-uptime-kuma.git";
stateless-uptime-kuma.flake = false;
flake.lock: Update Flake lock file updates: • Updated input 'hydra': 'git+https://git.lix.systems/lix-project/hydra.git?ref=refs/heads/main&rev=fb9e29d4d0f2f591cd1d706fd3b7334af7d34b84' (2024-07-13) → 'git+https://git.lix.systems/lix-project/hydra.git?ref=refs/heads/main&rev=b0e9b4b2f99f9d8f5c4e780e89f955c394b5ced4' (2024-07-17) • Added input 'hydra/lix': 'git+https://git.lix.systems/lix-project/lix?ref=refs/heads/main&rev=6b4d46e9e0e1dd80e0977684ab20d14bcd1a6bc3' (2024-07-16) • Added input 'hydra/lix/flake-compat': 'github:edolstra/flake-compat/0f9255e01c2351cc7d116c072cb317785dd33b33' (2023-10-04) • Added input 'hydra/lix/nix2container': 'github:nlewo/nix2container/20aad300c925639d5d6cbe30013c8357ce9f2a2e' (2024-04-13) • Added input 'hydra/lix/nixpkgs': follows 'hydra/nixpkgs' • Added input 'hydra/lix/nixpkgs-regression': 'github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2' (2022-01-24) • Added input 'hydra/lix/pre-commit-hooks': 'github:cachix/git-hooks.nix/e35aed5fda3cc79f88ed7f1795021e559582093a' (2024-04-02) • Removed input 'hydra/nix' • Removed input 'hydra/nix/flake-compat' • Removed input 'hydra/nix/nix2container' • Removed input 'hydra/nix/nixpkgs' • Removed input 'hydra/nix/nixpkgs-regression' • Removed input 'hydra/nix/pre-commit-hooks' • Added input 'hydra/nix-eval-jobs': 'git+https://git.lix.systems/lix-project/nix-eval-jobs?ref=refs/heads/main&rev=c057494450f2d1420726ddb0bab145a5ff4ddfdd' (2024-07-17) • Added input 'hydra/nix-eval-jobs/flake-parts': 'github:hercules-ci/flake-parts/9227223f6d922fee3c7b190b2cc238a99527bbb7' (2024-07-03) • Added input 'hydra/nix-eval-jobs/flake-parts/nixpkgs-lib': follows 'hydra/nix-eval-jobs/nixpkgs' • Added input 'hydra/nix-eval-jobs/lix': follows 'hydra/lix' • Added input 'hydra/nix-eval-jobs/nix-github-actions': 'github:nix-community/nix-github-actions/622f829f5fe69310a866c8a6cd07e747c44ef820' (2024-07-04) • Added input 'hydra/nix-eval-jobs/nix-github-actions/nixpkgs': follows 'hydra/nix-eval-jobs/nixpkgs' • Added input 'hydra/nix-eval-jobs/nixpkgs': follows 'hydra/nixpkgs' • Added input 'hydra/nix-eval-jobs/treefmt-nix': 'github:numtide/treefmt-nix/0fb28f237f83295b4dd05e342f333b447c097398' (2024-07-15) • Added input 'hydra/nix-eval-jobs/treefmt-nix/nixpkgs': follows 'hydra/nix-eval-jobs/nixpkgs' • Updated input 'lix': follows 'hydra/nix' → follows 'hydra/lix' • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/6794d064edc69918bb0fc0e0eda33ece324be17a' (2024-07-12) → 'github:NixOS/nixpkgs/9355fa86e6f27422963132c2c9aeedb0fb963d93' (2024-07-16)
2024-07-17 11:10:53 +00:00
lix.follows = "hydra/lix";
grapevine = {
type = "gitlab";
host = "gitlab.computer.surgery";
owner = "matrix";
repo = "grapevine-fork";
inputs.nixpkgs.follows = "nixpkgs";
};
2024-06-23 04:41:53 +00:00
};
outputs = { self, nixpkgs, terranix, colmena, ... } @ inputs:
let
supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
forEachSystem = f: builtins.listToAttrs (map (system: {
name = system;
value = f system;
}) supportedSystems);
systemBits = forEachSystem (system: rec {
inherit system;
pkgs = import nixpkgs {
localSystem = system;
overlays = [
inputs.hydra.overlays.default
inputs.lix.overlays.default
inputs.nix-gerrit.overlays.default
inputs.channel-scripts.overlays.default
(import "${inputs.stateless-uptime-kuma}/overlay.nix")
];
};
terraform = pkgs.opentofu;
terraformCfg = terranix.lib.terranixConfiguration {
inherit system;
extraArgs = {
inherit (self) nixosConfigurations;
};
modules = [
./terraform
{
bagel.dnsimple.enable = true;
bagel.hydra.enable = true;
}
];
};
});
forEachSystem' = f: forEachSystem (system: (f systemBits.${system}));
inherit (nixpkgs) lib;
in
{
apps = forEachSystem' ({ system, pkgs, terraformCfg, terraform, ... }: {
tf = {
type = "app";
program = toString (pkgs.writers.writeBash "tf" ''
set -eo pipefail
ln -snf ${terraformCfg} config.tf.json
exec ${lib.getExe terraform} "$@"
'');
};
2024-07-07 16:02:55 +00:00
default = self.apps.${system}.tf;
});
2024-07-05 09:43:53 +00:00
devShells = forEachSystem' ({ system, pkgs, ... }: {
default = pkgs.mkShell {
packages = [
inputs.agenix.packages.${system}.agenix
pkgs.opentofu
(pkgs.callPackage ./lib/colmena-wrapper.nix { })
];
};
});
2024-07-05 09:43:53 +00:00
nixosConfigurations = (colmena.lib.makeHive self.outputs.colmena).nodes;
2024-07-10 12:24:47 +00:00
colmena = let
commonModules = [
inputs.agenix.nixosModules.default
inputs.hydra.nixosModules.hydra
inputs.buildbot-nix.nixosModules.buildbot-coordinator
inputs.buildbot-nix.nixosModules.buildbot-worker
2024-07-10 12:24:47 +00:00
./services
./common
];
floralInfraModules = commonModules ++ [
({ config, lib, ... }: {
# This means that anyone with @floral-infra permissions
# can ssh on root of every machines handled here.
bagel.admins.allowedGroups = [
"floral-infra"
];
# Tag all machines which have local boot as local bootables.
deployment.tags = lib.mkMerge [
[ "floral" ]
# All nodes that can be local booted, including baremetal nodes.
(lib.mkIf (config.bagel.baremetal.enable -> !config.bagel.baremetal.netboot)
[ "localboot" ]
)
# Only baremetal nodes that can be local booted.
(lib.mkIf (config.bagel.baremetal.enable && !config.bagel.baremetal.netboot)
[ "bm-localboot" ]
)
];
bagel.monitoring.grafana-agent.tenant = "floral";
bagel.secrets.tenant = "floral";
bagel.builders.extra-build-capacity.provider.tenant = "floral";
bagel.services.buildbot.tenant = "floral";
})
2024-07-10 12:24:47 +00:00
];
# These are Floral baremetal builders.
makeColoBaremetal = i:
let
enableNetboot = i >= 6;
in
# bm for baremetal.
lib.nameValuePair "bm-${toString i}" {
imports = floralInfraModules;
bagel.baremetal = { enable = true; num = i; netboot = enableNetboot; };
};
setFlavorForNode = flavor: i: node: {
imports = [
node
];
bagel.baremetal.${flavor} = {
enable = true;
num = i;
};
};
setFlavorForNodes = flavor: { ranges }: nodes:
let
setFlavor = setFlavorForNode flavor;
# Test if i is in [range.start, range.end[.
inRange = i: range: i >= range.start && i < range.end;
# Perform an enumeration from values to indexes.
reverseEnumerate = list: lib.listToAttrs (lib.zipListsWith (i: x: lib.nameValuePair x i) (lib.range 0 (lib.length list - 1)) list);
# Filter all nodes by the range data for this flavor.
filteredNodes = lib.filterAttrs (name: node: lib.any (r: inRange node.bagel.baremetal.num r) ranges) nodes;
# The enumeration from baremetal numbers to flavor-specific numbers.
indexes = reverseEnumerate (map (n: toString n.bagel.baremetal.num) (builtins.attrValues filteredNodes));
in
# Build a new attrset with a new second-level index for the specific flavor.
lib.mapAttrs (name: node: setFlavor indexes.${toString node.bagel.baremetal.num} node) filteredNodes;
closedOpenInterval = a: b: { start = a; end = b; };
interval = a: b: closedOpenInterval a b;
setStorage = setFlavorForNodes "storage" {
# List the indexes for the baremetal nodes which are supposed to be storage nodes.
ranges = [ (interval 5 6) ];
};
setBuilders = setFlavorForNodes "builders" {
# List the indexes for the baremetal nodes which are supposed to be builders nodes.
ranges = [ (interval 0 5) (interval 6 10) ];
2024-07-10 12:24:47 +00:00
};
lixInfraModules = commonModules ++ [
{
# This means that anyone with @lix-infra permissions
# can ssh on root of every machines handled here.
bagel.admins.allowedGroups = [
"lix-infra"
];
# Tag all machines which have local boot as local bootables.
# Lix has no netbootable machine.
deployment.tags = [ "localboot" "lix" ];
bagel.monitoring.grafana-agent.tenant = "lix";
bagel.secrets.tenant = "lix";
bagel.builders.extra-build-capacity.provider = {
tenant = "lix";
buildfarmPublicKeys = [
# buildbot.lix.systems SSH key
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDu4cEqZzAI/1vZjSQkTJ4ijIg9nuloOuSKUrnkJIOFn"
];
};
bagel.services.buildbot.tenant = "lix";
}
];
checkForNonReuse = setOfNodes:
let
setOfNodesNames = lib.mapAttrs (name: nodes: builtins.attrNames nodes) setOfNodes;
in
lib.all (set:
lib.all (anotherSet: set != anotherSet -> lib.intersectLists setOfNodesNames.${set} setOfNodesNames.${anotherSet} == []) (builtins.attrNames setOfNodes)
) (builtins.attrNames setOfNodes);
baremetalNodes =
let
allNodes = lib.listToAttrs (lib.genList makeColoBaremetal 11);
perRoles = {
storageNodes = setStorage allNodes;
builderNodes = setBuilders allNodes;
};
in
assert (lib.assertMsg (checkForNonReuse perRoles) "A baremetal node is simultaneously storage and builder, please review the ranges.");
lib.foldl (a: b: a // b) { } (builtins.attrValues perRoles);
2024-07-10 12:24:47 +00:00
in {
meta.nixpkgs = systemBits.x86_64-linux.pkgs;
# Add any non-x86_64 native systems here.
# Cross compilation is not supported yet.
meta.nodeNixpkgs =
let
aarch64-systems = systems: lib.genAttrs systems (system: systemBits.aarch64-linux.pkgs);
in
aarch64-systems [
"build01-aarch64-lix"
];
2024-06-24 14:45:59 +00:00
meta.specialArgs.inputs = inputs;
bagel-box.imports = floralInfraModules ++ [ ./hosts/bagel-box ];
meta01.imports = floralInfraModules ++ [ ./hosts/meta01 ];
gerrit01.imports = floralInfraModules ++ [ ./hosts/gerrit01 ];
fodwatch.imports = floralInfraModules ++ [ ./hosts/fodwatch ];
git.imports = floralInfraModules ++ [ ./hosts/git ];
wob-vpn-gw.imports = floralInfraModules ++ [ ./hosts/wob-vpn-gw ];
buildbot.imports = floralInfraModules ++ [ ./hosts/buildbot ];
public01.imports = floralInfraModules ++ [ ./hosts/public01 ];
build-coord.imports = floralInfraModules ++ [ ./hosts/build-coord ];
build01-aarch64-lix.imports = lixInfraModules ++ [ ./hosts/build01-aarch64-lix ];
buildbot-lix.imports = lixInfraModules ++ [ ./hosts/buildbot-lix ];
} // baremetalNodes;
2024-08-01 20:47:25 +00:00
hydraJobs = builtins.mapAttrs (n: v: v.config.system.build.netbootDir or v.config.system.build.toplevel) self.nixosConfigurations;
buildbotJobs = builtins.mapAttrs (_: v: v.config.system.build.toplevel) self.nixosConfigurations;
2024-06-23 04:41:53 +00:00
};
}