From affdc02afe8f8070c8cbc7a66f5fdbbd4b29e236 Mon Sep 17 00:00:00 2001 From: teutat3s Date: Wed, 8 May 2024 14:05:41 +0200 Subject: [PATCH 1/2] style: check formatting using nixpkgs standard and fail early in CI to enforce it --- .forgejo/workflows/check.yml | 4 ++++ treefmt.toml | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 treefmt.toml diff --git a/.forgejo/workflows/check.yml b/.forgejo/workflows/check.yml index 0968832..5d03cdc 100644 --- a/.forgejo/workflows/check.yml +++ b/.forgejo/workflows/check.yml @@ -46,6 +46,10 @@ jobs: authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' useDaemon: false + - name: Check formatting + run: | + nix --accept-flake-config --access-tokens '' develop --command treefmt --fail-on-change + - name: Run flake checks run: | # Prevent cache garbage collection by creating GC roots diff --git a/treefmt.toml b/treefmt.toml new file mode 100644 index 0000000..0186e6a --- /dev/null +++ b/treefmt.toml @@ -0,0 +1,24 @@ +[formatter.nix] +command = "nix" +options = ["fmt"] +includes = ["*.nix"] +excludes = [] + +[formatter.prettier] +command = "prettier" +options = ["--write"] +includes = [ + "*.json", + "*.yaml", + "*.md", +] + +[formatter.shell] +command = "shfmt" +options = [ + "-s", + "-w", + "-i", + "2", +] +includes = ["*.sh"] From 2ca0bd7c3e743e699edb6e9c09d48b7c9106a64d Mon Sep 17 00:00:00 2001 From: teutat3s Date: Wed, 8 May 2024 22:57:07 +0200 Subject: [PATCH 2/2] style: run treefmt --- docs/deletion-request.md | 13 +- docs/deploying.md | 3 + docs/dns.md | 8 + docs/keycloak/keycloak-email-list.md | 3 + docs/keycloak/keycloak-reset-user-password.md | 3 + docs/keycloak/keycloak-update-realm.md | 3 + docs/mediawiki-updates.md | 1 + docs/obs-portal.md | 6 +- docs/reverting-version.md | 2 - docs/unlocking-root.md | 2 +- flake.nix | 87 +- hosts/flora-6/configuration.nix | 11 +- hosts/flora-6/default.nix | 15 +- hosts/flora-6/hardware-configuration.nix | 22 +- hosts/flora-6/triton-vmtools.nix | 6 +- hosts/flora-6/wireguard.nix | 13 +- hosts/nachtigall/backups.nix | 3 +- hosts/nachtigall/configuration.nix | 20 +- hosts/nachtigall/default.nix | 18 +- hosts/nachtigall/hardware-configuration.nix | 72 +- hosts/nachtigall/networking.nix | 8 +- hosts/nachtigall/wireguard.nix | 13 +- lib/compat/default.nix | 20 +- lib/default.nix | 8 +- lib/deploy.nix | 95 ++- logins/admins.nix | 37 +- logins/default.nix | 23 +- modules/caddy/default.nix | 18 +- modules/collabora/default.nix | 18 +- modules/core/default.nix | 15 +- modules/core/networking.nix | 7 +- modules/core/nix.nix | 22 +- modules/core/terminal-tooling.nix | 3 +- modules/core/users.nix | 11 +- modules/coturn/default.nix | 38 +- modules/docker/default.nix | 3 +- modules/drone/default.nix | 46 +- modules/forgejo-actions-runner/default.nix | 16 +- modules/forgejo/default.nix | 16 +- modules/grafana/default.nix | 14 +- .../node-exporter-full_rev33.json | 776 +++--------------- .../grafana/grafana-dashboards/synapse.json | 28 +- modules/keycloak/default.nix | 29 +- modules/loki/default.nix | 74 +- modules/mailman/default.nix | 11 +- modules/mastodon/default.nix | 20 +- modules/matrix-irc/default.nix | 24 +- modules/matrix-telegram/default.nix | 8 +- modules/matrix/default.nix | 69 +- modules/matrix/matrix-log-config.yaml | 2 +- modules/mediawiki/default.nix | 19 +- modules/nextcloud/default.nix | 9 +- modules/nginx-mastodon-files/default.nix | 5 +- modules/nginx-mastodon/default.nix | 20 +- modules/nginx-matrix/default.nix | 26 +- .../nginx-matrix/element-client-config.nix | 13 +- .../nginx-prometheus-exporters/default.nix | 19 +- modules/nginx-website-miom/default.nix | 4 +- modules/nginx-website/default.nix | 18 +- modules/nginx/default.nix | 16 +- modules/obs-portal/default.nix | 88 +- modules/owncast/default.nix | 14 +- modules/postgresql/default.nix | 8 +- modules/prometheus-exporters/default.nix | 5 +- modules/prometheus/default.nix | 56 +- modules/promtail/default.nix | 60 +- modules/searx/default.nix | 26 +- modules/tmate/default.nix | 2 +- modules/unlock-zfs-on-boot/default.nix | 3 +- overlays/default.nix | 41 +- .../pkgs/element-stickerpicker/default.nix | 6 +- overlays/pkgs/element-themes/default.nix | 6 +- secrets/secrets.nix | 15 +- tests/website.nix | 3 +- 74 files changed, 946 insertions(+), 1319 deletions(-) diff --git a/docs/deletion-request.md b/docs/deletion-request.md index 9af8009..d764010 100644 --- a/docs/deletion-request.md +++ b/docs/deletion-request.md @@ -1,9 +1,12 @@ # Process for handling a deletion request ### Keycloak + Required: + - auth.pub.solar ops user credentials - SSH access to host nachtigall + ``` ssh barkeeper@nachtigall.pub.solar @@ -20,8 +23,8 @@ sudo --user keycloak kcadm.sh update --config /tmp/kcadm.config users/2ec6f173-3 Docs: https://www.keycloak.org/docs/latest/server_admin/index.html#updating-a-user - ### Nextcloud + ``` ssh barkeeper@nachtigall.pub.solar nextcloud-occ user:delete @@ -29,8 +32,8 @@ nextcloud-occ user:delete Docs: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#user-commands-label - ### Mastodon + ``` ssh barkeeper@nachtigall.pub.solar sudo -u mastodon mastodon-tootctl accounts delete --email @@ -38,8 +41,8 @@ sudo -u mastodon mastodon-tootctl accounts delete --email Docs: https://docs.joinmastodon.org/admin/tootctl/#accounts-delete - ### Forgejo + ``` ssh barkeeper@nachtigall.pub.solar sudo -u gitea gitea admin user delete --config /var/lib/forgejo/custom/conf/app.ini --purge --email @@ -47,8 +50,8 @@ sudo -u gitea gitea admin user delete --config /var/lib/forgejo/custom/conf/app. Docs: https://forgejo.org/docs/latest/admin/command-line/#delete - ### Matrix + ``` ssh bartender@matrix.pub.solar -p 2020 curl --header "Authorization: Bearer " --request POST http://172.18.0.3:8008/_synapse/admin/v1/deactivate/@:pub.solar --data '{"erase": true}' @@ -56,6 +59,6 @@ curl --header "Authorization: Bearer " --request POST http:/ Docs: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account - ### OpenBikeSensor + Not implemented, see: https://github.com/openbikesensor/portal/issues/95 diff --git a/docs/deploying.md b/docs/deploying.md index 4c9f7ff..20af975 100644 --- a/docs/deploying.md +++ b/docs/deploying.md @@ -8,11 +8,13 @@ To deploy, make sure you have a [working development shell](./development-shell. Then, run `deploy-rs` with the hostname of the server you want to deploy: For nachtigall.pub.solar: + ``` deploy --targets '.#nachtigall' --magic-rollback false --auto-rollback false ``` For flora-6.pub.solar: + ``` deploy --targets '.#flora-6' --magic-rollback false --auto-rollback false ``` @@ -29,4 +31,5 @@ to enable switching to the new config quickly at a later moment. You'll need to have SSH Access to the boxes to be able to run `deploy`. ### Getting SSH access + See [administrative-access.md](./administrative-access.md). diff --git a/docs/dns.md b/docs/dns.md index 189ef53..c5725ff 100644 --- a/docs/dns.md +++ b/docs/dns.md @@ -15,12 +15,15 @@ Please follow https://docs.greenbaum.cloud/en/devops/triton-cli.html for the det You will need to setup the following [namecheap API credentials](https://www.namecheap.com/support/api/intro), look for "namecheap API key" in the pub.solar Keepass database. + ``` NAMECHEAP_API_KEY NAMECHEAP_API_USER NAMECHEAP_USER_NAME ``` + You will probably also need to add your external IP to the [API allow list](https://ap.www.namecheap.com/settings/tools/apiaccess/whitelisted-ips). + ``` dig -4 ip @dns.toys ``` @@ -35,16 +38,19 @@ terraform init ``` Make your changes, e.g. in `dns.tf`. + ``` $EDITOR dns.tf ``` Plan your changes using: + ``` terraform plan -out pub-solar-infra.plan ``` After verification, apply your changes with: + ``` terraform apply "pub-solar-infra.plan" ``` @@ -52,7 +58,9 @@ terraform apply "pub-solar-infra.plan" ### Useful links We use the Manta remote backend to save the terraform state for collaboration. + - https://www.terraform.io/language/v1.2.x/settings/backends/manta Namecheap Terraform provider docs: + - https://registry.terraform.io/providers/namecheap/namecheap/latest/docs diff --git a/docs/keycloak/keycloak-email-list.md b/docs/keycloak/keycloak-email-list.md index 5d91c0d..c92c05d 100644 --- a/docs/keycloak/keycloak-email-list.md +++ b/docs/keycloak/keycloak-email-list.md @@ -1,9 +1,12 @@ # Process for getting a list of email addresses of all keycloak users ### Keycloak + Required: + - auth.pub.solar ops user credentials - SSH access to host nachtigall + ``` ssh barkeeper@nachtigall.pub.solar diff --git a/docs/keycloak/keycloak-reset-user-password.md b/docs/keycloak/keycloak-reset-user-password.md index 8f123b3..b905d40 100644 --- a/docs/keycloak/keycloak-reset-user-password.md +++ b/docs/keycloak/keycloak-reset-user-password.md @@ -1,9 +1,12 @@ # Process for resetting keycloak user passwords ### Keycloak + Required: + - auth.pub.solar ops user credentials - SSH access to host nachtigall + ``` ssh barkeeper@nachtigall.pub.solar diff --git a/docs/keycloak/keycloak-update-realm.md b/docs/keycloak/keycloak-update-realm.md index a2cd2f8..6839017 100644 --- a/docs/keycloak/keycloak-update-realm.md +++ b/docs/keycloak/keycloak-update-realm.md @@ -1,9 +1,12 @@ # Process for updating a keycloak realm via CLI ### Keycloak + Required: + - auth.pub.solar ops user credentials - SSH access to host nachtigall + ``` ssh barkeeper@nachtigall.pub.solar diff --git a/docs/mediawiki-updates.md b/docs/mediawiki-updates.md index 4f49b6b..fe30e7d 100644 --- a/docs/mediawiki-updates.md +++ b/docs/mediawiki-updates.md @@ -24,6 +24,7 @@ deploy --targets '.#nachtigall' ``` Then, finalize the update by running the database migration script: + ``` ssh barkeeper@nachtigall.pub.solar docker exec -it mediawiki bash diff --git a/docs/obs-portal.md b/docs/obs-portal.md index a0ab53d..b9d895a 100644 --- a/docs/obs-portal.md +++ b/docs/obs-portal.md @@ -1,10 +1,10 @@ # OpenBikeSensor Portal ## Docker Containers -* portal -* worker -* db +- portal +- worker +- db ## Run database migrations diff --git a/docs/reverting-version.md b/docs/reverting-version.md index 83c4ebe..3ae112f 100644 --- a/docs/reverting-version.md +++ b/docs/reverting-version.md @@ -1,3 +1 @@ # Reverting to an old version - - diff --git a/docs/unlocking-root.md b/docs/unlocking-root.md index 2ec0d9a..463bd1b 100644 --- a/docs/unlocking-root.md +++ b/docs/unlocking-root.md @@ -6,4 +6,4 @@ After a boot, the encrypted root partition will have to be unlocked. This is don ssh root@nachtigall.pub.solar -p2222 ``` - After connecting, paste the crypt passphrase you can find in the shared keepass. This will disconnect the SSH session right away and the server will keep booting into stage 2. +After connecting, paste the crypt passphrase you can find in the shared keepass. This will disconnect the SSH session right away and the server will keep booting into stage 2. diff --git a/flake.nix b/flake.nix index 79c9858..d97687a 100644 --- a/flake.nix +++ b/flake.nix @@ -40,9 +40,13 @@ element-stickers.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = inputs@{ self, ... }: + outputs = + inputs@{ self, ... }: inputs.flake-parts.lib.mkFlake { inherit inputs; } { - systems = [ "x86_64-linux" "aarch64-linux" ]; + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; imports = [ inputs.nixos-flake.flakeModule @@ -52,37 +56,42 @@ ./hosts ]; - perSystem = { system, pkgs, config, ... }: { - _module.args = { - inherit inputs; - pkgs = import inputs.nixpkgs { - inherit system; - overlays = [ - inputs.agenix.overlays.default + perSystem = + { + system, + pkgs, + config, + ... + }: + { + _module.args = { + inherit inputs; + pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ inputs.agenix.overlays.default ]; + }; + unstable = import inputs.unstable { inherit system; }; + master = import inputs.master { inherit system; }; + }; + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + deploy-rs + nixpkgs-fmt + agenix + age-plugin-yubikey + cachix + editorconfig-checker + nodePackages.prettier + nvfetcher + shellcheck + shfmt + treefmt + nixos-generators + inputs.nixpkgs-2205.legacyPackages.${system}.terraform + jq ]; }; - unstable = import inputs.unstable { inherit system; }; - master = import inputs.master { inherit system; }; }; - devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ - deploy-rs - nixpkgs-fmt - agenix - age-plugin-yubikey - cachix - editorconfig-checker - nodePackages.prettier - nvfetcher - shellcheck - shfmt - treefmt - nixos-generators - inputs.nixpkgs-2205.legacyPackages.${system}.terraform - jq - ]; - }; - }; flake = let @@ -92,19 +101,15 @@ inherit username; nixosModules = builtins.listToAttrs ( - map - (x: { - name = x; - value = import (./modules + "/${x}"); - }) - (builtins.attrNames (builtins.readDir ./modules)) + map (x: { + name = x; + value = import (./modules + "/${x}"); + }) (builtins.attrNames (builtins.readDir ./modules)) ); - checks = builtins.mapAttrs - ( - system: deployLib: deployLib.deployChecks self.deploy - ) - inputs.deploy-rs.lib; + checks = builtins.mapAttrs ( + system: deployLib: deployLib.deployChecks self.deploy + ) inputs.deploy-rs.lib; formatter."x86_64-linux" = inputs.unstable.legacyPackages."x86_64-linux".nixfmt-rfc-style; diff --git a/hosts/flora-6/configuration.nix b/hosts/flora-6/configuration.nix index 6ac9c97..cbd0f90 100644 --- a/hosts/flora-6/configuration.nix +++ b/hosts/flora-6/configuration.nix @@ -1,8 +1,9 @@ -{ config -, lib -, pkgs -, flake -, ... +{ + config, + lib, + pkgs, + flake, + ... }: let psCfg = config.pub-solar; diff --git a/hosts/flora-6/default.nix b/hosts/flora-6/default.nix index 2175012..5f47905 100644 --- a/hosts/flora-6/default.nix +++ b/hosts/flora-6/default.nix @@ -1,12 +1,11 @@ { ... }: { - imports = - [ - # Include the results of the hardware scan. - ./hardware-configuration.nix - ./configuration.nix - ./triton-vmtools.nix - ./wireguard.nix - ]; + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + ./configuration.nix + ./triton-vmtools.nix + ./wireguard.nix + ]; } diff --git a/hosts/flora-6/hardware-configuration.nix b/hosts/flora-6/hardware-configuration.nix index b8375d9..b52b8e2 100644 --- a/hosts/flora-6/hardware-configuration.nix +++ b/hosts/flora-6/hardware-configuration.nix @@ -1,15 +1,23 @@ # 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 -, ... -}: { +{ + config, + lib, + pkgs, + modulesPath, + ... +}: +{ imports = [ ]; - boot.initrd.availableKernelModules = [ "ahci" "virtio_pci" "xhci_pci" "sr_mod" "virtio_blk" ]; + boot.initrd.availableKernelModules = [ + "ahci" + "virtio_pci" + "xhci_pci" + "sr_mod" + "virtio_blk" + ]; boot.initrd.kernelModules = [ ]; boot.kernelModules = [ ]; boot.extraModulePackages = [ ]; diff --git a/hosts/flora-6/triton-vmtools.nix b/hosts/flora-6/triton-vmtools.nix index 0fc5346..180eb06 100644 --- a/hosts/flora-6/triton-vmtools.nix +++ b/hosts/flora-6/triton-vmtools.nix @@ -1,7 +1,5 @@ -{ pkgs -, flake -, ... -}: { +{ pkgs, flake, ... }: +{ environment.systemPackages = with pkgs; [ flake.inputs.triton-vmtools.packages.${pkgs.system}.default ]; diff --git a/hosts/flora-6/wireguard.nix b/hosts/flora-6/wireguard.nix index cc9b6b7..c5bcd64 100644 --- a/hosts/flora-6/wireguard.nix +++ b/hosts/flora-6/wireguard.nix @@ -2,7 +2,8 @@ config, pkgs, flake, - ... }: + ... +}: { networking.firewall.allowedUDPPorts = [ 51820 ]; @@ -18,16 +19,20 @@ ]; privateKeyFile = config.age.secrets.wg-private-key.path; peers = flake.self.logins.admins.wireguardDevices ++ [ - { # nachtigall.pub.solar + { + # nachtigall.pub.solar endpoint = "138.201.80.102:51820"; publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk="; - allowedIPs = [ "10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96" ]; + allowedIPs = [ + "10.7.6.1/32" + "fd00:fae:fae:fae:fae:1::/96" + ]; } ]; }; }; - services.openssh.listenAddresses = [ + services.openssh.listenAddresses = [ { addr = "10.7.6.2"; port = 22; diff --git a/hosts/nachtigall/backups.nix b/hosts/nachtigall/backups.nix index 0e99c14..c5bf79b 100644 --- a/hosts/nachtigall/backups.nix +++ b/hosts/nachtigall/backups.nix @@ -1,4 +1,5 @@ -{ flake, ... }: { +{ flake, ... }: +{ age.secrets."restic-repo-droppie" = { file = "${flake.self}/secrets/restic-repo-droppie.age"; mode = "400"; diff --git a/hosts/nachtigall/configuration.nix b/hosts/nachtigall/configuration.nix index be33b2b..851e23d 100644 --- a/hosts/nachtigall/configuration.nix +++ b/hosts/nachtigall/configuration.nix @@ -1,8 +1,10 @@ -{ flake -, config -, pkgs -, ... -}: { +{ + flake, + config, + pkgs, + ... +}: +{ # Use GRUB2 as the boot loader. # We don't use systemd-boot because Hetzner uses BIOS legacy boot. boot.loader.systemd-boot.enable = false; @@ -11,15 +13,11 @@ efiSupport = false; mirroredBoots = [ { - devices = [ - "/dev/disk/by-id/nvme-SAMSUNG_MZVL21T0HCLR-00B00_S676NF0R517371" - ]; + devices = [ "/dev/disk/by-id/nvme-SAMSUNG_MZVL21T0HCLR-00B00_S676NF0R517371" ]; path = "/boot1"; } { - devices = [ - "/dev/disk/by-id/nvme-KXG60ZNV1T02_TOSHIBA_Z9NF704ZF9ZL" - ]; + devices = [ "/dev/disk/by-id/nvme-KXG60ZNV1T02_TOSHIBA_Z9NF704ZF9ZL" ]; path = "/boot2"; } ]; diff --git a/hosts/nachtigall/default.nix b/hosts/nachtigall/default.nix index 7ba250a..1b98981 100644 --- a/hosts/nachtigall/default.nix +++ b/hosts/nachtigall/default.nix @@ -1,15 +1,13 @@ { flake, ... }: { - imports = - [ - # Include the results of the hardware scan. - ./hardware-configuration.nix - ./configuration.nix + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + ./configuration.nix - ./networking.nix - ./wireguard.nix - ./backups.nix - - ]; + ./networking.nix + ./wireguard.nix + ./backups.nix + ]; } diff --git a/hosts/nachtigall/hardware-configuration.nix b/hosts/nachtigall/hardware-configuration.nix index 8fb74b7..2237b86 100644 --- a/hosts/nachtigall/hardware-configuration.nix +++ b/hosts/nachtigall/hardware-configuration.nix @@ -1,54 +1,54 @@ # 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, ... }: +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { - imports = - [ - (modulesPath + "/installer/scan/not-detected.nix") - ]; + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; - boot.initrd.availableKernelModules = [ "ahci" "nvme" ]; + boot.initrd.availableKernelModules = [ + "ahci" + "nvme" + ]; boot.initrd.kernelModules = [ ]; boot.kernelModules = [ "kvm-amd" ]; boot.extraModulePackages = [ ]; - fileSystems."/" = - { - device = "root_pool/root"; - fsType = "zfs"; - }; + fileSystems."/" = { + device = "root_pool/root"; + fsType = "zfs"; + }; - fileSystems."/var/lib" = - { - device = "root_pool/data"; - fsType = "zfs"; - }; + fileSystems."/var/lib" = { + device = "root_pool/data"; + fsType = "zfs"; + }; - fileSystems."/var/lib/postgresql" = - { - device = "root_pool/data/postgresql"; - fsType = "zfs"; - }; + fileSystems."/var/lib/postgresql" = { + device = "root_pool/data/postgresql"; + fsType = "zfs"; + }; - fileSystems."/var/lib/docker" = - { - device = "root_pool/data/docker"; - fsType = "zfs"; - }; + fileSystems."/var/lib/docker" = { + device = "root_pool/data/docker"; + fsType = "zfs"; + }; - fileSystems."/boot1" = - { - device = "/dev/disk/by-uuid/5493-EFF5"; - fsType = "vfat"; - }; + fileSystems."/boot1" = { + device = "/dev/disk/by-uuid/5493-EFF5"; + fsType = "vfat"; + }; - fileSystems."/boot2" = - { - device = "/dev/disk/by-uuid/5494-BA1E"; - fsType = "vfat"; - }; + fileSystems."/boot2" = { + device = "/dev/disk/by-uuid/5494-BA1E"; + fsType = "vfat"; + }; swapDevices = [ ]; diff --git a/hosts/nachtigall/networking.nix b/hosts/nachtigall/networking.nix index 91a0947..e7f9ecd 100644 --- a/hosts/nachtigall/networking.nix +++ b/hosts/nachtigall/networking.nix @@ -2,7 +2,8 @@ config, pkgs, flake, - ... }: + ... +}: { networking.hostName = "nachtigall"; @@ -24,5 +25,8 @@ } ]; networking.defaultGateway = "138.201.80.65"; - networking.defaultGateway6 = { address = "fe80::1"; interface = "enp35s0"; }; + networking.defaultGateway6 = { + address = "fe80::1"; + interface = "enp35s0"; + }; } diff --git a/hosts/nachtigall/wireguard.nix b/hosts/nachtigall/wireguard.nix index 8544918..3008ef3 100644 --- a/hosts/nachtigall/wireguard.nix +++ b/hosts/nachtigall/wireguard.nix @@ -2,7 +2,8 @@ config, pkgs, flake, - ... }: + ... +}: { networking.firewall.allowedUDPPorts = [ 51820 ]; @@ -18,16 +19,20 @@ ]; privateKeyFile = config.age.secrets.wg-private-key.path; peers = flake.self.logins.admins.wireguardDevices ++ [ - { # flora-6.pub.solar + { + # flora-6.pub.solar endpoint = "80.71.153.210:51820"; publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU="; - allowedIPs = [ "10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96" ]; + allowedIPs = [ + "10.7.6.2/32" + "fd00:fae:fae:fae:fae:2::/96" + ]; } ]; }; }; - services.openssh.listenAddresses = [ + services.openssh.listenAddresses = [ { addr = "10.7.6.1"; port = 22; diff --git a/lib/compat/default.nix b/lib/compat/default.nix index 27068ef..b5d6a19 100644 --- a/lib/compat/default.nix +++ b/lib/compat/default.nix @@ -1,16 +1,16 @@ let - lock = builtins.fromJSON (builtins.readFile builtins.path { - path = ../../flake.lock; - name = "lockPath"; - }); + lock = builtins.fromJSON ( + builtins.readFile builtins.path { + path = ../../flake.lock; + name = "lockPath"; + } + ); flake = import - ( - fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; - sha256 = lock.nodes.flake-compat.locked.narHash; - } - ) + (fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + }) { src = builtins.path { path = ../../.; diff --git a/lib/default.nix b/lib/default.nix index e1b39cb..3f14bf6 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,4 +1,10 @@ -{ self, lib, inputs, ... }: { +{ + self, + lib, + inputs, + ... +}: +{ # Configuration common to all Linux systems flake = { lib = diff --git a/lib/deploy.nix b/lib/deploy.nix index 1de2801..7f49289 100644 --- a/lib/deploy.nix +++ b/lib/deploy.nix @@ -1,9 +1,9 @@ /* - * The contents of this file are adapted from digga - * https://github.com/divnix/digga - * - * Licensed under the MIT license - */ + The contents of this file are adapted from digga + https://github.com/divnix/digga + + Licensed under the MIT license +*/ { lib, inputs }: let @@ -14,62 +14,61 @@ let inherit system; overlays = [ inputs.deploy-rs.overlay - (self: super: { deploy-rs = { inherit (pkgs) deploy-rs; lib = super.deploy-rs.lib; }; }) + (self: super: { + deploy-rs = { + inherit (pkgs) deploy-rs; + lib = super.deploy-rs.lib; + }; + }) ]; }; - getFqdn = c: + getFqdn = + c: let net = c.config.networking; fqdn = - if (net ? domain) && (net.domain != null) - then "${net.hostName}.${net.domain}" - else net.hostName; + if (net ? domain) && (net.domain != null) then "${net.hostName}.${net.domain}" else net.hostName; in fqdn; in { - mkDeployNodes = systemConfigurations: extraConfig: + mkDeployNodes = + systemConfigurations: extraConfig: /* - * - Synopsis: mkNodes _systemConfigurations_ _extraConfig_ + * + Synopsis: mkNodes _systemConfigurations_ _extraConfig_ - Generate the `nodes` attribute expected by deploy-rs - where _systemConfigurations_ are `nodes`. + Generate the `nodes` attribute expected by deploy-rs + where _systemConfigurations_ are `nodes`. - _systemConfigurations_ should take the form of a flake's - _nixosConfigurations_. Note that deploy-rs does not currently support - deploying to darwin hosts. + _systemConfigurations_ should take the form of a flake's + _nixosConfigurations_. Note that deploy-rs does not currently support + deploying to darwin hosts. - _extraConfig_, if specified, will be merged into each of the - nodes' configurations. + _extraConfig_, if specified, will be merged into each of the + nodes' configurations. - Example _systemConfigurations_ input: + Example _systemConfigurations_ input: - ``` - { - hostname-1 = { - fastConnection = true; - sshOpts = [ "-p" "25" ]; - }; - hostname-2 = { - sshOpts = [ "-p" "19999" ]; - sshUser = "root"; - }; - } - ``` - * - */ - lib.recursiveUpdate - (lib.mapAttrs - ( - _: c: { - hostname = getFqdn c; - profiles.system = { - user = "root"; - path = deployPkgs.deploy-rs.lib.activate.nixos c; - }; - } - ) - systemConfigurations) - extraConfig; + ``` + { + hostname-1 = { + fastConnection = true; + sshOpts = [ "-p" "25" ]; + }; + hostname-2 = { + sshOpts = [ "-p" "19999" ]; + sshUser = "root"; + }; + } + ``` + * + */ + lib.recursiveUpdate (lib.mapAttrs (_: c: { + hostname = getFqdn c; + profiles.system = { + user = "root"; + path = deployPkgs.deploy-rs.lib.activate.nixos c; + }; + }) systemConfigurations) extraConfig; } diff --git a/logins/admins.nix b/logins/admins.nix index 7bcdffb..18b1c18 100644 --- a/logins/admins.nix +++ b/logins/admins.nix @@ -10,7 +10,10 @@ { # tuxnix publicKey = "fTvULvdsc92binFaBV+uWwFi33bi8InShcaPnoxUZEA="; - allowedIPs = [ "10.7.6.203/32" "fd00:fae:fae:fae:fae:203::/96" ]; + allowedIPs = [ + "10.7.6.203/32" + "fd00:fae:fae:fae:fae:203::/96" + ]; } ]; }; @@ -27,9 +30,13 @@ } // sshPubKeys; wireguardDevices = [ - { # stroopwafel + { + # stroopwafel publicKey = "NNb7T8Jmn+V2dTZ8T6Fcq7hGomHGDckKoV3kK2oAhSE="; - allowedIPs = [ "10.7.6.200/32" "fd00:fae:fae:fae:fae:200::/96" ]; + allowedIPs = [ + "10.7.6.200/32" + "fd00:fae:fae:fae:fae:200::/96" + ]; } ]; }; @@ -42,9 +49,13 @@ secretEncryptionKeys = sshPubKeys; wireguardDevices = [ - { # judy + { + # judy publicKey = "I+gN7v1VXkAGoSir6L8aebtLbguvy5nAx1QVDTzdckk="; - allowedIPs = [ "10.7.6.202/32" "fd00:fae:fae:fae:fae:202::/96" ]; + allowedIPs = [ + "10.7.6.202/32" + "fd00:fae:fae:fae:fae:202::/96" + ]; } ]; }; @@ -59,13 +70,21 @@ }; wireguardDevices = [ - { # dumpyourvms + { + # dumpyourvms publicKey = "3UrVLQrwXnPAVXPiTAd7eM3fZYxnFSYgKAGpNMUwnUk="; - allowedIPs = [ "10.7.6.201/32" "fd00:fae:fae:fae:fae:201::/96" ]; + allowedIPs = [ + "10.7.6.201/32" + "fd00:fae:fae:fae:fae:201::/96" + ]; } - { # ryzensun + { + # ryzensun publicKey = "oVF2/s7eIxyVjtG0MhKPx5SZ1JllZg+ZFVF2eVYtPGo="; - allowedIPs = [ "10.7.6.204/32" "fd00:fae:fae:fae:fae:204::/96" ]; + allowedIPs = [ + "10.7.6.204/32" + "fd00:fae:fae:fae:fae:204::/96" + ]; } ]; }; diff --git a/logins/default.nix b/logins/default.nix index 374b513..cf81ff4 100644 --- a/logins/default.nix +++ b/logins/default.nix @@ -1,13 +1,24 @@ -{ lib, ... }: let +{ lib, ... }: +let admins = import ./admins.nix; robots = import ./robots.nix; -in { +in +{ flake = { logins = { - admins = lib.lists.foldl (logins: adminConfig: { - sshPubKeys = logins.sshPubKeys ++ (lib.attrsets.attrValues adminConfig.sshPubKeys); - wireguardDevices = logins.wireguardDevices ++ (if adminConfig ? "wireguardDevices" then adminConfig.wireguardDevices else []); - }) { sshPubKeys = []; wireguardDevices = []; } (lib.attrsets.attrValues admins); + admins = + lib.lists.foldl + (logins: adminConfig: { + sshPubKeys = logins.sshPubKeys ++ (lib.attrsets.attrValues adminConfig.sshPubKeys); + wireguardDevices = + logins.wireguardDevices + ++ (if adminConfig ? "wireguardDevices" then adminConfig.wireguardDevices else [ ]); + }) + { + sshPubKeys = [ ]; + wireguardDevices = [ ]; + } + (lib.attrsets.attrValues admins); robots.sshPubKeys = lib.attrsets.attrValues robots; }; }; diff --git a/modules/caddy/default.nix b/modules/caddy/default.nix index ee6c4c4..9d3edf4 100644 --- a/modules/caddy/default.nix +++ b/modules/caddy/default.nix @@ -1,11 +1,12 @@ -{ config -, lib -, pkgs -, flake -, ... +{ + config, + lib, + pkgs, + flake, + ... }: { - services.caddy = { + services.caddy = { enable = lib.mkForce true; group = config.pub-solar-os.authentication.robot.username; email = config.pub-solar-os.adminEmail; @@ -14,5 +15,8 @@ grace_period 60s ''; }; - networking.firewall.allowedTCPPorts = [ 80 443 ]; + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; } diff --git a/modules/collabora/default.nix b/modules/collabora/default.nix index 36f8aa7..6fdc592 100644 --- a/modules/collabora/default.nix +++ b/modules/collabora/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, self -, ... -}: { +{ + config, + lib, + pkgs, + self, + ... +}: +{ services.nginx.virtualHosts."collabora.${config.pub-solar-os.networking.domain}" = { enableACME = true; forceSSL = true; @@ -24,9 +26,7 @@ containers."collabora" = { image = "collabora/code"; autoStart = true; - ports = [ - "127.0.0.1:9980:9980" - ]; + ports = [ "127.0.0.1:9980:9980" ]; extraOptions = [ "--cap-add=MKNOD" "--pull=always" diff --git a/modules/core/default.nix b/modules/core/default.nix index 263984d..37b048a 100644 --- a/modules/core/default.nix +++ b/modules/core/default.nix @@ -1,4 +1,11 @@ -{ pkgs, config, flake, lib, ... }: { +{ + pkgs, + config, + flake, + lib, + ... +}: +{ imports = [ ./nix.nix ./networking.nix @@ -29,7 +36,11 @@ config = { environment = { # Just a couple of global packages to make our lives easier - systemPackages = with pkgs; [ git vim wget ]; + systemPackages = with pkgs; [ + git + vim + wget + ]; }; # Select internationalization properties diff --git a/modules/core/networking.nix b/modules/core/networking.nix index 37865f7..5351c30 100644 --- a/modules/core/networking.nix +++ b/modules/core/networking.nix @@ -3,7 +3,8 @@ lib, config, ... -}: { +}: +{ options.pub-solar-os.networking = with lib; { domain = mkOption { description = "domain on which all services should run. This defaults to pub.solar"; @@ -23,8 +24,8 @@ networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ 22 ]; networking.hosts = { - "10.7.6.1" = ["nachtigall.${config.pub-solar-os.networking.domain}"]; - "10.7.6.2" = ["flora-6.${config.pub-solar-os.networking.domain}"]; + "10.7.6.1" = [ "nachtigall.${config.pub-solar-os.networking.domain}" ]; + "10.7.6.2" = [ "flora-6.${config.pub-solar-os.networking.domain}" ]; }; services.openssh = { diff --git a/modules/core/nix.nix b/modules/core/nix.nix index c662f4d..338cdd1 100644 --- a/modules/core/nix.nix +++ b/modules/core/nix.nix @@ -1,11 +1,12 @@ -{ config -, pkgs -, lib -, flake -, ... -}: { - nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ - ]; +{ + config, + pkgs, + lib, + flake, + ... +}: +{ + nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ ]; nix = { # Use default version alias for nix package @@ -25,7 +26,10 @@ # Prevents impurities in builds sandbox = true; # Give root and @wheel special privileges with nix - trusted-users = [ "root" "@wheel" ]; + trusted-users = [ + "root" + "@wheel" + ]; # Allow only group wheel to connect to the nix daemon allowed-users = [ "@wheel" ]; }; diff --git a/modules/core/terminal-tooling.nix b/modules/core/terminal-tooling.nix index bb7853b..823898a 100644 --- a/modules/core/terminal-tooling.nix +++ b/modules/core/terminal-tooling.nix @@ -1,4 +1,5 @@ -{ flake, config, ... }: { +{ flake, config, ... }: +{ home-manager.users.${config.pub-solar-os.authentication.username} = { programs.git.enable = true; programs.starship.enable = true; diff --git a/modules/core/users.nix b/modules/core/users.nix index 3df4a1c..1ade4eb 100644 --- a/modules/core/users.nix +++ b/modules/core/users.nix @@ -4,7 +4,8 @@ lib, config, ... -}: { +}: +{ options.pub-solar-os.authentication = with lib; { username = mkOption { description = "Username for the adminstrative user"; @@ -41,7 +42,10 @@ users.users.${config.pub-solar-os.authentication.username} = { name = config.pub-solar-os.authentication.username; group = config.pub-solar-os.authentication.username; - extraGroups = [ "wheel" "docker" ]; + extraGroups = [ + "wheel" + "docker" + ]; isNormalUser = true; openssh.authorizedKeys.keys = config.pub-solar-os.authentication.sshPubKeys; }; @@ -63,7 +67,8 @@ users.groups.${config.pub-solar-os.authentication.robot.username} = { }; - users.users.root.initialHashedPassword = config.pub-solar-os.authentication.root.initialHashedPassword; + users.users.root.initialHashedPassword = + config.pub-solar-os.authentication.root.initialHashedPassword; security.sudo.wheelNeedsPassword = false; }; diff --git a/modules/coturn/default.nix b/modules/coturn/default.nix index 0bf3bc6..d8635aa 100644 --- a/modules/coturn/default.nix +++ b/modules/coturn/default.nix @@ -1,4 +1,9 @@ -{ flake, config, lib, ... }: +{ + flake, + config, + lib, + ... +}: { age.secrets."coturn-static-auth-secret" = { file = "${flake.self}/secrets/coturn-static-auth-secret.age"; @@ -19,8 +24,12 @@ pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; extraConfig = let - externalIPv4s = lib.strings.concatMapStringsSep "\n" ({ address, ... }: "external-ip=${address}") config.networking.interfaces.enp35s0.ipv4.addresses; - externalIPv6s = lib.strings.concatMapStringsSep "\n" ({ address, ... }: "external-ip=${address}") config.networking.interfaces.enp35s0.ipv6.addresses; + externalIPv4s = lib.strings.concatMapStringsSep "\n" ( + { address, ... }: "external-ip=${address}" + ) config.networking.interfaces.enp35s0.ipv4.addresses; + externalIPv6s = lib.strings.concatMapStringsSep "\n" ( + { address, ... }: "external-ip=${address}" + ) config.networking.interfaces.enp35s0.ipv6.addresses; in '' ${externalIPv4s} @@ -61,28 +70,35 @@ denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff ''; - }; networking.firewall = { interfaces.enp35s0 = let - range = with config.services.coturn; [{ - from = min-port; - to = max-port; - }]; + range = with config.services.coturn; [ + { + from = min-port; + to = max-port; + } + ]; in { allowedUDPPortRanges = range; - allowedUDPPorts = [ 3478 5349 ]; + allowedUDPPorts = [ + 3478 + 5349 + ]; allowedTCPPortRanges = [ ]; - allowedTCPPorts = [ 3478 5349 ]; + allowedTCPPorts = [ + 3478 + 5349 + ]; }; }; # get a certificate security.acme.certs.${config.services.coturn.realm} = { - /* insert here the right configuration to obtain a certificate */ + # insert here the right configuration to obtain a certificate postRun = "systemctl restart coturn.service"; group = "turnserver"; }; diff --git a/modules/docker/default.nix b/modules/docker/default.nix index 5cb9023..c7b3fc4 100644 --- a/modules/docker/default.nix +++ b/modules/docker/default.nix @@ -1,4 +1,5 @@ -{ pkgs, ... }: { +{ pkgs, ... }: +{ virtualisation.docker = { enable = true; extraOptions = '' diff --git a/modules/drone/default.nix b/modules/drone/default.nix index 48bc1e1..c6ef92c 100644 --- a/modules/drone/default.nix +++ b/modules/drone/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, flake -, ... -}: { +{ + config, + lib, + pkgs, + flake, + ... +}: +{ age.secrets.drone-secrets = { file = "${flake.self}/secrets/drone-secrets.age"; mode = "600"; @@ -26,9 +28,7 @@ users.groups.drone = { }; - systemd.tmpfiles.rules = [ - "d '/var/lib/drone-db' 0750 drone drone - -" - ]; + systemd.tmpfiles.rules = [ "d '/var/lib/drone-db' 0750 drone drone - -" ]; services.caddy.virtualHosts."ci.${config.pub-solar-os.networking.domain}" = { logFormat = lib.mkForce '' @@ -66,23 +66,15 @@ image = "postgres:14"; autoStart = true; user = "994"; - volumes = [ - "/var/lib/drone-db:/var/lib/postgresql/data" - ]; - extraOptions = [ - "--network=drone-net" - ]; - environmentFiles = [ - config.age.secrets.drone-db-secrets.path - ]; + volumes = [ "/var/lib/drone-db:/var/lib/postgresql/data" ]; + extraOptions = [ "--network=drone-net" ]; + environmentFiles = [ config.age.secrets.drone-db-secrets.path ]; }; containers."drone-server" = { image = "drone/drone:2"; autoStart = true; user = "994"; - ports = [ - "127.0.0.1:4000:80" - ]; + ports = [ "127.0.0.1:4000:80" ]; dependsOn = [ "drone-db" ]; extraOptions = [ "--network=drone-net" @@ -95,18 +87,14 @@ DRONE_SERVER_PROTO = "https"; DRONE_DATABASE_DRIVER = "postgres"; }; - environmentFiles = [ - config.age.secrets.drone-secrets.path - ]; + environmentFiles = [ config.age.secrets.drone-secrets.path ]; }; containers."drone-docker-runner" = { image = "drone/drone-runner-docker:1"; autoStart = true; # needs to run as root #user = "994"; - volumes = [ - "/var/run/docker.sock:/var/run/docker.sock" - ]; + volumes = [ "/var/run/docker.sock:/var/run/docker.sock" ]; dependsOn = [ "drone-db" ]; extraOptions = [ "--network=drone-net" @@ -119,9 +107,7 @@ DRONE_RUNNER_CAPACITY = "2"; DRONE_RUNNER_NAME = "flora-6-docker-runner"; }; - environmentFiles = [ - config.age.secrets.drone-secrets.path - ]; + environmentFiles = [ config.age.secrets.drone-secrets.path ]; }; }; }; diff --git a/modules/forgejo-actions-runner/default.nix b/modules/forgejo-actions-runner/default.nix index 045f0c2..0cd3c8e 100644 --- a/modules/forgejo-actions-runner/default.nix +++ b/modules/forgejo-actions-runner/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, flake -, ... -}: { +{ + config, + lib, + pkgs, + flake, + ... +}: +{ age.secrets.forgejo-actions-runner-token = { file = "${flake.self}/secrets/forgejo-actions-runner-token.age"; mode = "644"; @@ -20,7 +22,7 @@ isSystemUser = true; }; - users.groups.gitea-runner = {}; + users.groups.gitea-runner = { }; systemd.services."gitea-runner-flora\\x2d6".serviceConfig = { DynamicUser = lib.mkForce false; diff --git a/modules/forgejo/default.nix b/modules/forgejo/default.nix index 84218a7..7d8efc2 100644 --- a/modules/forgejo/default.nix +++ b/modules/forgejo/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, flake -, ... -}: { +{ + config, + lib, + pkgs, + flake, + ... +}: +{ age.secrets.forgejo-database-password = { file = "${flake.self}/secrets/forgejo-database-password.age"; mode = "600"; @@ -52,7 +54,7 @@ isSystemUser = true; }; - users.groups.gitea = {}; + users.groups.gitea = { }; # Expose SSH port only for forgejo SSH networking.firewall.interfaces.enp35s0.allowedTCPPorts = [ 2223 ]; diff --git a/modules/grafana/default.nix b/modules/grafana/default.nix index 9df0b73..e8fa718 100644 --- a/modules/grafana/default.nix +++ b/modules/grafana/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, flake -, ... -}: { +{ + config, + lib, + pkgs, + flake, + ... +}: +{ age.secrets.grafana-admin-password = { file = "${flake.self}/secrets/grafana-admin-password.age"; mode = "644"; diff --git a/modules/grafana/grafana-dashboards/node-exporter-full_rev33.json b/modules/grafana/grafana-dashboards/node-exporter-full_rev33.json index c28ea74..9df57f0 100644 --- a/modules/grafana/grafana-dashboards/node-exporter-full_rev33.json +++ b/modules/grafana/grafana-dashboards/node-exporter-full_rev33.json @@ -173,9 +173,7 @@ "options": { "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -261,9 +259,7 @@ "options": { "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -349,9 +345,7 @@ "options": { "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -427,9 +421,7 @@ "options": { "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -531,9 +523,7 @@ "options": { "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -617,9 +607,7 @@ "options": { "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -701,9 +689,7 @@ "justifyMode": "auto", "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -782,9 +768,7 @@ "justifyMode": "auto", "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -869,9 +853,7 @@ "justifyMode": "auto", "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -954,9 +936,7 @@ "justifyMode": "auto", "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -1037,9 +1017,7 @@ "justifyMode": "auto", "orientation": "horizontal", "reduceOptions": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "fields": "", "values": false }, @@ -2662,12 +2640,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -3169,12 +3142,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -3448,12 +3416,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -3563,12 +3526,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -3993,12 +3951,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -4220,12 +4173,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -4365,12 +4313,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -4498,12 +4441,7 @@ "id": 319, "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -4894,12 +4832,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -5284,12 +5217,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -5655,12 +5583,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -6084,12 +6007,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -6490,12 +6408,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -6917,12 +6830,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -7302,12 +7210,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -7687,12 +7590,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -8073,12 +7971,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -8443,12 +8336,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -8830,11 +8718,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "lastNotNull", - "max", - "min" - ], + "calcs": ["lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -9226,11 +9110,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "lastNotNull", - "max", - "min" - ], + "calcs": ["lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -9610,11 +9490,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "max", - "min" - ], + "calcs": ["mean", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -9993,12 +9869,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -10394,12 +10265,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -10535,12 +10401,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -10661,12 +10522,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -11050,12 +10906,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -11463,12 +11314,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -11609,12 +11455,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -11741,12 +11582,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -11860,12 +11696,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -11976,12 +11807,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -12119,12 +11945,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -12233,12 +12054,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -12336,12 +12152,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -12452,12 +12263,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -12614,12 +12420,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -12742,12 +12543,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -12878,12 +12674,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -13021,12 +12812,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -13136,12 +12922,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -13261,10 +13042,7 @@ { "id": "custom.lineStyle", "value": { - "dash": [ - 10, - 10 - ], + "dash": [10, 10], "fill": "dash" } }, @@ -13302,10 +13080,7 @@ { "id": "custom.lineStyle", "value": { - "dash": [ - 10, - 10 - ], + "dash": [10, 10], "fill": "dash" } }, @@ -13338,12 +13113,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -13540,12 +13310,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -13743,12 +13508,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -13845,12 +13605,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -13948,12 +13703,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -14049,12 +13799,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -14172,12 +13917,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -14352,12 +14092,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -14529,12 +14264,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -14645,12 +14375,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -14776,12 +14501,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -14954,12 +14674,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -15449,12 +15164,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -15874,12 +15584,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -16301,12 +16006,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -16719,12 +16419,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -17134,12 +16829,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -17548,12 +17238,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -17964,12 +17649,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -18367,12 +18047,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -18509,12 +18184,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -18640,12 +18310,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -18744,12 +18409,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -18859,12 +18519,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -18980,12 +18635,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -19194,12 +18844,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -19323,12 +18968,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -19450,12 +19090,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -19577,12 +19212,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -19704,12 +19334,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -19819,12 +19444,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -19946,12 +19566,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -20049,12 +19664,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -20164,12 +19774,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -20287,12 +19892,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -20401,12 +20001,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -20504,12 +20099,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -20607,12 +20197,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -20710,12 +20295,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -20824,12 +20404,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -20940,12 +20515,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21043,12 +20613,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21184,12 +20749,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21341,12 +20901,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21471,12 +21026,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21588,12 +21138,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21716,12 +21261,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21859,12 +21399,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -21975,12 +21510,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -22091,12 +21621,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -22219,12 +21744,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -22346,12 +21866,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -22461,12 +21976,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -22637,12 +22147,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -22755,12 +22260,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -22936,12 +22436,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -23067,12 +22562,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -23199,12 +22689,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -23312,12 +22797,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -23492,12 +22972,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -23619,12 +23094,7 @@ "links": [], "options": { "legend": { - "calcs": [ - "mean", - "lastNotNull", - "max", - "min" - ], + "calcs": ["mean", "lastNotNull", "max", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true @@ -23686,9 +23156,7 @@ "revision": 1, "schemaVersion": 38, "style": "dark", - "tags": [ - "linux" - ], + "tags": ["linux"], "templating": { "list": [ { @@ -23801,21 +23269,11 @@ "2h", "1d" ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] + "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] }, "timezone": "browser", "title": "Node Exporter Full", "uid": "rYdddlPWk", "version": 87, "weekStart": "" -} \ No newline at end of file +} diff --git a/modules/grafana/grafana-dashboards/synapse.json b/modules/grafana/grafana-dashboards/synapse.json index 30d6d87..db3c9dc 100644 --- a/modules/grafana/grafana-dashboards/synapse.json +++ b/modules/grafana/grafana-dashboards/synapse.json @@ -70,9 +70,7 @@ "icon": "external link", "includeVars": true, "keepTime": true, - "tags": [ - "matrix" - ], + "tags": ["matrix"], "title": "Dashboards", "type": "dashboards" } @@ -4313,9 +4311,7 @@ "id": "byNames", "options": { "mode": "exclude", - "names": [ - "libera.chat " - ], + "names": ["libera.chat "], "prefix": "All except:", "readOnly": true } @@ -4435,9 +4431,7 @@ "id": "byNames", "options": { "mode": "exclude", - "names": [ - "libera.chat" - ], + "names": ["libera.chat"], "prefix": "All except:", "readOnly": true } @@ -13266,9 +13260,7 @@ "refresh": false, "schemaVersion": 37, "style": "dark", - "tags": [ - "matrix" - ], + "tags": ["matrix"], "templating": { "list": [ { @@ -13453,17 +13445,7 @@ "2h", "1d" ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] + "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] }, "timezone": "", "title": "Synapse", diff --git a/modules/keycloak/default.nix b/modules/keycloak/default.nix index ebf11b2..0eec853 100644 --- a/modules/keycloak/default.nix +++ b/modules/keycloak/default.nix @@ -1,13 +1,15 @@ -{ flake -, config -, lib -, pkgs -, ... -}: { +{ + flake, + config, + lib, + pkgs, + ... +}: +{ options.pub-solar-os.auth = with lib; { - enable = mkEnableOption "Enable keycloak to run on the node"; + enable = mkEnableOption "Enable keycloak to run on the node"; - realm = mkOption { + realm = mkOption { description = "Name of the realm"; type = types.str; default = config.pub-solar-os.networking.domain; @@ -53,14 +55,13 @@ features = "declarative-user-profile"; }; themes = { - "pub.solar" = flake.inputs.keycloak-theme-pub-solar.legacyPackages.${pkgs.system}.keycloak-theme-pub-solar; + "pub.solar" = + flake.inputs.keycloak-theme-pub-solar.legacyPackages.${pkgs.system}.keycloak-theme-pub-solar; }; }; services.restic.backups.keycloak-droppie = { - paths = [ - "/tmp/keycloak-backup.sql" - ]; + paths = [ "/tmp/keycloak-backup.sql" ]; timerConfig = { OnCalendar = "*-*-* 02:00:00 Etc/UTC"; # droppie will be offline if nachtigall misses the timer @@ -83,9 +84,7 @@ }; services.restic.backups.keycloak-storagebox = { - paths = [ - "/tmp/keycloak-backup.sql" - ]; + paths = [ "/tmp/keycloak-backup.sql" ]; timerConfig = { OnCalendar = "*-*-* 04:10:00 Etc/UTC"; }; diff --git a/modules/loki/default.nix b/modules/loki/default.nix index 3aae445..cab6b8e 100644 --- a/modules/loki/default.nix +++ b/modules/loki/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, flake -, ... -}: { +{ + config, + lib, + pkgs, + flake, + ... +}: +{ services.caddy.virtualHosts = { "flora-6.${config.pub-solar-os.networking.domain}" = { logFormat = lib.mkForce '' @@ -51,16 +53,18 @@ retention_delete_worker_count = 150; }; schema_config = { - configs = [{ - from = "2020-05-15"; - store = "boltdb-shipper"; - object_store = "filesystem"; - schema = "v11"; - index = { - prefix = "index_"; - period = "24h"; - }; - }]; + configs = [ + { + from = "2020-05-15"; + store = "boltdb-shipper"; + object_store = "filesystem"; + schema = "v11"; + index = { + prefix = "index_"; + period = "24h"; + }; + } + ]; }; }; }; @@ -75,23 +79,29 @@ 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 = "journal"; - journal = { - max_age = "24h"; - labels = { - job = "systemd-journal"; - host = "flora-6"; + clients = [ + { + url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push"; + } + ]; + scrape_configs = [ + { + job_name = "journal"; + journal = { + max_age = "24h"; + labels = { + job = "systemd-journal"; + host = "flora-6"; + }; }; - }; - relabel_configs = [{ - source_labels = [ "__journal__systemd_unit" ]; - target_label = "unit"; - }]; - }]; + relabel_configs = [ + { + source_labels = [ "__journal__systemd_unit" ]; + target_label = "unit"; + } + ]; + } + ]; }; }; } diff --git a/modules/mailman/default.nix b/modules/mailman/default.nix index ff590b5..beb076e 100644 --- a/modules/mailman/default.nix +++ b/modules/mailman/default.nix @@ -1,8 +1,9 @@ -{ flake -, config -, lib -, pkgs -, ... +{ + flake, + config, + lib, + pkgs, + ... }: { networking.firewall.allowedTCPPorts = [ 25 ]; diff --git a/modules/mastodon/default.nix b/modules/mastodon/default.nix index d490440..fd22f18 100644 --- a/modules/mastodon/default.nix +++ b/modules/mastodon/default.nix @@ -1,4 +1,10 @@ -{ config, pkgs, flake, inputs, ... }: +{ + config, + pkgs, + flake, + inputs, + ... +}: { age.secrets."mastodon-secret-key-base" = { @@ -64,9 +70,7 @@ mediaAutoRemove = { olderThanDays = 7; }; - extraEnvFiles = [ - "/run/agenix/mastodon-extra-env-secrets" - ]; + extraEnvFiles = [ "/run/agenix/mastodon-extra-env-secrets" ]; extraConfig = { WEB_DOMAIN = "mastodon.${config.pub-solar-os.networking.domain}"; # Defined in ./opensearch.nix @@ -97,9 +101,7 @@ }; services.restic.backups.mastodon-droppie = { - paths = [ - "/tmp/mastodon-backup.sql" - ]; + paths = [ "/tmp/mastodon-backup.sql" ]; timerConfig = { OnCalendar = "*-*-* 02:00:00 Etc/UTC"; # droppie will be offline if nachtigall misses the timer @@ -122,9 +124,7 @@ }; services.restic.backups.mastodon-storagebox = { - paths = [ - "/tmp/mastodon-backup.sql" - ]; + paths = [ "/tmp/mastodon-backup.sql" ]; timerConfig = { OnCalendar = "*-*-* 04:05:00 Etc/UTC"; }; diff --git a/modules/matrix-irc/default.nix b/modules/matrix-irc/default.nix index e7b3597..f64d25c 100644 --- a/modules/matrix-irc/default.nix +++ b/modules/matrix-irc/default.nix @@ -1,15 +1,18 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: let # Find element in list config.services.matrix-synapse.settings.listeners.*.resources # that sets names = "client" nameHasClient = name: name == "client"; resourceHasClient = resource: builtins.any nameHasClient resource.names; - listenerWithClient = lib.findFirst - (listener: - builtins.any resourceHasClient listener.resources) - (throw "Found no matrix-synapse.settings.listeners.*.resources.*.names containing string client") - config.services.matrix-synapse.settings.listeners - ; + listenerWithClient = + lib.findFirst (listener: builtins.any resourceHasClient listener.resources) + (throw "Found no matrix-synapse.settings.listeners.*.resources.*.names containing string client") + config.services.matrix-synapse.settings.listeners; synapseClientPort = "${toString listenerWithClient.port}"; in { @@ -46,7 +49,11 @@ in }; metrics = { enabled = true; - remoteUserAgeBuckets = [ "1h" "1d" "1w" ]; + remoteUserAgeBuckets = [ + "1h" + "1d" + "1w" + ]; }; provisioning = { enabled = false; @@ -122,4 +129,3 @@ in }; }; } - diff --git a/modules/matrix-telegram/default.nix b/modules/matrix-telegram/default.nix index 2742a4f..dd2c4a0 100644 --- a/modules/matrix-telegram/default.nix +++ b/modules/matrix-telegram/default.nix @@ -1,4 +1,10 @@ -{ flake, lib, config, pkgs, ... }: +{ + flake, + lib, + config, + pkgs, + ... +}: { age.secrets."matrix-mautrix-telegram-env-file" = { file = "${flake.self}/secrets/matrix-mautrix-telegram-env-file.age"; diff --git a/modules/matrix/default.nix b/modules/matrix/default.nix index 433b7fa..da6c49d 100644 --- a/modules/matrix/default.nix +++ b/modules/matrix/default.nix @@ -1,4 +1,9 @@ -{ flake, config, pkgs, ... }: +{ + flake, + config, + pkgs, + ... +}: let publicDomain = "matrix.${config.pub-solar-os.networking.domain}"; serverDomain = "${config.pub-solar-os.networking.domain}"; @@ -40,22 +45,16 @@ in }; listeners = [ { - bind_addresses = [ - "127.0.0.1" - ]; + bind_addresses = [ "127.0.0.1" ]; port = 8008; resources = [ { compress = true; - names = [ - "client" - ]; + names = [ "client" ]; } { compress = false; - names = [ - "federation" - ]; + names = [ "federation" ]; } ]; tls = false; @@ -63,29 +62,23 @@ in x_forwarded = true; } { - bind_addresses = [ - "127.0.0.1" - ]; + bind_addresses = [ "127.0.0.1" ]; port = 8012; - resources = [ - { - names = [ - "metrics" - ]; - } - ]; + resources = [ { names = [ "metrics" ]; } ]; tls = false; type = "metrics"; } ]; account_threepid_delegates.msisdn = ""; - alias_creation_rules = [{ - action = "allow"; - alias = "*"; - room_id = "*"; - user_id = "*"; - }]; + alias_creation_rules = [ + { + action = "allow"; + alias = "*"; + room_id = "*"; + user_id = "*"; + } + ]; allow_guest_access = false; allow_public_rooms_over_federation = true; allow_public_rooms_without_auth = false; @@ -152,7 +145,7 @@ in }; per_user = { burst_count = 5; - per_second = 0.003; + per_second = 3.0e-3; }; }; rc_joins = { @@ -162,7 +155,7 @@ in }; remote = { burst_count = 10; - per_second = 0.01; + per_second = 1.0e-2; }; }; rc_login = { @@ -194,17 +187,19 @@ in registrations_require_3pid = [ "email" ]; report_stats = false; require_auth_for_profile_requests = false; - room_list_publication_rules = [{ - action = "allow"; - alias = "*"; - room_id = "*"; - user_id = "*"; - }]; + room_list_publication_rules = [ + { + action = "allow"; + alias = "*"; + room_id = "*"; + user_id = "*"; + } + ]; signing_key_path = "/run/agenix/matrix-synapse-signing-key"; stream_writers = { }; - trusted_key_servers = [{ server_name = "matrix.org"; }]; + trusted_key_servers = [ { server_name = "matrix.org"; } ]; suppress_key_server_warning = true; turn_allow_guests = false; @@ -276,9 +271,7 @@ in "redis" ]; - plugins = [ - config.services.matrix-synapse.package.plugins.matrix-synapse-shared-secret-auth - ]; + plugins = [ config.services.matrix-synapse.package.plugins.matrix-synapse-shared-secret-auth ]; sliding-sync = { enable = true; diff --git a/modules/matrix/matrix-log-config.yaml b/modules/matrix/matrix-log-config.yaml index 555f3aa..c7465ae 100644 --- a/modules/matrix/matrix-log-config.yaml +++ b/modules/matrix/matrix-log-config.yaml @@ -2,7 +2,7 @@ version: 1 formatters: precise: - format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + format: "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s" filters: context: diff --git a/modules/mediawiki/default.nix b/modules/mediawiki/default.nix index 0eca621..2205166 100644 --- a/modules/mediawiki/default.nix +++ b/modules/mediawiki/default.nix @@ -1,8 +1,9 @@ -{ flake -, config -, lib -, pkgs -, ... +{ + flake, + config, + lib, + pkgs, + ... }: let localSettingsPHP = pkgs.writeScript "LocalSettings.php" '' @@ -201,7 +202,9 @@ in group = "mediawiki"; inherit uid; }; - users.groups.mediawiki = { inherit gid; }; + users.groups.mediawiki = { + inherit gid; + }; virtualisation = { oci-containers = { @@ -212,9 +215,7 @@ in user = "1000:${builtins.toString gid}"; autoStart = true; - ports = [ - "127.0.0.1:8293:80" - ]; + ports = [ "127.0.0.1:8293:80" ]; extraOptions = [ "--add-host=host.docker.internal:host-gateway" diff --git a/modules/nextcloud/default.nix b/modules/nextcloud/default.nix index 1d47863..dc09b65 100644 --- a/modules/nextcloud/default.nix +++ b/modules/nextcloud/default.nix @@ -1,7 +1,8 @@ -{ config -, pkgs -, flake -, ... +{ + config, + pkgs, + flake, + ... }: { age.secrets."nextcloud-secrets" = { diff --git a/modules/nginx-mastodon-files/default.nix b/modules/nginx-mastodon-files/default.nix index ec93783..b549746 100644 --- a/modules/nginx-mastodon-files/default.nix +++ b/modules/nginx-mastodon-files/default.nix @@ -1,7 +1,4 @@ -{ - config, - ... -}: +{ config, ... }: let objStorHost = "link.tardigradeshare.io"; diff --git a/modules/nginx-mastodon/default.nix b/modules/nginx-mastodon/default.nix index 791974f..9209735 100644 --- a/modules/nginx-mastodon/default.nix +++ b/modules/nginx-mastodon/default.nix @@ -30,7 +30,12 @@ in }; locations."@proxy" = { - proxyPass = (if cfg.enableUnixSocket then "http://unix:/run/mastodon-web/web.socket" else "http://127.0.0.1:${toString(cfg.webPort)}"); + proxyPass = ( + if cfg.enableUnixSocket then + "http://unix:/run/mastodon-web/web.socket" + else + "http://127.0.0.1:${toString (cfg.webPort)}" + ); proxyWebsockets = true; }; @@ -45,13 +50,12 @@ in extraConfig = '' least_conn; ''; - servers = builtins.listToAttrs - (map - (i: { - name = "unix:/run/mastodon-streaming/streaming-${toString i}.socket"; - value = { }; - }) - (lib.range 1 cfg.streamingProcesses)); + servers = builtins.listToAttrs ( + map (i: { + name = "unix:/run/mastodon-streaming/streaming-${toString i}.socket"; + value = { }; + }) (lib.range 1 cfg.streamingProcesses) + ); }; }; } diff --git a/modules/nginx-matrix/default.nix b/modules/nginx-matrix/default.nix index a1f760e..0e236dc 100644 --- a/modules/nginx-matrix/default.nix +++ b/modules/nginx-matrix/default.nix @@ -1,4 +1,9 @@ -{ lib, pkgs, config, ... }: +{ + lib, + pkgs, + config, + ... +}: let commonHeaders = '' add_header Permissions-Policy interest-cohort=() always; @@ -71,9 +76,7 @@ in "chat.${config.pub-solar-os.networking.domain}" = { forceSSL = true; enableACME = true; - root = pkgs.element-web.override { - conf = clientConfig; - }; + root = pkgs.element-web.override { conf = clientConfig; }; }; "stickers.chat.${config.pub-solar-os.networking.domain}" = { @@ -126,16 +129,18 @@ in serverName = "matrix.${config.pub-solar-os.networking.domain}"; forceSSL = lib.mkDefault true; enableACME = lib.mkDefault true; - listen = [{ - port = 8448; - addr = "0.0.0.0"; - ssl = true; - } + listen = [ + { + port = 8448; + addr = "0.0.0.0"; + ssl = true; + } { port = 8448; addr = "[::]"; ssl = true; - }]; + } + ]; root = "/dev/null"; extraConfig = '' server_tokens off; @@ -159,4 +164,3 @@ in }; networking.firewall.allowedTCPPorts = [ 8448 ]; } - diff --git a/modules/nginx-matrix/element-client-config.nix b/modules/nginx-matrix/element-client-config.nix index 9c8607f..b3eaf9b 100644 --- a/modules/nginx-matrix/element-client-config.nix +++ b/modules/nginx-matrix/element-client-config.nix @@ -1,4 +1,5 @@ -{ pkgs, lib, ... }: { +{ pkgs, lib, ... }: +{ default_server_config = { "m.homeserver" = { base_url = "https://matrix.pub.solar"; @@ -35,10 +36,12 @@ homeUrl = ""; }; branding = { - auth_footer_links = [{ - text = "Privacy"; - url = "https://pub.solar/privacy"; - }]; + auth_footer_links = [ + { + text = "Privacy"; + url = "https://pub.solar/privacy"; + } + ]; # FUTUREWORK: Replace with pub.solar logo auth_header_logo_url = "themes/element/img/logos/element-logo.svg"; }; diff --git a/modules/nginx-prometheus-exporters/default.nix b/modules/nginx-prometheus-exporters/default.nix index 2edc969..391f782 100644 --- a/modules/nginx-prometheus-exporters/default.nix +++ b/modules/nginx-prometheus-exporters/default.nix @@ -1,13 +1,16 @@ -{ config, flake, lib, ... }: +{ + config, + flake, + lib, + ... +}: let # Find element in list config.services.matrix-synapse.settings.listeners # that sets type = "metrics" - listenerWithMetrics = lib.findFirst - (listener: - listener.type == "metrics") - (throw "Found no matrix-synapse.settings.listeners.*.type containing string metrics") - config.services.matrix-synapse.settings.listeners - ; + listenerWithMetrics = + lib.findFirst (listener: listener.type == "metrics") + (throw "Found no matrix-synapse.settings.listeners.*.type containing string metrics") + config.services.matrix-synapse.settings.listeners; synapseMetricsPort = "${toString listenerWithMetrics.port}"; in { @@ -22,7 +25,7 @@ in addSSL = true; basicAuthFile = "${config.age.secrets.nachtigall-metrics-nginx-basic-auth.path}"; locations."/metrics" = { - proxyPass = "http://127.0.0.1:${toString(config.services.prometheus.exporters.node.port)}"; + proxyPass = "http://127.0.0.1:${toString (config.services.prometheus.exporters.node.port)}"; }; locations."/_synapse/metrics" = { proxyPass = "http://127.0.0.1:${synapseMetricsPort}"; diff --git a/modules/nginx-website-miom/default.nix b/modules/nginx-website-miom/default.nix index dd01acd..2208464 100644 --- a/modules/nginx-website-miom/default.nix +++ b/modules/nginx-website-miom/default.nix @@ -1,9 +1,7 @@ { ... }: { - systemd.tmpfiles.rules = [ - "d '/srv/www/miom.space' 0750 hakkonaut hakkonaut - -" - ]; + systemd.tmpfiles.rules = [ "d '/srv/www/miom.space' 0750 hakkonaut hakkonaut - -" ]; services.nginx.virtualHosts = { "www.miom.space" = { diff --git a/modules/nginx-website/default.nix b/modules/nginx-website/default.nix index 03d2117..ebf1e8d 100644 --- a/modules/nginx-website/default.nix +++ b/modules/nginx-website/default.nix @@ -1,5 +1,5 @@ +{ lib, config, ... }: { - lib, config, ... }: { systemd.tmpfiles.rules = [ "d '/srv/www/${config.pub-solar-os.networking.domain}' 0750 hakkonaut hakkonaut - -" ]; @@ -54,7 +54,8 @@ }; # Responsible disclosure information https://securitytxt.org/ - "/.well-known/security.txt" = let + "/.well-known/security.txt" = + let securityTXT = lib.lists.foldr (a: b: a + "\n" + b) "" [ "Contact: mailto:admins@pub.solar" "Expires: 2025-01-04T23:00:00.000Z" @@ -62,12 +63,13 @@ "Preferred-Languages: en,de" "Canonical: https://${config.pub-solar-os.networking.domain}/.well-known/security.txt" ]; - in { - extraConfig = '' - add_header Content-Type text/plain; - return 200 '${securityTXT}'; - ''; - }; + in + { + extraConfig = '' + add_header Content-Type text/plain; + return 200 '${securityTXT}'; + ''; + }; "/satzung" = { extraConfig = '' diff --git a/modules/nginx/default.nix b/modules/nginx/default.nix index ff462d0..c836173 100644 --- a/modules/nginx/default.nix +++ b/modules/nginx/default.nix @@ -1,8 +1,9 @@ -{ config -, lib -, pkgs -, self -, ... +{ + config, + lib, + pkgs, + self, + ... }: let acmeEmailAddress = config.pub-solar-os.adminEmail; @@ -38,5 +39,8 @@ in defaults.email = acmeEmailAddress; }; - networking.firewall.allowedTCPPorts = [ 80 443 ]; + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; } diff --git a/modules/obs-portal/default.nix b/modules/obs-portal/default.nix index 5790663..e2733bf 100644 --- a/modules/obs-portal/default.nix +++ b/modules/obs-portal/default.nix @@ -1,29 +1,31 @@ -{ config -, lib -, pkgs -, self -, flake -, ... -}: let +{ + config, + lib, + pkgs, + self, + flake, + ... +}: +let configPy = pkgs.writeText "obs-portal-config.py" '' -DEBUG = False -VERBOSE = DEBUG -AUTO_RESTART = DEBUG -LEAN_MODE = False -FRONTEND_URL = None -FRONTEND_HTTPS = True -FRONTEND_DIR = "../frontend/build/" -FRONTEND_CONFIG = { - "imprintUrl": "${config.pub-solar-os.imprintUrl}", - "privacyPolicyUrl": "${config.pub-solar-os.privacyPolicyUrl}", - "mapHome": {"zoom": 12, "latitude": 50.93, "longitude": 6.97}, - "banner": { - "text": "This is an installation serving the Cologne/Bonn region run for Team OBSKöln by pub.solar n.e.V.", - "style": "info" - }, -} -TILES_FILE = None -ADDITIONAL_CORS_ORIGINS = None + DEBUG = False + VERBOSE = DEBUG + AUTO_RESTART = DEBUG + LEAN_MODE = False + FRONTEND_URL = None + FRONTEND_HTTPS = True + FRONTEND_DIR = "../frontend/build/" + FRONTEND_CONFIG = { + "imprintUrl": "${config.pub-solar-os.imprintUrl}", + "privacyPolicyUrl": "${config.pub-solar-os.privacyPolicyUrl}", + "mapHome": {"zoom": 12, "latitude": 50.93, "longitude": 6.97}, + "banner": { + "text": "This is an installation serving the Cologne/Bonn region run for Team OBSKöln by pub.solar n.e.V.", + "style": "info" + }, + } + TILES_FILE = None + ADDITIONAL_CORS_ORIGINS = None ''; env = { @@ -41,7 +43,8 @@ ADDITIONAL_CORS_ORIGINS = None OBS_DATA_DIR = "/data"; OBS_PROXIES_COUNT = "1"; }; -in { +in +{ age.secrets.obs-portal-env = { file = "${flake.self}/secrets/obs-portal-env.age"; mode = "600"; @@ -59,8 +62,16 @@ in { in { serviceConfig.Type = "oneshot"; - before = [ "docker-obs-portal.service" "docker-obs-portal-db.service" "docker-obs-portal-worker.service" ]; - requiredBy = [ "docker-obs-portal.service" "docker-obs-portal-db.service" "docker-obs-portal-worker.service" ]; + before = [ + "docker-obs-portal.service" + "docker-obs-portal-db.service" + "docker-obs-portal-worker.service" + ]; + requiredBy = [ + "docker-obs-portal.service" + "docker-obs-portal-db.service" + "docker-obs-portal-worker.service" + ]; script = '' ${dockerBin} network inspect obs-portal-net >/dev/null 2>&1 || ${dockerBin} network create obs-portal-net --subnet 172.20.0.0/24 ''; @@ -101,16 +112,17 @@ in { "/var/lib/obs-portal/pbf/:/pbf" ]; - extraOptions = [ - "--network=obs-portal-net" - ]; + extraOptions = [ "--network=obs-portal-net" ]; }; containers."obs-portal-worker" = { image = "git.pub.solar/pub-solar/obs-portal:latest"; autoStart = true; - cmd = [ "python" "tools/process_track.py" ]; + cmd = [ + "python" + "tools/process_track.py" + ]; environment = env; environmentFiles = [ config.age.secrets.obs-portal-env.path ]; @@ -120,9 +132,7 @@ in { "/var/lib/obs-portal${env.OBS_DATA_DIR}:${env.OBS_DATA_DIR}" ]; - extraOptions = [ - "--network=obs-portal-net" - ]; + extraOptions = [ "--network=obs-portal-net" ]; }; containers."obs-portal-db" = { @@ -131,13 +141,9 @@ in { environmentFiles = [ config.age.secrets.obs-portal-database-env.path ]; - volumes = [ - "/var/lib/postgres-obs-portal/data:/var/lib/postgresql/data" - ]; + volumes = [ "/var/lib/postgres-obs-portal/data:/var/lib/postgresql/data" ]; - extraOptions = [ - "--network=obs-portal-net" - ]; + extraOptions = [ "--network=obs-portal-net" ]; }; }; }; diff --git a/modules/owncast/default.nix b/modules/owncast/default.nix index 5512c3c..1752a5e 100644 --- a/modules/owncast/default.nix +++ b/modules/owncast/default.nix @@ -1,9 +1,11 @@ -{ flake -, config -, lib -, pkgs -, ... -}: { +{ + flake, + config, + lib, + pkgs, + ... +}: +{ services.nginx.virtualHosts."stream.${config.pub-solar-os.networking.domain}" = { enableACME = true; forceSSL = true; diff --git a/modules/postgresql/default.nix b/modules/postgresql/default.nix index 5ab56c6..2980bb0 100644 --- a/modules/postgresql/default.nix +++ b/modules/postgresql/default.nix @@ -7,11 +7,7 @@ }; systemd.services.postgresql = { - after = [ - "var-lib-postgresql.mount" - ]; - requisite = [ - "var-lib-postgresql.mount" - ]; + after = [ "var-lib-postgresql.mount" ]; + requisite = [ "var-lib-postgresql.mount" ]; }; } diff --git a/modules/prometheus-exporters/default.nix b/modules/prometheus-exporters/default.nix index 585474a..996a771 100644 --- a/modules/prometheus-exporters/default.nix +++ b/modules/prometheus-exporters/default.nix @@ -1,6 +1,5 @@ -{ config -, ... -}: { +{ config, ... }: +{ services.prometheus = { exporters = { node = { diff --git a/modules/prometheus/default.nix b/modules/prometheus/default.nix index 5b0356c..de5d88b 100644 --- a/modules/prometheus/default.nix +++ b/modules/prometheus/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, flake -, ... -}: { +{ + config, + lib, + pkgs, + flake, + ... +}: +{ age.secrets.nachtigall-metrics-prometheus-basic-auth-password = { file = "${flake.self}/secrets/nachtigall-metrics-prometheus-basic-auth-password.age"; mode = "600"; @@ -27,12 +29,14 @@ scrapeConfigs = [ { job_name = "node-exporter-http"; - static_configs = [{ - targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ]; - labels = { - instance = "flora-6"; - }; - }]; + static_configs = [ + { + targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ]; + labels = { + instance = "flora-6"; + }; + } + ]; } { job_name = "node-exporter-https"; @@ -42,12 +46,14 @@ username = "hakkonaut"; password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}"; }; - static_configs = [{ - targets = [ "nachtigall.${config.pub-solar-os.networking.domain}" ]; - labels = { - instance = "nachtigall"; - }; - }]; + static_configs = [ + { + targets = [ "nachtigall.${config.pub-solar-os.networking.domain}" ]; + labels = { + instance = "nachtigall"; + }; + } + ]; } { job_name = "matrix-synapse"; @@ -57,12 +63,14 @@ username = "hakkonaut"; password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}"; }; - static_configs = [{ - targets = [ "nachtigall.${config.pub-solar-os.networking.domain}" ]; - labels = { - instance = "nachtigall"; - }; - }]; + static_configs = [ + { + targets = [ "nachtigall.${config.pub-solar-os.networking.domain}" ]; + labels = { + instance = "nachtigall"; + }; + } + ]; } ]; }; diff --git a/modules/promtail/default.nix b/modules/promtail/default.nix index 8ffc9bb..2e65a28 100644 --- a/modules/promtail/default.nix +++ b/modules/promtail/default.nix @@ -1,9 +1,11 @@ -{ config -, lib -, pkgs -, flake -, ... -}: { +{ + config, + lib, + pkgs, + flake, + ... +}: +{ age.secrets.nachtigall-metrics-prometheus-basic-auth-password = { file = "${flake.self}/secrets/nachtigall-metrics-prometheus-basic-auth-password.age"; mode = "600"; @@ -20,27 +22,33 @@ positions = { filename = "/tmp/positions.yaml"; }; - clients = [{ - url = "https://flora-6.${config.pub-solar-os.networking.domain}/loki/api/v1/push"; - basic_auth = { - username = "hakkonaut"; - password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}"; - }; - }]; - scrape_configs = [{ - job_name = "journal"; - journal = { - max_age = "24h"; - labels = { - job = "systemd-journal"; - host = "nachtigall"; + clients = [ + { + url = "https://flora-6.${config.pub-solar-os.networking.domain}/loki/api/v1/push"; + basic_auth = { + username = "hakkonaut"; + password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}"; }; - }; - relabel_configs = [{ - source_labels = [ "__journal__systemd_unit" ]; - target_label = "unit"; - }]; - }]; + } + ]; + scrape_configs = [ + { + job_name = "journal"; + journal = { + max_age = "24h"; + labels = { + job = "systemd-journal"; + host = "nachtigall"; + }; + }; + relabel_configs = [ + { + source_labels = [ "__journal__systemd_unit" ]; + target_label = "unit"; + } + ]; + } + ]; }; }; } diff --git a/modules/searx/default.nix b/modules/searx/default.nix index d4c3b73..1c31f15 100644 --- a/modules/searx/default.nix +++ b/modules/searx/default.nix @@ -1,8 +1,9 @@ -{ flake -, config -, lib -, pkgs -, ... +{ + flake, + config, + lib, + pkgs, + ... }: { age.secrets.searx-environment = { @@ -64,9 +65,18 @@ }; engine = [ - { engine = "startpage"; disabled = false; } - { engine = "yahoo"; disabled = false; } - { engine = "tagesschau"; disabled = false; } + { + engine = "startpage"; + disabled = false; + } + { + engine = "yahoo"; + disabled = false; + } + { + engine = "tagesschau"; + disabled = false; + } ]; ui = { diff --git a/modules/tmate/default.nix b/modules/tmate/default.nix index 18a4c1d..a478441 100644 --- a/modules/tmate/default.nix +++ b/modules/tmate/default.nix @@ -1,4 +1,4 @@ -{ config,... }: +{ config, ... }: { services.tmate-ssh-server = { enable = true; diff --git a/modules/unlock-zfs-on-boot/default.nix b/modules/unlock-zfs-on-boot/default.nix index 7fade1b..2e68b39 100644 --- a/modules/unlock-zfs-on-boot/default.nix +++ b/modules/unlock-zfs-on-boot/default.nix @@ -1,4 +1,5 @@ -{ flake, config, ... }: { +{ flake, config, ... }: +{ # From https://nixos.wiki/wiki/ZFS#Unlock_encrypted_zfs_via_ssh_on_boot boot.initrd.network = { enable = true; diff --git a/overlays/default.nix b/overlays/default.nix index da437e5..5807ce8 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,24 +1,27 @@ -{ self -, inputs -, ... -}: { +{ self, inputs, ... }: +{ flake = { nixosModules = rec { - overlays = ({ ... }: { - nixpkgs.overlays = [ - (final: prev: - let - unstable = import inputs.unstable { - system = prev.system; - }; - in - { - forgejo-runner = unstable.forgejo-runner; - element-themes = prev.callPackage ./pkgs/element-themes { inherit (inputs) element-themes; }; - element-stickerpicker = prev.callPackage ./pkgs/element-stickerpicker { inherit (inputs) element-stickers maunium-stickerpicker; }; - }) - ]; - }); + overlays = ( + { ... }: + { + nixpkgs.overlays = [ + ( + final: prev: + let + unstable = import inputs.unstable { system = prev.system; }; + in + { + forgejo-runner = unstable.forgejo-runner; + element-themes = prev.callPackage ./pkgs/element-themes { inherit (inputs) element-themes; }; + element-stickerpicker = prev.callPackage ./pkgs/element-stickerpicker { + inherit (inputs) element-stickers maunium-stickerpicker; + }; + } + ) + ]; + } + ); }; }; } diff --git a/overlays/pkgs/element-stickerpicker/default.nix b/overlays/pkgs/element-stickerpicker/default.nix index 53489d0..b13b271 100644 --- a/overlays/pkgs/element-stickerpicker/default.nix +++ b/overlays/pkgs/element-stickerpicker/default.nix @@ -1,4 +1,8 @@ -{ stdenvNoCC, element-stickers, maunium-stickerpicker }: +{ + stdenvNoCC, + element-stickers, + maunium-stickerpicker, +}: stdenvNoCC.mkDerivation { src = maunium-stickerpicker; name = "element-stickers"; diff --git a/overlays/pkgs/element-themes/default.nix b/overlays/pkgs/element-themes/default.nix index c8a1a59..46d4937 100644 --- a/overlays/pkgs/element-themes/default.nix +++ b/overlays/pkgs/element-themes/default.nix @@ -1,4 +1,8 @@ -{ stdenvNoCC, jq, element-themes }: +{ + stdenvNoCC, + jq, + element-themes, +}: stdenvNoCC.mkDerivation { src = element-themes; name = "element-themes"; diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 9c40bfb..94a3b11 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -4,15 +4,13 @@ let nachtigall-host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP7G0ufi+MNvaAZLDgpieHrABPGN7e/kD5kMFwSk4ABj root@nachtigall"; flora-6-host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGP1InpTBN4AlF/4V8HHumAMLJzeO8DpzjUv9Co/+J09 root@flora-6"; - adminKeys = builtins.foldl' (keys: login: keys ++ (builtins.attrValues login.secretEncryptionKeys)) [] (builtins.attrValues admins); + adminKeys = builtins.foldl' ( + keys: login: keys ++ (builtins.attrValues login.secretEncryptionKeys) + ) [ ] (builtins.attrValues admins); - nachtigallKeys = [ - nachtigall-host - ]; + nachtigallKeys = [ nachtigall-host ]; - flora6Keys = [ - flora-6-host - ]; + flora6Keys = [ flora-6-host ]; in { # ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBB5XaH02a6+TchnyQED2VwaltPgeFCbildbE2h6nF5e root@nachtigall @@ -63,7 +61,8 @@ in "grafana-smtp-password.age".publicKeys = flora6Keys ++ adminKeys; "nachtigall-metrics-nginx-basic-auth.age".publicKeys = nachtigallKeys ++ adminKeys; - "nachtigall-metrics-prometheus-basic-auth-password.age".publicKeys = flora6Keys ++ nachtigallKeys ++ adminKeys; + "nachtigall-metrics-prometheus-basic-auth-password.age".publicKeys = + flora6Keys ++ nachtigallKeys ++ adminKeys; "obs-portal-env.age".publicKeys = nachtigallKeys ++ adminKeys; "obs-portal-database-env.age".publicKeys = nachtigallKeys ++ adminKeys; diff --git a/tests/website.nix b/tests/website.nix index dffd6a5..dc33aff 100644 --- a/tests/website.nix +++ b/tests/website.nix @@ -4,7 +4,8 @@ lib, config, ... -}: { +}: +{ name = "website"; nodes.nachtigall-test = self.nixosConfigurations.nachtigall-test;