From dc7afdf7916ec2fb568481921ce432391f711bf3 Mon Sep 17 00:00:00 2001 From: Chris Kruining Date: Mon, 15 Sep 2025 16:25:34 +0200 Subject: [PATCH] initial set up for k3s service --- clanServices/flake-module.nix | 21 ++ clanServices/k3s/README.md | 0 clanServices/k3s/agent.nix | 28 +++ clanServices/k3s/default.nix | 45 +++++ clanServices/k3s/flake-module.nix | 15 ++ clanServices/k3s/server.nix | 55 ++++++ clanServices/k3s/tests/vm/default.nix | 40 ++++ flake.lock | 264 ++++++++++++++++++++++++++ flake.nix | 23 +++ 9 files changed, 491 insertions(+) create mode 100644 clanServices/flake-module.nix create mode 100644 clanServices/k3s/README.md create mode 100644 clanServices/k3s/agent.nix create mode 100644 clanServices/k3s/default.nix create mode 100644 clanServices/k3s/flake-module.nix create mode 100644 clanServices/k3s/server.nix create mode 100644 clanServices/k3s/tests/vm/default.nix create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/clanServices/flake-module.nix b/clanServices/flake-module.nix new file mode 100644 index 0000000..97a4c91 --- /dev/null +++ b/clanServices/flake-module.nix @@ -0,0 +1,21 @@ +{ ... }: +{ + imports = + let + # Get all subdirectories in the current directory + dirContents = builtins.readDir ./.; + + # Filter to include only directories that have a flake-module.nix file + # and exclude special directories like 'result' + validModuleDirs = builtins.filter ( + name: + name != "result" + && dirContents.${name} == "directory" + && builtins.pathExists (./. + "/${name}/flake-module.nix") + ) (builtins.attrNames dirContents); + + # Create import paths for each valid directory + imports = map (name: ./. + "/${name}/flake-module.nix") validModuleDirs; + in + imports; +} diff --git a/clanServices/k3s/README.md b/clanServices/k3s/README.md new file mode 100644 index 0000000..e69de29 diff --git a/clanServices/k3s/agent.nix b/clanServices/k3s/agent.nix new file mode 100644 index 0000000..fe16499 --- /dev/null +++ b/clanServices/k3s/agent.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: +let + controller = head (lib.attrNames roles.controller.machines or {}); +in +{ + config = { + networking.firewall = { + allowedTCPPorts = [ + 6443 # k3s: required so that pods can reach the API server (running on port 6443 by default) + 2379 # k3s, etcd clients: required if using a "High Availability Embedded etcd" configuration + 2380 # k3s, etcd peers: required if using a "High Availability Embedded etcd" configuration + ]; + + allowedUDPPorts = [ + 8472 # k3s, flannel: required if using multi-node for inter-node networking + ]; + }; + + services = { + k3s = { + enable = true; + role = "agent"; + token = "somehow get the token that is generated for the controller"; # config.clan.core.vars.generators.k3s-token.token.value; + serverAddr = "https://"; + }; + }; + }; +} \ No newline at end of file diff --git a/clanServices/k3s/default.nix b/clanServices/k3s/default.nix new file mode 100644 index 0000000..5d00f01 --- /dev/null +++ b/clanServices/k3s/default.nix @@ -0,0 +1,45 @@ +{ ... }: +let + inherit (builtins) readFile head; +in +{ + _class = "clan.service"; + + manifest = { + name = "amarth/k3s"; + description = "amarth/k3s"; + categories = [ "System" "Network" ]; + readme = readFile ./README.md; + }; + + #============================================================================================================== + # Server configuration + #============================================================================================================== + roles.server = { + interface = { lib, ... }: { + options.name = lib.mkOption { + type = lib.types.str; + default = ""; + example = "some-name"; + description = '' + Temporary option till I figure out something useful + ''; + }; + }; + + perInstance = { settings, ... }: { + nixosModule = ./server.nix; + }; + }; + + #============================================================================================================== + # Agent configuration + #============================================================================================================== + roles.agent = { + interface = { lib, ... }: { }; + + perInstance = { settings, instanceName, roles, ... }: { + nixosModule = ./agent.nix; + }; + }; +} \ No newline at end of file diff --git a/clanServices/k3s/flake-module.nix b/clanServices/k3s/flake-module.nix new file mode 100644 index 0000000..37fc062 --- /dev/null +++ b/clanServices/k3s/flake-module.nix @@ -0,0 +1,15 @@ +{ lib, ... }: +let + module = lib.modules.importApply ./default.nix {}; +in +{ + clan.modules.k3s = module; + + perSystem = { ... }: { + # clan.nixosTests.k3s = { + # imports = [ ./tests/vm/default.nix ]; + + # clan.modules."@amarth/k3s" = module; + # }; + }; +} \ No newline at end of file diff --git a/clanServices/k3s/server.nix b/clanServices/k3s/server.nix new file mode 100644 index 0000000..2fc9208 --- /dev/null +++ b/clanServices/k3s/server.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: +{ + config = { + clan.core.vars.generators = { + k3s-ip = { + share = true; + files.ip_v6 = { + deploy = false; + secret = false; + }; + files.ip_v4 = { + deploy = false; + secret = false; + }; + script = '' + echo "::1" > "$out/ip_v6" + echo "127.0.0.1" > "$out/ip_v4" + ''; + }; + + k3s-token = { + share = true; + files.token = { + deploy = false; + secret = true; + }; + runtimeInputs = with pkgs; [ pwgen ]; + script = '' + pwgen 50 1 > "$out/token" + ''; + }; + }; + + networking.firewall = { + allowedTCPPorts = [ + 6443 # k3s: required so that pods can reach the API server (running on port 6443 by default) + 2379 # k3s, etcd clients: required if using a "High Availability Embedded etcd" configuration + 2380 # k3s, etcd peers: required if using a "High Availability Embedded etcd" configuration + ]; + + allowedUDPPorts = [ + 8472 # k3s, flannel: required if using multi-node for inter-node networking + ]; + }; + + services = { + k3s = { + enable = true; + role = "server"; + token = config.clan.core.vars.generators.k3s-token.token.value; + clusterInit = true; + }; + }; + }; +} \ No newline at end of file diff --git a/clanServices/k3s/tests/vm/default.nix b/clanServices/k3s/tests/vm/default.nix new file mode 100644 index 0000000..b011702 --- /dev/null +++ b/clanServices/k3s/tests/vm/default.nix @@ -0,0 +1,40 @@ +{ pkgs, ... }: +{ + name = "service-k3s"; + + clan = { + directory = ./.; + + inventory = { + machines = { + node1 = {}; + node2 = {}; + node3 = {}; + }; + + instances = { + k3s = { + module = { + name = "@amarth/k3s"; + input = "self"; + }; + + roles.server.machines."node1" = {}; + + roles.agent.machines."node2" = {}; + roles.agent.machines."node3" = {}; + }; + }; + }; + + nodes = { + node1 = {}; + node2 = {}; + node3 = {}; + }; + + testScript = '' + start_all() + ''; + }; +} \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..38c01a0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,264 @@ +{ + "nodes": { + "clan-core": { + "inputs": { + "data-mesher": "data-mesher", + "disko": "disko", + "flake-parts": "flake-parts", + "nix-darwin": "nix-darwin", + "nix-select": "nix-select", + "nixos-facter-modules": "nixos-facter-modules", + "nixpkgs": "nixpkgs", + "sops-nix": "sops-nix", + "systems": "systems", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1757912940, + "narHash": "sha256-Xypz7pxa1L09GooMueosv0CRW4Cx5/gdtvSPBrnXf6M=", + "rev": "93280a9f987bbe689c74f1ea21d0c2fa4645c359", + "type": "tarball", + "url": "https://git.clan.lol/api/v1/repos/clan/clan-core/archive/93280a9f987bbe689c74f1ea21d0c2fa4645c359.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://git.clan.lol/clan/clan-core/archive/main.tar.gz" + } + }, + "data-mesher": { + "inputs": { + "flake-parts": [ + "clan-core", + "flake-parts" + ], + "nixpkgs": [ + "clan-core", + "nixpkgs" + ], + "treefmt-nix": [ + "clan-core", + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1757905600, + "narHash": "sha256-Yd7buL9N7N7IaDVViItqP9HsECfnlDFykxvvNgMYcKk=", + "rev": "c10c4002bdc5aef040fcbb814d5f482e82dc8345", + "type": "tarball", + "url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/c10c4002bdc5aef040fcbb814d5f482e82dc8345.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://git.clan.lol/clan/data-mesher/archive/main.tar.gz" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1757508292, + "narHash": "sha256-7lVWL5bC6xBIMWWDal41LlGAG+9u2zUorqo3QCUL4p4=", + "owner": "nix-community", + "repo": "disko", + "rev": "146f45bee02b8bd88812cfce6ffc0f933788875a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1756770412, + "narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "4524271976b625a4a605beefd893f270620fd751", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1756770412, + "narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "4524271976b625a4a605beefd893f270620fd751", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1757430124, + "narHash": "sha256-MhDltfXesGH8VkGv3hmJ1QEKl1ChTIj9wmGAFfWj/Wk=", + "owner": "nix-darwin", + "repo": "nix-darwin", + "rev": "830b3f0b50045cf0bcfd4dab65fad05bf882e196", + "type": "github" + }, + "original": { + "owner": "nix-darwin", + "repo": "nix-darwin", + "type": "github" + } + }, + "nix-select": { + "locked": { + "lastModified": 1755887746, + "narHash": "sha256-lzWbpHKX0WAn/jJDoCijIDss3rqYIPawe46GDaE6U3g=", + "rev": "92c2574c5e113281591be01e89bb9ddb31d19156", + "type": "tarball", + "url": "https://git.clan.lol/api/v1/repos/clan/nix-select/archive/92c2574c5e113281591be01e89bb9ddb31d19156.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://git.clan.lol/clan/nix-select/archive/main.tar.gz" + } + }, + "nixos-facter-modules": { + "locked": { + "lastModified": 1756491981, + "narHash": "sha256-lXyDAWPw/UngVtQfgQ8/nrubs2r+waGEYIba5UX62+k=", + "owner": "nix-community", + "repo": "nixos-facter-modules", + "rev": "c1b29520945d3e148cd96618c8a0d1f850965d8c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-facter-modules", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 315532800, + "narHash": "sha256-h8Sx4S+/0FpodZji6W9lHzwY5BcuUG85Aj3GfhvGC2o=", + "rev": "a650b5d0de99158323597f048667c4d914243224", + "type": "tarball", + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.11pre845298.a650b5d0de99/nixexprs.tar.xz" + }, + "original": { + "type": "tarball", + "url": "https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz" + } + }, + "root": { + "inputs": { + "clan-core": "clan-core", + "flake-parts": "flake-parts_2", + "nixpkgs": [ + "clan-core", + "nixpkgs" + ], + "systems": "systems_2" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1757449901, + "narHash": "sha256-qwN8nYdSRnmmyyi+uR6m4gXnVktmy5smG1MOrSFD8PI=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "3b4a369df9dd6ee171a7ea4448b50e2528faf850", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "id": "systems", + "type": "indirect" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1756662192, + "narHash": "sha256-F1oFfV51AE259I85av+MAia221XwMHCOtZCMcZLK2Jk=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "1aabc6c05ccbcbf4a635fb7a90400e44282f61c4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e6842f2 --- /dev/null +++ b/flake.nix @@ -0,0 +1,23 @@ +{ + description = "Amarth Cloud's Clan services"; + + inputs = { + clan-core.url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz"; + + nixpkgs.follows = "clan-core/nixpkgs"; + + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + }; + + outputs = inputs@{ flake-parts, clan-core, systems, ... }: flake-parts.lib.mkFlake { inherit inputs; } ({ self, lib, ... }: { + imports = [ + clan-core.flakeModules.default + ./clanServices/flake-module.nix + ]; + + systems = import systems; + }); +} \ No newline at end of file