commit aae151cee631e00eb6038056c55ccc07613f66e9 Author: dokkae.cat Date: Sun Jan 11 01:42:54 2026 +0000 init diff --git a/flake.lock b/flake.lock new file mode 100755 index 0000000..9ef8a4c --- /dev/null +++ b/flake.lock @@ -0,0 +1,181 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1766150702, + "narHash": "sha256-P0kM+5o+DKnB6raXgFEk3azw8Wqg5FL6wyl9jD+G5a4=", + "owner": "nix-community", + "repo": "disko", + "rev": "916506443ecd0d0b4a0f4cf9d40a3c22ce39b378", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1767609335, + "narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "250481aafeb741edfe23d29195671c19b36b6dca", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1767909183, + "narHash": "sha256-u/bcU0xePi5bgNoRsiqSIwaGBwDilKKFTz3g0hqOBAo=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "cd6e96d56ed4b2a779ac73a1227e0bb1519b3509", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "impermanence", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1747978958, + "narHash": "sha256-pQQnbxWpY3IiZqgelXHIe/OAE/Yv4NSQq7fch7M6nXQ=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "7419250703fd5eb50e99bdfb07a86671939103ea", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "inputs": { + "home-manager": "home-manager_2", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1767822991, + "narHash": "sha256-iyrn9AcPZCoyxX4OT8eMkBsjG7SRUQXXS/V1JzxS7rA=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "82e5bc4508cab9e8d5a136626276eb5bbce5e9c5", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1748026106, + "narHash": "sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "063f43f2dbdef86376cc29ad646c45c46e93234c", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1765674936, + "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1767767207, + "narHash": "sha256-Mj3d3PfwltLmukFal5i3fFt27L6NiKXdBezC1EBuZs4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5912c1772a44e31bf1c63c0390b90501e5026886", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "flake-parts": "flake-parts", + "home-manager": "home-manager", + "impermanence": "impermanence", + "nixpkgs": "nixpkgs_2", + "sops-nix": "sops-nix" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1767826491, + "narHash": "sha256-WSBENPotD2MIhZwolL6GC9npqgaS5fkM7j07V2i/Ur8=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "ea3adcb6d2a000d9a69d0e23cad1f2cacb3a9fbe", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100755 index 0000000..006b1ff --- /dev/null +++ b/flake.nix @@ -0,0 +1,90 @@ +{ + description = "Personal system configurations"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + impermanence.url = "github:nix-community/impermanence"; + + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, flake-parts, ... } @ inputs: let + inherit (self) outputs; + in + flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ + inputs.home-manager.flakeModules.home-manager + ]; + + # Systems the "perSystem" option will target. + systems = [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-linux" + "aarch64-darwin" + "i686-linux" + ]; + + # Outputs for each above defined system. + perSystem = { pkgs, ... }: { + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + just + ]; + }; + }; + + # Flake configuration attributes. + flake = { + # Reusable nixos modules one might want to export. + # Usually bundled pre-configured configuration toggles for my systems. + nixosModules = import ./modules/nixos; + # Reusable home-manager modules one might want to export. + # Usually bundled pre-configured configuration toggles for my homes. + homeManagerModules = import ./modules/home-manager; + + nixosConfigurations = { + makise = inputs.nixpkgs.lib.nixosSystem { + specialArgs = { inherit inputs outputs; }; + modules = [ + ./hosts/makise/system/system.nix + ]; + }; + }; + + homeConfigurations = { + "kurisu@makise" = inputs.home-manager.lib.homeManagerConfiguration { + pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; + extraSpecialArgs = { inherit inputs outputs; }; + modules = [ + ./hosts/makise/homes/kurisu/home.nix + ]; + }; + + "admin@makise" = inputs.home-manager.lib.homeManagerConfiguration { + pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; + extraSpecialArgs = { inherit inputs outputs; }; + modules = [ + ./hosts/makise/homes/admin/default.nix + ]; + }; + }; + }; + }; +} diff --git a/hosts/makise/.sops.yaml b/hosts/makise/.sops.yaml new file mode 100755 index 0000000..d6e981f --- /dev/null +++ b/hosts/makise/.sops.yaml @@ -0,0 +1,9 @@ +keys: + - &host_makise age1pj86dmk8j5tne0r7zu09v3x40xjdae6mhvrzyw5squ9px96z9p0suj89f8 + - &user_kurisu age1w3n63wg0pkjy300hsaw6uvd6ell7hpkfpd7knjsp637u2dcjx3nql654fm +creation_rules: + - path_regex: secrets/[^/]+\.(yaml|json|env|ini)$ + key_groups: + - age: + - *host_makise + - *user_kurisu diff --git a/hosts/makise/homes/admin/default.nix b/hosts/makise/homes/admin/default.nix new file mode 100755 index 0000000..17b9d02 --- /dev/null +++ b/hosts/makise/homes/admin/default.nix @@ -0,0 +1,30 @@ +{ inputs +, pkgs +, ... +}: + +{ + imports = [ + # ./configuration + ]; + + nixpkgs = { + config = { + allowUnfree = true; + }; + }; + + home = { + username = "admin"; + homeDirectory = "/home/admin"; + + # !!! DO NOT TOUCH !!! + stateVersion = "26.05"; + }; + + # Enable essential programs. + programs.home-manager.enable = true; + + # Nicely reload user system units when changed. + systemd.user.startServices = "sd-switch"; +} diff --git a/hosts/makise/homes/kurisu/configuration/default.nix b/hosts/makise/homes/kurisu/configuration/default.nix new file mode 100755 index 0000000..d0cbcc1 --- /dev/null +++ b/hosts/makise/homes/kurisu/configuration/default.nix @@ -0,0 +1,27 @@ +{ outputs +, ... +}: +let + modules = outputs.homeManagerModules; +in +{ + imports = [ + modules.editors + modules.shells + + ./git.nix + ]; + + custom = { + editors = { + defaultEditor = "helix"; + helix.enable = true; + }; + + shells = { + fish.enable = true; + direnv.enable = true; + zellij.enable = true; + }; + }; +} diff --git a/hosts/makise/homes/kurisu/configuration/git.nix b/hosts/makise/homes/kurisu/configuration/git.nix new file mode 100644 index 0000000..56c33a0 --- /dev/null +++ b/hosts/makise/homes/kurisu/configuration/git.nix @@ -0,0 +1,27 @@ +{ ... +}: + +{ + programs.git = { + enable = true; + + settings = { + user = { + name = "dokkae.cat"; + email = "finnliry@gmail.com"; + }; + + init.defaultBranch = "main"; + safe.directory = "/etc/nixos"; + }; + + ignores = [ + ".idea/" + ".helix/" + ".direnv/" + + ".envrc" + ".ignore" + ]; + }; +} diff --git a/hosts/makise/homes/kurisu/home.nix b/hosts/makise/homes/kurisu/home.nix new file mode 100755 index 0000000..3d91be3 --- /dev/null +++ b/hosts/makise/homes/kurisu/home.nix @@ -0,0 +1,30 @@ +{ inputs +, pkgs +, ... +}: + +{ + imports = [ + ./configuration + ]; + + nixpkgs = { + config = { + allowUnfree = true; + }; + }; + + home = { + username = "kurisu"; + homeDirectory = "/home/kurisu"; + + # !!! DO NOT TOUCH !!! + stateVersion = "26.05"; + }; + + # Enable essential programs. + programs.home-manager.enable = true; + + # Nicely reload user system units when changed. + systemd.user.startServices = "sd-switch"; +} diff --git a/hosts/makise/secrets/default.yaml b/hosts/makise/secrets/default.yaml new file mode 100755 index 0000000..55a9d23 --- /dev/null +++ b/hosts/makise/secrets/default.yaml @@ -0,0 +1,35 @@ +users: + admin: + password_hash: ENC[AES256_GCM,data:xrlPAn4BIbijmhhytipFv+ok/sS5NCn9k+eoSsMXOSRqxwRJCtsv/+DCWg8jd7N3YpgarmDBxcr9LN51KnP+FmzRbmlYt4MDeG1ttvos/W+TEgj+v1bZOOjMoyBj5r1VRdWabbG3g3lTTQ==,iv:Ue8w4NgYgJvpeyEVvmPJODCW30VutJDYe7cSIWchVkc=,tag:3sQX2I+N9BmaxHEK4bMttA==,type:str] + kurisu: + password_hash: ENC[AES256_GCM,data:CeKLgF+zFhoHa6bjzweFbLeElgVGMzPaqxV08ggppHADaDf5cyZ0hg/hattQBppVPYKti907EJMmPewVmo4OfGa0E1gyN9JVAUTaKyG3eNqlij4SpUSx7rIm1JRuWz16QSdRQ/5U5ZFFXw==,iv:Ct6C2MnGg3P6VLv8GIeTDHwq0okdgK1Q/14znEpTqcw=,tag:+ldoe5MiGjcrha052NtkRQ==,type:str] +forgejo: + admin: + dokkae.cat: + password: ENC[AES256_GCM,data:FBmMqD+zROFZ4A==,iv:uh1t3+fMylalXqIQGwzRQoZwoT6kP0xRmkrs3ygVqeA=,tag:tXMNEFcWbPW/kaADN1urow==,type:str] + mailer: + password: ENC[AES256_GCM,data:HoxA9HNIMf0rnltDJrOynvoKzQ==,iv:/9YlRJI2WMjtuyLJJFJInxDpngdiQ1g+L9cel+tISy0=,tag:R3nRPmu23G0zOPEZQkUSug==,type:str] +sops: + age: + - recipient: age1pj86dmk8j5tne0r7zu09v3x40xjdae6mhvrzyw5squ9px96z9p0suj89f8 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0d1IvelNVbUhoUGY4TVRH + Q01zN0thbi9Jc2lZei9NcW5ZcUNTNkxJdVRFCkVscGNUWjVuT1dsMFFBSVRHZGI3 + VXZNdUtXaDVVQ0VJUGRlR21tbjZ4K28KLS0tIHhEK2lQRmJud2hDTENUeHpvb29H + ZlJjZkJnbXRBc0JkS3pidG13K1BPS1UKHTUkEfwNtDf+c2UVcp1SInS2e7frvFXd + o4aqAAD8w1/xdjDneus9OmMruwKUbh5bE3Oh0fZGHySVshkLpPhrJg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1w3n63wg0pkjy300hsaw6uvd6ell7hpkfpd7knjsp637u2dcjx3nql654fm + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjRXo0dEphcDVxVU9tUnov + TlRJZTVaZi9iZmVneE92WDZ5WlRHRGhCSWg0CjZES0duazdUOVJrcEFzWCt0UjVt + TEZNNkJEb0VKamFlUkVXWEl5Y01BeDAKLS0tIHMyT28vT09DRVFPdVhzQ0dJL0Rk + MTJWN0R6VUR6c21iVE1tK0VPL2NoYzAKrGwbTolQpUWcFRyJ6M1KVQ3odS4leYvW + KZZUx9n9O6j9LH2tHH6ut1maiDXfLkBTnEeXrogp+oK075QVKXfUBA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-01-10T19:58:26Z" + mac: ENC[AES256_GCM,data:N/eVKWgRdTCHxcTkeKpBUxiVF7OKRdUtpBj+dM2c5uclKxwSHB5jw/GuZjcrq8BQvTjgwZxnH6Q7D05c+tFOl+P1m/LrnZLtIxH/iynqMavFwXsBXFF+1ngY+CwLflsagtiNhKp/JxvIKRSaSlNTxGL7NqX6feeTNQirA0CFs0M=,iv:z0MpIYnONpEIfu90takM398GapmkuuGZGC0y3kFjZP0=,tag:/gz+ngidM0fJPCI7b7ABDw==,type:str] + unencrypted_suffix: _unencrypted + version: 3.11.0 diff --git a/hosts/makise/system/configuration/default.nix b/hosts/makise/system/configuration/default.nix new file mode 100755 index 0000000..f260f86 --- /dev/null +++ b/hosts/makise/system/configuration/default.nix @@ -0,0 +1,27 @@ +{ outputs +, ... +}: + +let + modules = outputs.nixosModules; +in +{ + imports = [ + modules.shells + + ./sops.nix + ./forgejo.nix + ./gc.nix + ./postgres.nix + ./ssh.nix + ./traefik.nix + ./users.nix + ]; + + custom = { + shells.fish = { + enable = true; + defaultFor = [ "root" "kurisu" ]; + }; + }; +} diff --git a/hosts/makise/system/configuration/forgejo.nix b/hosts/makise/system/configuration/forgejo.nix new file mode 100755 index 0000000..09a6a6f --- /dev/null +++ b/hosts/makise/system/configuration/forgejo.nix @@ -0,0 +1,85 @@ +{ config +, lib +, pkgs +, ... +}: + +{ + networking.firewall.allowedTCPPorts = [ 22 ]; + + services.traefik.dynamicConfigOptions.http = { + routers.forgejo = { + rule = "Host(`git.dokkae.duckdns.org`)"; + service = "forgejo"; + entryPoints = [ "websecure" ]; + tls = { certResolver = "letsencrypt"; }; + }; + + services.forgejo = { + loadBalancer.servers = [ + { url = "http://localhost:3003"; } + ]; + }; + }; + + services.forgejo = { + enable = true; + database = { + type = "postgres"; + host = "/run/postgresql"; + name = "forgejo"; + user = "forgejo"; + }; + + lfs.enable = false; + + settings = { + server = { + DOMAIN = "localhost"; + PROTOCOL = "http"; + HTTP_PORT = 3003; + + # Used for web-displayed URL references. + ROOT_URL = "https://git.dokkae.duckdns.org/"; + + # SSH Settings + SSH_DOMAIN = "git.dokkae.duckdns.org"; + SSH_PORT = 22; + START_SSH_SERVER = false; + }; + + services = { + # Can be temporarily disabled to allow registration of an admin user. + # Admin account can manually create new users via web interface. + DISABLE_REGISTRATION = true; + }; + + actions = { + ENABLED = true; + DEFAULT_ACTIONS_URL = "github"; + }; + + # Optional email server configuration. + # Test mails can be sent via: Profile Picture > Site Administration > Configuration > Mailer Configuration + mailer = { + ENABLED = true; + SMTP_ADDR = "smtp.gmail.com"; + FROM = "noreply@git.dokkae.duckdns.org"; + USER = "finnliry@gmail.com"; + }; + }; + + secrets = { + mailer.PASSWD = config.sops.secrets."forgejo/mailer/password".path; + }; + }; + + systemd.services.forgejo.preStart = let + adminCmd = "${lib.getExe config.services.forgejo.package} admin user"; + pwdPath = config.sops.secrets."forgejo/admin/dokkae.cat/password".path; + user = "dokkae.cat"; + in '' + PASSWORD="$(cat "${pwdPath}" | tr -d '\n')" + ${adminCmd} create --admin --email "finnliry@gmail.com" --username ${user} --password "$PASSWORD" || true + ''; +} diff --git a/hosts/makise/system/configuration/gc.nix b/hosts/makise/system/configuration/gc.nix new file mode 100755 index 0000000..dd1b4cb --- /dev/null +++ b/hosts/makise/system/configuration/gc.nix @@ -0,0 +1,13 @@ +{ ... +}: + +{ + nix.gc = { + # Enable automatic garbage collection + automatic = true; + # Run daily at 03:00 AM + dates = "03:00"; + # Keep only the latest generations (safety net for rollbacks) + options = "--delete-older-than 7d"; + }; +} diff --git a/hosts/makise/system/configuration/postgres.nix b/hosts/makise/system/configuration/postgres.nix new file mode 100755 index 0000000..9064979 --- /dev/null +++ b/hosts/makise/system/configuration/postgres.nix @@ -0,0 +1,31 @@ +{ pkgs +, ... +}: + +{ + services.postgresql = { + enable = true; + package = pkgs.postgresql_18; + + ensureDatabases = [ + "forgejo" + ]; + + ensureUsers = [ + { name = "forgejo"; ensureDBOwnership = true; } + ]; + + authentication = '' + # Socket connections + local forgejo forgejo peer + + # Localhost connections + host forgejo forgejo 127.0.0.1/32 trust + host forgejo forgejo ::1/128 trust + + # Deny everything else + host all all 0.0.0.0/0 reject + host all all ::0/0 reject + ''; + }; +} diff --git a/hosts/makise/system/configuration/sops.nix b/hosts/makise/system/configuration/sops.nix new file mode 100755 index 0000000..fb0bc43 --- /dev/null +++ b/hosts/makise/system/configuration/sops.nix @@ -0,0 +1,41 @@ +{ inputs +, ... +}: + +{ + imports = [ + inputs.sops-nix.nixosModules.sops + ]; + + sops = { + defaultSopsFile = ../../secrets/default.yaml; + defaultSopsFormat = "yaml"; + + gnupg.sshKeyPaths = [ ]; + age.sshKeyPaths = [ + "/persist/etc/ssh/ssh_host_ed25519_key" + ]; + + secrets = { + "users/admin/password_hash" = { + owner = "admin"; + neededForUsers = true; + }; + "users/kurisu/password_hash" = { + owner = "kurisu"; + neededForUsers = true; + }; + + "forgejo/admin/dokkae.cat/password" = { + owner = "forgejo"; + group = "forgejo"; + mode = "400"; + }; + "forgejo/mailer/password" = { + owner = "forgejo"; + group = "forgejo"; + mode = "400"; + }; + }; + }; +} diff --git a/hosts/makise/system/configuration/ssh.nix b/hosts/makise/system/configuration/ssh.nix new file mode 100755 index 0000000..c81a57e --- /dev/null +++ b/hosts/makise/system/configuration/ssh.nix @@ -0,0 +1,13 @@ +{ ... +}: + +{ + services.openssh = { + enable = true; + + settings = { + PermitRootLogin = "prohibit-password"; + PasswordAuthentication = false; + }; + }; +} diff --git a/hosts/makise/system/configuration/traefik.nix b/hosts/makise/system/configuration/traefik.nix new file mode 100755 index 0000000..e80149d --- /dev/null +++ b/hosts/makise/system/configuration/traefik.nix @@ -0,0 +1,39 @@ +{ ... +}: + +{ + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + services.traefik = { + enable = true; + dataDir = "/var/lib/traefik"; + + staticConfigOptions = { + global = { + checkNewVersion = false; + sendAnonymousUsage = false; + }; + + entryPoints = { + web = { + address = ":80"; + http.redirections.entrypoint = { + to = "websecure"; + scheme = "https"; + }; + }; + websecure.address = ":443"; + }; + + certificatesResolvers = { + letsencrypt = { + acme = { + email = "finnliry+acme-cl-00-00@gmail.com"; + storage = "/var/lib/traefik/acme.json"; + httpChallenge = { entryPoint = "web"; }; + }; + }; + }; + }; + }; +} diff --git a/hosts/makise/system/configuration/users.nix b/hosts/makise/system/configuration/users.nix new file mode 100755 index 0000000..ac266b0 --- /dev/null +++ b/hosts/makise/system/configuration/users.nix @@ -0,0 +1,38 @@ +{ config +, ... +}: + +{ + users = { + mutableUsers = false; + + users = { + root = { + # Disables password based authentication + hashedPassword = "!"; + }; + + admin = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + + hashedPasswordFile = config.sops.secrets."users/admin/password_hash".path; + + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZa7mIXvsHouMb3I9gq2uQjNZKsMV43bpWc7yX/RH/X finnliry@gmail.com" + ]; + }; + + kurisu = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + + hashedPasswordFile = config.sops.secrets."users/kurisu/password_hash".path; + + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZa7mIXvsHouMb3I9gq2uQjNZKsMV43bpWc7yX/RH/X finnliry@gmail.com" + ]; + }; + }; + }; +} diff --git a/hosts/makise/system/disk-configuration.nix b/hosts/makise/system/disk-configuration.nix new file mode 100755 index 0000000..590cf79 --- /dev/null +++ b/hosts/makise/system/disk-configuration.nix @@ -0,0 +1,124 @@ +{ inputs +, lib +, ... +}: + +{ + imports = [ + inputs.disko.nixosModules.disko + ]; + + # !!! DANGER !!! + # You have to carefully configure your partitions here. + boot.initrd.postDeviceCommands = lib.mkAfter '' + mkdir /btrfs_tmp + mount /dev/disk/by-label/nixos /btrfs_tmp + + if [[ -e /btrfs_tmp/root ]]; then + mkdir -p /btrfs_tmp/roots.old + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") + mv /btrfs_tmp/root "/btrfs_tmp/roots.old/$timestamp" + fi + + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } + + for i in $(find /btrfs_tmp/roots.old/ -maxdepth 1 -mtime +7); do + delete_subvolume_recursively "$i" + done + + btrfs subvolume create /btrfs_tmp/root + umount /btrfs_tmp + ''; + + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + boot = { + name = "boot"; + size = "1M"; + type = "EF02"; + priority = 1; + }; + esp = { + name = "ESP"; + end = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + root = { + size = "100%"; + content = { + type = "btrfs"; + extraArgs = [ "-L" "nixos" "-f" ]; # Override existing partition + # Subvolumes must set a mountpoint in order to be mounted, + # unless their parent is mounted + subvolumes = { + "/root" = { + mountpoint = "/"; + mountOptions = [ "subvol=root" "compress=zstd" "noatime" ]; + }; + "/home" = { + mountpoint = "/home"; + mountOptions = [ "subvol=home" "compress=zstd" "noatime" ]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ "subvol=nix" "compress=zstd" "noatime" ]; + }; + "/persist" = { + mountpoint = "/persist"; + mountOptions = [ "subvol=persist" "compress=zstd" "noatime" ]; + }; + "/var-lib" = { + mountpoint = "/var/lib"; + mountOptions = [ "subvol=var-lib" "compress=zstd" "noatime" ]; + }; + "/var-log" = { + mountpoint = "/var/log"; + mountOptions = [ "subvol=var-log" "compress=zstd" "noatime" ]; + }; + "/var-tmp" = { + mountpoint = "/var/tmp"; + mountOptions = [ "subvol=var-tmp" "compress=zstd" "noatime" ]; + }; + "/swap" = { + mountpoint = "/.swap"; + swap.swapfile.size = "4G"; + }; + }; + }; + }; + }; + }; + }; + }; + }; + + fileSystems = { + # /, /nix/, /nix/store, /var, /var/log, /var/lib, /var/lib/nixos, /etc, /usr + # are all automatically mounted marked as needed for boot. + + "/boot".neededForBoot = true; + + "/persist".neededForBoot = true; + + # Possibly not required + "/home".neededForBoot = true; + }; +} diff --git a/hosts/makise/system/hardware-configuration.nix b/hosts/makise/system/hardware-configuration.nix new file mode 100755 index 0000000..36a22e4 --- /dev/null +++ b/hosts/makise/system/hardware-configuration.nix @@ -0,0 +1,49 @@ +{ lib +, modulesPath +, ... +}: + +{ + imports = [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot = { + loader = { + grub = { + enable = true; + efiSupport = true; + efiInstallAsRemovable = true; + }; + + limine = { + enable = false; + efiSupport = true; + efiInstallAsRemovable = true; + }; + }; + + initrd = { + availableKernelModules = [ + "ahci" + "xhci_pci" + "virtio_pci" + "virtio_scsi" + "sd_mod" + "sr_mod" + ]; + + kernelModules = [ ]; + }; + + kernelModules = [ ]; + extraModulePackages = [ ]; + }; + + swapDevices = [ ]; + + networking.useDHCP = lib.mkDefault true; + networking.hostName = "cl-00-00"; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/hosts/makise/system/impermanence-configuration.nix b/hosts/makise/system/impermanence-configuration.nix new file mode 100755 index 0000000..6e26472 --- /dev/null +++ b/hosts/makise/system/impermanence-configuration.nix @@ -0,0 +1,24 @@ +{ inputs +, ... +}: + +{ + imports = [ + inputs.impermanence.nixosModules.impermanence + ]; + + environment.persistence."/persist" = { + enable = true; + hideMounts = true; + + directories = [ + "/root/.ssh" + + "/etc/nixos" + "/etc/ssh" + ]; + files = [ + "/etc/machine-id" + ]; + }; +} diff --git a/hosts/makise/system/system.nix b/hosts/makise/system/system.nix new file mode 100755 index 0000000..cd5f455 --- /dev/null +++ b/hosts/makise/system/system.nix @@ -0,0 +1,53 @@ +{ inputs +, pkgs +, lib +, ... +}: + +{ + imports = [ + ./disk-configuration.nix + ./hardware-configuration.nix + ./impermanence-configuration.nix + + ./configuration + ]; + + nixpkgs = { + overlays = [ ]; + + config = { + allowUnfree = true; + }; + }; + + nix = let + flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs; + in { + settings = { + # Enable flakes and new 'nix' command + experimental-features = "nix-command flakes"; + + # Disable global registry + flake-registry = ""; + + trusted-users = ["root" "@wheel"]; + }; + + # Disable channels in favor of flakes + channel.enable = false; + + # Make flake registry and nix path match flake inputs + registry = lib.mapAttrs (_: flake: {inherit flake;}) flakeInputs; + nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs; + }; + + # Relevant core programs + environment.systemPackages = with pkgs; [ + home-manager + nix + ]; + + # !!! DO NOT TOUCH !!! + system.stateVersion = "26.05"; +} diff --git a/justfile b/justfile new file mode 100755 index 0000000..0aa288a --- /dev/null +++ b/justfile @@ -0,0 +1,16 @@ +# Show recipe list as help by default. +default: + @just --list + +# Rebuilds the NixOS system configuration. +rebuild-system host='': + scripts/rebuild-system.sh {{host}} + +# Rebuilds the Home-Manager user configuration. +rebuild-home users='': + scripts/rebuild-home.sh {{users}} + +# Rebuilds both the home and the system configuration in that order. +rebuild-all: + just rebuild-home + just rebuild-system diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix new file mode 100755 index 0000000..bf10092 --- /dev/null +++ b/modules/home-manager/default.nix @@ -0,0 +1,4 @@ +{ + editors = import ./editors; + shells = import ./shells; +} diff --git a/modules/home-manager/editors/default.nix b/modules/home-manager/editors/default.nix new file mode 100755 index 0000000..84128ee --- /dev/null +++ b/modules/home-manager/editors/default.nix @@ -0,0 +1,29 @@ +{ lib +, config +, ... +}: + +let + cfg = config.custom.editors; +in +{ + imports = [ + ./helix.nix + ]; + + options.custom.editors = { + defaultEditor = lib.mkOption { + type = lib.types.enum [ "helix" ]; + default = null; + description = "Which editor to use as the default one. If set to null the default editor won't be set explicitly."; + }; + }; + + config = lib.mkIf (cfg.defaultEditor != null) { + assertions = [ + { assertion = (config.custom.editors.${cfg.defaultEditor}.enable); + message = "Can't set an editor as the default if it is disabled."; + } + ]; + }; +} diff --git a/modules/home-manager/editors/helix.nix b/modules/home-manager/editors/helix.nix new file mode 100755 index 0000000..d07eb9f --- /dev/null +++ b/modules/home-manager/editors/helix.nix @@ -0,0 +1,97 @@ +{ lib +, config +, pkgs +, inputs +, ... +}: + +let + cfg = config.custom.editors.helix; +in +{ + options.custom.editors.helix = { + enable = lib.mkEnableOption "Whether to enable the Helix editor."; + }; + + config = lib.mkIf cfg.enable { + programs.helix = { + enable = true; + defaultEditor = (config.custom.editors.defaultEditor == "helix"); + + settings = { + theme = "term16_dark"; + + editor = { + line-number = "relative"; + }; + }; + + languages = { + language-server = { + nixd = { + command = "nixd"; + args = [ "--semantic-tokens=true" ]; + config.nixd = let + host = "evergarden"; + flake = "(builtins.getFlake (toString ${inputs.self.outPath}))"; + nixosOptions = "${flake}.nixosConfigurations.${host}.options"; + homeManagerOptions = "${nixosOptions}.home-manager.users.type.getSubOptions []"; + in { + nixpkgs.expr = "import ${flake}.inputs.nixpkgs { }"; + options = { + nixos.expr = nixosOptions; + home-manager.expr = homeManagerOptions; + }; + }; + }; + + rust = { + command = "rust-analyzer"; + }; + + qml = { + command = "qmlls"; + args = [ ]; + }; + + dockerfile = { + command = "docker-language-server"; + }; + }; + + language = [ + { + name = "css"; + auto-format = false; + } + ]; + }; + + extraPackages = with pkgs; [ + nixd + + kdePackages.qtdeclarative + + just-lsp + yaml-language-server + tombi + docker-compose-language-service + docker-language-server + + rust-analyzer + clang-tools + ruff + + intelephense + vscode-langservers-extracted + typescript-language-server + + kotlin-language-server + jdt-language-server + + marksman + ]; + }; + }; +} + diff --git a/modules/home-manager/shells/default.nix b/modules/home-manager/shells/default.nix new file mode 100755 index 0000000..a3b458a --- /dev/null +++ b/modules/home-manager/shells/default.nix @@ -0,0 +1,10 @@ +{ ... +}: + +{ + imports = [ + ./direnv.nix + ./fish.nix + ./zellij.nix + ]; +} diff --git a/modules/home-manager/shells/direnv.nix b/modules/home-manager/shells/direnv.nix new file mode 100755 index 0000000..75cddc0 --- /dev/null +++ b/modules/home-manager/shells/direnv.nix @@ -0,0 +1,24 @@ +{ lib +, config +, ... +}: + +let + cfg = config.custom.shells.direnv; +in +{ + options.custom.shells.direnv = { + enable = lib.mkEnableOption "Whether to enable the direnv shell environment tool."; + }; + + config = lib.mkIf cfg.enable { + programs.direnv = { + enable = true; + nix-direnv.enable = true; + + enableBashIntegration = config.programs.bash.enable; + enableFishIntegration = config.programs.fish.enable; + }; + }; +} + diff --git a/modules/home-manager/shells/fish.nix b/modules/home-manager/shells/fish.nix new file mode 100755 index 0000000..7db1a15 --- /dev/null +++ b/modules/home-manager/shells/fish.nix @@ -0,0 +1,93 @@ +{ lib +, config +, pkgs +, ... +}: + +let + cfg = config.custom.shells.fish; +in +{ + options.custom.shells.fish = { + enable = lib.mkEnableOption "Whether to enable the Fish shell"; + }; + + config = lib.mkIf cfg.enable { + programs = { + fish = { + enable = true; + + # Disable annoying welcome message. + shellInit = '' + set fish_greeting + ''; + + shellAliases = { + e = "$EDITOR"; + + ".." = "cd .."; + "..." = "cd ../.."; + "...." = "cd ../../.."; + "....." = "cd ../../../.."; + "......" = "cd ../../../../.."; + + tree = "${pkgs.eza}/bin/eza --color=always --tree"; + ls = "${pkgs.eza}/bin/eza --color=always --group-directories-first --icons"; + ll = "${pkgs.eza}/bin/eza -la --icons --octal-permissions --group-directories-first"; + l = "${pkgs.eza}/bin/eza --long --all --group --group-directories-first --icons"; + lx = "${pkgs.eza}/bin/eza -lbhHigUmuSa@ --time-style=long-iso --git --color-scale --color=always --group-directories-first --icons"; + + cat = "${pkgs.bat}/bin/bat -Pp"; + }; + }; + + starship = { + enable = true; + + settings = { + character = { + success_symbol = "[[](mauve) ❯](maroon)"; + error_symbol = "[❯](red)"; + vimcmd_symbol = "[❮](green)"; + }; + + directory = { + truncation_length = 4; + style = "bold pink"; + }; + + palette = "catppuccin_mocha"; + + palettes.catppuccin_mocha = { + rosewater = "#f5e0dc"; + flamingo = "#f2cdcd"; + pink = "#f5c2e7"; + mauve = "#cba6f7"; + red = "#f38ba8"; + maroon = "#eba0ac"; + peach = "#fab387"; + yellow = "#f9e2af"; + green = "#a6e3a1"; + teal = "#94e2d5"; + sky = "#89dceb"; + sapphire = "#74c7ec"; + blue = "#89b4fa"; + lavender = "#b4befe"; + text = "#cdd6f4"; + subtext1 = "#bac2de"; + subtext0 = "#a6adc8"; + overlay2 = "#9399b2"; + overlay1 = "#7f849c"; + overlay0 = "#6c7086"; + surface2 = "#585b70"; + surface1 = "#45475a"; + surface0 = "#313244"; + base = "#1e1e2e"; + mantle = "#181825"; + crust = "#11111b"; + }; + }; + }; + }; + }; +} diff --git a/modules/home-manager/shells/zellij.nix b/modules/home-manager/shells/zellij.nix new file mode 100755 index 0000000..4d1cbf3 --- /dev/null +++ b/modules/home-manager/shells/zellij.nix @@ -0,0 +1,21 @@ +{ config +, lib +, pkgs +, ... +}: + +let + cfg = config.custom.shells.zellij; +in +{ + options.custom.shells.zellij = { + enable = lib.mkEnableOption "Enable the Zellij multiplexer."; + }; + + config = lib.mkIf cfg.enable { + programs.zellij = { + enable = true; + }; + }; +} + diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix new file mode 100755 index 0000000..bb3ee9d --- /dev/null +++ b/modules/nixos/default.nix @@ -0,0 +1,3 @@ +{ + shells = import ./shells; +} diff --git a/modules/nixos/shells/default.nix b/modules/nixos/shells/default.nix new file mode 100755 index 0000000..a9efd37 --- /dev/null +++ b/modules/nixos/shells/default.nix @@ -0,0 +1,8 @@ +{ ... +}: + +{ + imports = [ + ./fish.nix + ]; +} diff --git a/modules/nixos/shells/fish.nix b/modules/nixos/shells/fish.nix new file mode 100755 index 0000000..7f7d790 --- /dev/null +++ b/modules/nixos/shells/fish.nix @@ -0,0 +1,34 @@ +{ config +, lib +, pkgs +, ... +}: + +let + cfg = config.custom.shells.fish; +in +{ + options.custom.shells.fish = { + enable = lib.mkEnableOption "Enable the Fish shell."; + + defaultFor = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "Users to set Fish as their default shell. If set the shell must be enabled."; + }; + }; + + config = { + # Actually enable and assign the shell + programs = lib.mkIf cfg.enable { + fish.enable = true; + }; + + users.users = lib.mkIf cfg.enable ( + lib.genAttrs cfg.defaultFor (user: { + shell = lib.mkOverride 900 "${pkgs.fish}/bin/fish"; + }) + ); + }; +} + diff --git a/scripts/rebuild-home.sh b/scripts/rebuild-home.sh new file mode 100755 index 0000000..b93212f --- /dev/null +++ b/scripts/rebuild-home.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# rebuild-home.sh - Rebuild home-manager configurations +# +# USAGE: +# rebuild-home.sh # Rebuild current user +# rebuild-home.sh user1 user2 ... # Rebuild specified users +# +# EXAMPLES: +# rebuild-home.sh +# rebuild-home.sh kurisu admin + +set -e + +HOST=$(hostname) + +if [ $# -eq 0 ]; then + USERS=$(whoami) +else + USERS="$*" +fi + +for user in $USERS; do + echo "Rebuilding $user@$HOST..." + + sudo -u "$user" home-manager switch -b hmbak --flake .#"$user"@"$HOST" +done diff --git a/scripts/rebuild-system.sh b/scripts/rebuild-system.sh new file mode 100755 index 0000000..d6f5474 --- /dev/null +++ b/scripts/rebuild-system.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# rebuild-system.sh - Rebuild nixos configurations +# +# USAGE: +# rebuild-system.sh # Rebuild system with current hostname +# rebuild-system.sh hostname # Rebuild specific system +# +# EXAMPLES: +# rebuild-system.sh +# rebuild-system.sh makise + +if [ ! -z $1 ]; then + export HOST=$1 +else + export HOST=$(hostname) +fi + +nixos-rebuild switch --flake .#$HOST --sudo