diff --git a/.direnv/flake-profile b/.direnv/flake-profile deleted file mode 120000 index 8030af1..0000000 --- a/.direnv/flake-profile +++ /dev/null @@ -1 +0,0 @@ -flake-profile-9-link \ No newline at end of file diff --git a/.direnv/flake-profile-9-link b/.direnv/flake-profile-9-link deleted file mode 120000 index 4162ae4..0000000 --- a/.direnv/flake-profile-9-link +++ /dev/null @@ -1 +0,0 @@ -/nix/store/k88yspmzczh2hz8assh7447skldwjdw7-nix-shell-env \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 4dd1286..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,11 +0,0 @@ -on: - push: - branches: - - main -jobs: - build: - runs-on: nix - steps: - - uses: actions/checkout@v4 - - run: nix develop - - run: colmena build -v --on @fili diff --git a/.gitignore b/.gitignore index 0e6c978..a816f55 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ secret/ +.direnv diff --git a/.sops.yaml b/.sops.yaml deleted file mode 100644 index eb54ef9..0000000 --- a/.sops.yaml +++ /dev/null @@ -1,7 +0,0 @@ -keys: - - &jana age1ygkcl4ss92z5ptzt3w5g4n98qx2c4kagyssm96m5z4c7t299c5wszjchxw -creation_rules: - - path_regex: secrets/[^/]+\.(yaml|json|env|ini)$ - key_groups: - - age: - - *jana diff --git a/README.md b/README.md new file mode 100644 index 0000000..5badcbe --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Server Configuration + +This is the server configuration of: + +- currently only `fili` + +For my nix-based dotfiles (i.e. home-manager configuration) which I use on my laptops for example, see . +Note: on most of my machines I don't actually use nixos, but do use nix to manage dotfiles and many programs. diff --git a/default-machine-config.nix b/default-machine-config.nix index bd6655b..b43be5d 100644 --- a/default-machine-config.nix +++ b/default-machine-config.nix @@ -1,15 +1,18 @@ { lib, pkgs, + inputs, + flakes, ... }: { imports = [ - # ./cli-programs - # inputs.home-manager.nixosModules.home-manager + (inputs.self + /modules/machine-type.nix) + (inputs.self + /modules/program.nix) + (inputs.self + /programs) ]; - system.stateVersion = "25.05"; + system.stateVersion = "26.05"; services.resolved.enable = false; # Enable SSH @@ -38,6 +41,9 @@ atuin rcon lix + nix-output-monitor + wget + comma ]; # Set up direnv @@ -125,10 +131,14 @@ nixos.enable = lib.mkForce false; }; - # home-manager = { - # useGlobalPkgs = true; - # useUserPackages = true; - # verbose = true; - # extraSpecialArgs = { inherit inputs; }; - # }; + security.polkit.enable = true; + + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + + extraSpecialArgs = { + inherit flakes; + }; + }; } diff --git a/fili/lib/auth.nix b/fili/lib/auth.nix deleted file mode 100644 index f277d2e..0000000 --- a/fili/lib/auth.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ baseUrl, clientId }: -{ - inherit clientId; - - userAuthUrl = "${baseUrl}/ui/oauth2"; - apiAuthUrl = "${baseUrl}/oauth2/authorise"; - tokenUrl = "${baseUrl}/oauth2/token"; - - rfc7662TokenIntrospectionUrl = "${baseUrl}/oauth2/token/introspect"; - rfc7009TokenRevokeUrl = "${baseUrl}/oauth2/token/revoke"; - - oauth2Rfc8414Discovery = "${baseUrl}/oauth2/openid/${clientId}/.well-known/oauth-authorization-server"; - - oidcIssuerUri = "${baseUrl}/oauth2/openid/${clientId}"; - oidcDiscovery = "${baseUrl}/oauth2/openid/${clientId}/.well-known/openid-configuration"; - - oidcUserInfo = "${baseUrl}/oauth2/openid/${clientId}/userinfo"; - oidcTokenSigningPubkey = "${baseUrl}/openid/${clientId}/public_key.jwk"; - -} diff --git a/fili/services/auth/kanidm.nix b/fili/services/auth/kanidm.nix deleted file mode 100644 index 9e023e1..0000000 --- a/fili/services/auth/kanidm.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ pkgs, config, ... }: -let - lib = pkgs.lib; - domain = "auth.donsz.nl"; - port = 3013; - backupsDir = "/var/lib/kanidm/backup"; -in -{ - services.kanidm.enableServer = true; - services.kanidm.package = pkgs.kanidm_1_6; - services.kanidm.serverSettings = { - tls_chain = "/var/lib/acme/${domain}/fullchain.pem"; - tls_key = "/var/lib/acme/${domain}/key.pem"; - bindaddress = "[::1]:${toString port}"; - ldapbindaddress = "[::1]:3636"; - inherit domain; - origin = "https://${domain}"; - trust_x_forward_for = true; - - online_backup = { - path = backupsDir; - schedule = "0 0 * * *"; - }; - }; - - systemd.services.kanidm = { - preStart = lib.mkBefore '' - mkdir -p "${backupsDir}" - ''; - serviceConfig = { - SupplementaryGroups = [ config.security.acme.certs.${domain}.group ]; - }; - }; - - environment.systemPackages = [ pkgs.kanidm ]; - - services.nginx.virtualHosts.${domain} = { - forceSSL = true; - http2 = true; - enableACME = true; - - locations."/" = { - proxyPass = "https://[::1]:${toString port}"; - }; - }; -} diff --git a/fili/services/auth/oauth2-proxy.nix b/fili/services/auth/oauth2-proxy.nix deleted file mode 100644 index ec19873..0000000 --- a/fili/services/auth/oauth2-proxy.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ pkgs, config, ... }: -{ - sops.secrets.oauth2-proxy = { - sopsFile = ../../../secrets/oauth2-proxy.env; - }; - - services.oauth2-proxy = - let - auth = import ../../lib/auth.nix { - baseUrl = "https://auth.donsz.nl"; - clientId = "homeserver"; - }; - in - { - enable = true; - - provider = "oidc"; - clientID = "${auth.clientId}"; - oidcIssuerUrl = auth.oidcIssuerUri; - - proxyPrefix = "/oauth2"; - reverseProxy = true; - - keyFile = config.sops.secrets.oauth2-proxy.path; - - loginURL = auth.apiAuthUrl; - redeemURL = auth.tokenUrl; - validateURL = auth.rfc7662TokenIntrospectionUrl; - profileURL = auth.oidcUserInfo; - - scope = "openid profile email"; - - email.domains = [ "*" ]; - - cookie = { - domain = "donsz.nl"; - refresh = "1h"; - secure = true; - }; - - extraConfig = { - whitelist-domain = [ "*.donsz.nl" ]; - }; - - nginx.domain = "oauth2.donsz.nl"; - }; - - services.nginx.virtualHosts."oauth2.donsz.nl" = { - forceSSL = true; - http2 = true; - enableACME = true; - - locations."/".return = "301 https://oauth2.donsz.nl/oauth2/sign_in"; - }; -} diff --git a/fili/services/media/jackett.nix b/fili/services/media/jackett.nix deleted file mode 100644 index 2318ee4..0000000 --- a/fili/services/media/jackett.nix +++ /dev/null @@ -1,19 +0,0 @@ -_: { - services.nginx = { - virtualHosts."jackett.donsz.nl" = { - forceSSL = true; - http2 = true; - enableACME = true; - - locations."/" = { - proxyPass = "http://[::1]:9117"; - }; - }; - }; - - services.jackett = { - enable = true; - group = "jellyfin"; - user = "jellyfin"; - }; -} diff --git a/fili/services/media/overseerr.nix b/fili/services/media/overseerr.nix deleted file mode 100644 index 6a41605..0000000 --- a/fili/services/media/overseerr.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ config, ... }: -let - port = 11002; -in -{ - config.networking.firewall.allowedTCPPorts = [ port ]; - - config.virtualisation.oci-containers.containers = { - overseerr = { - image = "mirror.gcr.io/fallenbagel/jellyseerr:develop"; - environment = { - PORT = "5555"; - TZ = "Europe/Amsterdam"; - LOG_LEVEL = "debug"; - }; - extraOptions = [ "--network=host" ]; - volumes = [ - "/var/lib/microvms/rr/storage/data/overseerr:/app/config" - ]; - }; - }; -} diff --git a/fili/services/media/plex.nix b/fili/services/media/plex.nix deleted file mode 100644 index 605882d..0000000 --- a/fili/services/media/plex.nix +++ /dev/null @@ -1,82 +0,0 @@ -_: { - services.plex = { - enable = true; - openFirewall = true; - user = "jellyfin"; - }; - - users.groups.jellyfin = { }; - users.users.jellyfin = { - isSystemUser = true; - group = "jellyfin"; - - extraGroups = [ "storage" ]; - }; - - services.nginx = { - virtualHosts."media.donsz.nl" = { - forceSSL = true; - http2 = true; - enableACME = true; - extraConfig = '' - #Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause - send_timeout 100m; - - # Why this is important: https://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30/ - ssl_stapling on; - ssl_stapling_verify on; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - #Intentionally not hardened for security for player support and encryption video streams has a lot of overhead with something like AES-256-GCM-SHA384. - ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; - - # Forward real ip and host to Plex - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $server_addr; - proxy_set_header Referer $server_addr; - proxy_set_header Origin $server_addr; - - # Plex has A LOT of javascript, xml and html. This helps a lot, but if it causes playback issues with devices turn it off. - gzip on; - gzip_vary on; - gzip_min_length 1000; - gzip_proxied any; - gzip_types text/plain text/css text/xml application/xml text/javascript application/x-javascript image/svg+xml; - gzip_disable "MSIE [1-6]\."; - - # Nginx default client_max_body_size is 1MB, which breaks Camera Upload feature from the phones. - # Increasing the limit fixes the issue. Anyhow, if 4K videos are expected to be uploaded, the size might need to be increased even more - client_max_body_size 100M; - - # Plex headers - proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; - proxy_set_header X-Plex-Device $http_x_plex_device; - proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; - proxy_set_header X-Plex-Platform $http_x_plex_platform; - proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; - proxy_set_header X-Plex-Product $http_x_plex_product; - proxy_set_header X-Plex-Token $http_x_plex_token; - proxy_set_header X-Plex-Version $http_x_plex_version; - proxy_set_header X-Plex-Nocache $http_x_plex_nocache; - proxy_set_header X-Plex-Provides $http_x_plex_provides; - proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; - proxy_set_header X-Plex-Model $http_x_plex_model; - - # Websockets - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Buffering off send to the client as soon as the data is received from Plex. - proxy_redirect off; - proxy_buffering off; - ''; - locations."/" = { - proxyPass = "http://[::1]:32400"; - }; - }; - }; -} diff --git a/fili/services/media/torrent.nix b/fili/services/media/torrent.nix deleted file mode 100644 index 4b0a0d5..0000000 --- a/fili/services/media/torrent.nix +++ /dev/null @@ -1,120 +0,0 @@ -{ - config, - pkgs, - ... -}: -{ - sops.secrets.mullvad = { - sopsFile = ../../../secrets/mullvad.yaml; - owner = "root"; - format = "yaml"; - }; - - vpnNamespaces.mullvad = { - enable = true; - wireguardConfigFile = config.sops.secrets.mullvad.path; - accessibleFrom = [ - "192.168.0.0/16" - ]; - portMappings = [ - { - from = 9091; - to = 9091; - } # UI Port. - { - from = 5432; - to = 5432; - } # DB Port. - ]; - openVPNPorts = [ - { - port = 50901; - protocol = "both"; - } - { - port = 50902; - protocol = "both"; - } - { - port = 50903; - protocol = "both"; - } - { - port = 50904; - protocol = "both"; - } - { - port = 50905; - protocol = "both"; - } - { - port = 50906; - protocol = "both"; - } - { - port = 50907; - protocol = "both"; - } - { - port = 50908; - protocol = "both"; - } - { - port = 50909; - protocol = "both"; - } - ]; - }; - - services.nginx = { - virtualHosts."dl.donsz.nl" = { - forceSSL = true; - http2 = true; - enableACME = true; - - locations."/" = { - proxyPass = "http://192.168.15.1:9091"; - }; - }; - }; - services.oauth2-proxy.nginx.virtualHosts."dl.donsz.nl" = { }; - - systemd.services.transmission.vpnConfinement = { - enable = true; - vpnNamespace = "mullvad"; - }; - - services.transmission = { - enable = true; - package = pkgs.transmission_4; - webHome = pkgs.stdenv.mkDerivation { - name = "flood-modified"; - version = "1.0"; - src = pkgs.flood-for-transmission; - installPhase = '' - mkdir -p $out - cp -r ./* $out - cp ./config.json.defaults $out/config.json - ''; - }; - home = "/var/lib/transmission"; - user = "jellyfin"; - group = "jellyfin"; - - settings = { - download-dir = "/storage/storage/torrents"; - incomplete-dir-enabled = false; - # incomplete-dir = "/storage/storage/torrents"; - - rpc-bind-address = "192.168.15.1"; - rpc-host-whitelist-enabled = false; - rpc-whitelist-enabled = false; - - rpc-port = 9091; - - peer-port = 50909; - cache-size-mb = 2048; - preallocation = 1; - }; - }; -} diff --git a/fili/services/websites/homepage.nix b/fili/services/websites/homepage.nix deleted file mode 100644 index 3de7867..0000000 --- a/fili/services/websites/homepage.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ flakes, pkgs, ... }: -{ - services.nginx = { - virtualHosts."donsz.nl" = { - forceSSL = true; - http2 = true; - enableACME = true; - - locations."/" = { - root = flakes.homepage.packages.${pkgs.system}.website; - }; - }; - virtualHosts."jdonszelmann.nl" = { - forceSSL = true; - http2 = true; - enableACME = true; - - locations."/" = { - root = flakes.homepage.packages.${pkgs.system}.website; - }; - }; - }; -} diff --git a/fili/services/websites/mapf.nix b/fili/services/websites/mapf.nix deleted file mode 100644 index 5fb3a7c..0000000 --- a/fili/services/websites/mapf.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ flakes, ... }: -{ - # imports = [ - # flakes.mapf.nixosModules.default - # ]; - - sops.secrets.mapf = { - sopsFile = ../../../secrets/mapf-prod.env; - }; - - services.nginx = { - virtualHosts."mapf.donsz.nl" = { - forceSSL = true; - http2 = true; - enableACME = true; - - locations."/" = { - proxyPass = "http://[::1]:8080"; - }; - }; - }; - - # donsz.services.mapf = { - # enable = true; - # envfile = "/run/secrets/sops/mapf"; - # db_name = "mapfprod"; - # db_user = "mapfprod"; - # db_password = ""; - # }; -} diff --git a/flake.lock b/flake.lock index 2c5e0b2..99101de 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,88 @@ { "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": [ + "p1n3appl3", + "home-manager" + ], + "nixpkgs": [ + "p1n3appl3", + "ragenix", + "nixpkgs" + ], + "systems": "systems_12" + }, + "locked": { + "lastModified": 1761656077, + "narHash": "sha256-lsNWuj4Z+pE7s0bd2OKicOFq9bK86JE0ZGeKJbNqb94=", + "owner": "ryantm", + "repo": "agenix", + "rev": "9ba0d85de3eaa7afeab493fed622008b6e4924f5", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "agenix_2": { + "inputs": { + "darwin": [ + "rahul-config", + "darwin" + ], + "home-manager": [ + "rahul-config", + "home-manager" + ], + "nixpkgs": [ + "rahul-config", + "nixpkgs" + ], + "systems": [ + "rahul-config", + "flake-utils", + "systems" + ] + }, + "locked": { + "lastModified": 1720546205, + "narHash": "sha256-boCXsjYVxDviyzoEyAk624600f3ZBo/DKtUdvMTpbGY=", + "owner": "ryantm", + "repo": "agenix", + "rev": "de96bd907d5fbc3b14fc33ad37d1b9a3cb15edc6", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "catppuccin": { + "inputs": { + "nixpkgs": [ + "p1n3appl3", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1767967164, + "narHash": "sha256-Cx4VETh9dGoQYDtWhre7g66d7SAr+h1h6f+SSHxVrck=", + "owner": "catppuccin", + "repo": "nix", + "rev": "e973584280e3b0e1d5b5a1a5e9948dc222c54af7", + "type": "github" + }, + "original": { + "owner": "catppuccin", + "repo": "nix", + "type": "github" + } + }, "colmena": { "inputs": { "flake-compat": "flake-compat", @@ -9,11 +92,11 @@ "stable": "stable" }, "locked": { - "lastModified": 1749739748, - "narHash": "sha256-csQQPoCA5iv+Nd9yCOCQNKflP7qUKEe7D27wsz+LPKM=", + "lastModified": 1762034856, + "narHash": "sha256-QVey3iP3UEoiFVXgypyjTvCrsIlA4ecx6Acaz5C8/PQ=", "owner": "zhaofengli", "repo": "colmena", - "rev": "c61641b156dfa3e82fc0671e77fccf7d7ccfaa3b", + "rev": "349b035a5027f23d88eeb3bc41085d7ee29f18ed", "type": "github" }, "original": { @@ -22,10 +105,131 @@ "type": "github" } }, + "compiler-construction-2021": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1759157554, + "narHash": "sha256-BLdqS+zBfG+QHEuRV3iJHaBkizlohD+hgvz8KvpDPOA=", + "ref": "refs/heads/main", + "rev": "9d739f22726a4f3078369ade0c3646fbf058ce01", + "revCount": 4, + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/eelco-visser-compiler-construction.git" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/eelco-visser-compiler-construction.git" + } + }, + "crane": { + "locked": { + "lastModified": 1760924934, + "narHash": "sha256-tuuqY5aU7cUkR71sO2TraVKK2boYrdW3gCSXUkF4i44=", + "owner": "ipetkov", + "repo": "crane", + "rev": "c6b4d5308293d0d04fcfeee92705017537cad02f", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "crane_2": { + "inputs": { + "nixpkgs": [ + "rahul-config", + "ragenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1708794349, + "narHash": "sha256-jX+B1VGHT0ruHHL5RwS8L21R6miBn4B6s9iVyUJsJJY=", + "owner": "ipetkov", + "repo": "crane", + "rev": "2c94ff9a6fbeb9f3ea0107f28688edbe9c81deaa", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "p1n3appl3", + "ragenix", + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744478979, + "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "43975d782b418ebf4969e9ccba82466728c2851b", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "darwin_2": { + "inputs": { + "nixpkgs": [ + "rahul-config", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722082646, + "narHash": "sha256-od8dBWVP/ngg0cuoyEl/w9D+TCNDj6Kh4tr151Aax7w=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "0413754b3cdb879ba14f6e96915e5fdf06c6aab6", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "dumpasm": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1732916787, + "narHash": "sha256-CIidjQcQNvwuxMOGc6WKVTXO4MWTOp+Rr5HN2ZCRR58=", + "owner": "jdonszelmann", + "repo": "dumpasm", + "rev": "8f2bb630aa90bddf3ada83e5a57eba6aa42a06f5", + "type": "github" + }, + "original": { + "owner": "jdonszelmann", + "repo": "dumpasm", + "type": "github" + } + }, "fenix": { "inputs": { "nixpkgs": [ - "reviewqueue", + "mifg", "naersk", "nixpkgs" ], @@ -45,6 +249,67 @@ "type": "github" } }, + "fenix_2": { + "inputs": { + "nixpkgs": [ + "reviewqueue", + "naersk", + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src_2" + }, + "locked": { + "lastModified": 1752475459, + "narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=", + "owner": "nix-community", + "repo": "fenix", + "rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "firefox-addons": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "dir": "pkgs/firefox-addons", + "lastModified": 1768881817, + "narHash": "sha256-yEG418W8a7C/bcmRI5Lgd03XbBc8K2yV0kp1WUHTYbA=", + "owner": "rycee", + "repo": "nur-expressions", + "rev": "bbd2046d41083954fd28c31cb4f2d3510c9e2b1e", + "type": "gitlab" + }, + "original": { + "dir": "pkgs/firefox-addons", + "owner": "rycee", + "repo": "nur-expressions", + "type": "gitlab" + } + }, + "firefox-sidebar-css": { + "flake": false, + "locked": { + "lastModified": 1755054837, + "narHash": "sha256-E2TBqMuSco0D53nozFNWNgoy8y8Mw0hO2aRdM4awoC8=", + "owner": "drannex", + "repo": "FirefoxSidebar", + "rev": "ec3bbe90028bd80d255dfe802c28599bb3b358bc", + "type": "github" + }, + "original": { + "owner": "drannex", + "repo": "FirefoxSidebar", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -61,6 +326,27 @@ "type": "github" } }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1765835352, + "narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "a34fae9c08a15ad73f295041fec82323541400a9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "locked": { "lastModified": 1659877975, @@ -76,6 +362,114 @@ "type": "github" } }, + "flake-utils_10": { + "inputs": { + "systems": "systems_13" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_11": { + "inputs": { + "systems": "systems_14" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_12": { + "inputs": { + "systems": "systems_15" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_13": { + "inputs": { + "systems": "systems_16" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_14": { + "inputs": { + "systems": "systems_17" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_15": { + "inputs": { + "systems": "systems_18" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "flake-utils_2": { "inputs": { "systems": "systems" @@ -99,11 +493,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -116,6 +510,24 @@ "inputs": { "systems": "systems_3" }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_4" + }, "locked": { "lastModified": 1710146030, "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", @@ -130,9 +542,63 @@ "type": "github" } }, - "flake-utils_5": { + "flake-utils_6": { "inputs": { - "systems": "systems_4" + "systems": "systems_5" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_7": { + "inputs": { + "systems": "systems_6" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_8": { + "inputs": { + "systems": "systems_8" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_9": { + "inputs": { + "systems": "systems_10" }, "locked": { "lastModified": 1731533236, @@ -150,7 +616,7 @@ }, "harmonica": { "inputs": { - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs_4" }, "locked": { "lastModified": 1738890519, @@ -166,17 +632,80 @@ "url": "ssh://git@github.com/jdonszelmann/harmonica-tabs" } }, - "homepage": { + "home-manager": { "inputs": { - "flake-utils": "flake-utils_3", - "nixpkgs": "nixpkgs_3" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { - "lastModified": 1747823174, - "narHash": "sha256-8P6od55oOAaE0/QAaHn33ADFISTiE+QOt2s0AmaPAFQ=", + "lastModified": 1768836546, + "narHash": "sha256-nJZkTamcXXMW+SMYiGFB6lB8l0aJw0xjssfN8xYd/Fs=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "b56c5ad14fcf8b5bc887463552483bf000ca562a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "p1n3appl3", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768512489, + "narHash": "sha256-jZi945d3e6DYhrw3K5Pew+QaL3qSgq3O6xiVaEVLgXs=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "bba859cd85b90dd9e4e6fd44b2af4aa64ae801a1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_3": { + "inputs": { + "nixpkgs": [ + "rahul-config", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722203588, + "narHash": "sha256-91V5FMSQ4z9bkhTCf0f86Zjw0bh367daSf0mzCIW0vU=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "792757f643cedc13f02098d8ed506d82e19ec1da", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "home-manager", + "type": "github" + } + }, + "homepage": { + "inputs": { + "flake-utils": "flake-utils_5", + "nixpkgs": "nixpkgs_5" + }, + "locked": { + "lastModified": 1769115257, + "narHash": "sha256-Ju8QvCoBECGHoCfE9TQTUnMrK9E4BvBpyhCzh+VrerM=", "owner": "jdonszelmann", "repo": "homepage", - "rev": "39ef8624648f4e8803aa7510036ad48f5d4a459c", + "rev": "53b9b3b1e3f13ea3e3f0b09856b5236c96e4cded", "type": "github" }, "original": { @@ -185,17 +714,71 @@ "type": "github" } }, + "impermanence": { + "locked": { + "lastModified": 1675359654, + "narHash": "sha256-FPxzuvJkcO49g4zkWLSeuZkln54bLoTtrggZDJBH90I=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "6138eb8e737bffabd4c8fc78ae015d4fd6a7e2fd", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "rev": "6138eb8e737bffabd4c8fc78ae015d4fd6a7e2fd", + "type": "github" + } + }, + "jujutsu": { + "inputs": { + "flake-utils": "flake-utils_6", + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1768781827, + "narHash": "sha256-IbWOHI/IlGC43Mg7AZUu6jCHjIEzFIPAoSlFDJG43A4=", + "owner": "martinvonz", + "repo": "jj", + "rev": "de8531b018a08fd1e2ee67b5c8848146c62be5f4", + "type": "github" + }, + "original": { + "owner": "martinvonz", + "repo": "jj", + "type": "github" + } + }, + "kitty-search": { + "flake": false, + "locked": { + "lastModified": 1749065041, + "narHash": "sha256-Xy4dH2fzEQmKfqhmotVDEszuTqoISONGNfC1yfcdevs=", + "owner": "trygveaa", + "repo": "kitty-kitten-search", + "rev": "992c1f3d220dc3e1ae18a24b15fcaf47f4e61ff8", + "type": "github" + }, + "original": { + "owner": "trygveaa", + "repo": "kitty-kitten-search", + "type": "github" + } + }, "mapf": { "inputs": { - "flake-utils": "flake-utils_4", - "nixpkgs": "nixpkgs_4" + "flake-utils": "flake-utils_7", + "nixpkgs": "nixpkgs_6" }, "locked": { - "lastModified": 1721482233, - "narHash": "sha256-zNTFyWdpOOTSXfCtcvdU7MjHohnKQpZcSlhCPS/C93Y=", + "lastModified": 1757529600, + "narHash": "sha256-QSubvX4HaBx1LoePLBesrQqq0UuLuL4tM0uT0ipWlu8=", "ref": "refs/heads/master", - "rev": "aa47dd1bc41ba25d14b1ac62edcee14f6fec1aa5", - "revCount": 677, + "rev": "85e88fdc8f9947cb847db49e59e3ab1b5befac97", + "revCount": 678, "type": "git", "url": "ssh://git@github.com/jdonszelmann/mapf-server" }, @@ -204,10 +787,72 @@ "url": "ssh://git@github.com/jdonszelmann/mapf-server" } }, + "matugen": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_7" + }, + "locked": { + "lastModified": 1768585282, + "narHash": "sha256-JTH+wQTt8pyS5iPb7+r/70pYfLgi/OFTzimcRmMcs2g=", + "owner": "InioX", + "repo": "matugen", + "rev": "5905cae968e02d3c1d23ee556e9a0719e5231227", + "type": "github" + }, + "original": { + "owner": "InioX", + "ref": "main", + "repo": "matugen", + "type": "github" + } + }, + "mifg": { + "inputs": { + "flake-utils": "flake-utils_8", + "naersk": "naersk", + "nixpkgs": "nixpkgs_8", + "nixpkgs-mozilla": "nixpkgs-mozilla" + }, + "locked": { + "lastModified": 1768926700, + "narHash": "sha256-/bANzWLzVAzdRDXua/p9wIDS/RGIHSBHqyduXoCd+P8=", + "ref": "refs/heads/main", + "rev": "7c883e02e2a77061bfa048d249df0d39b362a5cf", + "revCount": 72, + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/money.is.fckn.gay.git" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/money.is.fckn.gay.git" + } + }, "naersk": { "inputs": { "fenix": "fenix", - "nixpkgs": "nixpkgs_6" + "nixpkgs": "nixpkgs_7" + }, + "locked": { + "lastModified": 1763384566, + "narHash": "sha256-r+wgI+WvNaSdxQmqaM58lVNvJYJ16zoq+tKN20cLst4=", + "owner": "nix-community", + "repo": "naersk", + "rev": "d4155d6ebb70fbe2314959842f744aa7cabbbf6a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "naersk", + "type": "github" + } + }, + "naersk_2": { + "inputs": { + "fenix": "fenix_2", + "nixpkgs": "nixpkgs_16" }, "locked": { "lastModified": 1752689277, @@ -223,6 +868,67 @@ "type": "github" } }, + "niri": { + "inputs": { + "niri-stable": "niri-stable", + "niri-unstable": [ + "niri-unstable" + ], + "nixpkgs": "nixpkgs_9", + "nixpkgs-stable": "nixpkgs-stable", + "xwayland-satellite-stable": "xwayland-satellite-stable", + "xwayland-satellite-unstable": "xwayland-satellite-unstable" + }, + "locked": { + "lastModified": 1768767453, + "narHash": "sha256-Omq1UHEJ1oxkTo2j8l6qQtmyPR7Uj+k7HC5Khd3jVVA=", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "8eab7c21ef4edc97cc56ddb8e76a842e0818d6d7", + "type": "github" + }, + "original": { + "owner": "sodiboo", + "repo": "niri-flake", + "type": "github" + } + }, + "niri-stable": { + "flake": false, + "locked": { + "lastModified": 1756556321, + "narHash": "sha256-RLD89dfjN0RVO86C/Mot0T7aduCygPGaYbog566F0Qo=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "01be0e65f4eb91a9cd624ac0b76aaeab765c7294", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "ref": "v25.08", + "repo": "niri", + "type": "github" + } + }, + "niri-unstable": { + "inputs": { + "nixpkgs": "nixpkgs_10", + "rust-overlay": "rust-overlay_2" + }, + "locked": { + "lastModified": 1768678265, + "narHash": "sha256-Ub8eed4DsfIDWyg30xEe+8bSxL/z5Af/gCjmvJ0V/Hs=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "d7184a04b904e07113f4623610775ae78d32394c", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "repo": "niri", + "type": "github" + } + }, "nix-github-actions": { "inputs": { "nixpkgs": [ @@ -244,13 +950,87 @@ "type": "github" } }, + "nix-index-database": { + "inputs": { + "nixpkgs": [ + "p1n3appl3", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1765267181, + "narHash": "sha256-d3NBA9zEtBu2JFMnTBqWj7Tmi7R5OikoU2ycrdhQEws=", + "owner": "Mic92", + "repo": "nix-index-database", + "rev": "82befcf7dc77c909b0f2a09f5da910ec95c5b78f", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "nix-index-database", + "type": "github" + } + }, + "nix-index-database_2": { + "inputs": { + "nixpkgs": [ + "rahul-config", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722136042, + "narHash": "sha256-x3FmT4QSyK28itMiR5zfYhUrG5nY+2dv+AIcKfmSp5A=", + "owner": "Mic92", + "repo": "nix-index-database", + "rev": "c0ca47e8523b578464014961059999d8eddd4aae", + "type": "github" + }, + "original": { + "owner": "Mic92", + "ref": "main", + "repo": "nix-index-database", + "type": "github" + } + }, + "nixos-hardware": { + "locked": { + "lastModified": 1768499669, + "narHash": "sha256-jJr/zDxu5evfQxlXtMrFFF68/RNj1UrctS/eIsay4k0=", + "owner": "NixOS", + "repo": "nixos-hardware", + "rev": "7297dfc69ae9b06e984a6f69900ce25e67c76f46", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixos-hardware_2": { + "locked": { + "lastModified": 1662587984, + "narHash": "sha256-fcfx8hEeAfQLzIQFy94/qADIHAhvDxk8t/QNJPXosy8=", + "owner": "rrbutani", + "repo": "nixos-hardware", + "rev": "0ac5732b0e4c8ca8287c3451f272c3c4b1bea8b0", + "type": "github" + }, + "original": { + "owner": "rrbutani", + "ref": "master", + "repo": "nixos-hardware", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1746461020, - "narHash": "sha256-7+pG1I9jvxNlmln4YgnlW4o+w0TZX24k688mibiFDUE=", + "lastModified": 1750134718, + "narHash": "sha256-v263g4GbxXv87hMXMCpjkIxd/viIF7p3JpJrwgKdNiI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3730d8a308f94996a9ba7c7138ede69c1b9ac4ae", + "rev": "9e83b64f727c88a7711a2c463a7b16eedb69a84c", "type": "github" }, "original": { @@ -261,6 +1041,22 @@ } }, "nixpkgs-mozilla": { + "flake": false, + "locked": { + "lastModified": 1762256096, + "narHash": "sha256-Hzj/d8eRpfRfjHSRX6gGRf0jSg2zIJMXl6S5opuKsHc=", + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "rev": "80c058cf774c198fb838fc3549806b232dd3e320", + "type": "github" + }, + "original": { + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "type": "github" + } + }, + "nixpkgs-mozilla_2": { "flake": false, "locked": { "lastModified": 1744624473, @@ -278,27 +1074,74 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1703950681, - "narHash": "sha256-veU5bE4eLOmi7aOzhE7LfZXcSOONRMay0BKv01WHojo=", + "lastModified": 1768621446, + "narHash": "sha256-6YwHV1cjv6arXdF/PQc365h1j+Qje3Pydk501Rm4Q+4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0aad9113182747452dbfc68b93c86e168811fa6c", + "rev": "72ac591e737060deab2b86d6952babd1f896d7c5", "type": "github" }, "original": { "owner": "NixOS", - "ref": "release-23.05", + "ref": "nixos-25.11", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs_2": { + "nixpkgs-stable_2": { "locked": { - "lastModified": 1738680400, - "narHash": "sha256-ooLh+XW8jfa+91F1nhf9OF7qhuA/y1ChLx6lXDNeY5U=", + "lastModified": 1767313136, + "narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "799ba5bffed04ced7067a91798353d360788b30d", + "rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_10": { + "locked": { + "lastModified": 1757967192, + "narHash": "sha256-/aA9A/OBmnuOMgwfzdsXRusqzUpd8rQnQY8jtrHK+To=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0d7c15863b251a7a50265e57c1dca1a7add2e291", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_11": { + "locked": { + "lastModified": 1768845192, + "narHash": "sha256-TQH6ERJGCGEoYBALwU8hP0IhghsOoTtp+xFC9E54S3M=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2e606f2c977dd1f6b607eccfdb57fc249ddedc23", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_12": { + "locked": { + "lastModified": 1768305791, + "narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e", "type": "github" }, "original": { @@ -308,13 +1151,13 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_13": { "locked": { - "lastModified": 1716137900, - "narHash": "sha256-sowPU+tLQv8GlqtVtsXioTKeaQvlMz/pefcdwg8MvfM=", + "lastModified": 1767379071, + "narHash": "sha256-EgE0pxsrW9jp9YFMkHL9JMXxcqi/OoumPJYwf+Okucw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6c0b7a92c30122196a761b440ac0d46d3d9954f1", + "rev": "fb7944c166a3b630f177938e478f0378e64ce108", "type": "github" }, "original": { @@ -324,13 +1167,29 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_14": { "locked": { - "lastModified": 1721379653, - "narHash": "sha256-8MUgifkJ7lkZs3u99UDZMB4kbOxvMEXQZ31FO3SopZ0=", + "lastModified": 1722062969, + "narHash": "sha256-QOS0ykELUmPbrrUGmegAUlpmUFznDQeR4q7rFhl8eQg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b73c2221a46c13557b1b3be9c2070cc42cf01eb3", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_15": { + "locked": { + "lastModified": 1767379071, + "narHash": "sha256-EgE0pxsrW9jp9YFMkHL9JMXxcqi/OoumPJYwf+Okucw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1d9c2c9b3e71b9ee663d11c5d298727dace8d374", + "rev": "fb7944c166a3b630f177938e478f0378e64ce108", "type": "github" }, "original": { @@ -340,23 +1199,7 @@ "type": "github" } }, - "nixpkgs_5": { - "locked": { - "lastModified": 1751104741, - "narHash": "sha256-xPlVbk6WlgTzDvWFRyzvXMdh/ZFLEOTCQik18wg5AFQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "e6117712d8b930e3aa8cf77b4816a3f0a88b3637", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "release-25.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { + "nixpkgs_16": { "locked": { "lastModified": 1752077645, "narHash": "sha256-HM791ZQtXV93xtCY+ZxG1REzhQenSQO020cu6rHtAPk=", @@ -372,7 +1215,7 @@ "type": "github" } }, - "nixpkgs_7": { + "nixpkgs_17": { "locked": { "lastModified": 1755020227, "narHash": "sha256-gGmm+h0t6rY88RPTaIm3su95QvQIVjAJx558YUG4Id8=", @@ -386,13 +1229,29 @@ "type": "indirect" } }, - "nixpkgs_8": { + "nixpkgs_18": { "locked": { - "lastModified": 1703499205, - "narHash": "sha256-lF9rK5mSUfIZJgZxC3ge40tp1gmyyOXZ+lRY3P8bfbg=", + "lastModified": 1769248673, + "narHash": "sha256-oyxrDiV2yFToXpzwiJUYkxCjFHvL21tMQ2BpQMyMDTw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e1fa12d4f6c6fe19ccb59cac54b5b3f25e160870", + "rev": "c0301d62ba146fee37e79fbc4b6323af52a2834e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_19": { + "locked": { + "lastModified": 1768569498, + "narHash": "sha256-bB6Nt99Cj8Nu5nIUq0GLmpiErIT5KFshMQJGMZwgqUo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "be5afa0fcb31f0a96bf9ecba05a516c66fcd8114", "type": "github" }, "original": { @@ -402,7 +1261,37 @@ "type": "github" } }, - "nixpkgs_9": { + "nixpkgs_2": { + "locked": { + "lastModified": 1759036355, + "narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_20": { + "locked": { + "lastModified": 1710377395, + "narHash": "sha256-KMubsUWtVr7L55pXMBibBDBdmk3xrjbBPduc0E8z28c=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "db001797591bf76f7b8d4c4ed3b49233391e0c97", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_21": { "locked": { "lastModified": 1732014248, "narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=", @@ -418,19 +1307,348 @@ "type": "github" } }, - "reviewqueue": { + "nixpkgs_3": { + "locked": { + "lastModified": 1732521221, + "narHash": "sha256-2ThgXBUXAE1oFsVATK1ZX9IjPcS4nKFOAjhPNKuiMn0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4633a7c72337ea8fd23a4f2ba3972865e3ec685d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1738680400, + "narHash": "sha256-ooLh+XW8jfa+91F1nhf9OF7qhuA/y1ChLx6lXDNeY5U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "799ba5bffed04ced7067a91798353d360788b30d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1716137900, + "narHash": "sha256-sowPU+tLQv8GlqtVtsXioTKeaQvlMz/pefcdwg8MvfM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6c0b7a92c30122196a761b440ac0d46d3d9954f1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1721379653, + "narHash": "sha256-8MUgifkJ7lkZs3u99UDZMB4kbOxvMEXQZ31FO3SopZ0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1d9c2c9b3e71b9ee663d11c5d298727dace8d374", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1752077645, + "narHash": "sha256-HM791ZQtXV93xtCY+ZxG1REzhQenSQO020cu6rHtAPk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "be9e214982e20b8310878ac2baa063a961c1bdf6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1766070988, + "narHash": "sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c6245e83d836d0433170a16eb185cefe0572f8b8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_9": { + "locked": { + "lastModified": 1768564909, + "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixvim": { "inputs": { - "flake-utils": "flake-utils_5", - "naersk": "naersk", - "nixpkgs": "nixpkgs_7", - "nixpkgs-mozilla": "nixpkgs-mozilla" + "flake-parts": "flake-parts", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_9" }, "locked": { - "lastModified": 1755627228, - "narHash": "sha256-0BiTSjVWxgFnhOFxM1hpeMoMZcQBsgZTeVIgXOSUMcg=", + "lastModified": 1768795384, + "narHash": "sha256-gZIXLzhupxAwRMMRTFgrl669ciYiiPmnA3PwocJ+6jQ=", + "owner": "nix-community", + "repo": "nixvim", + "rev": "57d393deb53af1b28b14973d3e3885c3d17e7bbe", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixvim", + "type": "github" + } + }, + "noctalia": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768845494, + "narHash": "sha256-PKlKrQMhk+ygsVPny9iOcttZRic870ZbFLTpZEz3MUg=", + "owner": "noctalia-dev", + "repo": "noctalia-shell", + "rev": "77aaf6923d19ec824ea142ce02018bfe9a967da4", + "type": "github" + }, + "original": { + "owner": "noctalia-dev", + "repo": "noctalia-shell", + "type": "github" + } + }, + "obs-gamepad": { + "inputs": { + "nixpkgs": [ + "p1n3appl3", + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1760151712, + "narHash": "sha256-Xod+hqFnhok9rrSH42/2ON74S2Kp/EzgHDmffIbY6TQ=", + "owner": "p1n3appl3", + "repo": "obs-gamepad", + "rev": "42026f9c1496b7b263086468a3334bc72795ad56", + "type": "github" + }, + "original": { + "owner": "p1n3appl3", + "repo": "obs-gamepad", + "type": "github" + } + }, + "p1n3appl3": { + "inputs": { + "catppuccin": "catppuccin", + "flake-utils": "flake-utils_9", + "home-manager": "home-manager_2", + "nix-index-database": "nix-index-database", + "nixos-hardware": "nixos-hardware", + "nixpkgs": "nixpkgs_12", + "nixpkgs-stable": "nixpkgs-stable_2", + "obs-gamepad": "obs-gamepad", + "ragenix": "ragenix", + "rahul-config": [ + "rahul-config" + ], + "slippi": "slippi" + }, + "locked": { + "lastModified": 1768515258, + "narHash": "sha256-MBDxLHOIIminP+BPP74UQ3WBDnkbFguoW6MV6WXaepE=", + "owner": "p1n3appl3", + "repo": "config", + "rev": "e6de5bc3c0a67c2a0ed51231df0cd9e0adcfac60", + "type": "github" + }, + "original": { + "owner": "p1n3appl3", + "repo": "config", + "type": "github" + } + }, + "pipethon": { + "inputs": { + "flake-utils": "flake-utils_10", + "nixpkgs": "nixpkgs_13" + }, + "locked": { + "lastModified": 1767634075, + "narHash": "sha256-dusZCtuQ0rlu0gKD+zknHRnd74OoyX6KWAMYGYDTxkE=", + "ref": "refs/heads/main", + "rev": "1c9882a2cb6e9cbd4ba2ec0f47866c6117641c63", + "revCount": 7, + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/pipethon.git" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/pipethon.git" + } + }, + "ragenix": { + "inputs": { + "agenix": "agenix", + "crane": "crane", + "flake-utils": [ + "p1n3appl3", + "flake-utils" + ], + "nixpkgs": [ + "p1n3appl3", + "nixpkgs-stable" + ], + "rust-overlay": "rust-overlay_3" + }, + "locked": { + "lastModified": 1761832913, + "narHash": "sha256-VCNVjjuRvrKPiYYwqhE3BAKIaReiKXGpxGp27lZ0MFM=", + "owner": "yaxitech", + "repo": "ragenix", + "rev": "83bccfdea758241999f32869fb6b36f7ac72f1ac", + "type": "github" + }, + "original": { + "owner": "yaxitech", + "repo": "ragenix", + "type": "github" + } + }, + "ragenix_2": { + "inputs": { + "agenix": [ + "rahul-config", + "agenix" + ], + "crane": "crane_2", + "flake-utils": [ + "rahul-config", + "flake-utils" + ], + "nixpkgs": [ + "rahul-config", + "nixpkgs" + ], + "rust-overlay": "rust-overlay_4" + }, + "locked": { + "lastModified": 1718869541, + "narHash": "sha256-smhpGh1x/8mNl+sFL8SbeWnx0bK4HWjmdRA3mIwGjPU=", + "owner": "yaxitech", + "repo": "ragenix", + "rev": "8a254bbaa93fbd38e16f70fa81af6782794e046e", + "type": "github" + }, + "original": { + "owner": "yaxitech", + "repo": "ragenix", + "type": "github" + } + }, + "rahul-config": { + "inputs": { + "agenix": "agenix_2", + "darwin": "darwin_2", + "flake-utils": "flake-utils_11", + "home-manager": "home-manager_3", + "impermanence": "impermanence", + "nix-index-database": "nix-index-database_2", + "nixos-hardware": "nixos-hardware_2", + "nixpkgs": "nixpkgs_14", + "ragenix": "ragenix_2" + }, + "locked": { + "lastModified": 1739102974, + "narHash": "sha256-0ab3H7ODqB4CaZxRaWPRn9SA2Fq1NPTxQJ/fd12deuM=", + "owner": "jdonszelmann", + "repo": "nix-config", + "rev": "b43d53141becd33181672a7a355c4b195a9aeff1", + "type": "github" + }, + "original": { + "owner": "jdonszelmann", + "repo": "nix-config", + "type": "github" + } + }, + "raw-data": { + "inputs": { + "flake-utils": "flake-utils_12", + "nixpkgs": "nixpkgs_15" + }, + "locked": { + "lastModified": 1768919451, + "narHash": "sha256-AxIoJlIh3J8MgsMyJDeLSD76jJhenEdMN6EEi2G2Oew=", + "ref": "refs/heads/main", + "rev": "f5031750d33ea588cfa64a50bf4e15a8d373afe4", + "revCount": 1, + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/raw-data.git" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/raw-data.git" + } + }, + "reviewqueue": { + "inputs": { + "flake-utils": "flake-utils_13", + "naersk": "naersk_2", + "nixpkgs": "nixpkgs_17", + "nixpkgs-mozilla": "nixpkgs-mozilla_2" + }, + "locked": { + "lastModified": 1768928997, + "narHash": "sha256-YuG6heuos8YhDJYinNyllucglC33Rgi69FEGVl7pYI0=", "owner": "jdonszelmann", "repo": "review-queue", - "rev": "e2cf27dea96d2fde03c913d4b4462d3785019b36", + "rev": "5ab3617eab847a3007f7b70a11f912315afc3ec1", "type": "github" }, "original": { @@ -442,13 +1660,32 @@ "root": { "inputs": { "colmena": "colmena", - "flake-utils": "flake-utils_2", + "compiler-construction-2021": "compiler-construction-2021", + "dumpasm": "dumpasm", + "firefox-addons": "firefox-addons", + "firefox-sidebar-css": "firefox-sidebar-css", + "flake-utils": "flake-utils_4", "harmonica": "harmonica", + "home-manager": "home-manager", "homepage": "homepage", + "jujutsu": "jujutsu", + "kitty-search": "kitty-search", "mapf": "mapf", - "nixpkgs": "nixpkgs_5", + "matugen": "matugen", + "mifg": "mifg", + "niri": "niri", + "niri-unstable": "niri-unstable", + "nixpkgs": "nixpkgs_11", + "nixvim": "nixvim", + "noctalia": "noctalia", + "p1n3appl3": "p1n3appl3", + "pipethon": "pipethon", + "rahul-config": "rahul-config", + "raw-data": "raw-data", "reviewqueue": "reviewqueue", + "secrets": "secrets", "sops-nix": "sops-nix", + "t": "t", "totpal": "totpal", "vpn-confinement": "vpn-confinement" } @@ -470,37 +1707,191 @@ "type": "github" } }, - "sops-nix": { - "inputs": { - "nixpkgs": "nixpkgs_8", - "nixpkgs-stable": "nixpkgs-stable" - }, + "rust-analyzer-src_2": { + "flake": false, "locked": { - "lastModified": 1704122840, - "narHash": "sha256-K+ubwROTgvoMzBe6h/JExJTdDSrX3gWNHX2XNOsybB0=", - "owner": "jdonszelmann", - "repo": "sops-nix", - "rev": "162696bebe125a43aaaf6a249aea16fab6925762", + "lastModified": 1752428706, + "narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "591e3b7624be97e4443ea7b5542c191311aa141d", "type": "github" }, "original": { - "owner": "jdonszelmann", + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "jujutsu", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1762915112, + "narHash": "sha256-d9j1g8nKmYDHy+/bIOPQTh9IwjRliqaTM0QLHMV92Ic=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "aa1e85921cfa04de7b6914982a94621fbec5cc02", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_2": { + "inputs": { + "nixpkgs": [ + "niri-unstable", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1757989933, + "narHash": "sha256-9cpKYWWPCFhgwQTww8S94rTXgg8Q8ydFv9fXM6I8xQM=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "8249aa3442fb9b45e615a35f39eca2fe5510d7c3", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_3": { + "inputs": { + "nixpkgs": [ + "p1n3appl3", + "ragenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1761791894, + "narHash": "sha256-myRIDh+PxaREz+z9LzbqBJF+SnTFJwkthKDX9zMyddY=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "59c45eb69d9222a4362673141e00ff77842cd219", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_4": { + "inputs": { + "flake-utils": [ + "rahul-config", + "ragenix", + "flake-utils" + ], + "nixpkgs": [ + "rahul-config", + "ragenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1708740535, + "narHash": "sha256-NCTw235XwSDbeTAtAwg/hOeNOgwYhVq7JjDdbkOgBeA=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "9b24383d77f598716fa0cbb8b48c97249f5ee1af", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "secrets": { + "inputs": { + "flake-utils": "flake-utils_14", + "nixpkgs": "nixpkgs_18" + }, + "locked": { + "lastModified": 1769256063, + "narHash": "sha256-fVFJ10YXPF8RfUuyL3OHOP6v0pzU78mTeKvlOCRCuuA=", + "ref": "refs/heads/main", + "rev": "179e0bf0028c929978a3fbe7f77a27b2254eeb18", + "revCount": 7, + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/server-secrets.git" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@git.donsz.nl/jana/server-secrets.git" + } + }, + "slippi": { + "inputs": { + "git-hooks": [ + "p1n3appl3" + ], + "home-manager": [ + "p1n3appl3", + "home-manager" + ], + "nixpkgs": [ + "p1n3appl3", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1760294822, + "narHash": "sha256-VSzDcCkS/kGrALPv81x5yjqjt5o7n4lVjE/gknlz+1w=", + "owner": "lytedev", + "repo": "slippi-nix", + "rev": "abee78f6ad931c2a2f18dae102f51abcaf1a26c6", + "type": "github" + }, + "original": { + "owner": "lytedev", + "repo": "slippi-nix", + "type": "github" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": "nixpkgs_19" + }, + "locked": { + "lastModified": 1768709255, + "narHash": "sha256-aigyBfxI20FRtqajVMYXHtj5gHXENY2gLAXEhfJ8/WM=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "5e8fae80726b66e9fec023d21cd3b3e638597aa9", + "type": "github" + }, + "original": { + "owner": "Mic92", "repo": "sops-nix", "type": "github" } }, "stable": { "locked": { - "lastModified": 1746557022, - "narHash": "sha256-QkNoyEf6TbaTW5UZYX0OkwIJ/ZMeKSSoOMnSDPQuol0=", + "lastModified": 1750133334, + "narHash": "sha256-urV51uWH7fVnhIvsZIELIYalMYsyr2FCalvlRTzqWRw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1d3aeb5a193b9ff13f63f4d9cc169fb88129f860", + "rev": "36ab78dab7da2e4e27911007033713bab534187b", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-24.11", + "ref": "nixos-25.05", "repo": "nixpkgs", "type": "github" } @@ -520,6 +1911,141 @@ "type": "github" } }, + "systems_10": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_11": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_12": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_13": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_14": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_15": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_16": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_17": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_18": { + "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, @@ -565,9 +2091,103 @@ "type": "github" } }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_7": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_8": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_9": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "t": { + "inputs": { + "flake-utils": "flake-utils_15", + "nixpkgs": "nixpkgs_20" + }, + "locked": { + "lastModified": 1710410762, + "narHash": "sha256-pCCCdoW4+ipCOwzJCYZJ8CNINDsQvACCaxh2xT6uqmw=", + "owner": "jdonszelmann", + "repo": "t-rs", + "rev": "1178091650351fc8372e4c84c786433f9bce69d5", + "type": "github" + }, + "original": { + "owner": "jdonszelmann", + "repo": "t-rs", + "type": "github" + } + }, "totpal": { "inputs": { - "nixpkgs": "nixpkgs_9" + "nixpkgs": "nixpkgs_21" }, "locked": { "lastModified": 1737322813, @@ -583,13 +2203,31 @@ "type": "github" } }, + "utils": { + "inputs": { + "systems": "systems_11" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "vpn-confinement": { "locked": { - "lastModified": 1749672087, - "narHash": "sha256-j8LG0s0QcvNkZZLcItl78lvTZemvsScir0dG3Ii4B1c=", + "lastModified": 1767604552, + "narHash": "sha256-FddhMxnc99KYOZ/S3YNqtDSoxisIhVtJ7L4s8XD2u0A=", "owner": "Maroka-chan", "repo": "VPN-Confinement", - "rev": "880b3bd2c864dce4f6afc79f6580ca699294c011", + "rev": "a6b2da727853886876fd1081d6bb2880752937f3", "type": "github" }, "original": { @@ -597,6 +2235,39 @@ "repo": "VPN-Confinement", "type": "github" } + }, + "xwayland-satellite-stable": { + "flake": false, + "locked": { + "lastModified": 1755491097, + "narHash": "sha256-m+9tUfsmBeF2Gn4HWa6vSITZ4Gz1eA1F5Kh62B0N4oE=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "388d291e82ffbc73be18169d39470f340707edaa", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "ref": "v0.7", + "repo": "xwayland-satellite", + "type": "github" + } + }, + "xwayland-satellite-unstable": { + "flake": false, + "locked": { + "lastModified": 1768765571, + "narHash": "sha256-C1JbyJ3ftogmN3vmLNfyPtnJw2wY64TiUTIhFtk1Leg=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "ed1cef792b4def3321ff9ab5479df09609f17a69", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index a458091..c92b588 100644 --- a/flake.nix +++ b/flake.nix @@ -1,11 +1,19 @@ { description = "jana's server infrastructure"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/release-25.05"; + nixpkgs.url = "github:NixOS/nixpkgs"; colmena.url = "github:zhaofengli/colmena"; flake-utils.url = "github:numtide/flake-utils"; - sops-nix.url = "github:jdonszelmann/sops-nix"; + sops-nix.url = "github:Mic92/sops-nix"; vpn-confinement.url = "github:Maroka-chan/VPN-Confinement"; + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + firefox-addons = { + url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons"; + inputs.nixpkgs.follows = "nixpkgs"; + }; # websites @@ -14,6 +22,54 @@ harmonica.url = "git+ssh://git@github.com/jdonszelmann/harmonica-tabs"; mapf.url = "git+ssh://git@github.com/jdonszelmann/mapf-server"; reviewqueue.url = "github:jdonszelmann/review-queue"; + compiler-construction-2021.url = "git+ssh://forgejo@git.donsz.nl/jana/eelco-visser-compiler-construction.git"; + mifg.url = "git+ssh://forgejo@git.donsz.nl/jana/money.is.fckn.gay.git"; + + secrets.url = "git+ssh://forgejo@git.donsz.nl/jana/server-secrets.git"; + + nixvim = { + url = "github:nix-community/nixvim"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + t.url = "github:jdonszelmann/t-rs"; + dumpasm.url = "github:jdonszelmann/dumpasm"; + + kitty-search = { + url = "github:trygveaa/kitty-kitten-search"; + flake = false; + }; + + jujutsu = { + url = "github:martinvonz/jj"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + p1n3appl3 = { + url = "github:p1n3appl3/config"; + inputs.rahul-config.follows = "rahul-config"; + }; + rahul-config.url = "github:jdonszelmann/nix-config"; + + niri-unstable.url = "github:YaLTeR/niri"; + niri = { + url = "github:sodiboo/niri-flake"; + inputs.niri-unstable.follows = "niri-unstable"; + }; + matugen = { + url = "github:/InioX/matugen/main"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + noctalia = { + url = "github:noctalia-dev/noctalia-shell"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + pipethon.url = "git+ssh://forgejo@git.donsz.nl/jana/pipethon.git"; + firefox-sidebar-css = { + url = "github:drannex/FirefoxSidebar"; + flake = false; + }; + raw-data.url = "git+ssh://forgejo@git.donsz.nl/jana/raw-data.git"; }; outputs = { @@ -23,7 +79,19 @@ flake-utils, sops-nix, vpn-confinement, + home-manager, mapf, + nixvim, + t, + dumpasm, + jujutsu, + pipethon, + niri, + niri-unstable, + matugen, + noctalia, + firefox-addons, + raw-data, ... }@inputs: let @@ -32,18 +100,36 @@ import nixpkgs { inherit system; config.allowUnfree = true; - overlays = [ ]; + overlays = [ + (_: _: { + custom = { + t = t.packages.${system}.default; + inherit (dumpasm.packages.${system}) dumpasm; + inherit (jujutsu.packages.${system}) jujutsu; + pipethon = pipethon.packages.${system}.python; + niri = niri-unstable.packages.${system}.niri; + raw-data = raw-data.packages.${system}.default; + }; + p1n3appl3 = inputs.p1n3appl3.packages.${system}; + }) + ]; }; in { colmenaHive = colmena.lib.makeHive self.outputs.colmena; colmena = { - meta = { - nixpkgs = pkgsForSystem "x86_64-linux"; + meta = + let + system = "x86_64-linux"; + in + { + nixpkgs = pkgsForSystem system; - specialArgs.flakes = inputs; - }; + specialArgs.flakes = inputs; + specialArgs.inputs = inputs; + specialArgs.secrets = inputs.secrets.packages.${system}.secrets; + }; fili = { deployment = { @@ -56,13 +142,30 @@ }; imports = [ - ./fili/configuration.nix - ./users/users.nix + home-manager.nixosModules.home-manager + ./hosts/fili/configuration.nix + ./users ./default-machine-config.nix sops-nix.nixosModules.sops vpn-confinement.nixosModules.default ]; }; + + kili = { + deployment = { + allowLocalDeployment = true; + targetHost = null; + replaceUnknownProfiles = false; + tags = [ "laptop" ]; + # buildOnTarget = true; + targetUser = "jana"; + }; + imports = [ + home-manager.nixosModules.home-manager + ./hosts/kili/configuration.nix + ./users + ]; + }; }; } // flake-utils.lib.eachDefaultSystem ( @@ -78,11 +181,14 @@ (pkgs.writeShellScriptBin "apply" '' colmena apply --no-substitute '') + (pkgs.writeShellScriptBin "apply-local" '' + colmena apply-local --sudo + '') ]; shellHook = "exec $NIX_BUILD_SHELL"; }; - formatter = pkgs.nixfmt-rfc-style; + formatter = pkgs.nixfmt; } ); diff --git a/fili/configuration.nix b/hosts/fili/configuration.nix similarity index 75% rename from fili/configuration.nix rename to hosts/fili/configuration.nix index 0b41d94..81eab81 100644 --- a/fili/configuration.nix +++ b/hosts/fili/configuration.nix @@ -6,6 +6,13 @@ _: { ./services ]; + custom.machine = { + type = "server"; + capabilities = [ + "cli" + ]; + }; + networking.nameservers = [ "1.1.1.1" "9.9.9.9" @@ -35,4 +42,12 @@ _: { # secrets sops.age.keyFile = "/sops/sops-key.txt"; sops.defaultSopsFormat = "dotenv"; + + users.extraUsers.jana.extraGroups = [ + "storage" + "syncthing" + "jellyfin" + "media" + "nginx" + ]; } diff --git a/fili/hardware-configuration.nix b/hosts/fili/hardware-configuration.nix similarity index 100% rename from fili/hardware-configuration.nix rename to hosts/fili/hardware-configuration.nix diff --git a/fili/networking.nix b/hosts/fili/networking.nix similarity index 100% rename from fili/networking.nix rename to hosts/fili/networking.nix diff --git a/fili/services/auth/default.nix b/hosts/fili/services/auth/default.nix similarity index 72% rename from fili/services/auth/default.nix rename to hosts/fili/services/auth/default.nix index a96e992..9aa0dea 100644 --- a/fili/services/auth/default.nix +++ b/hosts/fili/services/auth/default.nix @@ -1,6 +1,6 @@ _: { imports = [ - ./kanidm.nix ./oauth2-proxy.nix + ./pocketid.nix ]; } diff --git a/hosts/fili/services/auth/oauth2-proxy.nix b/hosts/fili/services/auth/oauth2-proxy.nix new file mode 100644 index 0000000..3581d6b --- /dev/null +++ b/hosts/fili/services/auth/oauth2-proxy.nix @@ -0,0 +1,47 @@ +{ + config, + secrets, + ... +}: +{ + sops.secrets.oauth2-proxy = { + sopsFile = "${secrets}/oauth2-proxy.env"; + }; + + services.oauth2-proxy = { + enable = true; + + provider = "oidc"; + scope = "openid profile email groups"; + clientID = "38aa51e2-783e-48f0-a4b9-440e269f1217"; + oidcIssuerUrl = "https://auth.donsz.nl"; + reverseProxy = true; + + proxyPrefix = "/oauth2"; + + keyFile = config.sops.secrets.oauth2-proxy.path; + + email.domains = [ "*" ]; + + cookie = { + domain = "donsz.nl"; + refresh = "1h"; + secure = true; + }; + + extraConfig = { + whitelist-domain = [ "*.donsz.nl" ]; + insecure-oidc-allow-unverified-email = true; + }; + + nginx.domain = "oauth2.donsz.nl"; + }; + + services.nginx.virtualHosts."oauth2.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/".return = "301 https://oauth2.donsz.nl/oauth2/sign_in"; + }; +} diff --git a/hosts/fili/services/auth/pocketid.nix b/hosts/fili/services/auth/pocketid.nix new file mode 100644 index 0000000..0802392 --- /dev/null +++ b/hosts/fili/services/auth/pocketid.nix @@ -0,0 +1,57 @@ +{ config, secrets, ... }: +{ + sops.secrets.pocketid = { + owner = config.services.pocket-id.user; + sopsFile = "${secrets}/pocketid.env"; + }; + + services.nginx.virtualHosts."auth.donsz.nl" = { + forceSSL = true; + enableACME = true; + extraConfig = '' + proxy_busy_buffers_size 512k; + proxy_buffers 4 512k; + proxy_buffer_size 256k; + ''; + locations."/".proxyPass = "http://[::1]:${toString config.services.pocket-id.settings.PORT}"; + }; + + services.pocket-id = { + enable = true; + user = "pocket-id"; + environmentFile = config.sops.secrets.pocketid.path; + settings = { + PORT = 1411; + + TRUST_PROXY = true; + APP_URL = "https://auth.donsz.nl"; + ALLOW_USER_SIGNUPS = "withToken"; + + UI_CONFIG_DISABLED = true; + ALLOW_OWN_ACCOUNT_EDIT = true; + DB_PROVIDER = "postgres"; + DB_CONNECTION_STRING = "postgres://pocketid:pocketid@localhost:5432/pocketid"; + KEYS_STORAGE = "database"; + + METRICS_ENABLED = false; + TRACING_ENABLED = false; + ANALYTICS_DISABLED = true; + + SESSION_DURATION = 1440; + + SMTP_HOST = "smtp.fastmail.com"; + SMTP_PORT = "587"; + SMTP_FROM = "auth@donsz.nl"; + SMTP_USER = "pocketid-auth"; + SMTP_TLS = "starttls"; + + EMAIL_LOGIN_NOTIFICATION_ENABLED = true; + EMAIL_API_KEY_EXPIRATION_ENABLED = true; + EMAIL_ONE_TIME_ACCESS_AS_ADMIN_ENABLED = true; + + ACCENT_COLOR = "#c66995"; + + LOG_LEVEL = "debug"; + }; + }; +} diff --git a/fili/services/databases.nix b/hosts/fili/services/databases.nix similarity index 90% rename from fili/services/databases.nix rename to hosts/fili/services/databases.nix index b6f7e84..2e75d8e 100644 --- a/fili/services/databases.nix +++ b/hosts/fili/services/databases.nix @@ -50,6 +50,14 @@ name = "forgejo"; ensureDBOwnership = true; } + { + name = "pocketid"; + ensureDBOwnership = true; + } + { + name = "immich"; + ensureDBOwnership = true; + } ]; ensureDatabases = map (i: i.name) ensureUsers; }; diff --git a/fili/services/default.nix b/hosts/fili/services/default.nix similarity index 66% rename from fili/services/default.nix rename to hosts/fili/services/default.nix index 88e607e..39f6075 100644 --- a/fili/services/default.nix +++ b/hosts/fili/services/default.nix @@ -4,7 +4,11 @@ _: { ./databases.nix ./matrix-synapse.nix ./forgejo.nix + ./obsidian-sync.nix + ./metrics.nix + ./immich.nix + ./factorio ./media ./websites ./auth diff --git a/hosts/fili/services/factorio/default.nix b/hosts/fili/services/factorio/default.nix new file mode 100644 index 0000000..7ad9399 --- /dev/null +++ b/hosts/fili/services/factorio/default.nix @@ -0,0 +1,136 @@ +{ + lib, + pkgs, + config, + secrets, + ... +}: +let + factorioVersion = + version: sha: + pkgs.factorio-headless.overrideAttrs (_: { + inherit version; + src = pkgs.fetchurl { + url = "https://factorio.com/get-download/${version}/headless/linux64"; + name = "factorio-headless-${version}.tar.xz"; + sha256 = sha; + }; + }); + getMods = + modDir: + let + modList = lib.pipe modDir [ + builtins.readDir + (lib.filterAttrs (k: v: v == "regular")) + (lib.mapAttrsToList (k: v: k)) + (builtins.filter (lib.hasSuffix ".zip")) + ]; + validPath = + modFileName: + builtins.path { + path = modDir + "/${modFileName}"; + name = lib.strings.sanitizeDerivationName modFileName; + }; + modToDrv = + modFileName: + pkgs.runCommand "copy-factorio-mods" { } '' + mkdir $out + ln -s '${validPath modFileName}' $out/'${modFileName}' + '' + // { + deps = [ ]; + }; + in + builtins.map modToDrv modList; + factorioContainer = name: factorio-config: { + "factorio-${name}" = { + autoStart = true; + bindMounts = { + "/var/lib/factorio" = { + hostPath = "/factorio/${name}"; + isReadOnly = false; + }; + "/run/secrets" = { + hostPath = "/run/secrets"; + isReadOnly = true; + }; + "/etc/resolv.conf" = { + hostPath = "/etc/resolv.conf"; + isReadOnly = true; + }; + }; + privateUsers = "no"; + + config = + { + config, + pkgs, + lib, + ... + }: + { + systemd.services.factorio.serviceConfig.User = "factorio"; + services.factorio = factorio-config // { + enable = true; + openFirewall = true; + + game-name = name; + saveName = name; + stateDirName = "factorio"; + }; + + nixpkgs.config = { + allowUnfree = true; + }; + + system.stateVersion = "23.11"; + + networking = { + firewall.enable = false; + }; + }; + }; + }; +in +{ + users.groups.factorio = { }; + users.users.factorio = { + isSystemUser = true; + group = "factorio"; + extraGroups = [ "storage" ]; + }; + + sops.secrets.factorio = { + sopsFile = "${secrets}/factorio.json"; + format = "json"; + key = ""; + owner = "factorio"; + }; + + containers = + factorioContainer "tawney" { + autosave-interval = 20; + admins = [ + "jonay2000" + "computerdruid" + "pineapple" + ]; + extraSettingsFile = config.sops.secrets.factorio.path; + # mods = getMods .factorio-mods/tawney; + package = factorioVersion "2.0.69" "sha256-I1FHuz7WtfCmmTiTxskv3+U1upWrhmBG9R+GUoS1c0E="; + port = 20001; + } + // factorioContainer "snek" { + autosave-interval = 20; + admins = [ + "jonay2000" + "computerdruid" + "pineapple" + "koragendum" + ]; + extraSettingsFile = config.sops.secrets.factorio.path; + mods = getMods ./factorio-mods/snek; + package = factorioVersion "2.0.69" "sha256-I1FHuz7WtfCmmTiTxskv3+U1upWrhmBG9R+GUoS1c0E="; + port = 20002; + }; +} diff --git a/hosts/fili/services/factorio/factorio-mods/snek/VehicleSnap_2.0.2.zip b/hosts/fili/services/factorio/factorio-mods/snek/VehicleSnap_2.0.2.zip new file mode 100644 index 0000000..62e26bb Binary files /dev/null and b/hosts/fili/services/factorio/factorio-mods/snek/VehicleSnap_2.0.2.zip differ diff --git a/hosts/fili/services/factorio/factorio-mods/snek/factoryplanner_2.0.30.zip b/hosts/fili/services/factorio/factorio-mods/snek/factoryplanner_2.0.30.zip new file mode 100644 index 0000000..38dc08a Binary files /dev/null and b/hosts/fili/services/factorio/factorio-mods/snek/factoryplanner_2.0.30.zip differ diff --git a/hosts/fili/services/factorio/factorio-mods/snek/flib_0.16.3.zip b/hosts/fili/services/factorio/factorio-mods/snek/flib_0.16.3.zip new file mode 100644 index 0000000..eab4f7e Binary files /dev/null and b/hosts/fili/services/factorio/factorio-mods/snek/flib_0.16.3.zip differ diff --git a/hosts/fili/services/factorio/factorio-mods/snek/valerian-planets_1.0.2.zip b/hosts/fili/services/factorio/factorio-mods/snek/valerian-planets_1.0.2.zip new file mode 100644 index 0000000..5d77424 Binary files /dev/null and b/hosts/fili/services/factorio/factorio-mods/snek/valerian-planets_1.0.2.zip differ diff --git a/hosts/fili/services/factorio/factorio-mods/snek/visible-planets_1.4.8.zip b/hosts/fili/services/factorio/factorio-mods/snek/visible-planets_1.4.8.zip new file mode 100644 index 0000000..e1b3ce6 Binary files /dev/null and b/hosts/fili/services/factorio/factorio-mods/snek/visible-planets_1.4.8.zip differ diff --git a/fili/services/forgejo.nix b/hosts/fili/services/forgejo.nix similarity index 70% rename from fili/services/forgejo.nix rename to hosts/fili/services/forgejo.nix index 21c942f..4efb2c2 100644 --- a/fili/services/forgejo.nix +++ b/hosts/fili/services/forgejo.nix @@ -1,35 +1,44 @@ { - lib, pkgs, config, + flakes, + secrets, ... }: -let - cfg = config.services.forgejo; - srv = cfg.settings.server; -in { sops.secrets.forgejo = { - sopsFile = ../../secrets/forgejo.yaml; + sopsFile = "${secrets}/forgejo.yaml"; key = "email_password"; format = "yaml"; }; - - users.groups.forgejo = { }; - users.users.forgejo = { - isSystemUser = true; - group = "forgejo"; - extraGroups = [ "storage" ]; + users = { + groups = { + forgejo = { }; + forgejo-runner = { }; + }; + users.forgejo = { + isSystemUser = true; + group = "forgejo"; + extraGroups = [ "storage" ]; + }; + users.forgejo-runner = { + isSystemUser = true; + group = "forgejo-runner"; + }; }; - services.nginx = { - virtualHosts."git.donsz.nl" = { - forceSSL = true; - enableACME = true; + services.nginx.virtualHosts."git.donsz.nl" = { + forceSSL = true; + enableACME = true; + extraConfig = '' + client_max_body_size 512M; + ''; + + locations."/" = { + proxyPass = "http://[::1]:13121"; extraConfig = '' - client_max_body_size 512M; + rewrite ^/user/login.*$ /user/oauth2/pocketid last; ''; - locations."/".proxyPass = "http://[::1]:13121"; }; }; @@ -57,36 +66,41 @@ in HTTP_PORT = 13121; }; service = { - DISABLE_REGISTRATION = true; + DISABLE_REGISTRATION = false; ALLOW_ONLY_EXTERNAL_REGISTRATION = true; + SHOW_REGISTRATION_BUTTON = false; ENABLE_PASSWORD_SIGNIN_FORM = false; }; + openid = { + ENABLE_OPENID_SIGNUP = true; + }; + oauth2_client = { + REGISTER_EMAIL_CONFIRM = false; + ENABLE_AUTO_REGISTRATION = true; + UPDATE_AVATAR = true; + ACCOUNT_LINKING = "auto"; + }; actions = { ENABLED = true; DEFAULT_ACTIONS_URL = "github"; }; repository = { DEFAULT_PRIVATE = "private"; + DISABLE_HTTP_GIT = true; }; mailer = { ENABLED = true; SMTP_ADDR = "smtp.fastmail.com"; FROM = "git@donsz.nl"; USER = "git@donsz.nl"; + PASSWD = config.sops.secrets.forgejo.path; }; }; - mailerPasswordFile = config.sops.secrets.forgejo.path; - }; - - users.groups.forgejo-runner = { }; - users.users.forgejo-runner = { - isSystemUser = true; - group = "forgejo-runner"; }; sops.secrets.forgejo-runner = { - sopsFile = ../../secrets/forgejo-runner.env; + sopsFile = "${secrets}/forgejo-runner.env"; }; nix = { @@ -136,6 +150,7 @@ in wget # used in deployments + flakes.colmena.defaultPackage."x86_64-linux" lix openssh ]; @@ -149,5 +164,4 @@ in }; }; networking.firewall.trustedInterfaces = [ "br-+" ]; - } diff --git a/hosts/fili/services/immich.nix b/hosts/fili/services/immich.nix new file mode 100644 index 0000000..a75bf07 --- /dev/null +++ b/hosts/fili/services/immich.nix @@ -0,0 +1,96 @@ +{ + config, + pkgs, + secrets, + ... +}: +{ + + users.groups.jellyfin = { }; + users.users.immich = { + isSystemUser = true; + group = "immich"; + + extraGroups = [ + "video" + "render" + ]; + }; + + hardware.graphics = { + enable = true; + + extraPackages = with pkgs; [ + intel-ocl + intel-media-driver + ]; + }; + + sops.secrets.immich-session-secret = { + sopsFile = "${secrets}/immich.yaml"; + key = "client_secret"; + format = "yaml"; + }; + + services.nginx.virtualHosts."photos.donsz.nl" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://[::1]:${toString config.services.immich.port}"; + proxyWebsockets = true; + recommendedProxySettings = true; + extraConfig = '' + client_max_body_size 50000M; + proxy_read_timeout 600s; + proxy_send_timeout 600s; + send_timeout 600s; + ''; + }; + }; + + services.immich = { + enable = true; + port = 2283; + + database = { + name = "immich"; + createDB = false; + user = "postgres"; + host = "localhost"; + port = 5432; + }; + + secretsFile = toString ( + pkgs.writeText "db-password" '' + DB_PASSWORD=immich + '' + ); + + settings = { + server.externalDomain = "https://photos.donsz.nl"; + logging.level = "verbose"; + + oauth = { + enabled = true; + + clientSecret._secret = config.sops.secrets.immich-session-secret.path; + autoLaunch = true; + autoRegister = true; + buttonText = "Log in"; + clientId = "8fd9c066-2298-4991-ba24-7c41bd73192b"; + issuerUrl = "https://auth.donsz.nl"; + roleClaim = "immich_role"; + scope = "openid email profile groups"; + tokenEndpointAuthMethod = "client_secret_post"; + # storageLabelClaim: "", + # "mobileOverrideEnabled": false, + # "mobileRedirectUri": "", + + }; + }; + mediaLocation = "/storage/storage/media-server/photos"; + accelerationDevices = [ + "/dev/dri/renderD128" + ]; + }; +} diff --git a/fili/services/matrix-synapse.nix b/hosts/fili/services/matrix-synapse.nix similarity index 95% rename from fili/services/matrix-synapse.nix rename to hosts/fili/services/matrix-synapse.nix index ed1562c..e76238f 100644 --- a/fili/services/matrix-synapse.nix +++ b/hosts/fili/services/matrix-synapse.nix @@ -89,6 +89,7 @@ in } ]; + settings.registration_shared_secret = "eaU6JgZloozOfFU0tdkYh50CQBs8us0WzTuaaoGDWfwzGPwvABBSVXuqJHh5Pijx"; settings.database = { name = "psycopg2"; args = { diff --git a/hosts/fili/services/media/autobrr.nix b/hosts/fili/services/media/autobrr.nix new file mode 100644 index 0000000..16379d8 --- /dev/null +++ b/hosts/fili/services/media/autobrr.nix @@ -0,0 +1,54 @@ +{ config, secrets, ... }: +{ + sops.secrets.autobrr = { + sopsFile = "${secrets}/autobrr.yaml"; + key = "key"; + format = "yaml"; + }; + + services.nginx = { + virtualHosts."autobrr.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://${config.services.autobrr.settings.host}:${toString config.services.autobrr.settings.port}"; + }; + }; + }; + + # oauth access to the service + services.oauth2-proxy.nginx.virtualHosts."autobrr.donsz.nl" = { + allowed_groups = [ "torrent" ]; + }; + + # vpnNamespaces.mullvad.portMappings = [ + # { + # from = config.services.autobrr.settings.port; + # to = config.services.autobrr.settings.port; + # } + # ]; + # vpnNamespaces.mullvad.openVPNPorts = [ + # { + # # irc port + # port = 7021; + # protocol = "both"; + # } + # ]; + # systemd.services.autobrr.vpnConfinement = { + # enable = true; + # vpnNamespace = "mullvad"; + # }; + + services.autobrr = { + enable = true; + settings = { + logLevel = "DEBUG"; + checkForUpdates = false; + host = "localhost"; + port = 11012; + }; + secretFile = config.sops.secrets.autobrr.path; + }; +} diff --git a/fili/services/media/default.nix b/hosts/fili/services/media/default.nix similarity index 69% rename from fili/services/media/default.nix rename to hosts/fili/services/media/default.nix index e644e91..3ad1eb9 100644 --- a/fili/services/media/default.nix +++ b/hosts/fili/services/media/default.nix @@ -5,6 +5,8 @@ _: { ./sonarr.nix ./torrent.nix ./jackett.nix - ./plex.nix + ./jellyfin.nix + ./autobrr.nix + ./vpn.nix ]; } diff --git a/hosts/fili/services/media/jackett.nix b/hosts/fili/services/media/jackett.nix new file mode 100644 index 0000000..cec59f3 --- /dev/null +++ b/hosts/fili/services/media/jackett.nix @@ -0,0 +1,36 @@ +{ config, ... }: +{ + services.nginx = { + virtualHosts."jackett.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://localhost:${toString config.services.jackett.port}"; + }; + }; + }; + + # vpnNamespaces.mullvad.portMappings = [ + # { + # from = config.services.jackett.port; + # to = config.services.jackett.port; + # } + # ]; + # systemd.services.autobrr.vpnConfinement = { + # enable = true; + # vpnNamespace = "mullvad"; + # }; + + services.oauth2-proxy.nginx.virtualHosts."jackett.donsz.nl" = { + allowed_groups = [ "torrent" ]; + }; + + services.jackett = { + enable = true; + group = "jellyfin"; + user = "jellyfin"; + port = 11013; + }; +} diff --git a/hosts/fili/services/media/jellyfin.nix b/hosts/fili/services/media/jellyfin.nix new file mode 100644 index 0000000..e49c3e3 --- /dev/null +++ b/hosts/fili/services/media/jellyfin.nix @@ -0,0 +1,150 @@ +{ + pkgs, + config, + ... +}: +let + jellyfin-config = '' + + { + "includeCorsCredentials": false, + "multiserver": false, + "themes": [ + { + "name": "Apple TV", + "id": "appletv", + "color": "#bcbcbc" + }, { + "name": "Blue Radiance", + "id": "blueradiance", + "color": "#011432" + }, { + "name": "Dark", + "id": "dark", + "color": "#202020", + "default": true + }, { + "name": "Light", + "id": "light", + "color": "#303030" + }, { + "name": "Purple Haze", + "id": "purplehaze", + "color": "#000420" + }, { + "name": "WMC", + "id": "wmc", + "color": "#0c2450" + } + ], + "menuLinks": [ + { + "name": "Link SSO Account", + "icon": "add_link", + "url": "https://media.donsz.nl/SSOViews/linking" + } + ], + "servers": [], + "plugins": [ + "playAccessValidation/plugin", + "experimentalWarnings/plugin", + "htmlAudioPlayer/plugin", + "htmlVideoPlayer/plugin", + "photoPlayer/plugin", + "comicsPlayer/plugin", + "bookPlayer/plugin", + "youtubePlayer/plugin", + "backdropScreensaver/plugin", + "pdfPlayer/plugin", + "logoScreensaver/plugin", + "sessionPlayer/plugin", + "chromecastPlayer/plugin", + "syncPlay/plugin" + ] + } + + ''; +in +{ + environment.systemPackages = [ + pkgs.jellyfin + pkgs.jellyfin-web + pkgs.jellyfin-ffmpeg + ]; + + services.nginx.virtualHosts."media.donsz.nl" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:8096"; + extraConfig = '' + proxy_buffering off; + ''; + }; + locations."/socket" = { + inherit (config.services.nginx.virtualHosts."media.donsz.nl".locations."/") + proxyPass + ; + proxyWebsockets = true; + }; + }; + + users.groups.jellyfin = { }; + users.users.jellyfin = { + isSystemUser = true; + group = "jellyfin"; + + extraGroups = [ "storage" ]; + }; + + services.nginx.virtualHosts."media.donsz.nl".locations."/web/config.json".extraConfig = '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${jellyfin-config}'; + ''; + + services.jellyfin = { + enable = true; + openFirewall = true; + user = "jellyfin"; + group = "jellyfin"; + }; + + # Only set this if you're using intel-vaapi-driver (see below): + nixpkgs.config.packageOverrides = pkgs: { + intel-vaapi-driver = pkgs.intel-vaapi-driver.override { enableHybridCodec = true; }; + }; + + systemd.services.jellyfin.environment.LIBVA_DRIVER_NAME = "iHD"; # or i965, see below + environment.sessionVariables = { + LIBVA_DRIVER_NAME = "iHD"; + }; # ditto + + hardware.graphics = { + enable = true; + + extraPackages = with pkgs; [ + intel-ocl + intel-media-driver + # intel-media-sdk + ]; + }; + + # hardware.graphics = { + # enable = true; + # package = pkgs.intel-media-driver; + # }; + # systemd.services.jellyfin = { + # # if EncoderAppPath is manually set in the web UI, it can never be updated through --ffmpeg + # preStart = "test ! -e /var/lib/jellyfin/config/encoding.xml || sed -i '//d' /var/lib/jellyfin/config/encoding.xml"; + # serviceConfig = { + # # allow access to GPUs for hardware transcoding + # DeviceAllow = lib.mkForce "char-drm"; + # BindPaths = lib.mkForce "/dev/dri"; + # # to allow restarting from web ui + # Restart = lib.mkForce "always"; + + # Slice = "mediaplayback.slice"; + # }; + # }; +} diff --git a/hosts/fili/services/media/overseerr.nix b/hosts/fili/services/media/overseerr.nix new file mode 100644 index 0000000..e0e2fdc --- /dev/null +++ b/hosts/fili/services/media/overseerr.nix @@ -0,0 +1,27 @@ +{ ... }: +let + port = 11002; +in +{ + services.nginx.virtualHosts."req.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://[::1]:${toString port}"; + }; + }; + + virtualisation.oci-containers.containers = { + overseerr = { + image = "ghcr.io/fallenbagel/jellyseerr:preview-seerr"; + environment = { + }; + extraOptions = [ "--network=host" ]; + volumes = [ + "/var/lib/microvms/rr/storage/data/overseerr:/app/config" + ]; + }; + }; +} diff --git a/fili/services/media/radarr.nix b/hosts/fili/services/media/radarr.nix similarity index 57% rename from fili/services/media/radarr.nix rename to hosts/fili/services/media/radarr.nix index e9f1352..4f685ab 100644 --- a/fili/services/media/radarr.nix +++ b/hosts/fili/services/media/radarr.nix @@ -1,4 +1,4 @@ -{ ... }: +{ pkgs, ... }: { services.nginx = { virtualHosts."radarr.donsz.nl" = { @@ -11,10 +11,19 @@ }; }; }; + services.oauth2-proxy.nginx.virtualHosts."radarr.donsz.nl" = { + allowed_groups = [ "torrent" ]; + }; services.radarr = { enable = true; group = "jellyfin"; user = "jellyfin"; + + environmentFiles = [ + (pkgs.writeText "env" '' + RADARR__AUTH__METHOD="External" + '') + ]; }; } diff --git a/fili/services/media/sonarr.nix b/hosts/fili/services/media/sonarr.nix similarity index 56% rename from fili/services/media/sonarr.nix rename to hosts/fili/services/media/sonarr.nix index c7d28d0..204f843 100644 --- a/fili/services/media/sonarr.nix +++ b/hosts/fili/services/media/sonarr.nix @@ -1,4 +1,5 @@ -_: { +{ pkgs, ... }: +{ services.nginx = { virtualHosts."sonarr.donsz.nl" = { forceSSL = true; @@ -10,10 +11,19 @@ _: { }; }; }; + services.oauth2-proxy.nginx.virtualHosts."sonarr.donsz.nl" = { + allowed_groups = [ "torrent" ]; + }; services.sonarr = { enable = true; group = "jellyfin"; user = "jellyfin"; + + environmentFiles = [ + (pkgs.writeText "env" '' + SONARR__AUTH__METHOD="External" + '') + ]; }; } diff --git a/hosts/fili/services/media/torrent.nix b/hosts/fili/services/media/torrent.nix new file mode 100644 index 0000000..c615145 --- /dev/null +++ b/hosts/fili/services/media/torrent.nix @@ -0,0 +1,73 @@ +{ pkgs, ... }: +{ + vpnNamespaces.mullvad.portMappings = [ + { + from = 9091; + to = 9091; + } # UI Port. + { + from = 5432; + to = 5432; + } # DB Port. + ]; + vpnNamespaces.mullvad.openVPNPorts = [ + { + port = 50909; + protocol = "both"; + } + ]; + + services.nginx = { + virtualHosts."dl.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://192.168.15.1:9091"; + }; + }; + }; + services.oauth2-proxy.nginx.virtualHosts."dl.donsz.nl" = { + allowed_groups = [ "torrent" ]; + }; + + systemd.services.transmission.vpnConfinement = { + enable = true; + vpnNamespace = "mullvad"; + }; + + services.transmission = { + enable = true; + package = pkgs.transmission_4; + webHome = pkgs.stdenv.mkDerivation { + name = "flood-modified"; + version = "1.0"; + src = pkgs.flood-for-transmission; + installPhase = '' + mkdir -p $out + cp -r ./* $out + cp ./config.json.defaults $out/config.json + ''; + }; + home = "/var/lib/transmission"; + user = "jellyfin"; + group = "jellyfin"; + + settings = { + download-dir = "/storage/storage/torrents"; + incomplete-dir-enabled = false; + incomplete-dir = "/storage/storage/torrents"; + + rpc-bind-address = "192.168.15.1"; + rpc-host-whitelist-enabled = false; + rpc-whitelist-enabled = false; + + rpc-port = 9091; + + peer-port = 50909; + cache-size-mb = 2048; + preallocation = 1; + }; + }; +} diff --git a/hosts/fili/services/media/vpn.nix b/hosts/fili/services/media/vpn.nix new file mode 100644 index 0000000..a958334 --- /dev/null +++ b/hosts/fili/services/media/vpn.nix @@ -0,0 +1,16 @@ +{ config, secrets, ... }: +{ + sops.secrets.mullvad = { + sopsFile = "${secrets}/mullvad.yaml"; + owner = "root"; + format = "yaml"; + }; + + vpnNamespaces.mullvad = { + enable = true; + wireguardConfigFile = config.sops.secrets.mullvad.path; + accessibleFrom = [ + "192.168.0.0/16" + ]; + }; +} diff --git a/hosts/fili/services/metrics.nix b/hosts/fili/services/metrics.nix new file mode 100644 index 0000000..48841ec --- /dev/null +++ b/hosts/fili/services/metrics.nix @@ -0,0 +1,371 @@ +{ + pkgs, + config, + secrets, + ... +}: +let + lib = pkgs.lib; +in +{ + + services.prometheus = { + enable = true; + globalConfig = { + scrape_interval = "15s"; + }; + scrapeConfigs = + map + ( + { name, value }: + { + job_name = name; + static_configs = [ + { + targets = [ + "${config.services.prometheus.exporters.${name}.listenAddress}:${ + toString config.services.prometheus.exporters.${name}.port + }" + ]; + } + ]; + } + ) + ( + builtins.filter ( + { value, ... }: (builtins.tryEval value).success && (builtins.isAttrs value) && value.enable + ) (lib.attrsToList config.services.prometheus.exporters) + ); + + }; + + services.prometheus.exporters = { + node = { + enable = true; + port = 9001; + listenAddress = "127.0.0.1"; + enabledCollectors = [ + "cpu" + "filesystem" + "loadavg" + "systemd" + ]; + disabledCollectors = [ "rapl" ]; + extraFlags = [ + "--collector.ethtool" + "--collector.softirqs" + "--collector.tcpstat" + ]; + }; + process = { + enable = true; + listenAddress = "127.0.0.1"; + port = 9256; + }; + smartctl = { + enable = true; + port = 9633; + listenAddress = "127.0.0.1"; + }; + postgres = { + enable = true; + port = 9634; + listenAddress = "127.0.0.1"; + runAsLocalSuperUser = true; + }; + }; + + services.loki = { + enable = true; + configuration = { + auth_enabled = false; + server = { + http_listen_port = 3100; + grpc_listen_port = 9096; + }; + common = { + instance_addr = "127.0.0.1"; + path_prefix = "/tmp/loki"; + storage = { + filesystem = { + chunks_directory = "/tmp/loki/chunks"; + rules_directory = "/tmp/loki/rules"; + }; + }; + replication_factor = 1; + ring = { + kvstore = { + store = "inmemory"; + }; + }; + }; + query_range = { + results_cache = { + cache = { + embedded_cache = { + enabled = true; + max_size_mb = 100; + }; + }; + }; + }; + limits_config = { + allow_structured_metadata = false; + reject_old_samples = true; + reject_old_samples_max_age = "120d"; + retention_period = "120d"; + }; + schema_config = { + configs = [ + { + from = "2020-10-24"; + store = "tsdb"; + object_store = "filesystem"; + schema = "v13"; + index = { + prefix = "index_"; + period = "24h"; + }; + } + { + from = "2024-07-11"; + store = "tsdb"; + object_store = "filesystem"; + schema = "v13"; + index = { + prefix = "index_"; + period = "24h"; + }; + } + ]; + }; + ruler = { + alertmanager_url = "http://localhost:9093"; + }; + analytics.reporting_enabled = false; + }; + }; + + systemd.services.promtail.serviceConfig.User = lib.mkForce "nginx"; + services.promtail = { + enable = true; + configuration = { + server = { + http_listen_port = 3031; + grpc_listen_port = 0; + }; + positions = { + filename = "/tmp/positions.yaml"; + }; + clients = [ + { + url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push"; + } + ]; + scrape_configs = [ + { + job_name = "nginx"; + static_configs = [ + { + targets = [ "localhost" ]; + labels = { + job = "nginx"; + host = "fili"; + __path__ = "/var/log/nginx/json_access.log"; + }; + } + ]; + pipeline_stages = [ + { + json = { + expressions = { + msec = "msec"; + connection = "connection"; + connection_requests = "connection_requests"; + pid = "pid"; + request_id = "request_id"; + request_length = "request_length"; + remote_addr = "remote_addr"; + remote_user = "remote_user"; + remote_port = "remote_port"; + time_local = "time_local"; + time_iso8601 = "time_iso8601"; + request = "request"; + request_uri = "request_uri"; + args = "args"; + status = "status"; + body_bytes_sent = "body_bytes_sent"; + bytes_sent = "bytes_sent"; + http_referer = "http_referer"; + http_user_agent = "http_user_agent"; + http_x_forwarded_for = "http_x_forwarded_for"; + http_host = "http_host"; + server_name = "server_name"; + request_time = "request_time"; + upstream = "upstream"; + upstream_connect_time = "upstream_connect_time"; + upstream_header_time = "upstream_header_time"; + upstream_response_time = "upstream_response_time"; + upstream_response_length = "upstream_response_length"; + upstream_cache_status = "upstream_cache_status"; + ssl_protocol = "ssl_protocol"; + ssl_cipher = "ssl_cipher"; + scheme = "scheme"; + request_method = "request_method"; + server_protocol = "server_protocol"; + pipe = "pipe"; + gzip_ratio = "gzip_ratio"; + http_cf_ray = "http_cf_ray"; + }; + }; + } + { + timestamp = { + source = "msec"; + format = "Unix"; + }; + } + # { + # geoip = { + # db = "/var/lib/geoip-databases/GeoLite2-City.mmdb"; + # source = "remote_addr"; + # db_type = "city"; + # }; + # } + # { + # pack = { + # labels = [ "geoip_country_name" ]; + # }; + # } + ]; + } + { + job_name = "journal"; + journal = { + max_age = "12h"; + labels = { + job = "systemd-journal"; + host = "fili"; + }; + }; + relabel_configs = [ + { + source_labels = [ "__journal__systemd_unit" ]; + target_label = "unit"; + } + ]; + } + ]; + }; + }; + services.grafana = { + enable = true; + + settings = { + server = { + domain = "metrics.donsz.nl"; + http_port = 2342; + http_addr = "127.0.0.1"; + }; + "auth.anonymous".enabled' = true; + }; + + provision = { + enable = true; + datasources = { + settings.datasources = [ + { + type = "prometheus"; + name = "Prometheus"; + url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}"; + } + { + name = "Loki"; + type = "loki"; + url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}"; + } + ]; + }; + }; + }; + + sops.secrets.geoip = { + sopsFile = "${secrets}/geoip.yaml"; + key = "key"; + format = "yaml"; + }; + services.geoipupdate = { + enable = true; + settings = { + LicenseKey = config.sops.secrets.geoip.path; + AccountID = 1247225; + DatabaseDirectory = "/var/lib/geoip-databases"; + EditionIDs = [ + "GeoLite2-ASN" + "GeoLite2-City" + "GeoLite2-Country" + ]; + }; + }; + + services.nginx.virtualHosts.${config.services.grafana.settings.server.domain} = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = + "http://${config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}"; + }; + + services.nginx.package = pkgs.nginxStable.override (oldAttrs: { + modules = with pkgs.nginxModules; [ geoip2 ]; + buildInputs = oldAttrs.buildInputs ++ [ pkgs.libmaxminddb ]; + }); + + services.nginx.commonHttpConfig = '' + autoindex_localtime on; + geoip2 /var/lib/geoip-databases/GeoLite2-Country.mmdb { + $geoip2_data_country_iso_code country iso_code; + } + + log_format json_analytics escape=json '{' + '"msec": "$msec", ' # request unixtime in seconds with a milliseconds resolution + '"connection": "$connection", ' # connection serial number + '"connection_requests": "$connection_requests", ' # number of requests made in connection + '"pid": "$pid", ' # process pid + '"request_id": "$request_id", ' # the unique request id + '"request_length": "$request_length", ' # request length (including headers and body) + '"remote_addr": "$remote_addr", ' # client IP + '"remote_user": "$remote_user", ' # client HTTP username + '"remote_port": "$remote_port", ' # client port + '"time_local": "$time_local", ' + '"time_iso8601": "$time_iso8601", ' # local time in the ISO 8601 standard format + '"request": "$request", ' # full path no arguments if the request + '"request_uri": "$request_uri", ' # full path and arguments if the request + '"args": "$args", ' # args + '"status": "$status", ' # response status code + '"body_bytes_sent": "$body_bytes_sent", ' # the number of body bytes exclude headers sent to a client + '"bytes_sent": "$bytes_sent", ' # the number of bytes sent to a client + '"http_referer": "$http_referer", ' # HTTP referer + '"http_user_agent": "$http_user_agent", ' # user agent + '"http_x_forwarded_for": "$http_x_forwarded_for", ' # http_x_forwarded_for + '"http_host": "$http_host", ' # the request Host: header + '"server_name": "$server_name", ' # the name of the vhost serving the request + '"request_time": "$request_time", ' # request processing time in seconds with msec resolution + '"upstream": "$upstream_addr", ' # upstream backend server for proxied requests + '"upstream_connect_time": "$upstream_connect_time", ' # upstream handshake time incl. TLS + '"upstream_header_time": "$upstream_header_time", ' # time spent receiving upstream headers + '"upstream_response_time": "$upstream_response_time", ' # time spend receiving upstream body + '"upstream_response_length": "$upstream_response_length", ' # upstream response length + '"upstream_cache_status": "$upstream_cache_status", ' # cache HIT/MISS where applicable + '"ssl_protocol": "$ssl_protocol", ' # TLS protocol + '"ssl_cipher": "$ssl_cipher", ' # TLS cipher + '"scheme": "$scheme", ' # http or https + '"request_method": "$request_method", ' # request method + '"server_protocol": "$server_protocol", ' # request protocol, like HTTP/1.1 or HTTP/2.0 + '"pipe": "$pipe", ' # "p" if request was pipelined, "." otherwise + '"gzip_ratio": "$gzip_ratio", ' + '"http_cf_ray": "$http_cf_ray", ' + '"geoip_country_code": "$geoip2_data_country_iso_code"' + '}'; + access_log /var/log/nginx/json_access.log json_analytics; + ''; +} diff --git a/fili/services/nginx.nix b/hosts/fili/services/nginx.nix similarity index 90% rename from fili/services/nginx.nix rename to hosts/fili/services/nginx.nix index e58c7b6..819a3cb 100644 --- a/fili/services/nginx.nix +++ b/hosts/fili/services/nginx.nix @@ -19,5 +19,4 @@ security.acme.defaults.email = "jana@donsz.nl"; security.acme.acceptTerms = true; - security.acme.preliminarySelfsigned = true; } diff --git a/hosts/fili/services/obsidian-sync.nix b/hosts/fili/services/obsidian-sync.nix new file mode 100644 index 0000000..ab1f514 --- /dev/null +++ b/hosts/fili/services/obsidian-sync.nix @@ -0,0 +1,56 @@ +{ + pkgs, + config, + secrets, + ... +}: +let + port = 5984; +in +{ + sops.secrets.obsidian-sync = { + sopsFile = "${secrets}/obsidian-sync.ini"; + format = "ini"; + owner = "couchdb"; + }; + + services.couchdb = { + enable = true; + inherit port; + package = pkgs.couchdb3; + configFile = config.sops.secrets.obsidian-sync.path; + + extraConfig = { + chttpd = { + require_valid_user = true; + enable_cors = true; + max_http_request_size = 4294967296; + }; + + chttpd_auth.require_valid_user = true; + httpd = { + WWW-Authenticate = ''Basic realm="couchdb"''; + enable_cors = true; + }; + + couchdb.max_document_size = 50000000; + + cors = { + credentials = true; + headers = "accept, authorization, content-type, origin, referer"; + methods = "GET,PUT,POST,HEAD,DELETE"; + max_age = 3600; + origins = "app://obsidian.md,capacitor://localhost,http://localhost,https://localhost,capacitor://obsidian.donsz.nl,http://obsidian.donsz.nl,https://obsidian.donsz.nl"; + }; + }; + }; + + services.nginx.virtualHosts."obsidian.donsz.nl" = { + forceSSL = true; + enableACME = true; + extraConfig = '' + client_max_body_size 512M; + ''; + locations."/".proxyPass = "http://localhost:${toString port}"; + }; +} diff --git a/hosts/fili/services/websites/compiler-construction-2021.nix b/hosts/fili/services/websites/compiler-construction-2021.nix new file mode 100644 index 0000000..f7901db --- /dev/null +++ b/hosts/fili/services/websites/compiler-construction-2021.nix @@ -0,0 +1,14 @@ +{ pkgs, flakes, ... }: +{ + services.nginx = { + virtualHosts."compiler-construction-2021.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + root = flakes.compiler-construction-2021.packages.${pkgs.system}.website; + }; + }; + }; +} diff --git a/fili/services/websites/default.nix b/hosts/fili/services/websites/default.nix similarity index 58% rename from fili/services/websites/default.nix rename to hosts/fili/services/websites/default.nix index 4cf107d..668d7f5 100644 --- a/fili/services/websites/default.nix +++ b/hosts/fili/services/websites/default.nix @@ -5,5 +5,8 @@ _: { ./totpal.nix ./harmonica-tabs.nix ./mapf.nix + ./compiler-construction-2021.nix + ./mapfm-poster.nix + ./money-is-fckn-gay.nix ]; } diff --git a/fili/services/websites/harmonica-tabs.nix b/hosts/fili/services/websites/harmonica-tabs.nix similarity index 100% rename from fili/services/websites/harmonica-tabs.nix rename to hosts/fili/services/websites/harmonica-tabs.nix diff --git a/hosts/fili/services/websites/homepage.nix b/hosts/fili/services/websites/homepage.nix new file mode 100644 index 0000000..ce17421 --- /dev/null +++ b/hosts/fili/services/websites/homepage.nix @@ -0,0 +1,48 @@ +{ flakes, pkgs, ... }: +{ + services.nginx = { + virtualHosts."donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + root = "${flakes.homepage.packages.${pkgs.system}.website}"; + }; + }; + virtualHosts."blog.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/".return = "301 https://donsz.nl/blog"; + }; + virtualHosts."gay.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + root = "${flakes.homepage.packages.${pkgs.system}.website-gay}"; + }; + }; + virtualHosts."jana.is.fckn.gay" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + root = "${flakes.homepage.packages.${pkgs.system}.website-gay}"; + }; + }; + virtualHosts."jdonszelmann.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + root = "${flakes.homepage.packages.${pkgs.system}.website}"; + }; + }; + }; +} diff --git a/hosts/fili/services/websites/mapf.nix b/hosts/fili/services/websites/mapf.nix new file mode 100644 index 0000000..9a7e22e --- /dev/null +++ b/hosts/fili/services/websites/mapf.nix @@ -0,0 +1,51 @@ +{ + config, + flakes, + pkgs, + secrets, + ... +}: +{ + sops.secrets.mapf = { + sopsFile = "${secrets}/mapf-prod.env"; + }; + + services.nginx = { + virtualHosts."mapf.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://[::1]:8080"; + }; + }; + }; + + systemd.services.mapf-server = + let + package = flakes.mapf.packages.${pkgs.system}.default; + in + { + description = "mapf-server"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + DynamicUser = "yes"; + ExecStart = "${package}/mapf_server_bin"; + Restart = "on-failure"; + RestartSec = "5s"; + EnvironmentFile = config.sops.secrets.mapf.path; + WorkingDirectory = "${package}"; + }; + + environment = { + MAPF_TEMPLATEFOLDER = "${package}/templates"; + MAPF_DBUSER = "mapfprod"; + MAPF_DBPASSWORD = ""; + MAPF_DBPORT = "3306"; + MAPF_DBHOST = "localhost"; + MAPF_DBDATABASE = "mapfprod"; + }; + }; +} diff --git a/hosts/fili/services/websites/mapfm-poster.nix b/hosts/fili/services/websites/mapfm-poster.nix new file mode 100644 index 0000000..5c026f4 --- /dev/null +++ b/hosts/fili/services/websites/mapfm-poster.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: +{ + services.nginx.virtualHosts."mapfm-poster.donsz.nl" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + root = pkgs.stdenv.mkDerivation rec { + pname = "research-project-poster"; + version = "2021-06-27"; + src = pkgs.fetchFromGitHub { + owner = "jdonszelmann"; + repo = "research-project"; + rev = "f1c0c5d839197f825b555780271781281ba10ac3"; + sha256 = "sha256-YJxcLRABU3yRS/U/XNLpTIXtve0cFfnwPKr+1oY0HeY="; + }; + + installPhase = '' + mkdir -p $out + cp -r assets/final_poster/* $out + ''; + }; + }; + }; +} diff --git a/hosts/fili/services/websites/money-is-fckn-gay.nix b/hosts/fili/services/websites/money-is-fckn-gay.nix new file mode 100644 index 0000000..50072e1 --- /dev/null +++ b/hosts/fili/services/websites/money-is-fckn-gay.nix @@ -0,0 +1,86 @@ +{ + pkgs, + flakes, + ... +}: +let + mifg-config = api-url: api-port: public-url: service-name: { + nginx = { + virtualHosts."${api-url}" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://localhost:${toString api-port}"; + proxyWebsockets = true; + }; + }; + virtualHosts."${public-url}" = { + forceSSL = true; + http2 = true; + enableACME = true; + + locations."/" = { + root = flakes.mifg.packages.${pkgs.system}.frontend.override { + api_base_url = "https://${api-url}"; + }; + tryFiles = "$uri $uri/ /index.html"; + }; + }; + }; + + service = { + description = "money is fckn gay"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + restartIfChanged = true; + + serviceConfig = { + ExecStart = "${flakes.mifg.packages.${pkgs.system}.backend}/bin/backend"; + Restart = "always"; + # EnvironmentFile = "/run/secrets/reviewqueue"; + StateDirectory = "${service-name}"; + }; + + environment = { + MIFG_DATABASE_LOCATION = "/var/lib/${service-name}/db.sqlite"; + MIFG_FRONTEND_ORIGIN = "https://${public-url}"; + MIFG_PORT = toString api-port; + LD_LIBRARY_PATH = + with pkgs; + lib.makeLibraryPath [ + openssl + sqlite + ]; + }; + }; + }; + real = (mifg-config "api.money.is.fckn.gay" 11009 "money.is.fckn.gay" "money"); + staging = (mifg-config "api.money-staging.donsz.nl" 11010 "money-staging.donsz.nl" "money-staging"); + lib = pkgs.lib; +in +{ + services.nginx = lib.mkMerge [ + real.nginx + staging.nginx + ]; + systemd.services.money = real.service; + systemd.services.money-staging = lib.mkMerge [ + staging.service + { + serviceConfig.ExecStartPre = "${(pkgs.writeShellScriptBin "setup-staging" '' + REAL_DB_LOCATION="/var/lib/money/" + STAGING_DB_LOCATION="/var/lib/money-staging/" + + echo "$REAL_DB_LOCATION" + echo "$STAGING_DB_LOCATION" + + mkdir -p $STAGING_DB_LOCATION + cp -r $REAL_DB_LOCATION/* $STAGING_DB_LOCATION + '')}/bin/setup-staging"; + } + ]; +} diff --git a/fili/services/websites/reviewqueue.nix b/hosts/fili/services/websites/reviewqueue.nix similarity index 61% rename from fili/services/websites/reviewqueue.nix rename to hosts/fili/services/websites/reviewqueue.nix index baaff65..b19aeed 100644 --- a/fili/services/websites/reviewqueue.nix +++ b/hosts/fili/services/websites/reviewqueue.nix @@ -1,7 +1,12 @@ -{ pkgs, flakes, ... }: +{ + pkgs, + flakes, + secrets, + ... +}: { sops.secrets.reviewqueue = { - sopsFile = ../../../secrets/reviewqueue.env; + sopsFile = "${secrets}/reviewqueue.env"; }; services.nginx = { @@ -11,7 +16,8 @@ enableACME = true; locations."/" = { - proxyPass = "http://[::1]:3000"; + proxyPass = "http://localhost:3000"; + proxyWebsockets = true; }; }; }; @@ -20,19 +26,25 @@ description = "Review Queue"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; # if networking is needed + after = [ "network.target" ]; - restartIfChanged = true; # set to false, if restarting is problematic + restartIfChanged = true; serviceConfig = { ExecStart = "${flakes.reviewqueue.packages.${pkgs.system}.default}/bin/reviewqueue"; Restart = "always"; EnvironmentFile = "/run/secrets/reviewqueue"; - StateDirectory = "/var/lib/reviewqueue"; + StateDirectory = "reviewqueue"; }; environment = { DB_PATH = "/var/lib/reviewqueue/db.sqlite"; + LD_LIBRARY_PATH = + with pkgs; + lib.makeLibraryPath [ + openssl + sqlite + ]; }; }; } diff --git a/fili/services/websites/totpal.nix b/hosts/fili/services/websites/totpal.nix similarity index 100% rename from fili/services/websites/totpal.nix rename to hosts/fili/services/websites/totpal.nix diff --git a/fili/storage.nix b/hosts/fili/storage.nix similarity index 100% rename from fili/storage.nix rename to hosts/fili/storage.nix diff --git a/hosts/kili/configuration.nix b/hosts/kili/configuration.nix new file mode 100644 index 0000000..d7acb40 --- /dev/null +++ b/hosts/kili/configuration.nix @@ -0,0 +1,170 @@ +{ + pkgs, + config, + ... +}: +{ + imports = [ + ./hardware-configuration.nix + ../../default-machine-config.nix + ]; + + custom.machine = { + type = "pc"; + capabilities = [ + "cli" + "graphical" + "work" + "fun" + ]; + }; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "kili"; + networking.networkmanager.enable = true; + + # Set your time zone. + time.timeZone = "Europe/Amsterdam"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "nl_NL.UTF-8"; + LC_IDENTIFICATION = "nl_NL.UTF-8"; + LC_MEASUREMENT = "nl_NL.UTF-8"; + LC_MONETARY = "nl_NL.UTF-8"; + LC_NAME = "nl_NL.UTF-8"; + LC_NUMERIC = "nl_NL.UTF-8"; + LC_PAPER = "nl_NL.UTF-8"; + LC_TELEPHONE = "nl_NL.UTF-8"; + LC_TIME = "nl_NL.UTF-8"; + }; + + services.xserver.xkb = { + layout = "us"; + variant = ""; + }; + + users.users.jana = { + extraGroups = [ + "networkmanager" + "wheel" + ]; + packages = with pkgs; [ ]; + }; + + nixpkgs.config.allowUnfree = true; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + + firefox + kitty + pkgs.custom.niri + zed-editor + signal-desktop + discord + nautilus + + adwaita-icon-theme + (pkgs.callPackage ( + { stdenv }: + stdenv.mkDerivation { + name = "global-cursor-theme"; + unpackPhase = "true"; + outputs = [ "out" ]; + installPhase = '' + mkdir -p $out/share/icons/default + cat << EOF > $out/share/icons/default/index.theme + [Icon Theme] + Name=Default + Comment=Default Cursor Theme + Inherits=Adwaita + EOF + ''; + } + ) { }) + ]; + + services.xserver.enable = true; + services.displayManager.gdm.enable = true; + services.desktopManager.gnome.enable = true; + + services.gnome.gnome-keyring.enable = true; + services.gvfs.enable = true; + services.displayManager.sessionPackages = [ pkgs.custom.niri ]; + programs.dconf.enable = true; + + nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; + + services.xserver.videoDrivers = [ + "modesetting" + "nvidia" + ]; + + hardware.graphics.enable = true; + hardware.graphics.extraPackages = with pkgs; [ + libva-vdpau-driver + intel-media-driver + ]; + environment.sessionVariables = { + LIBVA_DRIVER_NAME = "iHD"; + }; + + hardware.nvidia = { + modesetting.enable = true; + powerManagement.enable = true; + powerManagement.finegrained = false; + + # use nvidia opensource driver (not nouveau!!) + open = true; + nvidiaSettings = true; + + prime = { + offload = { + enable = true; + enableOffloadCmd = true; + }; + + intelBusId = "PCI:0@00:02:0"; + nvidiaBusId = "PCI:0@01:00:0"; + }; + + package = config.boot.kernelPackages.nvidiaPackages.mkDriver { + version = "580.95.05"; + sha256_64bit = "sha256-hJ7w746EK5gGss3p8RwTA9VPGpp2lGfk5dlhsv4Rgqc="; + sha256_aarch64 = "sha256-zLRCbpiik2fGDa+d80wqV3ZV1U1b4lRjzNQJsLLlICk="; + openSha256 = "sha256-RFwDGQOi9jVngVONCOB5m/IYKZIeGEle7h0+0yGnBEI="; + settingsSha256 = "sha256-F2wmUEaRrpR1Vz0TQSwVK4Fv13f3J9NJLtBe4UP2f14="; + persistencedSha256 = "sha256-QCwxXQfG/Pa7jSTBB0xD3lsIofcerAWWAHKvWjWGQtg="; + patchesOpen = [ + (pkgs.fetchpatch { + name = "get_dev_pagemap.patch"; + url = "https://github.com/NVIDIA/open-gpu-kernel-modules/commit/3e230516034d29e84ca023fe95e284af5cd5a065.patch"; + hash = "sha256-BhL4mtuY5W+eLofwhHVnZnVf0msDj7XBxskZi8e6/k8="; + }) + ]; + }; + }; + + # programs.mtr.enable = true; + # programs.gnupg.agent = { + # enable = true; + # enableSSHSupport = true; + # }; + + nix.settings = { + # users that can interact with nix + trusted-users = [ + "jana" + "root" + ]; + }; +} diff --git a/hosts/kili/hardware-configuration.nix b/hosts/kili/hardware-configuration.nix new file mode 100644 index 0000000..a64dd08 --- /dev/null +++ b/hosts/kili/hardware-configuration.nix @@ -0,0 +1,31 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/4919727e-d114-4d57-b206-522b5df5fccc"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/26CD-373C"; + fsType = "vfat"; + options = [ "fmask=0077" "dmask=0077" ]; + }; + + swapDevices = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/modules/capabilities.nix b/modules/capabilities.nix new file mode 100644 index 0000000..9b69a64 --- /dev/null +++ b/modules/capabilities.nix @@ -0,0 +1,10 @@ +[ + # needs configs for cli access + "cli" + # needs configs for ui like a desktop manager and login manager + "graphical" + # needs configs for work computers like libreoffice etc + "work" + # needs configs for fun use, like steam + "fun" +] diff --git a/modules/home-info.nix b/modules/home-info.nix new file mode 100644 index 0000000..251ab1e --- /dev/null +++ b/modules/home-info.nix @@ -0,0 +1,16 @@ +{ + lib, + ... +}: +with lib; +{ + options = { + custom.home-info = mkOption { + type = types.submodule { + options = { + + }; + }; + }; + }; +} diff --git a/modules/machine-type.nix b/modules/machine-type.nix new file mode 100644 index 0000000..75d4542 --- /dev/null +++ b/modules/machine-type.nix @@ -0,0 +1,25 @@ +{ + lib, + ... +}: +with lib; +{ + options = { + custom.machine = mkOption { + type = types.submodule { + options = { + type = mkOption { + type = types.enum [ + "server" + "pc" + ]; + }; + capabilities = mkOption { + type = types.listOf (types.enum (import ./capabilities.nix)); + default = [ "cli" ]; + }; + }; + }; + }; + }; +} diff --git a/modules/program.nix b/modules/program.nix new file mode 100644 index 0000000..a791eb1 --- /dev/null +++ b/modules/program.nix @@ -0,0 +1,36 @@ +{ + lib, + options, + ... +}: +with lib; +{ + options = { + custom.program = mkOption { + type = types.attrsOf ( + types.submodule ( + { config, ... }: + { + options = { + name = mkOption { + type = types.string; + }; + requirements = mkOption { + type = types.listOf (types.enum (import ./capabilities.nix)); + default = [ "cli" ]; + }; + home-config = mkOption { + type = types.deferredModule; + }; + system-config = mkOption { + # type = types.attrs; + type = types.deferredModule; + default = { }; + }; + }; + } + ) + ); + }; + }; +} diff --git a/modules/users.nix b/modules/users.nix new file mode 100644 index 0000000..00d80c7 --- /dev/null +++ b/modules/users.nix @@ -0,0 +1,109 @@ +{ + lib, + pkgs, + config, + ... +}: +with lib; +let + cfg = config.custom.users; + machine = config.custom.machine; + valid-on-machine = + on: + # TODO: iterate over possibilities + if machine.type == "server" then + on.server + else if machine.type == "pc" then + on.pc + else + false; + matches-capabilities = + # all requirements are contained in the machine capabilities + requirements: lib.all (req: builtins.elem req machine.capabilities) requirements; + users = lib.filterAttrs (_: value: valid-on-machine value.on) cfg; + home-users = lib.filterAttrs (_: value: value.apply-home-configs) users; + stateVersion = config.system.stateVersion; + programs = lib.attrsets.attrValues config.custom.program; + valid-programs = builtins.filter (program: matches-capabilities program.requirements) programs; +in +{ + options = + let + userType = types.submodule { + options = { + name = mkOption { + type = types.str; + default = [ ]; + }; + groups = mkOption { + type = types.listOf types.str; + default = [ ]; + }; + keys = mkOption { + type = types.listOf types.str; + default = [ ]; + }; + shell = mkOption { + type = types.package; + default = pkgs.fish; + }; + on = mkOption { + type = types.submodule { + options = { + server = mkOption { + type = types.bool; + default = true; + }; + pc = mkOption { + type = types.bool; + default = false; + }; + }; + }; + default = { }; + }; + apply-home-configs = mkOption { + type = types.bool; + default = false; + }; + }; + }; + in + { + custom.users = mkOption { + type = types.attrsOf userType; + }; + }; + + config = lib.mkMerge ([ + { + users.extraUsers = lib.mapAttrs (name: value: { + isNormalUser = true; + extraGroups = value.groups; + openssh.authorizedKeys.keys = value.keys; + shell = value.shell; + description = name; + }) users; + home-manager.users = lib.mapAttrs ( + name: value: + ( + { pkgs, lib, ... }: + { + imports = ( + [ + ./home-info.nix + ] + ++ (map (program: program.home-config) valid-programs) + ); + + home = { + inherit stateVersion; + username = name; + homeDirectory = "/home/${name}"; + }; + } + ) + ) home-users; + } + ]); +} diff --git a/programs/cosmic/default.nix b/programs/cosmic/default.nix new file mode 100644 index 0000000..9d7bf9c --- /dev/null +++ b/programs/cosmic/default.nix @@ -0,0 +1,25 @@ +{ pkgs +, lib +, cosmicLib +, ... +}: +let + ron = cosmicLib.cosmic.mkRON; +in + +{ + wayland.desktopManager.cosmic = { + enable = true; + + # shortcuts = [ + # { + # action = ron "enum" "Close"; + # key = "Super+Q"; + # } + # { + # action = ron "enum" "maximize"; + # key = "Super+d"; + # } + # ]; + }; +} diff --git a/programs/default.nix b/programs/default.nix new file mode 100644 index 0000000..9e4ba40 --- /dev/null +++ b/programs/default.nix @@ -0,0 +1,80 @@ +{ + pkgs, + ... +}: +{ + imports = [ + ./nvim + ./fish + ./kanata + ./kitty + ./tmux + ./git + ./jj + ./niri + ./zed + ./firefox + ]; + + custom.program.graphcial-packages = { + requirements = [ "graphical" ]; + home-config = _: { + home.packages = with pkgs; [ + spotify + obsidian + ]; + }; + }; + + custom.program.fun-packages = { + requirements = [ "fun" ]; + home-config = _: { + home.packages = with pkgs; [ + p1n3appl3.tab + ]; + }; + }; + + custom.program.cli-packages = { + requirements = [ "cli" ]; + home-config = _: { + home.packages = with pkgs; [ + rustup + sops + ]; + }; + }; + + custom.program.homedirs = { + home-config = + { config, ... }: + { + home.file = { + "dl".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.userDirs.download}"; + "doc".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.userDirs.documents}"; + }; + }; + }; + + custom.program.xdg = { + home-config = + { config, ... }: + { + xdg = { + enable = true; + + configHome = "${config.home.homeDirectory}/.config"; + userDirs = { + enable = true; + documents = "${config.home.homeDirectory}/Documents"; + desktop = "${config.home.homeDirectory}/Documents"; + download = "${config.home.homeDirectory}/Downloads"; + music = "${config.home.homeDirectory}/Documents/personal/music"; + pictures = "${config.home.homeDirectory}/Documents/personal/pictures"; + }; + + mime.enable = true; + }; + }; + }; +} diff --git a/programs/firefox/default.nix b/programs/firefox/default.nix new file mode 100644 index 0000000..2a0c394 --- /dev/null +++ b/programs/firefox/default.nix @@ -0,0 +1,165 @@ +_: { + custom.program.firefox.requirements = [ "graphical" ]; + custom.program.firefox.home-config = + { + config, + flakes, + pkgs, + ... + }: + let + ff-pkgs = flakes.firefox-addons.packages.${pkgs.system}; + lock-false = { + Value = false; + Status = "locked"; + }; + # lock-true = { + # Value = true; + # Status = "locked"; + # }; + in + { + programs.firefox = { + enable = true; + package = pkgs.wrapFirefox pkgs.firefox-unwrapped { + extraPolicies = { + DisableFormHistory = true; + OfferToSaveLogins = false; + PasswordManagerEnabled = false; + AppAutoUpdate = false; + DisableFirefoxStudies = true; + DisablePocket = true; + DisableTelemetry = true; + UserMessaging = { + WhatsNew = true; + ExtensionRecommendations = false; + FeatureRecommendations = false; + UrlbarInterventions = false; + SkipOnboarding = true; + MoreFromMozilla = false; + Locked = true; + }; + FirefoxHome = { + Search = true; + TopSites = false; + SponsoredTopSites = false; + Highlights = false; + Pocket = false; + SponsoredPocket = false; + Snippets = false; + Locked = false; + }; + FirefoxSuggest = { + WebSuggestions = false; + SponsoredSuggestions = false; + ImproveSuggest = false; + Locked = true; + }; + # TODO: https://github.com/TheRealGramdalf/nixos/blob/83f4339b121175f47940314bf5811080ac42c316/users/games/firefox/privacy.nix + }; + + }; + + profiles.default = { + id = 0; + name = "profile_0"; + isDefault = true; + settings = { + # specify profile-specific preferences here; check about:config for options + "browser.newtabpage.activity-stream.feeds.section.highlights" = false; + "browser.startup.page" = 3; # Restore previous tabs + "extensions.autoDisableScopes" = 0; + "extensions.pocket.enabled" = lock-false; + "browser.tabs.closeWindowWithLastTab" = lock-false; + "sidebar.position_start" = false; # sidebar on the right + "toolkit.legacyUserProfileCustomizations.stylesheets" = true; + "browser.toolbars.bookmarks.visibility" = "always"; + }; + + userChrome = builtins.readFile ./userChrome.css; + userContent = builtins.readFile ./userChrome.css; + + extensions.packages = with ff-pkgs; [ + bitwarden + ublock-origin + sidebery + sponsorblock + # vimium + ]; + + bookmarks = { + force = true; + settings = [ + { + keyword = "!w"; + url = "https://www.wikipedia.org/w/index.php?title=Special:Search&search=%s"; + } + { + keyword = "!m"; + url = "https://www.google.com/maps?q=%s"; + } + { + keyword = "!git"; + url = "https://github.com/search?q=%s&type=code"; + } + { + keyword = "!std"; + url = "https://std.rs%s"; + } + { + keyword = "!rust"; + url = "https://docs.rs/releases/search?query=%s"; + } + { + keyword = "!np"; + url = "https://search.nixos.org/packages?query=%s"; + } + { + keyword = "!nho"; + url = "https://home-manager-options.extranix.com/?query=%s"; + } + { + keyword = "!no"; + url = "https://search.nixos.org/options?query=%s"; + } + + # { + # name = "bank"; + # toolbar = true; + # url = "https://web.bunq.com/user"; + # } + ]; + }; + + # extensions.settings = { + # "${ff-pkgs.sidebery.addonId}".settings = { + # sidebar = { + # # panels = with builtins; with lib; listToAttrs (map ffContainerToSideberryPanel (attrsToList containers)); + # # nav = [ "Personal" "Programming"]; + # }; + # # https://github.com/Dash-L/nixconfig/blob/c30f6d1486a3fe2b3793ab0cb13a88edefe83b7a/home/firefox.nix#L82 + # settings = { + # pinnedTabsPosition = "top"; + # hideEmptyPanels = false; + # activateAfterClosing = "prev"; + # activateAfterClosingStayInPanel = true; + # newTabCtxReopen = true; + # }; + # }; + # }; + }; + }; + + xdg.mimeApps = { + defaultApplications."x-scheme-handler/http" = [ + "firefox.desktop" + ]; + defaultApplications."x-scheme-handler/https" = [ + "firefox.desktop" + ]; + defaultApplications."text/html" = [ "firefox.desktop" ]; + defaultApplications."x-scheme-handler/about" = [ "firefox.desktop" ]; + defaultApplications."x-scheme-handler/unknown" = [ "firefox.desktop" ]; + }; + }; +} diff --git a/programs/firefox/userChrome.css b/programs/firefox/userChrome.css new file mode 100644 index 0000000..244f1f7 --- /dev/null +++ b/programs/firefox/userChrome.css @@ -0,0 +1,3 @@ +#TabsToolbar { + visibility: collapse; +} diff --git a/programs/fish/default.nix b/programs/fish/default.nix new file mode 100644 index 0000000..51013f7 --- /dev/null +++ b/programs/fish/default.nix @@ -0,0 +1,241 @@ +_: { + custom.program.fish.requirements = [ "cli" ]; + custom.program.fish.home-config = + { + config, + pkgs, + lib, + ... + }: + with builtins; + with lib.attrsets; + let + scripts = (import ./scripts.nix) pkgs; + aliases = with scripts; { + "cp-mov" = cp-media "mov" "movies"; + "cp-ser" = cp-media "ser" "shows"; + "cp-ani" = cp-media "ani" "anime"; + "dumpasm" = "${pkgs.custom.dumpasm}/bin/dumpasm"; + "p" = builtins.trace calc calc; + "s" = "systemctl"; + "j" = "journalctl"; + "ju" = "journalctl -u"; + "jfu" = "journalctl -fu"; + "ls" = "${pkgs.eza}/bin/eza --git"; + "ll" = "${pkgs.eza}/bin/eza --git"; + "lt" = "${pkgs.eza}/bin/eza --long --tree -L 3"; + "open" = "${pkgs.xdg-utils}/bin/xdg-open"; + "cb" = "${pkgs.wl-clipboard-rs}/bin/wl-copy"; + "cat" = "${pkgs.bat}/bin/bat"; + + # "pull" = "${pkgs.git}/bin/git pull"; + # "push" = "${pkgs.git}/bin/git push"; + # "commit" = "${pkgs.git}/bin/git commit"; + # "add" = "${pkgs.git}/bin/git add"; + # "patch" = "${pkgs.git}/bin/git add -p"; + # "amend" = "${pkgs.git}/bin/git commit --amend"; + # "log" = "${pkgs.git}/bin/git log --all --graph --decorate"; + # "st" = "${pkgs.git}/bin/git status"; + # "checkout" = "${pkgs.git}/bin/git checkout"; + # "rebase" = "${pkgs.git}/bin/git rebase"; + # "stash" = "${pkgs.git}/bin/git stash"; + + "edit" = "jj edit"; + "old" = "jj edit @-"; + "new" = "jj edit @+"; + "rebase" = "jj rebase"; + "pull" = "jj git fetch; jj catchup"; + "msg" = "jj describe -m"; + "branch" = "jj bookmark set"; + "stat" = "jj status"; + "push" = "jj git push"; + + "tidy" = "x test tidy --bless"; + "ui" = "x test tests/ui/"; + + "f" = "nautilus --no-desktop . &"; + }; + # extracting any compressed format + extract = '' + function extract -a file -d "decompress a file" + if not test -f $file + echo "'$file' is not a valid file" + return 1 + end + switch $file + # tar can automatically figure out how to decompress + case '*.{tar,tar.{bz2,zst,gz,xz},tbz2,tgz'; ${pkgs.gnutar}/bin/tar xf $file; end + case '*.bz2'; bunzip2 $file; end + case '*.rar'; unrar e $file; end + case '*.gz'; gunzip $file; end + case '*.zip'; ${pkgs.unzip}/bin/unzip $file; end + case '*.Z'; uncompress $file; end + case '*.7z'; 7z x $file; end + case '*'; + echo "'$file' cannot be extracted" + return 1 + end + end + ''; + in + { + programs = { + atuin = { + enable = true; + enableFishIntegration = true; + + settings = { + filter_mode_shell_up_key_binding = "directory"; + exit_mode = "return-original"; + + workspaces = true; + }; + }; + + zoxide = { + enable = true; + enableFishIntegration = true; + }; + + direnv = { + enable = true; + # enableFishIntegration = lib.mkDefault true; + }; + + fzf = { + enable = true; + enableFishIntegration = true; + }; + + fish = { + enable = true; + shellAliases = aliases; + plugins = with pkgs.fishPlugins; [ + { + name = "bang-bang"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "plugin-bang-bang"; + rev = "ec991b80ba7d4dda7a962167b036efc5c2d79419"; + hash = "sha256-oPPCtFN2DPuM//c48SXb4TrFRjJtccg0YPXcAo0Lxq0="; + }; + } + { + name = "tide"; + inherit (tide) src; + } + { + name = "sponge"; + inherit (sponge) src; + } + { + name = "autopair"; + inherit (autopair) src; + } + ]; + + functions = { + fish_jj_prompt = { + body = '' + if not ${config.programs.jujutsu.package}/bin/jj root --quiet &>/dev/null + return 1 + end + + ${config.programs.jujutsu.package}/bin/jj log --ignore-working-copy --no-graph --color always -r @ -T ' + separate( + " ", + bookmarks.join(", "), + change_id.shortest(), + commit_id.shortest(), + if(conflict, "conflict"), + if(empty, "empty"), + if(divergent, "divergent"), + if(hidden, "hidden"), + ) + ' + ''; + }; + + _tide_item_jj = { + body = '' + set -l _tide_item_jj_color $_tide_location_color + echo -ns $_tide_item_jj_color" ("(fish_jj_prompt)$_tide_item_jj_color")" + ''; + }; + + _tide_item_git = { + body = '' + if not test -d .jj + fish_git_prompt '%s' + end + ''; + }; + }; + + interactiveShellInit = '' + fish_vi_key_bindings + + set -g sponge_successful_exit_codes 0 + set -g sponge_allow_previously_successful false + set -g sponge_delay 10 + + ${config.programs.jujutsu.package}/bin/jj util completion fish | source + + # if set -q tide_left_prompt_items; and not contains "jj" $tide_left_prompt_items + # set -l tide_item_jj_idx (contains -i "pwd" $tide_left_prompt_items) + # if test $tide_item_jj_idx + # set tide_left_prompt_items \ + # $tide_left_prompt_items[1..$tide_item_jj_idx] \ + # jj \ + # $tide_left_prompt_items[(math $tide_item_jj_idx + 1)..-1] + # end + # end + + function t + cd "$(${pkgs.custom.t}/bin/t-rs $argv | tail -n 1)" + end + + function temp + t $argv + end + + function rs + cd "$(${pkgs.custom.t}/bin/t-rs $argv | tail -n 1)" + cargo init . --bin --name $(basename "$PWD") + vim src/main.rs + end + + fish_add_path "$HOME/.cargo/bin" + fish_add_path "$HOME/.local/bin" + fish_add_path "$HOME/Documents/scripts" + fish_add_path "$HOME/.nix-profile/bin" + + function fish_greeting + ${pkgs.blahaj}/bin/blahaj -s + end + ''; + }; + }; + + home.activation = { + setupTide = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + setupTide() { + ${pkgs.fish}/bin/fish -c ${lib.escapeShellArg "tide configure ${ + lib.cli.toGNUCommandLineShell { } { + auto = true; + style = "Lean"; + prompt_colors = "True color"; + show_time = "No"; + lean_prompt_height = "Two lines"; + prompt_connection = "Disconnected"; + prompt_spacing = "Compact"; + icons = "Few icons"; + transient = "Yes"; + } + }"} >/dev/null 2>&1 + } + setupTide + ''; + }; + }; +} diff --git a/programs/fish/scripts.nix b/programs/fish/scripts.nix new file mode 100644 index 0000000..465b3ea --- /dev/null +++ b/programs/fish/scripts.nix @@ -0,0 +1,25 @@ +{ pkgs, ... }: +{ + calc = "${pkgs.custom.pipethon}/bin/python -i ${pkgs.writeText "init.py" '' + import sys + sys.path.append("${../../scriptlib}") + + from scriptlib import * + ''} "; + + # sys.path.append("${pkgs.python314Packages.numpy}/lib/python3.14/site-packages/") + cp-media = + name: media: + let + s = pkgs.writeScriptBin "cp-${name}" '' + echo "copying to library ${media}" + echo "calculating hash" + find "$1" - type f - print0 | sort - z | xargs - 0 sha1sum | awk '{ + print $1}' | sha1sum | awk '{print $1}' > "$1.hash" + + rsync -azP "$1" fili:/media/${media} + rsync -azP "$1.hash" fili:/media/${media} + ''; + in + "${s}/bin/cp-${name}"; +} diff --git a/programs/git/default.nix b/programs/git/default.nix new file mode 100644 index 0000000..e364ce9 --- /dev/null +++ b/programs/git/default.nix @@ -0,0 +1,39 @@ +_: { + custom.program.git.requirements = [ "cli" ]; + custom.program.git.home-config = _: { + programs.git = { + enable = true; + signing.key = "/home/jana/.ssh/id_ed25519.pub"; + signing.signByDefault = true; + + settings = { + user.email = "jana@donsz.nl"; + user.name = "Jana Dönszelmann"; + + push.autoSetupRemote = true; + pull.rebase = true; + init.defaultBranch = "main"; + gpg.format = "ssh"; + diff.colorMoved = "default"; + rerere.enabled = true; + + alias.conflicts = "diff --check"; + }; + + }; + + programs.delta = { + enable = true; + options = { + navigate = true; + light = false; + side-by-side = true; + features = "decorations interactive"; + interactive = { + keep-plus-minus-markers = false; + }; + }; + enableGitIntegration = true; + }; + }; +} diff --git a/programs/gnome/default.nix b/programs/gnome/default.nix new file mode 100644 index 0000000..65baabc --- /dev/null +++ b/programs/gnome/default.nix @@ -0,0 +1,255 @@ +{ pkgs, lib, ... }: +let + unbound = [ "@as []" ]; + custom-keys = [ + { + binding = "Return"; + command = "gnome-terminal"; + name = "Launch terminal"; + } + { + binding = "z"; + command = "gnome-system-monitor"; + name = "launch system monitor"; + } + { + binding = "Return"; + command = "${pkgs.custom.ghostty}/bin/ghostty"; + name = "focus-terminal"; + } + { + binding = "F12"; + command = "${pkgs.custom.ghostty}/bin/ghostty -- ${((import ../fish/scripts.nix) pkgs).calc}"; + name = "calculator"; + } + ]; +in +{ + dconf = { + enable = true; + + settings = + { + "org/gnome/shell" = { + # pinned app bar + favorite-apps = [ + "firefox.desktop" + "org.gnome.Nautilus.desktop" + "org.gnome.Settings.desktop" + "org.gnome.Terminal.desktop" + "jetbrains-clion-ec2b1366-55e3-4ecc-8780-ab6c7542eb56.desktop" + "discord-canary.desktop" + "io.element.Element.desktop" + "mattermost-desktop.desktop" + "org.mozilla.Thunderbird.desktop" + "spotify.desktop" + ]; + disable-user-extensions = false; + enabled-extensions = [ + "horizontal-workspaces@gnome-shell-extensions.gcampax.github.com" + "org.gnome-shell.desktop-icons" + "auto-move-windows@gnome-shell-extensions.gcampax.github.com" + ]; + }; + + "org/gnome/desktop/background" = rec { + # picture-uri ="file:///${home.homeDirectory}/Pictures/backgrounds/2023-09-01-14-56-45-Road-saturated.png"; + # picture-uri-dark = picture-uri; + }; + + "org/gnome/desktop/input-sources" = { + per-window = false; + show-all-sources = false; + sources = [ "('xkb', 'us')" ]; + xkb-options = [ + "lv3:switch" + "caps:escape" + "eurosign:4" + "compose:ralt" + ]; + }; + + "org/gnome/desktop/interface" = { + clock-show-seconds = true; + clock-show-weekday = true; + color-scheme = "prefer-dark"; + cursor-theme = "Adwaita"; + enable-animations = true; + enable-hot-corners = true; + font-name = "Noto Sans, 10"; + }; + + "org/gnome/desktop/peripherals/mouse" = { + accel-profile = "adaptive"; + natural-scroll = false; + }; + + "org/gnome/desktop/peripherals/touchpad" = { + click-method = "fingers"; + disable-while-typing = false; + edge-scrolling-enabled = false; + natural-scroll = false; + send-events = "enabled"; + speed = 0.5; + tap-to-click = true; + two-finger-scrolling-enabled = true; + }; + "org/gnome/desktop/sound" = { + allow-volume-above-100-percent = true; + event-sounds = true; + }; + + "org/gnome/desktop/wm/keybindings" = { + always-on-top = [ "t" ]; + begin-move = unbound; + begin-resize = unbound; + close = [ "q" ]; + lower = unbound; + maximize = unbound; + minimize = [ "w" ]; + move-to-monitor-down = [ "Down" ]; + move-to-monitor-left = [ "Left" ]; + move-to-monitor-right = [ "Right" ]; + move-to-monitor-up = [ "Up" ]; + move-to-workspace-1 = [ "exclam" ]; + move-to-workspace-2 = [ "at" ]; + move-to-workspace-3 = [ "numbersign" ]; + move-to-workspace-4 = [ "dollar" ]; + move-to-workspace-5 = [ "percent" ]; + move-to-workspace-6 = [ "asciicircum" ]; + panel-main-menu = [ "" ]; + raise-or-lower = [ "s" ]; + switch-applications = [ "Tab" ]; + switch-applications-backward = [ "Tab" ]; + switch-input-source = unbound; + switch-input-source-backward = unbound; + switch-to-workspace-1 = [ "1" ]; + switch-to-workspace-2 = [ "2" ]; + switch-to-workspace-3 = [ "3" ]; + switch-to-workspace-4 = [ "4" ]; + switch-to-workspace-5 = [ "5" ]; + switch-to-workspace-6 = [ "6" ]; + switch-to-workspace-down = [ "j" ]; + switch-to-workspace-last = [ "0" ]; + switch-to-workspace-up = [ "k" ]; + switch-windows = unbound; + switch-windows-backward = unbound; + toggle-fullscreen = [ "f" ]; + toggle-maximized = [ "d" ]; + unmaximize = unbound; + }; + + "org/gnome/desktop/wm/preferences" = { + auto-raise = false; + button-layout = ":,maximize,minimize,close"; + focus-mode = "click"; + mouse-button-modifier = ""; + num-workspaces = 6; + resize-with-right-button = false; + visual-bell = false; + }; + + "org/gnome/mutter" = { + center-new-windows = true; + dynamic-workspaces = false; + edge-tiling = true; + experimental-features = [ "scale-monitor-framebuffer" ]; + overlay-key = "Super_L"; + workspaces-only-on-primary = true; + }; + + "org/gnome/mutter/keybindings" = { + switch-monitor = [ "o" ]; + toggle-tiled-left = [ "bracketleft" ]; + toggle-tiled-right = [ "bracketright" ]; + }; + + "org/gnome/settings-daemon/plugins/media-keys" = { + area-screenshot = unbound; + area-screenshot-clip = [ "s" ]; + custom-keybindings = + with builtins; + (map ( + i: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${toString (i - 1)}/" + ) (genList (x: x + 1) (length custom-keys))); + email = [ "Display" ]; + home = [ "e" ]; + mic-mute = [ "AudioMicMute" ]; + next = [ "period" ]; + on-screen-keyboard = unbound; + pause = unbound; + play = [ "slash" ]; + previous = [ "comma" ]; + screensaver = [ "l" ]; + screenshot = unbound; + screenshot-clip = unbound; + stop = unbound; + volume-down = [ "AudioLowerVolume" ]; + volume-mute = [ "AudioMute" ]; + volume-up = [ "AudioRaiseVolume" ]; + window-screenshot = unbound; + window-screenshot-clip = unbound; + }; + + "org/gnome/settings-daemon/plugins/power" = { + ambient-enabled = false; + idle-dim = false; + power-button-action = "nothing"; + power-saver-profile-on-low-battery = true; + sleep-inactive-ac-timeout = 7200; + sleep-inactive-ac-type = "nothing"; + sleep-inactive-battery-timeout = 7200; + sleep-inactive-battery-type = "suspend"; + }; + "org/gnome/shell/extensions/auto-move-windows" = { + application-list = [ + "firefox.desktop:1" + "discord.desktop:3" + "jetbrains-clion.desktop:2" + "jetbrains-goland.desktop:2" + "jetbrains-pycharm.desktop:2" + "jetbrains-idea.desktop:2" + "spotify.desktop:5" + ]; + }; + + "org/gnome/shell/keybindings" = { + open-application-menu = [ "Menu" ]; + show-screenshot-ui = [ "s" ]; + switch-to-application-1 = unbound; + switch-to-application-2 = unbound; + switch-to-application-3 = unbound; + switch-to-application-4 = unbound; + switch-to-application-5 = unbound; + switch-to-application-6 = unbound; + switch-to-application-7 = unbound; + switch-to-application-8 = unbound; + switch-to-application-9 = unbound; + toggle-message-tray = unbound; + toggle-overview = [ "p" ]; + }; + + "org/gnome/terminal/legacy" = { + menu-accelerator-enabled = false; + mnemonics-enabled = true; + new-terminal-mode = "window"; + shortcuts-enabled = true; + theme-variant = "dark"; + }; + + "org/gnome/terminal/legacy/keybindings" = { + zoom-in = "equal"; + }; + } + // ( + with builtins; + foldl' (a: b: a // b) { } ( + map (i: { + "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${toString (i - 1)}" = + elemAt custom-keys + (i - 1); + }) (genList (x: x + 1) (length custom-keys)) + ) + ); + }; +} diff --git a/programs/jj/default.nix b/programs/jj/default.nix new file mode 100644 index 0000000..4ea0e7b --- /dev/null +++ b/programs/jj/default.nix @@ -0,0 +1,184 @@ +_: { + custom.program.jujutsu.requirements = [ "cli" ]; + custom.program.jujutsu.home-config = + { config, pkgs, ... }: + { + programs.jujutsu = { + enable = true; + # package = pkgs.custom.jujutsu; + + settings = { + user = { + email = config.programs.git.settings.user.email; + name = config.programs.git.settings.user.name; + }; + + ui = { + paginate = "never"; + # pager = "${pkgs.delta}/bin/delta"; + # for delta + # diff-formatter = ":git"; + diff-formatter = [ + "${pkgs.difftastic}/bin/difft" + "--color=always" + "$left" + "$right" + ]; + + default-command = [ + "log" + "--reversed" + "--no-pager" + ]; + merge-editor = [ + "${pkgs.meld}/bin/meld" + "$left" + "$base" + "$right" + "-o" + "$output" + "--auto-merge" + ]; + # diff-editor = "${pkgs.meld}/bin/meld"; + }; + + fsmonitor.backend = "watchman"; + fsmonitor.watchman.register-snapshot-trigger = true; + + # revsets.log = "@ | ancestors(trunk()..(visible_heads() & mine()), 2) | trunk()"; + # revsets.log = "trunk()..@ | @..trunk() | trunk() | @:: | fork_point(trunk() | @)"; + revsets.log = "trunk() | ancestors(trunk()..heads(((trunk()..visible_heads()) & my() | @)::), 2)"; + + revset-aliases = { + "my()" = "user(\"${config.programs.jujutsu.settings.user.email}\")"; + "user(x)" = "author(x) | committer(x)"; + current = "bookmarks() & my() & ~immutable()"; + "closest_bookmark(to)" = "heads(::to & bookmarks())"; + }; + + template-aliases = { + "format_timestamp(timestamp)" = "timestamp.ago()"; + log_oneline = '' + if(root, + format_root_commit(self), + label(if(current_working_copy, "working_copy"), + concat( + separate(" ", + format_short_change_id_with_change_offset(self), + if(empty, label("empty", "(empty)")), + if(description, + description.first_line(), + label(if(empty, "empty"), description_placeholder), + ), + bookmarks, + tags, + working_copies, + if(conflict, label("conflict", "conflict")), + if(config("ui.show-cryptographic-signatures").as_boolean(), + format_short_cryptographic_signature(signature)), + ) ++ "\n", + ), + ) + ) + ''; + # if(.contained_in('first_parent(@)'), label("git_head", "HEAD")), + status_summary = "'\n' ++ self.diff().summary() ++ '\n'"; + log_oneline_with_status_summary = "log_oneline ++ if(self.current_working_copy() && self.diff().files().len() > 0, status_summary)"; + }; + + aliases = + let + util = script: [ + "util" + "exec" + "--" + "bash" + "-c" + script + ]; + in + { + tug = [ + "bookmark" + "move" + "--from" + "heads(::@- & bookmarks())" + "--to" + "coalesce(@ & ~empty(), @-)" + ]; + catchup = [ + "rebase" + "-b" + "bookmarks() & mine() & ~immutable()" + "-d" + "trunk()" + "--skip-emptied" + ]; + pull = util '' + jj git fetch + jj catchup + ''; + ch = [ + "show" + "--stat" + ]; + move = [ + "rebase" + "-r" + ]; + push = [ + "git" + "push" + ]; + ll = [ + "log" + "-T" + "builtin_log_compact" + ]; + mdiff = [ + "diff" + "--from" + "trunk()" + ]; + }; + + templates = { + log_node = '' + label("node", + coalesce( + if(!self, label("elided", "~")), + if(current_working_copy, label("working_copy", "@")), + if(conflict, label("conflict", "×")), + if(immutable, label("immutable", "*")), + label("normal", "·") + ) + ) + ''; + log = "log_oneline_with_status_summary"; + git_push_bookmark = ''"jdonszelmann/" ++ change_id.short()''; + }; + + signing = { + # sign-all = true; + behavior = "own"; + backend = "ssh"; + key = "~/.ssh/id_ed25519.pub"; + }; + + # remotes.origin.auto-track-bookmarks = true; + # remotes.upstream.auto-track-bookmarks = true; + + git = { + private-commits = "description(glob:'wip:*') | description(glob:'trial:*')"; + write-change-id-header = true; + + fetch = [ + "upstream" + "origin" + ]; + push = "origin"; + }; + }; + }; + }; +} diff --git a/programs/kanata/default.nix b/programs/kanata/default.nix new file mode 100644 index 0000000..7e6a3b4 --- /dev/null +++ b/programs/kanata/default.nix @@ -0,0 +1,125 @@ +{ pkgs, ... }: +let + kanata-config = '' + (defcfg + process-unmapped-keys yes + danger-enable-cmd yes + ) + + (defsrc + esc + grv 1 2 3 4 5 6 7 8 9 0 - = bspc + tab q w e r t y u i o p [ ] \ + caps a s d f g h j k l ; ' ret + lsft z x c v b n m , . / rsft + lctl lmet lalt spc ralt rctl + ) + + (deflayer qwerty + @esc + grv 1 2 3 4 5 6 7 8 9 0 - = bspc + tab q w e r t y u i o p [ ] \ + @cap a s d f g h j k l ; ' ret + lsft z x c v b n m , . / rsft + lctl @lmet lalt spc ralt @rctl + ) + + (deflayer control + @esc + grv 1 2 3 4 5 6 7 8 9 0 - = bspc + tab q w e @replay t y u i o p @wup @wdown \ + @cap a s d f g left down up right ; ' bspc + lsft z x C-c v bspc n @macro , . C-f rsft + lctl lmet lalt spc ralt @rctl + ) + + (deflayermap (programming) + f (macro f n spc) + w (macro w h e r e spc) + l (macro l o o p { ret) + u (macro u s e spc) + i (macro i m p o r t spc) + s (macro s e l f spc) + ) + + (defalias + ;; hold esc + esc (tap-hold 800 800 esc caps) + + ;; control + cap (tap-hold-release 200 200 + (multi dynamic-macro-record-stop esc) + (layer-while-held control) + ) + + lmet ( + tap-hold-press 200 200 + (cmd ${pkgs.lib.getExe' pkgs.custom.niri "niri"} msg action toggle-overview) + lmet + ) + + macro (dynamic-macro-record 0) + replay (dynamic-macro-play 0) + + wup (mwheel-up 50 120) + wdown (mwheel-down 50 120) + + ;; programming + rctl ( + tap-hold-release + 200 200 + C-k (layer-while-held programming) + ) + ) + ''; +in +{ + custom.program.kanata.requirements = [ "graphical" ]; + custom.program.kanata.home-config = + { pkgs, config, ... }: + { + systemd.user.services.kanata = { + Unit = { + Description = "kanata"; + }; + + Service = { + Restart = "always"; + RestartSec = "3"; + ExecStart = "${pkgs.kanata-with-cmd}/bin/kanata --cfg ${pkgs.writeText "kanata.kbd" kanata-config}"; + Nice = "-20"; + }; + + Install = { + WantedBy = [ "default.target" ]; + }; + }; + + home.file.kanata = { + target = ".config/kanata/kanata.kbd"; + text = kanata-config; + }; + }; + + # custom.program.kanata.system-config = + # { pkgs, ... }: + # { + # sudo groupadd uinput + # sudo usermod -aG input $USER + # sudo usermod -aG uinput $USER + # echo "KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"" >> /etc/udev/rules.d/99-input.rules + # reboot or sudo udevadm control --reload-rules && sudo udevadm trigger + # sudo modprobe uinput + + users.groups.uinput = { }; + users.extraUsers.jana.extraGroups = [ + "uinput" + "input" + ]; + environment.systemPackages = [ pkgs.kanata-with-cmd ]; + services.udev.extraRules = '' + KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput" + ''; + # }; + +} diff --git a/programs/kitty/default.nix b/programs/kitty/default.nix new file mode 100644 index 0000000..f61c3d2 --- /dev/null +++ b/programs/kitty/default.nix @@ -0,0 +1,57 @@ +_: { + custom.program.kitty.requirements = [ "graphical" ]; + custom.program.kitty.home-config = + { pkgs, flakes, ... }: + { + programs.kitty = { + enable = true; + font = { + name = "Jetbrains Mono"; + size = 13.0; + package = pkgs.jetbrains-mono; + }; + + settings = { + scrollback_lines = 20000; + allow_hyperlinks = true; + + repaint_delay = 10; + input_delay = 3; + + enable_audio_bell = false; + update_check_interval = 0; + + initial_window_width = "95c"; + initial_window_height = "30c"; + remember_window_size = "no"; + + draw_minimal_borders = false; + hide_window_decorations = true; + + shell = "${pkgs.tmux}/bin/tmux"; + clipboard_control = "write-clipboard write-primary read-clipboard read-primary"; + + foreground = "#fcfcfc"; + background = "#232627"; + linux_display_server = "auto"; + }; + + keybindings = { + "ctrl+f" = + "launch --location=hsplit --allow-remote-control kitty +kitten ${flakes.kitty-search}/search.py @active-kitty-window-id"; + "ctrl+alt+r" = "load_config_file"; + "ctrl+shift+r" = "no_op"; + "super+`" = "no_op"; + "ctrl+EQUAL" = "change_font_size all +2.0"; + "ctrl+minus" = "change_font_size all -2.0"; + "ctrl+0" = "change_font_size all 0"; + # "ctrl+/" = "send_text all "; + "super+~" = "no_op"; + }; + + extraConfig = '' + mouse_map left click ungrabbed no-op + ''; + }; + }; +} diff --git a/programs/niri/default.nix b/programs/niri/default.nix new file mode 100644 index 0000000..c849840 --- /dev/null +++ b/programs/niri/default.nix @@ -0,0 +1,601 @@ +_: { + custom.program.niri.requirements = [ "graphical" ]; + custom.program.niri.home-config = + { + config, + pkgs, + flakes, + lib, + ... + }: + let + noctalia = + cmd: + [ + "${pkgs.lib.getExe' flakes.noctalia.packages.${pkgs.system}.default "noctalia-shell"}" + "ipc" + "call" + ] + ++ (pkgs.lib.splitString " " cmd); + + wallpaper = ("${pkgs.custom.raw-data}/pacific.png"); + matugenSchemeType = "scheme-tonal-spot"; + in + { + imports = [ + flakes.niri.homeModules.niri + flakes.matugen.nixosModules.default + flakes.noctalia.homeModules.default + ]; + + home.packages = with pkgs; [ + matugen + glib + dconf + gsettings-desktop-schemas + xwayland-satellite + # gtk + nwg-look + # qt config tool + kdePackages.qt6ct + + fira + jetbrains-mono + fira-mono + noto-fonts + ]; + + programs.niri.settings = { + # main laptop screen + outputs."eDP-1" = { + mode = { + width = 1928; + height = 1200; + refresh = 59.987; + }; + position = { + x = 0; + y = 0; + }; + }; + + outputs."LG Electronics LG ULTRAWIDE 411NTBK28189" = { + mode = { + width = 3440; + height = 1440; + refresh = 59.987; + }; + position = { + x = -3440; + y = 240; + }; + + # focus the external screen first + focus-at-startup = true; + }; + }; + + home.sessionVariables = { + QT_QPA_PLATFORMTHEME = "qt6ct"; + XCURSOR_THEME = "Adwaita"; + XCURSOR_SIZE = "10"; + }; + + programs.niri.settings = { + input = { + keyboard = { + xkb = { + layout = "us"; + options = "grp:win_space_toggle,compose:ralt"; + }; + numlock = true; + }; + + mouse = { + accel-speed = 0.5; + }; + + touchpad = { + dwt = true; + tap = true; + tap-button-map = "left-right-middle"; + click-method = "clickfinger"; + natural-scroll = false; + }; + }; + + debug = { + render-drm-device = "/dev/dri/renderD128"; + }; + + cursor = { + theme = "Adwaita"; + size = 10; + }; + + gestures.hot-corners.enable = false; + + layout = { + gaps = 5; + center-focused-column = "never"; + + preset-column-widths = [ + { proportion = 0.33333; } + { proportion = 0.5; } + { proportion = 0.66667; } + { proportion = 1.0; } + ]; + + default-column-width = { + proportion = 0.5; + }; + + shadow = { + softness = 20; + spread = 5; + offset = { + x = 0; + y = 5; + }; + }; + + focus-ring = { + width = 1; + active.color = "#${config.programs.matugen.theme.colors.primary.default}"; + inactive.color = "#${config.programs.matugen.theme.colors.surface.default}"; + urgent.color = "#${config.programs.matugen.theme.colors.error.default}"; + }; + + border = { + active.color = "#${config.programs.matugen.theme.colors.primary.default}"; + inactive.color = "#${config.programs.matugen.theme.colors.surface.default}"; + urgent.color = "#${config.programs.matugen.theme.colors.error.default}"; + }; + + shadow = { + color = "#${config.programs.matugen.theme.colors.shadow.default}70"; + }; + + tab-indicator = { + active.color = "#${config.programs.matugen.theme.colors.primary.default}"; + inactive.color = "#${config.programs.matugen.theme.colors.primary_container.default}"; + urgent.color = "#${config.programs.matugen.theme.colors.error.default}"; + }; + + insert-hint = { + display.color = "#${config.programs.matugen.theme.colors.primary.default}80"; + }; + }; + + hotkey-overlay.skip-at-startup = true; + + screenshot-path = "~/Documents/personal/pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"; + + workspaces."01-browser" = { + name = "browser"; + }; + workspaces."02-programming" = { + name = "programming"; + }; + workspaces."03-chat" = { + name = "chat"; + }; + + window-rules = [ + { + matches = [ { title = "Extension: (Bitwarden Password Manager).*"; } ]; + open-floating = true; + open-focused = true; + block-out-from = "screen-capture"; + } + + { + matches = [ { app-id = "firefox"; } ]; + open-on-workspace = "browser"; + } + + { + matches = [ + { + app-id = "org.gnome.Nautilus"; + title = "Open Files"; + } + { + app-id = "steam"; + title = "Steam Settings"; + } + ]; + open-floating = true; + } + + { + matches = [ + { app-id = "discord"; } + { app-id = "org.element.desktop"; } # TODO + { app-id = "signal"; } # TODO + ]; + open-on-workspace = "chat"; + } + + { + matches = [ + { app-id = "dev.zed.Zed"; } + ]; + open-on-workspace = "programming"; + } + + { + geometry-corner-radius = { + top-left = 8.0; + top-right = 8.0; + bottom-right = 8.0; + bottom-left = 8.0; + }; + clip-to-geometry = true; + } + ]; + + spawn-at-startup = [ + { argv = [ "firefox" ]; } + { argv = [ "discord" ]; } + { argv = [ "signal-desktop" ]; } + { argv = [ "zeditor" ]; } + { + argv = [ "${pkgs.lib.getExe' flakes.noctalia.packages.${pkgs.system}.default "noctalia-shell"}" ]; + } + ]; + + animations = { }; + + binds = { + "Ctrl+Alt+Delete" = { + hotkey-overlay.title = "Power menu"; + action.spawn = noctalia "sessionMenu toggle"; + }; + + "Mod+O" = { + hotkey-overlay.title = "Run an Application"; + action.spawn = noctalia "launcher toggle"; + }; + + "Mod+L" = { + hotkey-overlay.title = "Lock the Screen"; + action.spawn = noctalia "lockScreen lock"; + }; + + "Mod+Shift+Slash".action.show-hotkey-overlay = { }; + + "Mod+Return" = { + hotkey-overlay.title = "Open a Terminal"; + action.spawn = "kitty"; + }; + + "XF86AudioRaiseVolume" = { + allow-when-locked = true; + action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1+"; + }; + "XF86AudioLowerVolume" = { + allow-when-locked = true; + action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1-"; + }; + "XF86AudioMute" = { + allow-when-locked = true; + action.spawn-sh = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; + }; + "XF86AudioMicMute" = { + allow-when-locked = true; + action.spawn-sh = "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; + }; + "XF86AudioPlay" = { + allow-when-locked = true; + action.spawn-sh = "playerctl play-pause"; + }; + "XF86AudioStop" = { + allow-when-locked = true; + action.spawn-sh = "playerctl stop"; + }; + "XF86AudioPrev" = { + allow-when-locked = true; + action.spawn-sh = "playerctl previous"; + }; + "XF86AudioNext" = { + allow-when-locked = true; + action.spawn-sh = "playerctl next"; + }; + "Mod+Period" = { + allow-when-locked = true; + action.spawn-sh = "playerctl previous"; + }; + "Mod+Comma" = { + allow-when-locked = true; + action.spawn-sh = "playerctl next"; + }; + "Mod+Slash" = { + allow-when-locked = true; + action.spawn-sh = "playerctl next"; + }; + + # TODO + "XF86MonBrightnessUp" = { + allow-when-locked = true; + action.spawn = [ + "brightnessctl" + "--device=amdgpu_bl1" + "--class=backlight" + "set" + "+10%" + ]; + }; + "XF86MonBrightnessDown" = { + allow-when-locked = true; + action.spawn = [ + "brightnessctl" + "--device=amdgpu_bl1" + "--class=backlight" + "set" + "10%-" + ]; + }; + + "Mod+Q" = { + repeat = false; + action.close-window = { }; + }; + + "Mod+Left".action.focus-column-left = { }; + "Mod+Down".action.focus-window-or-workspace-down = { }; + "Mod+Up".action.focus-window-or-workspace-up = { }; + "Mod+Right".action.focus-column-right = { }; + + "Mod+Shift+Left".action.move-column-left = { }; + "Mod+Shift+Down".action.move-window-down-or-to-workspace-down = { }; + "Mod+Shift+Up".action.move-window-up-or-to-workspace-up = { }; + "Mod+Shift+Right".action.move-column-right = { }; + + "Mod+Home".action.focus-column-first = { }; + "Mod+End".action.focus-column-last = { }; + "Mod+Shift+Home".action.move-column-to-first = { }; + "Mod+Shift+End".action.move-column-to-last = { }; + + "Mod+Ctrl+Left".action.focus-monitor-left = { }; + "Mod+Ctrl+Down".action.focus-monitor-down = { }; + "Mod+Ctrl+Up".action.focus-monitor-up = { }; + "Mod+Ctrl+Right".action.focus-monitor-right = { }; + + "Mod+Shift+Ctrl+Left".action.move-column-to-monitor-left = { }; + "Mod+Shift+Ctrl+Down".action.move-column-to-monitor-down = { }; + "Mod+Shift+Ctrl+Up".action.move-column-to-monitor-up = { }; + "Mod+Shift+Ctrl+Right".action.move-column-to-monitor-right = { }; + + "Mod+1".action.focus-workspace = 1; + "Mod+2".action.focus-workspace = 2; + "Mod+3".action.focus-workspace = 3; + "Mod+4".action.focus-workspace = 4; + "Mod+5".action.focus-workspace = 5; + "Mod+6".action.focus-workspace = 6; + "Mod+7".action.focus-workspace = 7; + "Mod+8".action.focus-workspace = 8; + "Mod+9".action.focus-workspace = 9; + "Mod+Shift+1".action.move-column-to-workspace = 1; + "Mod+Shift+2".action.move-column-to-workspace = 2; + "Mod+Shift+3".action.move-column-to-workspace = 3; + "Mod+Shift+4".action.move-column-to-workspace = 4; + "Mod+Shift+5".action.move-column-to-workspace = 5; + "Mod+Shift+6".action.move-column-to-workspace = 6; + "Mod+Shift+7".action.move-column-to-workspace = 7; + "Mod+Shift+8".action.move-column-to-workspace = 8; + "Mod+Shift+9".action.move-column-to-workspace = 9; + + "Mod+WheelScrollDown" = { + cooldown-ms = 150; + action.focus-workspace-down = { }; + }; + "Mod+WheelScrollUp" = { + cooldown-ms = 150; + action.focus-workspace-up = { }; + }; + "Mod+Shift+WheelScrollDown".action.focus-column-left = { }; + "Mod+Shift+WheelScrollUp".action.focus-column-right = { }; + + # "Mod+Shift+WheelScrollDown" = { + # cooldown-ms = 150; + # action.move-column-to-workspace-down = { }; + # }; + # "Mod+Shift+WheelScrollUp" = { + # cooldown-ms = 150; + # action.move-column-to-workspace-up = { }; + # }; + + # "Mod+WheelScrollRight".action.focus-column-right = { }; + # "Mod+WheelScrollLeft".action.focus-column-left = { }; + # "Mod+Shift+WheelScrollRight".action.move-column-right = { }; + # "Mod+Shift+WheelScrollLeft".action.move-column-left = { }; + + "Mod+BracketLeft".action.consume-or-expel-window-left = { }; + "Mod+BracketRight".action.consume-or-expel-window-right = { }; + + "Mod+Shift+BracketLeft".action.consume-window-into-column = { }; + "Mod+Shift+BracketRight".action.expel-window-from-column = { }; + + "Mod+R".action.switch-preset-column-width = { }; + "Mod+Shift+R".action.switch-preset-window-height = { }; + "Mod+Ctrl+R".action.reset-window-height = { }; + + "Mod+D".action.maximize-column = { }; + "Mod+F".action.fullscreen-window = { }; + "Mod+S".action.expand-column-to-available-width = { }; + "Mod+C".action.center-column = { }; + "Mod+Shift+C".action.center-visible-columns = { }; + + "Mod+Minus".action.set-column-width = "-10%"; + "Mod+Equal".action.set-column-width = "+10%"; + "Mod+Shift+Minus".action.set-window-height = "-10%"; + "Mod+Shift+Equal".action.set-window-height = "+10%"; + + "Mod+E".action.toggle-window-floating = { }; + "Mod+Shift+E".action.switch-focus-between-floating-and-tiling = { }; + + "Mod+W".action.toggle-column-tabbed-display = { }; + + "Mod+Shift+S".action.screenshot = { }; + + "Mod+Escape" = { + allow-inhibiting = false; + action.toggle-keyboard-shortcuts-inhibit = { }; + }; + + "Mod+Shift+P".action.power-off-monitors = { }; + }; + }; + + programs.noctalia-shell = { + enable = true; + systemd.enable = false; + settings = { + general = { + # avatarImage = cfg.pfp; + }; + colorSchemes = { + darkMode = true; + generateTemplatesForPredefined = true; + inherit matugenSchemeType; + predefinedScheme = "Noctalia (default)"; + useWallpaperColors = true; + }; + location = { + monthBeforeDay = false; + name = "Amsterdam"; + }; + wallpaper = { + enabled = true; + setWallpaperOnAllMonitors = true; + fillMode = "crop"; + }; + appLauncher = { + enableClipboardHistory = true; + terminalCommand = "kitty -e"; + }; + sessionMenu = { + enableCountdown = true; + countdownDuration = 5000; + }; + controlCenter = { + position = "close_to_bar_button"; + shortcuts = { + left = [ + { + id = "WiFi"; + } + { + id = "Bluetooth"; + } + { + id = "PowerProfile"; + } + { + id = "KeepAwake"; + } + ]; + right = [ ]; + }; + }; + bar = { + density = "compact"; + position = "right"; + backgroundOpacity = 0.5; + widgets = { + left = [ + { + id = "ControlCenter"; + useDistroLogo = true; + } + { + id = "NotificationHistory"; + } + { + id = "plugin:catwalk"; + } + ]; + center = [ + { + hideUnoccupied = false; + id = "Workspace"; + labelMode = "none"; + } + ]; + right = [ + { + id = "Tray"; + drawerEnabled = false; + } + { + id = "WiFi"; + } + { + id = "Bluetooth"; + } + ] + ++ [ { id = "Battery"; } ] + ++ [ + { + id = "KeyboardLayout"; + displayMode = "forceOpen"; + } + { + formatHorizontal = "HH:mm"; + formatVertical = "HH mm"; + id = "Clock"; + useMonospacedFont = true; + usePrimaryColor = true; + } + ]; + }; + }; + templates = { + gtk = true; + qt = true; + niri = true; + }; + }; + }; + + home.file.".cache/noctalia/wallpapers.json" = { + text = builtins.toJSON { + defaultWallpaper = wallpaper; + }; + }; + + home.activation.themeFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + mkdir -p ${config.xdg.configHome}/gtk-4.0 + mkdir -p ${config.xdg.configHome}/gtk-3.0 + mkdir -p ${config.xdg.configHome}/qt5ct/colors + mkdir -p ${config.xdg.configHome}/qt6ct/colors + + touch ${config.xdg.configHome}/gtk-4.0/gtk.css + touch ${config.xdg.configHome}/gtk-3.0/gtk.css + touch ${config.xdg.configHome}/qt5ct/colors/noctalia.conf + touch ${config.xdg.configHome}/qt6ct/colors/noctalia.conf + ''; + + programs.matugen = { + enable = true; + wallpaper = wallpaper; + type = matugenSchemeType; + }; + + gtk.cursorTheme = { + package = pkgs.adwaita-icon-theme; + name = "Adwaita"; + size = 24; + }; + + dconf.settings = { + # appearance + "org/gnome/desktop/interface" = { + color-scheme = "prefer-dark"; + enable-hot-corners = false; + gtk-enable-primary-paste = false; + }; + }; + }; +} diff --git a/programs/nvim/config.lua b/programs/nvim/config.lua new file mode 100644 index 0000000..0507bae --- /dev/null +++ b/programs/nvim/config.lua @@ -0,0 +1,248 @@ +vim.o.sessionoptions="blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal,localoptions" + + +vim.filetype.add({ + extension = { + mdx = "markdown", + } +}) + + +-- key mapping +local keymap = vim.api.nvim_set_keymap +local opts = { noremap = true, silent = true } +local builtin = require('telescope.builtin') + +-- comment +local esc = vim.api.nvim_replace_termcodes( + '', true, false, true +) +local api = require('Comment.api') + +vim.keymap.set("n", "", ":lua require('Comment.api').toggle.linewise.current() j", { remap = true }) +vim.keymap.set("i", "", ":lua require('Comment.api').toggle.linewise.current()", { remap = true }) +vim.keymap.set("x", "", function() + vim.api.nvim_feedkeys(esc, 'nx', false) + api.toggle.linewise(vim.fn.visualmode()) +end, { remap = true }) + +vim.keymap.set('n', 'gr', (function() builtin.lsp_references({jump_type="vsplit"}) end), {}) +vim.keymap.set('n', 'gd', (function() builtin.lsp_definitions({jump_type="vsplit"}) end), {}) +vim.keymap.set('n', 'gt', (function() builtin.lsp_type_definitions({jump_type="vsplit"}) end), {}) + +local barbar_state = require("barbar.state") +function find_windows_with_buffer(bufnum) + windows = {} + + local window_list = vim.api.nvim_list_wins() + + for _, window in ipairs(window_list) do + local win_info = vim.fn.getwininfo(window) + + if win_info ~= nil then + for _, buf in ipairs(win_info) do + if buf.bufnr == bufnum then + table.insert(windows, window) + end + end + end + end + + return windows +end + +function num_useful_windows() + local window_list = vim.api.nvim_tabpage_list_wins(0) + local num = 0 + + for _, window in ipairs(window_list) do + local win_info = vim.fn.getwininfo(window) + + if win_info ~= nil then + for _, win_info in ipairs(win_info) do + if buf_is_useful(win_info.bufnr) then + num = num + 1 + end + end + end + end + + return num +end + +function buf_is_useful(bufnr) + local bufname = vim.api.nvim_buf_get_name(bufnr) + + -- if the window's buffer has no name, it's not useful + if bufname == '' then + return false + end + + -- print("bufname: ", bufname) + + -- if the window's buffer is read only, it's not useful + local readonly = vim.api.nvim_buf_get_option(bufnr, 'readonly') + if readonly then + -- print("=readonly") + return false + end + + -- -- if the buffer is not listed, it's not useful + local listed = vim.api.nvim_buf_get_option(bufnr, 'buflisted') + if not listed then + -- print("=unlisted") + return false + end + + local buftype = vim.api.nvim_buf_get_option(bufnr, 'buftype') + if buftype == "quickfix" then + -- print("=readonly") + return false + end + + local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) + if #lines > 1 or (#lines == 1 and #lines[1] > 0) then + return true -- If the buffer has content, return false + else + return false + end + + -- the window contains a useful buffer + return true +end + +function quit_window(window) + vim.api.nvim_win_call(window, function() + vim.cmd "quit" + end) +end + +vim.api.nvim_create_user_command('CloseBuffer', function (opts) + if num_useful_windows() > 1 then + vim.cmd { + cmd = "quit", + bang = opts.bang, + } + else + vim.cmd { + cmd = "BufferDelete", + bang = opts.bang, + } + if not buf_is_useful(vim.api.nvim_get_current_buf()) then + vim.cmd { + cmd = "quit", + bang = opts.bang, + } + end + end +end, { desc = "Close Current Buffer", bang = true, }) + +local function close_floating() + for _, win in ipairs(vim.api.nvim_list_wins()) do + local config = vim.api.nvim_win_get_config(win) + if config.relative ~= "" then + vim.api.nvim_win_close(win, false) + end + end +end + +vim.keymap.set("n", "", close_floating, { desc = "Close floats, clear highlights" }) + +local builtin = require('telescope.builtin') + +vim.keymap.set("n", "x", require("telescope.builtin").resume, { + noremap = true, + silent = true, + desc = "Resume", +}) + +-- local gitsigns = require('gitsigns') +-- vim.keymap.set('n', 'gr', gitsigns.reset_hunk) +-- vim.keymap.set('n', 'gd', gitsigns.diffthis) +-- vim.keymap.set({'o', 'x'}, 'ig', ':Gitsigns select_hunk') + + +-- better search +vim.cmd([[ + " Better search + set incsearch + set ignorecase + set smartcase + set gdefault + + nnoremap n n:call BlinkNextMatch() + nnoremap N N:call BlinkNextMatch() + + function! BlinkNextMatch() abort + highlight JustMatched ctermfg=white ctermbg=magenta cterm=bold + + let pat = '\c\%#' . @/ + let id = matchadd('JustMatched', pat) + redraw + + exec 'sleep 150m' + call matchdelete(id) + redraw + endfunction + + nnoremap :silent nohecho + nnoremap :silent nohecho + + nnoremap n nzz + nnoremap N Nzz + nnoremap * *zz + nnoremap # #zz + nnoremap g* g*zz +]]) + +vim.cmd([[ + inoremap FloatermToggle + nnoremap FloatermToggle + tnoremap FloatermToggle +]]) + +vim.cmd([[ + let g:suda_smart_edit = 1 + filetype plugin indent on +]]) + + +-- multicursor +vim.g.VM_default_mappings = 1 +vim.g.VM_reselect_first = 1 +vim.g.VM_notify_previously_selected = 1 +vim.g.VM_theme = "iceblue" + + + +-- workaround for rust-analyzer server cancelled request +for _, method in ipairs { 'textDocument/diagnostic', 'workspace/diagnostic' } do + local default_diagnostic_handler = vim.lsp.handlers[method] + vim.lsp.handlers[method] = function(err, result, context, config) + if err ~= nil and err.code == -32802 then + return + end + return default_diagnostic_handler(err, result, context, config) + end +end + +require("hover").setup { + init = function() + require("hover.providers.lsp") + require('hover.providers.gh') + require('hover.providers.diagnostic') + end, + preview_opts = { + border = 'rounded' + }, + -- Whether the contents of a currently open hover window should be moved + -- to a :h preview-window when pressing the hover keymap. + preview_window = false, + title = true, +} + +-- Setup keymaps +vim.keymap.set("n", "K", require("hover").hover, {desc = "hover.nvim"}) +vim.keymap.set("n", "gK", require("hover").hover_select, {desc = "hover.nvim (select)"}) +-- vim.keymap.set("n", "", function() require("hover").hover_switch("previous") end, {desc = "hover.nvim (previous source)"}) +-- vim.keymap.set("n", "", function() require("hover").hover_switch("next") end, {desc = "hover.nvim (next source)"}) diff --git a/programs/nvim/default.nix b/programs/nvim/default.nix new file mode 100644 index 0000000..e733593 --- /dev/null +++ b/programs/nvim/default.nix @@ -0,0 +1,104 @@ +_: { + custom.program.nvim.requirements = [ "cli" ]; + custom.program.nvim.home-config = + { pkgs, flakes, ... }: + { + + home = { + sessionVariables = { + EDITOR = "nvim"; + }; + }; + + imports = [ + flakes.nixvim.homeModules.nixvim + ./options.nix + ./plugins.nix + ./keys.nix + ]; + + programs.nixvim = { + enable = true; + globals.mapleader = " "; + globals.maplocalleader = " "; + + viAlias = true; + vimAlias = true; + + # Highlight and remove extra white spaces + # same color as cursorline as per + # https://github.com/joshdick/onedark.vim/blob/390b893d361c356ac1b00778d849815f2aa44ae4/autoload/onedark.vim + highlight.ExtraWhitespace.bg = "#2C323C"; + match.ExtraWhitespace = "\\s\\+$"; + + clipboard.providers.wl-copy.enable = true; + + performance = { + byteCompileLua.enable = true; + combinePlugins = { + enable = true; + + standalonePlugins = [ + # clashes with lualine + "onedark.nvim" + ]; + }; + }; + + extraLuaPackages = ps: [ ps.magick ]; + extraPackages = [ pkgs.imagemagick ]; + + # package = (import inputs.unstable { inherit (pkgs) system; }).neovim-unwrapped; + package = pkgs.neovim-unwrapped; + + colorschemes.onedark = { + enable = true; + settings = { + style = "deep"; + + highlights = { + # bright green doccomments + "@lsp.type.comment".fg = "#77B767"; + "@comment.documentation.rust".fg = "#77B767"; + "@comment.documentation".fg = "#77B767"; + "@comment".fg = "#426639"; + # "Visual".bg = "#2a2e36"; + # "Cursorline".bg = "#2a2e36"; + }; + + }; + }; + + extraConfigLuaPre = '' + require("neoconf").setup({}) + ''; + extraConfigLua = '' + require("render-markdown").setup { + latex_converter = '${pkgs.python312Packages.pylatexenc}/bin/latex2text', + } + '' + + # local lspconfig = require 'lspconfig' + # local configs = require 'lspconfig.configs' + # if not configs.foo_lsp then + # configs.noteslsp = { + # default_config = { + # -- cmd = {'${pkgs.custom.noteslsp}/bin/noteslsp'}, + # cmd = {'./noteslsp/target/debug/noteslsp'}, + # filetypes = {'markdown'}, + # root_dir = function(fname) + # return lspconfig.util.find_git_ancestor(fname) + # end, + # settings = {} + # , + # }, + # } + # end + # + # lspconfig.noteslsp.setup{} + # '' + + (builtins.readFile ./config.lua); + + }; + }; +} diff --git a/programs/nvim/keys.nix b/programs/nvim/keys.nix new file mode 100644 index 0000000..0080355 --- /dev/null +++ b/programs/nvim/keys.nix @@ -0,0 +1,103 @@ +_: +let + map = mode: key: action: { + inherit mode key action; + }; + luamap = + mode: key: action: + map mode key "lua ${action}"; + telescope = "require('telescope.builtin')"; +in +{ + programs.nixvim.keymaps = [ + (map "" "" "Lspsaga rename") + (map "" "o" "Lspsaga outline") + (map "" "." "Lspsaga code_action") + + # splitting + (map "n" "s" "vertical sb") + + # closing + (map "n" "w" "BufferClose") # single buffer + (map "n" "cb" "BufferClose") # single buffer + + (map "n" "ct" "CloseBuffer") # buffer or extra tab + (map "n" "q" "CloseBuffer") # buffer or extra tab + + (map "n" "co" "silent! BufferCloseAllButVisible") # other buffers + (map "n" "cl" "silent! BufferCloseBuffersLeft") # other buffers (left) + (map "n" "cr" "silent! BufferCloseBuffersRight") # other buffers (right) + + # moving + (map "n" "mL" "BufferMovePrevious") # left + (map "n" "mr" "BufferMoveNext") # right + (map "n" "m0" "BufferMoveStart") # start + (map "n" "m$" "BufferMoveEnd") # end + + (map "n" "jb" "BufferPick") # jump to tab + + # jumplist + # (map "n" "" "") + # (map "n" "" "") + (luamap "n" "r" "${telescope}.jumplist()") + + # pickers + (luamap "n" "" "${telescope}.find_files()") + (luamap "n" "f" "${telescope}.live_grep()") + (luamap "n" "t" "${telescope}.lsp_document_symbols()") + (luamap "n" "T" "${telescope}.lsp_dynamic_workspace_symbols()") + # last used pickers/searches + (luamap "n" "h" "${telescope}.pickers()") + # open buffers + (luamap "n" "b" "${telescope}.buffers({sort_mru = true})") + + # diagnostics + (map "n" "d" "Trouble diagnostics toggle filter.buf=0") + (map "n" "ad" "Trouble diagnostics toggle") + (luamap "n" "]d" + "vim.diagnostic.goto_next({ severity = vim.diagnostic.severity.ERROR, wrap=true })" + ) + (luamap "n" "[d" + "vim.diagnostic.goto_prev({ severity = vim.diagnostic.severity.ERROR, wrap=true })" + ) + (luamap "n" "]w" "vim.diagnostic.goto_next({ wrap=true })") + (luamap "n" "[w" "vim.diagnostic.goto_prev({ wrap=true })") + + # docs with control-d just like in autocomplete + (map "n" "" "K") + + # expand macro + (map "n" "em" "RustLsp expandMacro") + + # easier quitting etc + (map "ca" "W" "w") + (map "ca" "X" "x") + + (map "ca" "Q" "CloseBuffer") + (map "ca" "q" "CloseBuffer") + + # navigation + (map "" "" "") + (map "" "" "") + (map "" "" "") + (map "" "" "") + (map "" "" "") + + # { + # key = "/"; + # action = "lua require('spectre').open_file_search({select_word=true})"; + # } + + (map "n" "t" "Neotree toggle") + + # tab for indent/dedent + (map "n" "" ">>_") + (map "n" "" "<<_") + (map "i" "" "") + (map "v" "" ">gv") + (map "v" "" "