commit 2c975b0df8b5d20b9b121f9dca3fec50a878916b Author: Moritz Böhme Date: Sat Mar 29 22:03:52 2025 +0100 feat: init diff --git a/.clan-flake b/.clan-flake new file mode 100644 index 0000000..406fcfe --- /dev/null +++ b/.clan-flake @@ -0,0 +1,2 @@ +# DO NOT DELETE +# This file is used by the clan cli to discover a clan flake diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..0f94eed --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +# shellcheck shell=bash +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..329b006 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +### direnv ### +.direnv diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c11db04 --- /dev/null +++ b/flake.lock @@ -0,0 +1,204 @@ +{ + "nodes": { + "clan-core": { + "inputs": { + "data-mesher": "data-mesher", + "disko": "disko", + "flake-parts": [ + "flake-parts" + ], + "nixos-facter-modules": "nixos-facter-modules", + "nixpkgs": [ + "nixpkgs" + ], + "sops-nix": "sops-nix", + "systems": "systems", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1743267409, + "narHash": "sha256-A/vHHePZ0R1mCejxQinJlWhZQ0VvyYVjoP0Ln8ZhRvk=", + "ref": "refs/heads/main", + "rev": "f2b04e74f1de4c91c20fe3370402e599da5602b8", + "revCount": 5997, + "type": "git", + "url": "https://git.clan.lol/clan/clan-core" + }, + "original": { + "type": "git", + "url": "https://git.clan.lol/clan/clan-core" + } + }, + "data-mesher": { + "inputs": { + "flake-parts": [ + "clan-core", + "flake-parts" + ], + "nixpkgs": [ + "clan-core", + "nixpkgs" + ], + "systems": [ + "clan-core", + "systems" + ], + "treefmt-nix": [ + "clan-core", + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1743260125, + "narHash": "sha256-sASn5hr5JftCWebc0Ouq+Egy4lX8EE0TQHRm++IT0w0=", + "ref": "refs/heads/main", + "rev": "734883c056e83d24952f5b02e9717a42afc85015", + "revCount": 373, + "type": "git", + "url": "https://git.clan.lol/clan/data-mesher" + }, + "original": { + "type": "git", + "url": "https://git.clan.lol/clan/data-mesher" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741786315, + "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", + "owner": "nix-community", + "repo": "disko", + "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741352980, + "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixos-facter-modules": { + "locked": { + "lastModified": 1738752252, + "narHash": "sha256-/nA3tDdp/2g0FBy8966ppC2WDoyXtUWaHkZWL+N3ZKc=", + "owner": "numtide", + "repo": "nixos-facter-modules", + "rev": "60f8b8f3f99667de6a493a44375e5506bf0c48b1", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nixos-facter-modules", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1743095683, + "narHash": "sha256-gWd4urRoLRe8GLVC/3rYRae1h+xfQzt09xOfb0PaHSk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "5e5402ecbcb27af32284d4a62553c019a3a49ea6", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "clan-core": "clan-core", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1742700801, + "narHash": "sha256-ZGlpUDsuBdeZeTNgoMv+aw0ByXT2J3wkYw9kJwkAS4M=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "67566fe68a8bed2a7b1175fdfb0697ed22ae8852", + "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" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "clan-core", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743081648, + "narHash": "sha256-WRAylyYptt6OX5eCEBWyTwOEqEtD6zt33rlUkr6u3cE=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "29a3d7b768c70addce17af0869f6e2bd8f5be4b7", + "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..86eeb3a --- /dev/null +++ b/flake.nix @@ -0,0 +1,44 @@ +{ + inputs = + { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + + # New flake-parts input + flake-parts.url = "github:hercules-ci/flake-parts"; + flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; + + clan-core = { + url = "git+https://git.clan.lol/clan/clan-core"; + inputs.nixpkgs.follows = "nixpkgs"; # Needed if your configuration uses nixpkgs unstable. + # New + inputs.flake-parts.follows = "flake-parts"; + }; + }; + + outputs = inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } ({ self, pkgs, ... }: { + # We define our own systems below. you can still use this to add system specific outputs to your flake. + # See: https://flake.parts/getting-started + systems = [ "x86_64-linux" ]; + + # import clan-core modules + imports = [ + inputs.clan-core.flakeModules.default + ]; + + perSystem = { config, inputs', pkgs, ... }: { + devShells.default = pkgs.mkShell { + packages = [ inputs'.clan-core.packages.clan-cli ]; + }; + }; + + # Define your clan + # See: https://docs.clan.lol/reference/nix-api/buildclan/ + clan = { + # Clan wide settings. (Required) + meta.name = "cool-clan"; # Ensure to choose a unique name. + + machines = { }; + }; + }); +} diff --git a/machines/moritz-server/configuration.nix b/machines/moritz-server/configuration.nix new file mode 100644 index 0000000..5b85261 --- /dev/null +++ b/machines/moritz-server/configuration.nix @@ -0,0 +1,31 @@ +{ + imports = [ + ../../modules/zfs_unencrypted.nix + ../../modules/shared.nix + ]; + + # This is your user login name. + users.users.user.name = "moritz"; + + # Set this for clan commands use ssh i.e. `clan machines update` + # If you change the hostname, you need to update this line to root@ + # This only works however if you have avahi running on your admin machine else use IP + clan.core.networking.targetHost = "root@"; + + # You can get your disk id by running the following command on the installer: + # Replace with the IP of the installer printed on the screen or by running the `ip addr` command. + # ssh root@ lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT + disko.devices.disk.main.device = "/dev/disk/by-id/ata-TWSC_TSC10N512-F7T10S_TTSMA24C2X01780"; + + # IMPORTANT! Add your SSH key here + # e.g. > cat ~/.ssh/id_ed25519.pub + users.users.root.openssh.authorizedKeys.keys = [ + '' + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDHlemuKagHwz2T5rEwgJNlVUdUdOXyPtCEzD73CrwY2zmpR4AMj7y9u3Rm7HwHUDjLap1ZFwg+53bAsVP6HFZccCXoIfO/8BL0WDGQJrfgb+A+UiRhSqSvyZ77bGJkadbBkadguz3qR3PHcb41DOlhuqVcHxsY8ceHMxAuyb0pLJVJLeytMD+CHS/r7hoj2hckTNAZ+VhCXBtdZfZ7uPUBxLfluYRNNMmdwCglsg3RUS242nJUzy3A84+CXIGeWmNG9Fu45IDkwMthxSW9klyU9R38R9DBDcugkyb6vz+JKSuRVAa47qh/kmtsYekfL3ul9D2JN32P8S+6ZoXx+gXupGJ0ltwJWAFkhLJ+yeXj9kCOv/mIUmCB14jMGsvKiSwV25O/twyjqe2LEkMVgimgrjEYoHu+ZTyp0iFtUvSrFo4tsAhfWPV9yj4F/hUksW7xKIwq5Niyx7he5M/XddudtnAximyiBDGCdJm1Ejl0UaGa6ZQv7y6VZdx0PyZuraT7l9ub8so6JlE4cVgSSU9vE0IS2QqBuHhsIjh8RVksoTR2NQbeDdGaGpGnq2C8y0rDXwE/EJA4LK45khX/GPn73n8F0kBG8dBrWgRDAEODpmebScO7d5mCeM0z3lPcRmh+3e3DPnVVOl+uR7udlc7NauLzl7q913UtxZaF1PlD7Q== cardno:15_584_308 + '' + ]; + + # Zerotier needs one controller to accept new nodes. Once accepted + # the controller can be offline and routing still works. + clan.core.networking.zerotier.controller.enable = true; +} diff --git a/modules/shared.nix b/modules/shared.nix new file mode 100644 index 0000000..16a33e3 --- /dev/null +++ b/modules/shared.nix @@ -0,0 +1,29 @@ +{ config, clan-core, ... }: +{ + imports = [ + # Enables the OpenSSH server for remote access + clan-core.clanModules.sshd + # Set a root password + clan-core.clanModules.root-password + clan-core.clanModules.user-password + clan-core.clanModules.state-version + ]; + + # Locale service discovery and mDNS + services.avahi.enable = true; + + # generate a random password for our user below + # can be read using `clan secrets get -user-password` command + clan.user-password.user = "user"; + users.users.user = { + isNormalUser = true; + extraGroups = [ + "wheel" + "networkmanager" + "video" + "input" + ]; + uid = 1000; + openssh.authorizedKeys.keys = config.users.users.root.openssh.authorizedKeys.keys; + }; +} diff --git a/modules/zfs_unencrypted.nix b/modules/zfs_unencrypted.nix new file mode 100644 index 0000000..81f2d06 --- /dev/null +++ b/modules/zfs_unencrypted.nix @@ -0,0 +1,87 @@ +{ lib +, clan-core +, config +, ... +}: + +let + suffix = config.clan.core.vars.generators.disk-id.files.diskId.value; +in +{ + imports = [ + clan-core.clanModules.disk-id + ]; + + # DO NOT EDIT THIS FILE AFTER INSTALLATION of a machine + # Otherwise your system might not boot because of missing partitions / filesystems + boot.loader.grub.efiSupport = lib.mkDefault true; + boot.loader.grub.efiInstallAsRemovable = lib.mkDefault true; + disko.devices = { + disk = { + "main" = { + # suffix is to prevent disk name collisions + name = "main-" + suffix; + type = "disk"; + # Set the following in flake.nix for each maschine: + # device = ; + content = { + type = "gpt"; + partitions = { + "boot" = { + size = "1M"; + type = "EF02"; # for grub MBR + priority = 1; + }; + "ESP" = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "nofail" ]; + }; + }; + "zfs" = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; + }; + zpool = { + zroot = { + type = "zpool"; + # Workaround: cannot import 'zroot': I/O error in disko tests + options.cachefile = "none"; + rootFsOptions = { + compression = "zstd"; + "com.sun:auto-snapshot" = "false"; + }; + mountpoint = "/"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot@blank$' || zfs snapshot zroot@blank"; + + datasets = { + nix = { + type = "zfs_fs"; + mountpoint = "/nix"; + }; + srv = { + type = "zfs_fs"; + mountpoint = "/srv"; + options."com.sun:auto-snapshot" = "true"; + }; + home = { + type = "zfs_fs"; + mountpoint = "/home"; + options."com.sun:auto-snapshot" = "true"; + }; + }; + }; + }; + }; +}