diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 647579d5..c26c4b8b 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,9 +1,9 @@ --- name: Feature request about: Suggest an improvement for this project -title: '' +title: "" labels: enhancement -assignees: '' +assignees: "" --- **Is your feature request related to a problem? Please describe.** diff --git a/.github/ISSUE_TEMPLATE/service_disruption.md b/.github/ISSUE_TEMPLATE/service_disruption.md index e37813e3..8d03f1b6 100644 --- a/.github/ISSUE_TEMPLATE/service_disruption.md +++ b/.github/ISSUE_TEMPLATE/service_disruption.md @@ -1,9 +1,9 @@ --- name: Service disruption report about: Use this to report service instabilities -title: ': ' +title: ": " labels: bug -assignees: '' +assignees: "" --- **Affected service** diff --git a/build/common.nix b/build/common.nix index 78eefd13..1fcdcfb3 100644 --- a/build/common.nix +++ b/build/common.nix @@ -15,14 +15,6 @@ nixpkgs.config.allowUnfree = true; - nixpkgs.overlays = [ - (_prev: final: { - # fails to find nix-main against nix 2.28.x - # https://github.com/NixOS/infra/pull/620#issuecomment-2784979947 - nixos-option = final.nixos-option.override { nix = pkgs.nixVersions.nix_2_24; }; - }) - ]; - hardware.enableAllFirmware = true; hardware.cpu.amd.updateMicrocode = true; hardware.cpu.intel.updateMicrocode = true; diff --git a/build/diffoscope.nix b/build/diffoscope.nix index 8f94469c..9a6a4211 100644 --- a/build/diffoscope.nix +++ b/build/diffoscope.nix @@ -11,7 +11,7 @@ let echo "" echo "non-determinism detected in $2; diff with previous round follows:" echo "" - time ${pkgs.utillinux}/bin/runuser -u diffoscope -- ${pkgs.diffoscope}/bin/diffoscope "$1" "$2" + time ${pkgs.util-linux}/bin/runuser -u diffoscope -- ${pkgs.diffoscope}/bin/diffoscope "$1" "$2" exit 0 ''; diff --git a/build/flake-module.nix b/build/flake-module.nix index 92449793..43c9864b 100644 --- a/build/flake-module.nix +++ b/build/flake-module.nix @@ -23,6 +23,7 @@ in haumea = { }; pluto = { }; mimas = { }; + titan = { }; }; flake = { @@ -55,6 +56,16 @@ in ./mimas ]; }; + + nixosConfigurations.titan = lib.nixosSystem { + system = "x86_64-linux"; + + specialArgs = { inherit inputs; }; + modules = [ + flakesModule + ./titan + ]; + }; }; perSystem = diff --git a/build/hydra-proxy.nix b/build/hydra-proxy.nix index 7f057e52..411a725f 100644 --- a/build/hydra-proxy.nix +++ b/build/hydra-proxy.nix @@ -34,7 +34,6 @@ recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; - recommendedZstdSettings = true; proxyTimeout = "900s"; diff --git a/build/mimas/firewall.nix b/build/mimas/firewall.nix index 5a6f12ed..e2bbf2a1 100644 --- a/build/mimas/firewall.nix +++ b/build/mimas/firewall.nix @@ -51,7 +51,7 @@ in Group = "nft-asblock"; ExecStart = toString ( [ - (lib.getExe inputs.nft-prefix-import.packages.${pkgs.hostPlatform.system}.default) + (lib.getExe inputs.nft-prefix-import.packages.${pkgs.stdenv.hostPlatform.system}.default) "--table" "abuse" "--ipv4set" diff --git a/build/pluto/prometheus/exporters/channel.nix b/build/pluto/prometheus/exporters/channel.nix index e1b05adf..79a073a5 100644 --- a/build/pluto/prometheus/exporters/channel.nix +++ b/build/pluto/prometheus/exporters/channel.nix @@ -12,8 +12,8 @@ in (pkgs.python3.withPackages ( pypkgs: with pypkgs; [ requests - dateutil - prometheus_client + prometheus-client + python-dateutil ] )) ]; diff --git a/build/pluto/prometheus/exporters/github.nix b/build/pluto/prometheus/exporters/github.nix index bd01c41c..e12fcb15 100644 --- a/build/pluto/prometheus/exporters/github.nix +++ b/build/pluto/prometheus/exporters/github.nix @@ -33,7 +33,7 @@ in path = [ (pkgs.python3.withPackages ( ps: with ps; [ - prometheus_client + prometheus-client requests ] )) diff --git a/build/pluto/prometheus/exporters/hydra.nix b/build/pluto/prometheus/exporters/hydra.nix index 82c23577..20b2ca0d 100644 --- a/build/pluto/prometheus/exporters/hydra.nix +++ b/build/pluto/prometheus/exporters/hydra.nix @@ -16,7 +16,7 @@ python = pkgs.python3.withPackages ( ps: with ps; [ requests - prometheus_client + prometheus-client ] ); in diff --git a/build/pluto/prometheus/exporters/nixos.nix b/build/pluto/prometheus/exporters/nixos.nix index 9819538a..8e3a958d 100644 --- a/build/pluto/prometheus/exporters/nixos.nix +++ b/build/pluto/prometheus/exporters/nixos.nix @@ -19,6 +19,7 @@ labels.role = "database"; targets = [ "haumea.nixos.org:9300" + "titan.nixos.org:9300" ]; } ]; diff --git a/build/pluto/prometheus/exporters/node.nix b/build/pluto/prometheus/exporters/node.nix index 4ece8e8a..9e089e21 100644 --- a/build/pluto/prometheus/exporters/node.nix +++ b/build/pluto/prometheus/exporters/node.nix @@ -16,6 +16,7 @@ labels.role = "database"; targets = [ "haumea.nixos.org:9100" + "titan.nixos.org:9100" ]; } { diff --git a/build/pluto/prometheus/exporters/postgresql.nix b/build/pluto/prometheus/exporters/postgresql.nix index e604141a..e9aad076 100644 --- a/build/pluto/prometheus/exporters/postgresql.nix +++ b/build/pluto/prometheus/exporters/postgresql.nix @@ -7,6 +7,7 @@ { targets = [ "haumea.nixos.org:9187" + "titan.nixos.org:9187" "tracker.security.nixos.org:9187" ]; } diff --git a/build/pluto/prometheus/exporters/rasdaemon.nix b/build/pluto/prometheus/exporters/rasdaemon.nix index 0eaf8374..3a8a0c7b 100644 --- a/build/pluto/prometheus/exporters/rasdaemon.nix +++ b/build/pluto/prometheus/exporters/rasdaemon.nix @@ -12,6 +12,7 @@ "mimas.nixos.org:10029" "haumea.nixos.org:10029" "pluto.nixos.org:10029" + "titan.nixos.org:10029" # builders "elated-minsky.builder.nixos.org:10029" diff --git a/build/pluto/prometheus/exporters/zfs.nix b/build/pluto/prometheus/exporters/zfs.nix index e76e95bf..147b2b72 100644 --- a/build/pluto/prometheus/exporters/zfs.nix +++ b/build/pluto/prometheus/exporters/zfs.nix @@ -13,6 +13,7 @@ "haumea.nixos.org:9134" "mimas.nixos.org:9134" "pluto.nixos.org:9134" + "titan.nixos.org:9134" ]; } ]; diff --git a/build/titan/boot.nix b/build/titan/boot.nix new file mode 100644 index 00000000..b930ae74 --- /dev/null +++ b/build/titan/boot.nix @@ -0,0 +1,30 @@ +{ + boot = { + initrd.availableKernelModules = [ + "ahci" + "xhci_pci" + "nvme" + "usbhid" + ]; + kernelModules = [ "kvm-amd" ]; + supportedFilesystems.zfs = true; + loader = { + efi.canTouchEfiVariables = false; + grub = { + enable = true; + efiSupport = true; + efiInstallAsRemovable = true; + mirroredBoots = [ + { + devices = [ "nodev" ]; + path = "/efi/a"; + } + { + devices = [ "nodev" ]; + path = "/efi/b"; + } + ]; + }; + }; + }; +} diff --git a/build/titan/default.nix b/build/titan/default.nix new file mode 100644 index 00000000..78cb70dc --- /dev/null +++ b/build/titan/default.nix @@ -0,0 +1,21 @@ +{ + imports = [ + ../common.nix + ./boot.nix + ./network.nix + ./postgresql.nix + ./zrepl.nix + ]; + + disko.devices = import ./disko.nix; + + networking = { + hostId = "e1ce6466"; + hostName = "titan"; + domain = "nixos.org"; + }; + + services.zfs.autoScrub.enable = true; + + system.stateVersion = "25.11"; +} diff --git a/build/titan/disko.nix b/build/titan/disko.nix new file mode 100644 index 00000000..e685d159 --- /dev/null +++ b/build/titan/disko.nix @@ -0,0 +1,78 @@ +let + layout = id: { + type = "gpt"; + partitions = { + esp = { + type = "EF00"; + size = "1G"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/efi/${id}"; + }; + }; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; +in +{ + disk = { + nvme0n1 = { + type = "disk"; + device = "/dev/disk/by-id/nvme-MTFDKCC1T9TGP-1BK1DABYY_0925109FB623"; + content = layout "a"; + }; + nvme1n1 = { + type = "disk"; + device = "/dev/disk/by-id/nvme-MTFDKCC1T9TGP-1BK1DABYY_0925109FB922"; + content = layout "b"; + }; + }; + + zpool.zroot = { + type = "zpool"; + mode = "mirror"; + options.ashift = "12"; + + rootFsOptions = { + acltype = "posixacl"; + atime = "off"; + compression = "zstd-3"; + mountpoint = "none"; + xattr = "sa"; + }; + + datasets = { + "root" = { + type = "zfs_fs"; + mountpoint = "/"; + }; + "nix" = { + type = "zfs_fs"; + mountpoint = "/nix"; + }; + "pg" = { + type = "zfs_fs"; + mountpoint = "/var/lib/postgresql"; + options = { + logbias = "latency"; + recordsize = "16K"; + redundant_metadata = "most"; + }; + }; + "reserved" = { + type = "zfs_fs"; + options = { + canmount = "off"; + refreservation = "16G"; # roughly one system closure + }; + }; + }; + }; +} diff --git a/build/titan/network.nix b/build/titan/network.nix new file mode 100644 index 00000000..e29f8ac1 --- /dev/null +++ b/build/titan/network.nix @@ -0,0 +1,49 @@ +{ + systemd.network = { + enable = true; + netdevs = { + "20-vlan4000" = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan4000"; + }; + vlanConfig.Id = 4000; + }; + }; + networks = { + "30-enp35s0" = { + matchConfig = { + MACAddress = "9c:6b:00:1f:aa:fd"; + Type = "ether"; + }; + address = [ + "159.69.62.224/26" + "2a01:4f8:231:e53::1/64" + ]; + routes = [ + { Gateway = "159.69.62.193"; } + { Gateway = "fe80::1"; } + ]; + vlan = [ + "vlan4000" + ]; + networkConfig.Description = "WAN"; + linkConfig.RequiredForOnline = true; + }; + "30-vlan4000" = { + matchConfig.Name = "vlan4000"; + networkConfig = { + DHCP = false; + IPv6AcceptRA = false; + }; + linkConfig = { + MTUBytes = "1400"; + RequiredForOnline = "routable"; + }; + address = [ + "10.0.40.3/31" + ]; + }; + }; + }; +} diff --git a/build/titan/postgresql.nix b/build/titan/postgresql.nix new file mode 100644 index 00000000..bf7bb378 --- /dev/null +++ b/build/titan/postgresql.nix @@ -0,0 +1,109 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + services.prometheus.exporters.postgres = { + enable = true; + dataSourceName = "user=root database=hydra host=/run/postgresql sslmode=disable"; + openFirewall = true; + firewallRules = '' + ip6 saddr $prometheus_inet6 tcp dport ${toString config.services.prometheus.exporters.postgres.port} accept + ip saddr $prometheus_inet4 tcp dport ${toString config.services.prometheus.exporters.postgres.port} accept + ''; + }; + + networking.firewall.interfaces."vlan4000".allowedTCPPorts = [ 5432 ]; + + services.postgresql = { + enable = false; # TODO: enable after data migration + enableJIT = true; + package = pkgs.postgresql_16; + # https://pgtune.leopard.in.ua/#/ + settings = { + listen_addresses = lib.mkForce "10.254.1.9"; + + # https://vadosware.io/post/everything-ive-seen-on-optimizing-postgres-on-zfs-on-linux/#zfs-related-tunables-on-the-postgres-side + full_page_writes = "off"; + + wal_init_zero = "off"; + wal_recycle = "off"; + + checkpoint_completion_target = "0.9"; + default_statistics_target = 100; + + log_duration = "off"; + log_statement = "none"; + + # pgbadger-compatible logging + log_transaction_sample_rate = 0.01; + log_min_duration_statement = 5000; + log_checkpoints = "on"; + log_connections = "on"; + log_disconnections = "on"; + log_lock_waits = "on"; + log_temp_files = 0; + log_autovacuum_min_duration = 0; + log_line_prefix = "user=%u,db=%d,app=%a,client=%h "; + + max_connections = 500; + work_mem = "20MB"; + maintenance_work_mem = "2GB"; + + # 25% of memory + shared_buffers = "32GB"; + + # Checkpoint every 1GB. (default) + # increased after seeing many warnings about frequent checkpoints + min_wal_size = "1GB"; + max_wal_size = "4GB"; + wal_buffers = "16MB"; + + max_worker_processes = 32; + max_parallel_workers_per_gather = 4; + max_parallel_workers = 32; + + # NVMe related performance tuning + effective_io_concurrency = 200; + random_page_cost = "1.1"; + + # We can risk losing some transactions. + synchronous_commit = "off"; + + effective_cache_size = "64GB"; + + # try to allocate huge pages, if possible + huge_pages = "try"; + + # Enable JIT compilation if possible. + jit = "on"; + + # autovacuum and autoanalyze much more frequently: + # at these values vacuum should run approximately + # every 2 mass rebuilds, or a couple times a day + # on the builds table. Some of those queries really + # benefit from frequent vacuums, so this should + # help. In particular, I'm thinking the jobsets + # pages. + autovacuum_vacuum_scale_factor = 0.02; + autovacuum_analyze_scale_factor = 0.01; + + shared_preload_libraries = "pg_stat_statements"; + compute_query_id = "on"; + }; + + # FIXME: don't use 'trust'. + authentication = '' + host hydra all 10.254.1.1/32 trust + local all root peer map=prometheus + ''; + + identMap = '' + prometheus root root + prometheus postgres-exporter root + ''; + }; +} diff --git a/build/titan/zrepl.nix b/build/titan/zrepl.nix new file mode 100644 index 00000000..62e53324 --- /dev/null +++ b/build/titan/zrepl.nix @@ -0,0 +1,135 @@ +{ + config, + lib, + ... +}: + +{ + age.secrets."zrepl-ssh-key" = { + file = ../secrets/zrepl-ssh-key.age; + mode = "0400"; + }; + + programs.ssh = { + knownHosts = { + rsync-net = { + hostNames = [ + "zh2543b.rsync.net" + "2001:1620:2019::324" + ]; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKlIcNwmx7id/XdYKZzVX2KtZQ4PAsEa9KVQ9N43L3PX"; + }; + }; + }; + + services.zrepl = + let + defaultBackupJob = { + type = "push"; + filesystems."zroot/pg<" = true; + snapshotting = { + type = "periodic"; + interval = "30m"; + prefix = "zrepl_snap_"; + hooks = [ + { + # https://zrepl.github.io/master/configuration/snapshotting.html#postgres-checkpoint-hook + type = "postgres-checkpoint"; + dsn = "host=/run/postgresql dbname=hydra user=root sslmode=disable"; + filesystems."zroot/pg" = true; + } + ]; + }; + + # The current pruning setup is an exponentially growing scheme, at both sides. + pruning = { + keep_sender = [ + { type = "not_replicated"; } + { + type = "grid"; + regex = "^zrepl_snap_.*"; + grid = lib.concatStringsSep " | " [ + "1x1h(keep=all)" + "1x1h" + "1x2h" + "1x4h" + # "grid" acts weird if an interval isn't a whole-number multiple + # of the previous one, so we jump from 8h to 24h + "2x8h" + "1x1d" + "1x2d" + "1x4d" + "1x8d" + # At this point we keep ~10 snapshots spanning 8--16 days (depends on moment), + # with exponentially increasing spacing (almost). + ]; + } + ]; + keep_receiver = [ + { + type = "grid"; + regex = "^zrepl_snap_.*"; + grid = lib.concatStringsSep " | " [ + "2x1h(keep=all)" + "2x1h" + "2x2h" + "2x4h" + "4x8h" + # At this point the grid spans 2 days by ~13 snapshots. + # (See note above about 8h -> 24h.) + "2x1d" + "2x2d" + "2x4d" + "2x8d" + "2x16d" + "2x32d" + "2x64d" + "2x128d" + # At this point we keep ~29 snapshots spanning 384--512 days (depends on moment), + # with exponentially increasing spacing (almost). + ]; + } + ]; + }; + }; + in + { + enable = false; # TODO: enable post migration + settings = { + global = { + logging = [ + { + type = "syslog"; + level = "info"; + format = "human"; + } + ]; + }; + + jobs = [ + # Covers 20240629+ + ( + defaultBackupJob + // { + name = "rsyncnet"; + connect = { + identity_file = config.age.secrets."zrepl-ssh-key".path; + type = "ssh+stdinserver"; + host = "zh4461b.rsync.net"; + user = "root"; + port = 22; + }; + } + ) + /* + rsync.net provides a VM with FreeBSD + - almost nothing is preserved on upgrades except this "data1" zpool + $ scp ./zrepl.yml root@zh4461b.rsync.net:/usr/local/etc/zrepl/zrepl.yml + # pkg install zrepl + # service zrepl enable + # service zrepl start + */ + ]; + }; + }; +} diff --git a/build/titan/zrepl.yml b/build/titan/zrepl.yml new file mode 100644 index 00000000..8d08f62a --- /dev/null +++ b/build/titan/zrepl.yml @@ -0,0 +1,24 @@ +# root@zh4461b.rsync.net:/usr/local/etc/zrepl/zrepl.yml +# zrepl main configuration file. +# For documentation, refer to https://zrepl.github.io/ +# +global: + logging: + - type: "stdout" + level: "error" + format: "human" + - type: "syslog" + level: "info" + format: "logfmt" + +# mostly from https://blog.lenny.ninja/zrepl-on-rsync-net.html +jobs: + - name: sink + type: sink + serve: + type: stdinserver + client_identities: [titan] + recv: + placeholder: + encryption: off + root_fs: "data1" diff --git a/builders/common/nix.nix b/builders/common/nix.nix index 4c1b33b6..ce136430 100644 --- a/builders/common/nix.nix +++ b/builders/common/nix.nix @@ -48,10 +48,9 @@ serviceConfig = { ExecStart = lib.concatStringsSep " " [ (lib.getExe pkgs.findutils) - "/tmp" + "/nix/var/nix/builds" "-maxdepth 1" "-type d" - "-iname \"nix-build-*\"" "-mtime +1" # days "-exec rm -rf {} +" ]; diff --git a/builders/common/system.nix b/builders/common/system.nix index 73152c21..e112e9ae 100644 --- a/builders/common/system.nix +++ b/builders/common/system.nix @@ -17,7 +17,4 @@ # use memory more efficiently at the cost of some compute zramSwap.enable = true; - - # enable huge pages for tmpfs on /tmp - boot.tmp.tmpfsHugeMemoryPages = "within_size"; } diff --git a/builders/profiles/hetzner-ax101r.nix b/builders/profiles/hetzner-ax101r.nix index c66df630..c5d1aa53 100644 --- a/builders/profiles/hetzner-ax101r.nix +++ b/builders/profiles/hetzner-ax101r.nix @@ -13,11 +13,23 @@ boot.supportedFilesystems.zfs = true; networking.hostId = "91312b0a"; - boot.tmp = { - useTmpfs = true; - # 128G tmpfs, 128G RAM for standard builders - # 160G tmpfs, 96G RAM for big parallel builders - tmpfsSize = if lib.elem "big-parallel" config.nix.settings.system-features then "160G" else "128G"; + fileSystems."/nix/var/nix/builds" = { + device = "none"; + fsType = "tmpfs"; + options = [ + "huge=within_size" + "mode=0700" + "nosuid" + "nodev" + ] + # 128G tmpfs, 128G RAM (+zram swap) for standard builders + # 160GB tmpfs, 96 GB RAM (+zram swap) for big-parallel builders + ++ ( + if lib.elem "big-parallel" config.nix.settings.system-features then + [ "size=160G" ] + else + [ "size=128G" ] + ); }; boot.initrd.availableKernelModules = [ diff --git a/channels.nix b/channels.nix index 8aeaa13d..9078e856 100644 --- a/channels.nix +++ b/channels.nix @@ -25,7 +25,7 @@ rec { # status = "beta"; # }; "nixos-unstable" = { - job = "nixos/trunk-combined/tested"; + job = "nixos/unstable/tested"; variant = "primary"; status = "rolling"; }; @@ -35,7 +35,7 @@ rec { status = "rolling"; }; "nixpkgs-unstable" = { - job = "nixpkgs/trunk/unstable"; + job = "nixpkgs/unstable/unstable"; status = "rolling"; }; diff --git a/flake.lock b/flake.lock index 9c81a4d0..12c313dd 100644 --- a/flake.lock +++ b/flake.lock @@ -96,16 +96,16 @@ ] }, "locked": { - "lastModified": 1759509947, - "narHash": "sha256-4XifSIHfpJKcCf5bZZRhj8C4aCpjNBaE3kXr02s4rHU=", + "lastModified": 1764161084, + "narHash": "sha256-HN84sByg9FhJnojkGGDSrcjcbeioFWoNXfuyYfJ1kBE=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "000eadb231812ad6ea6aebd7526974aaf4e79355", + "rev": "e95de00a471d07435e0527ff4db092c84998698e", "type": "github" }, "original": { "owner": "LnL7", - "ref": "nix-darwin-25.05", + "ref": "nix-darwin-25.11", "repo": "nix-darwin", "type": "github" } @@ -149,11 +149,11 @@ "flake-compat_2": { "flake": false, "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", "owner": "edolstra", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", "type": "github" }, "original": { @@ -236,11 +236,11 @@ ] }, "locked": { - "lastModified": 1742649964, - "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", + "lastModified": 1763319842, + "narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", + "rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761", "type": "github" }, "original": { @@ -412,16 +412,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1762765860, - "narHash": "sha256-eC9lOOs9XIbyXStB1DZ+9CNNNsLRmCktrIRCBlxuMWo=", + "lastModified": 1764105034, + "narHash": "sha256-bghpbJoogiHRe6yXMM4ipRJBQmQDkbHv3DrRp+TP7mo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "37a52ecc83b26df6447531b1629d2f49b6107834", + "rev": "740856ac7fe3a5068c8a3d7edff39e44ffd17804", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-25.05-small", + "ref": "nixos-25.11-small", "repo": "nixpkgs", "type": "github" } @@ -510,23 +510,20 @@ "flake-compat": "flake-compat_2", "git-hooks": "git-hooks", "nixpkgs": [ - "nixpkgs-unstable" - ], - "nixpkgs-25_05": [ "nixpkgs" ] }, "locked": { - "lastModified": 1755110674, - "narHash": "sha256-PigqTAGkdBYXVFWsJnqcirrLeFqRFN4PFigLA8FzxeI=", + "lastModified": 1764075554, + "narHash": "sha256-cykmhDd6foCZktxewyeu/9WL0Lxl0P0s5GssiXNs1Ps=", "owner": "simple-nixos-mailserver", "repo": "nixos-mailserver", - "rev": "f5936247dbdb8501221978562ab0b302dd75456c", + "rev": "faeb1b04d85693cb3804a4c2e96e7ef811bc2ed7", "type": "gitlab" }, "original": { "owner": "simple-nixos-mailserver", - "ref": "nixos-25.05", + "ref": "nixos-25.11", "repo": "nixos-mailserver", "type": "gitlab" } diff --git a/flake.nix b/flake.nix index 143fe747..8cd2d3f2 100644 --- a/flake.nix +++ b/flake.nix @@ -27,8 +27,7 @@ inputs.nixpkgs.follows = "nixpkgs"; }; - nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05-small"; - + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11-small"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; flake-parts = { @@ -37,7 +36,7 @@ }; darwin = { - url = "github:LnL7/nix-darwin/nix-darwin-25.05"; + url = "github:LnL7/nix-darwin/nix-darwin-25.11"; inputs.nixpkgs.follows = "nixpkgs"; }; @@ -81,11 +80,8 @@ }; simple-nixos-mailserver = { - url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-25.05"; - inputs = { - nixpkgs.follows = "nixpkgs-unstable"; - nixpkgs-25_05.follows = "nixpkgs"; - }; + url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-25.11"; + inputs.nixpkgs.follows = "nixpkgs"; }; sops-nix = { diff --git a/lib/service-order.nix b/lib/service-order.nix index f30c8245..a48cce56 100644 --- a/lib/service-order.nix +++ b/lib/service-order.nix @@ -2,7 +2,7 @@ # # Given a set of services, make them run one at a time in a specific # order, on a timer. -{ lib }: +{ }: { # Given a list of systemd service, give each one an After # attribute, so they start in a specific order. The returned diff --git a/macs/common.nix b/macs/common.nix index 9c8b9d84..335f4a9c 100644 --- a/macs/common.nix +++ b/macs/common.nix @@ -40,9 +40,6 @@ in }; nix = { - package = pkgs.nixVersions.nix_2_24.overrideAttrs (oldAttrs: { - patches = oldAttrs.patches or [ ] ++ [ ./disable-chroot.patch ]; - }); settings = { extra-experimental-features = [ "nix-command" diff --git a/macs/disable-chroot.patch b/macs/disable-chroot.patch deleted file mode 100644 index 3a7270a2..00000000 --- a/macs/disable-chroot.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc -index 2a09e3dd4..baeae54f8 100644 ---- a/src/libstore/unix/build/local-derivation-goal.cc -+++ b/src/libstore/unix/build/local-derivation-goal.cc -@@ -509,11 +509,11 @@ void LocalDerivationGoal::startBuilder() - /* Create a temporary directory where the build will take - place. */ - topTmpDir = createTempDir(settings.buildDir.get().value_or(""), "nix-build-" + std::string(drvPath.name()), false, false, 0700); --#if __APPLE__ -+//#if __APPLE__ - if (false) { --#else -- if (useChroot) { --#endif -+//#else -+// if (useChroot) { -+//#endif - /* If sandboxing is enabled, put the actual TMPDIR underneath - an inaccessible root-owned directory, to prevent outside - access. diff --git a/metrics/fastly/flake.nix b/metrics/fastly/flake.nix index 249f66b3..187d2985 100644 --- a/metrics/fastly/flake.nix +++ b/metrics/fastly/flake.nix @@ -1,6 +1,6 @@ { outputs = - { nixpkgs }: + { }: { nixosModules.nix-metrics = { pkgs, ... }: diff --git a/modules/hydra-mirror.nix b/modules/hydra-mirror.nix index 925896be..0e51bf2d 100644 --- a/modules/hydra-mirror.nix +++ b/modules/hydra-mirror.nix @@ -9,7 +9,7 @@ let channels = (import ../channels.nix).channels-with-urls; - orderLib = import ../lib/service-order.nix { inherit lib; }; + orderLib = import ../lib/service-order.nix { }; makeUpdateChannel = channelName: mainJob: { name = "update-${channelName}"; @@ -17,7 +17,7 @@ let description = "Update Channel ${channelName}"; path = with pkgs; [ git - inputs.nixos-channel-scripts.packages.${pkgs.hostPlatform.system}.default + inputs.nixos-channel-scripts.packages.${pkgs.stdenv.hostPlatform.system}.default ]; script = '' # Hardcoded in channel scripts. diff --git a/non-critical-infra/hosts/caliban/default.nix b/non-critical-infra/hosts/caliban/default.nix index b0477425..d3584094 100644 --- a/non-critical-infra/hosts/caliban/default.nix +++ b/non-critical-infra/hosts/caliban/default.nix @@ -15,10 +15,10 @@ ../../modules/draupnir.nix ../../modules/backup.nix ../../modules/element-web.nix + ../../modules/limesurvey.nix ../../modules/matrix-synapse.nix ../../modules/owncast.nix ../../modules/vaultwarden.nix - ./limesurvey-tmp.nix ./nixpkgs-swh.nix ]; diff --git a/non-critical-infra/hosts/caliban/limesurvey-tmp.nix b/non-critical-infra/hosts/caliban/limesurvey-tmp.nix deleted file mode 100644 index 620b92bb..00000000 --- a/non-critical-infra/hosts/caliban/limesurvey-tmp.nix +++ /dev/null @@ -1,30 +0,0 @@ -# the content of this file should be put in the modules folder once the actual module has been upstreamed -# PR: https://github.com/NixOS/nixpkgs/pull/325665/ -{ config, ... }: -{ - disabledModules = [ "services/web-apps/limesurvey.nix" ]; - - imports = [ ../../modules/limesurvey.nix ]; - - services.limesurvey = { - enable = true; - encryptionKeyFile = config.sops.secrets.limesurvey-encryption-key.path; - encryptionNonceFile = config.sops.secrets.limesurvey-encryption-nonce.path; - virtualHost = { - serverName = "survey.nixos.org"; - enableACME = true; - forceSSL = true; - }; - }; - - sops.secrets.limesurvey-encryption-key = { - format = "binary"; - sopsFile = ../../secrets/limesurvey-encryption-key.caliban; - }; - - sops.secrets.limesurvey-encryption-nonce = { - format = "binary"; - sopsFile = ../../secrets/limesurvey-encryption-nonce.caliban; - }; - -} diff --git a/non-critical-infra/hosts/staging-hydra/hydra-proxy.nix b/non-critical-infra/hosts/staging-hydra/hydra-proxy.nix index 3bea6b98..99bba596 100644 --- a/non-critical-infra/hosts/staging-hydra/hydra-proxy.nix +++ b/non-critical-infra/hosts/staging-hydra/hydra-proxy.nix @@ -37,7 +37,6 @@ in recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; - recommendedZstdSettings = true; proxyTimeout = "900s"; diff --git a/non-critical-infra/modules/hydra-queue-builder-v2.nix b/non-critical-infra/modules/hydra-queue-builder-v2.nix index daca2c30..58b89c5d 100644 --- a/non-critical-infra/modules/hydra-queue-builder-v2.nix +++ b/non-critical-infra/modules/hydra-queue-builder-v2.nix @@ -2,12 +2,10 @@ config, pkgs, lib, - inputs, ... }: let cfg = config.services.hydra-queue-builder-v2; - unstable = import inputs.nixpkgs-unstable { inherit (pkgs) system; }; in { options = { @@ -135,12 +133,7 @@ in package = lib.mkOption { type = lib.types.package; - default = - (pkgs.recurseIntoAttrs ( - pkgs.callPackage ../packages/hydra-queue-runner { - inherit (unstable) nixVersions openssl; - } - )).builder; + default = (lib.recurseIntoAttrs (pkgs.callPackage ../packages/hydra-queue-runner { })).builder; }; }; }; diff --git a/non-critical-infra/modules/hydra-queue-runner-v2.nix b/non-critical-infra/modules/hydra-queue-runner-v2.nix index db562bc7..de68c3d0 100644 --- a/non-critical-infra/modules/hydra-queue-runner-v2.nix +++ b/non-critical-infra/modules/hydra-queue-runner-v2.nix @@ -2,14 +2,12 @@ config, pkgs, lib, - inputs, ... }: let cfg = config.services.hydra-queue-runner-v2; format = pkgs.formats.toml { }; - unstable = import inputs.nixpkgs-unstable { inherit (pkgs) system; }; in { options = { @@ -187,12 +185,7 @@ in }; package = lib.mkOption { type = lib.types.package; - default = - (pkgs.recurseIntoAttrs ( - pkgs.callPackage ../packages/hydra-queue-runner { - inherit (unstable) nixVersions openssl; - } - )).runner; + default = (lib.recurseIntoAttrs (pkgs.callPackage ../packages/hydra-queue-runner { })).runner; }; }; }; @@ -254,7 +247,7 @@ in StateDirectoryMode = "0700"; ReadWritePaths = [ "/nix/var/nix/gcroots/" - "/run/postgresql/.s.PGSQL.${toString config.services.postgresql.port}" + "/run/postgresql/.s.PGSQL.${toString config.services.postgresql.settings.port}" "/nix/var/nix/daemon-socket/socket" "/var/lib/hydra/build-logs/" ]; diff --git a/non-critical-infra/modules/limesurvey.nix b/non-critical-infra/modules/limesurvey.nix index e852639a..74a73715 100644 --- a/non-critical-infra/modules/limesurvey.nix +++ b/non-critical-infra/modules/limesurvey.nix @@ -1,448 +1,28 @@ { config, - lib, - pkgs, - inputs, ... }: - -let - - inherit (lib) - mkDefault - mkEnableOption - mkForce - mkIf - mkMerge - mkOption - mkPackageOption - ; - inherit (lib) - literalExpression - mapAttrs - optional - optionalString - types - recursiveUpdate - ; - - cfg = config.services.limesurvey; - - user = "limesurvey"; - group = config.services.nginx.group; - stateDir = "/var/lib/limesurvey"; - - configType = - with types; - oneOf [ - (attrsOf configType) - str - int - bool - ] - // { - description = "limesurvey config type (str, int, bool or attribute set thereof)"; - }; - - limesurveyConfig = pkgs.writeText "config.php" '' - [ - 'encryptionnonce' => \trim(\file_get_contents(\getenv('CREDENTIALS_DIRECTORY') . DIRECTORY_SEPARATOR . 'encryption_nonce')), - 'encryptionsecretboxkey' => \trim(\file_get_contents(\getenv('CREDENTIALS_DIRECTORY') . DIRECTORY_SEPARATOR . 'encryption_key')), - ] - ] - ); - ?> - ''; - - mysqlLocal = cfg.database.createLocally && cfg.database.type == "mysql"; - pgsqlLocal = cfg.database.createLocally && cfg.database.type == "pgsql"; - -in { - # interface - - options.services.limesurvey = { - enable = mkEnableOption "Limesurvey web application"; - - package = mkPackageOption pkgs "limesurvey" { }; - - encryptionKey = mkOption { - type = types.nullOr types.str; - default = null; - visible = false; - description = '' - This is a 32-byte key used to encrypt variables in the database. - You _must_ change this from the default value. - ''; - }; - - encryptionNonce = mkOption { - type = types.nullOr types.str; - default = null; - visible = false; - description = '' - This is a 24-byte nonce used to encrypt variables in the database. - You _must_ change this from the default value. - ''; - }; - - encryptionKeyFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - 32-byte key used to encrypt variables in the database. - - Note: It should be string not a store path in order to prevent the password from being world readable - ''; - }; - - encryptionNonceFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - 24-byte used to encrypt variables in the database. - - Note: It should be string not a store path in order to prevent the password from being world readable - ''; - }; - - database = { - type = mkOption { - type = types.enum [ - "mysql" - "pgsql" - "odbc" - "mssql" - ]; - example = "pgsql"; - default = "mysql"; - description = "Database engine to use."; - }; - - dbEngine = mkOption { - type = types.enum [ - "MyISAM" - "InnoDB" - ]; - default = "InnoDB"; - description = "Database storage engine to use."; - }; - - host = mkOption { - type = types.str; - default = "localhost"; - description = "Database host address."; - }; - - port = mkOption { - type = types.port; - default = if cfg.database.type == "pgsql" then 5442 else 3306; - defaultText = literalExpression "3306"; - description = "Database host port."; - }; - - name = mkOption { - type = types.str; - default = "limesurvey"; - description = "Database name."; - }; - - user = mkOption { - type = types.str; - default = "limesurvey"; - description = "Database user."; - }; - - passwordFile = mkOption { - type = types.nullOr types.path; - default = null; - example = "/run/keys/limesurvey-dbpassword"; - description = '' - A file containing the password corresponding to - {option}`database.user`. - ''; - }; - - socket = mkOption { - type = types.nullOr types.path; - default = - if mysqlLocal then - "/run/mysqld/mysqld.sock" - else if pgsqlLocal then - "/run/postgresql" - else - null; - defaultText = literalExpression "/run/mysqld/mysqld.sock"; - description = "Path to the unix socket file to use for authentication."; - }; - - createLocally = mkOption { - type = types.bool; - default = cfg.database.type == "mysql"; - defaultText = literalExpression "true"; - description = '' - Create the database and database user locally. - This currently only applies if database type "mysql" is selected. - ''; - }; - }; - - virtualHost = mkOption { - type = types.submodule ( - recursiveUpdate (import - "${inputs.nixpkgs}/nixos/modules/services/web-servers/nginx/vhost-options.nix" - { inherit config lib; } - ) { } - ); - example = literalExpression '' - { - serverName = "survey.example.org"; - forceSSL = true; - enableACME = true; - } - ''; - description = '' - Nginx configuration can be done by adapting `services.nginx.virtualHosts.`. - See [](#opt-services.nginx.virtualHosts) for further information. - ''; - }; - - poolConfig = mkOption { - type = - with types; - attrsOf (oneOf [ - str - int - bool - ]); - default = { - "pm" = "dynamic"; - "pm.max_children" = 32; - "pm.start_servers" = 2; - "pm.min_spare_servers" = 2; - "pm.max_spare_servers" = 4; - "pm.max_requests" = 500; - }; - description = '' - Options for the LimeSurvey PHP pool. See the documentation on `php-fpm.conf` - for details on configuration directives. - ''; - }; - - config = mkOption { - type = configType; - default = { }; - description = '' - LimeSurvey configuration. Refer to - - for details on supported values. - ''; + services.limesurvey = { + enable = true; + encryptionKeyFile = config.sops.secrets.limesurvey-encryption-key.path; + encryptionNonceFile = config.sops.secrets.limesurvey-encryption-nonce.path; + webserver = "nginx"; + nginx.virtualHost = { + serverName = "survey.nixos.org"; + enableACME = true; + forceSSL = true; }; }; - # implementation - - config = mkIf cfg.enable { - - assertions = [ - { - assertion = cfg.database.createLocally -> cfg.database.type == "mysql"; - message = "services.limesurvey.createLocally is currently only supported for database type 'mysql'"; - } - { - assertion = cfg.database.createLocally -> cfg.database.user == user; - message = "services.limesurvey.database.user must be set to ${user} if services.limesurvey.database.createLocally is set true"; - } - { - assertion = cfg.database.createLocally -> cfg.database.socket != null; - message = "services.limesurvey.database.socket must be set if services.limesurvey.database.createLocally is set to true"; - } - { - assertion = cfg.database.createLocally -> cfg.database.passwordFile == null; - message = "a password cannot be specified if services.limesurvey.database.createLocally is set to true"; - } - { - assertion = cfg.encryptionKey != null || cfg.encryptionKeyFile != null; - message = '' - You must set `services.limesurvey.encryptionKeyFile` to a file containing a 32-character uppercase hex string. - - If this message appears when updating your system, please turn off encryption - in the LimeSurvey interface and create backups before filling the key. - ''; - } - { - assertion = cfg.encryptionNonce != null || cfg.encryptionNonceFile != null; - message = '' - You must set `services.limesurvey.encryptionNonceFile` to a file containing a 24-character uppercase hex string. - - If this message appears when updating your system, please turn off encryption - in the LimeSurvey interface and create backups before filling the nonce. - ''; - } - ]; - - services.limesurvey.config = mapAttrs (_name: mkDefault) { - runtimePath = "${stateDir}/tmp/runtime"; - components = { - db = { - connectionString = - "${cfg.database.type}:dbname=${cfg.database.name};host=${ - if pgsqlLocal then cfg.database.socket else cfg.database.host - };port=${toString cfg.database.port}" - + optionalString mysqlLocal ";socket=${cfg.database.socket}"; - username = cfg.database.user; - password = mkIf ( - cfg.database.passwordFile != null - ) "file_get_contents(\"${toString cfg.database.passwordFile}\");"; - tablePrefix = "limesurvey_"; - }; - assetManager.basePath = "${stateDir}/tmp/assets"; - urlManager = { - urlFormat = "path"; - showScriptName = false; - }; - }; - config = { - tempdir = "${stateDir}/tmp"; - uploaddir = "${stateDir}/upload"; - userquestionthemerootdir = "${stateDir}/upload/themes/question"; - force_ssl = mkIf ( - cfg.virtualHost.addSSL || cfg.virtualHost.forceSSL || cfg.virtualHost.onlySSL - ) "on"; - config.defaultlang = "en"; - }; - }; - - services.mysql = mkIf mysqlLocal { - enable = true; - package = mkDefault pkgs.mariadb; - ensureDatabases = [ cfg.database.name ]; - ensureUsers = [ - { - name = cfg.database.user; - ensurePermissions = { - "${cfg.database.name}.*" = "SELECT, CREATE, INSERT, UPDATE, DELETE, ALTER, DROP, INDEX"; - }; - } - ]; - }; - - services.phpfpm.pools.limesurvey = { - inherit user group; - phpPackage = pkgs.php81; - phpEnv.DBENGINE = "${cfg.database.dbEngine}"; - phpEnv.LIMESURVEY_CONFIG = "${limesurveyConfig}"; - # App code cannot access credentials directly since the service starts - # with the root user so we copy the credentials to a place accessible to Limesurvey - phpEnv.CREDENTIALS_DIRECTORY = "${stateDir}/credentials"; - settings = { - "listen.owner" = config.services.nginx.user; - "listen.group" = config.services.nginx.group; - } - // cfg.poolConfig; - }; - systemd.services.phpfpm-limesurvey.serviceConfig = { - ExecStartPre = pkgs.writeShellScript "limesurvey-phpfpm-exec-pre" '' - cp -f "''${CREDENTIALS_DIRECTORY}"/encryption_key "${stateDir}/credentials/encryption_key" - chown ${user}:${group} "${stateDir}/credentials/encryption_key" - cp -f "''${CREDENTIALS_DIRECTORY}"/encryption_nonce "${stateDir}/credentials/encryption_nonce" - chown ${user}:${group} "${stateDir}/credentials/encryption_nonce" - ''; - LoadCredential = [ - "encryption_key:${ - if cfg.encryptionKeyFile != null then - cfg.encryptionKeyFile - else - pkgs.writeText "key" cfg.encryptionKey - }" - "encryption_nonce:${ - if cfg.encryptionNonceFile != null then - cfg.encryptionNonceFile - else - pkgs.writeText "nonce" cfg.encryptionKey - }" - ]; - }; - - services.nginx = { - enable = true; - virtualHosts.${cfg.virtualHost.serverName} = lib.mkMerge [ - cfg.virtualHost - { - root = lib.mkForce "${cfg.package}/share/limesurvey"; - locations = { - "/" = { - index = "index.php"; - tryFiles = "$uri /index.php?$args"; - }; - - "~ \.php$".extraConfig = '' - fastcgi_pass unix:${config.services.phpfpm.pools."limesurvey".socket}; - ''; - "/tmp".root = "/var/lib/limesurvey"; - "/upload/".root = "/var/lib/limesurvey"; - - }; - extraConfig = '' - access_log off; - ''; - } - ]; - }; - - systemd.tmpfiles.rules = [ - "d ${stateDir} 0750 ${user} ${group} - -" - "d ${stateDir}/tmp 0750 ${user} ${group} - -" - "d ${stateDir}/tmp/assets 0750 ${user} ${group} - -" - "d ${stateDir}/tmp/runtime 0750 ${user} ${group} - -" - "d ${stateDir}/tmp/upload 0750 ${user} ${group} - -" - "d ${stateDir}/credentials 0700 ${user} ${group} - -" - "C ${stateDir}/upload 0750 ${user} ${group} - ${cfg.package}/share/limesurvey/upload" - ]; - - systemd.services.limesurvey-init = { - wantedBy = [ "multi-user.target" ]; - before = [ "phpfpm-limesurvey.service" ]; - after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; - environment.DBENGINE = "${cfg.database.dbEngine}"; - environment.LIMESURVEY_CONFIG = limesurveyConfig; - script = '' - # update or install the database as required - ${pkgs.php81}/bin/php ${cfg.package}/share/limesurvey/application/commands/console.php updatedb || \ - ${pkgs.php81}/bin/php ${cfg.package}/share/limesurvey/application/commands/console.php install admin password admin admin@example.com verbose - ''; - serviceConfig = { - User = user; - Group = group; - Type = "oneshot"; - LoadCredential = [ - "encryption_key:${ - if cfg.encryptionKeyFile != null then - cfg.encryptionKeyFile - else - pkgs.writeText "key" cfg.encryptionKey - }" - "encryption_nonce:${ - if cfg.encryptionNonceFile != null then - cfg.encryptionNonceFile - else - pkgs.writeText "nonce" cfg.encryptionKey - }" - ]; - }; - }; - - systemd.services.nginx.after = - optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; - - users.users.${user} = { - group = group; - isSystemUser = true; - }; + sops.secrets.limesurvey-encryption-key = { + format = "binary"; + sopsFile = ../secrets/limesurvey-encryption-key.caliban; + }; + sops.secrets.limesurvey-encryption-nonce = { + format = "binary"; + sopsFile = ../secrets/limesurvey-encryption-nonce.caliban; }; + } diff --git a/non-critical-infra/modules/mailserver/default.nix b/non-critical-infra/modules/mailserver/default.nix index af37a09a..fc363ee5 100644 --- a/non-critical-infra/modules/mailserver/default.nix +++ b/non-critical-infra/modules/mailserver/default.nix @@ -9,7 +9,6 @@ imports = [ inputs.simple-nixos-mailserver.nixosModule ./mailing-lists.nix - ./postsrsd.nix ./freescout.nix ]; @@ -19,6 +18,7 @@ mailserver = { enable = true; enableImap = false; + stateVersion = 3; certificateScheme = "acme-nginx"; fqdn = config.networking.fqdn; @@ -27,6 +27,8 @@ "nixcon.org" "nixos.org" ]; + + srs.enable = true; }; # https://nixos-mailserver.readthedocs.io/en/latest/backup-guide.html @@ -67,7 +69,7 @@ path = "${config.mailserver.dkimKeyDirectory}/nixcon.org.mail.key"; }; - services.postfix.config.bounce_template_file = "${pkgs.writeText "bounce-template.cf" '' + services.postfix.settings.main.bounce_template_file = "${pkgs.writeText "bounce-template.cf" '' failure_template = < "$SECRET_PATH" + # sops encrypt --in-place "$SECRET_PATH" + # ``` + sops.secrets.postsrsd-secret = { + format = "binary"; + owner = config.services.postsrsd.user; + group = config.services.postsrsd.group; + sopsFile = ../../secrets/postsrsd-secret.umbriel; + restartUnits = [ "postsrsd.service" ]; + }; } diff --git a/non-critical-infra/modules/mailserver/mailing-lists-options.nix b/non-critical-infra/modules/mailserver/mailing-lists-options.nix index ac822e8c..ee92f8de 100644 --- a/non-critical-infra/modules/mailserver/mailing-lists-options.nix +++ b/non-critical-infra/modules/mailserver/mailing-lists-options.nix @@ -138,6 +138,6 @@ in services.postfix.mapFiles.virtual-mailing-lists = config.sops.templates."postfix-virtual-mailing-lists".path; - services.postfix.config.virtual_alias_maps = [ "hash:/etc/postfix/virtual-mailing-lists" ]; + services.postfix.settings.main.virtual_alias_maps = [ "hash:/etc/postfix/virtual-mailing-lists" ]; }; } diff --git a/non-critical-infra/modules/mailserver/postsrsd.nix b/non-critical-infra/modules/mailserver/postsrsd.nix deleted file mode 100644 index dc758dd8..00000000 --- a/non-critical-infra/modules/mailserver/postsrsd.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ config, ... }: -# We use `postsrsd` to enable Sender Rewriting Scheme (SRS) so mail we forward -# to another domain does not fail SPF. See -# https://github.com/NixOS/infra/issues/485#issuecomment-2787490679 for -# details. -{ - services.postsrsd = { - enable = true; - domains = [ "nixos.org" ]; - secretsFile = config.sops.secrets.postsrsd-secret.path; - }; - - # Configure postfix as per - # https://github.com/roehling/postsrsd?tab=readme-ov-file#postfix-setup - services.postfix.config = { - sender_canonical_maps = "socketmap:unix:${config.services.postsrsd.socketPath}:forward"; - sender_canonical_classes = "envelope_sender"; - - recipient_canonical_maps = "socketmap:unix:${config.services.postsrsd.socketPath}:reverse"; - recipient_canonical_classes = "envelope_recipient, header_recipient"; - }; - - # ``` - # How to generate: - # - # ```console - # cd non-critical-infra - # SECRET_PATH=secrets/postsrsd-secret.umbriel - # dd if=/dev/random bs=18 count=1 status=none | base64 > "$SECRET_PATH" - # sops encrypt --in-place "$SECRET_PATH" - # ``` - sops.secrets.postsrsd-secret = { - format = "binary"; - owner = config.services.postsrsd.user; - group = config.services.postsrsd.group; - sopsFile = ../../secrets/postsrsd-secret.umbriel; - restartUnits = [ "postsrsd.service" ]; - }; -} diff --git a/non-critical-infra/modules/nginx.nix b/non-critical-infra/modules/nginx.nix index f689ada1..d17cc4bc 100644 --- a/non-critical-infra/modules/nginx.nix +++ b/non-critical-infra/modules/nginx.nix @@ -21,6 +21,5 @@ recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; - recommendedZstdSettings = true; }; } diff --git a/non-critical-infra/modules/postfix.nix b/non-critical-infra/modules/postfix.nix index 0151536d..146bcb44 100644 --- a/non-critical-infra/modules/postfix.nix +++ b/non-critical-infra/modules/postfix.nix @@ -24,9 +24,9 @@ services.postfix = { enable = true; - hostname = config.networking.fqdn; - domain = config.networking.fqdn; - config = { + settings.main = { + myhostname = config.networking.fqdn; + mydomain = config.networking.fqdn; smtp_tls_note_starttls_offer = "yes"; smtp_tls_security_level = "may"; tls_medium_cipherlist = "AES128+EECDH:AES128+EDH"; diff --git a/non-critical-infra/packages/hydra-queue-runner/default.nix b/non-critical-infra/packages/hydra-queue-runner/default.nix index 1fd89d9e..e83ab5fe 100644 --- a/non-critical-infra/packages/hydra-queue-runner/default.nix +++ b/non-critical-infra/packages/hydra-queue-runner/default.nix @@ -1,5 +1,5 @@ { - rustPackages_1_88, + rustPackages_1_91, fetchFromGitHub, pkg-config, openssl, @@ -14,15 +14,14 @@ withOtel ? false, }: let - version = "unstable-2025-11-05"; + version = "unstable-2025-11-27"; src = fetchFromGitHub { owner = "helsinki-systems"; repo = "hydra-queue-runner"; - rev = "81e6209e9107a62e9fba3d29f2ead8e9cf35bea1"; - hash = "sha256-MGoC9bLa9Ih66UbHkxGuAGvj/GfPZzG9N6liiHX0Sos="; + rev = "8266ce9818393ee9d0fe3ffd7bcde3eb09c2221f"; + hash = "sha256-tC4s+opt4BpN0qFx96AXhtUEJj8T7J5C68Hjj2OEetM="; }; - useFetchCargoVendor = true; - cargoHash = "sha256-eFfrwLUnI35WhzO+enr2dTe5blwY00cGQoT5mfs9ZTw="; + cargoHash = "sha256-49p2mC0DmsdgWdj4mWZf7SZj4Gd9eQFqTGRDzvMYSQM="; nativeBuildInputs = [ pkg-config protobuf @@ -33,7 +32,7 @@ let zlib protobuf - nixVersions.nix_2_31 + nixVersions.nix_2_32 nlohmann_json libsodium boost @@ -47,14 +46,13 @@ let }; in { - runner = rustPackages_1_88.rustPlatform.buildRustPackage { + runner = rustPackages_1_91.rustPlatform.buildRustPackage { pname = "hydra-queue-runner"; inherit version src; __structuredAttrs = true; strictDeps = true; inherit - useFetchCargoVendor cargoHash nativeBuildInputs buildInputs @@ -62,10 +60,11 @@ in buildAndTestSubdir = "queue-runner"; buildFeatures = lib.optional withOtel "otel"; + doCheck = false; postInstall = '' wrapProgram $out/bin/queue-runner \ - --prefix PATH : ${lib.makeBinPath [ nixVersions.nix_2_31 ]} \ + --prefix PATH : ${lib.makeBinPath [ nixVersions.nix_2_32 ]} \ --set-default JEMALLOC_SYS_WITH_MALLOC_CONF "background_thread:true,narenas:1,tcache:false,dirty_decay_ms:0,muzzy_decay_ms:0,abort_conf:true" ''; @@ -74,14 +73,13 @@ in }; }; - builder = rustPackages_1_88.rustPlatform.buildRustPackage { + builder = rustPackages_1_91.rustPlatform.buildRustPackage { pname = "hydra-queue-builder"; inherit src version; __structuredAttrs = true; strictDeps = true; inherit - useFetchCargoVendor cargoHash nativeBuildInputs buildInputs @@ -89,10 +87,11 @@ in buildAndTestSubdir = "builder"; buildFeatures = lib.optional withOtel "otel"; + doCheck = false; postInstall = '' wrapProgram $out/bin/builder \ - --prefix PATH : ${lib.makeBinPath [ nixVersions.nix_2_31 ]} \ + --prefix PATH : ${lib.makeBinPath [ nixVersions.nix_2_32 ]} \ --set-default JEMALLOC_SYS_WITH_MALLOC_CONF "background_thread:true,narenas:1,tcache:false,dirty_decay_ms:0,muzzy_decay_ms:0,abort_conf:true" ''; diff --git a/terraform-iam/.envrc b/terraform-iam/.envrc index cd7e606b..e828500b 100644 --- a/terraform-iam/.envrc +++ b/terraform-iam/.envrc @@ -1,5 +1,5 @@ # shellcheck shell=bash -use flake .#terraform-iam +use flake .#terraform export AWS_CONFIG_FILE=$PWD/aws-config export AWS_PROFILE=nixos-prod diff --git a/terraform/flake-module.nix b/terraform/flake-module.nix index 694df0ef..3994320a 100644 --- a/terraform/flake-module.nix +++ b/terraform/flake-module.nix @@ -1,16 +1,3 @@ -let - convert2Tofu = - provider: - provider.override (prev: { - homepage = - builtins.replaceStrings - [ "registry.terraform.io/providers" ] - [ - "registry.opentofu.org" - ] - prev.homepage; - }); -in { perSystem = { pkgs, ... }: @@ -18,30 +5,12 @@ in devShells.terraform = pkgs.mkShellNoCC { packages = [ pkgs.awscli2 - # TODO: migrate registry for opentofu as well. (pkgs.opentofu.withPlugins ( - p: - builtins.map convert2Tofu [ - p.aws - p.fastly - p.netlify - p.secret - ] - )) - ]; - }; - - # get rid of this, once we fix the migration above. - devShells.terraform-iam = pkgs.mkShellNoCC { - packages = [ - pkgs.awscli2 - (pkgs.opentofu.withPlugins ( - p: - builtins.map convert2Tofu [ - p.aws - p.fastly - p.netlify - p.secret + plugin: with plugin; [ + hashicorp_aws + fastly_fastly + aegirhealth_netlify + numtide_secret ] )) ];