From 4fba0c9ddb3476fac672a1b4cf6a50fb04aaafa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Mon, 18 Nov 2024 16:13:05 +0000 Subject: [PATCH 1/2] use nixfmt --- checks/default.nix | 74 +++++++++++++++++++++++-------------------- formatter/default.nix | 58 +++++++++++++++++---------------- 2 files changed, 71 insertions(+), 61 deletions(-) diff --git a/checks/default.nix b/checks/default.nix index 6e0445d..98a7ae9 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -1,42 +1,48 @@ -{inputs, ...}: { +{ + inputs, + ... +}: +{ imports = [ ./vmTests.nix ./licenses.nix ]; - perSystem = { - pkgs, - config, - ... - }: { - apps = { - nix-build-all.program = pkgs.writeShellApplication { - name = "nix-build-all"; - runtimeInputs = [ - (pkgs.callPackage inputs.devour-flake {}) - ]; - text = '' - # Make sure that flake.lock is sync - nix flake lock --no-update-lock-file + perSystem = + { + pkgs, + config, + ... + }: + { + apps = { + nix-build-all.program = pkgs.writeShellApplication { + name = "nix-build-all"; + runtimeInputs = [ + (pkgs.callPackage inputs.devour-flake { }) + ]; + text = '' + # Make sure that flake.lock is sync + nix flake lock --no-update-lock-file - # Do a full nix build (all outputs) - devour-flake . "$@" - ''; + # Do a full nix build (all outputs) + devour-flake . "$@" + ''; + }; }; - }; - devshells.default.commands = [ - { - category = "tests"; - name = "build-all"; - help = "build all packages and checks with `devour-flake`"; - command = config.apps.nix-build-all.program; - } - { - category = "tests"; - name = "check"; - help = "run `nix flake check`"; - command = "nix flake check"; - } - ]; - }; + devshells.default.commands = [ + { + category = "tests"; + name = "build-all"; + help = "build all packages and checks with `devour-flake`"; + command = config.apps.nix-build-all.program; + } + { + category = "tests"; + name = "check"; + help = "run `nix flake check`"; + command = "nix flake check"; + } + ]; + }; } diff --git a/formatter/default.nix b/formatter/default.nix index a9f8786..03b9677 100644 --- a/formatter/default.nix +++ b/formatter/default.nix @@ -1,35 +1,39 @@ -{inputs, ...}: { +{ inputs, ... }: +{ imports = [ inputs.flake-root.flakeModule inputs.treefmt-nix.flakeModule ]; - perSystem = { - config, - pkgs, - lib, - ... - }: { - treefmt.config = { - inherit (config.flake-root) projectRootFile; - package = pkgs.treefmt; - flakeFormatter = true; - flakeCheck = true; - programs = { - alejandra.enable = true; - deadnix.enable = true; - prettier.enable = true; - statix.enable = true; + perSystem = + { + config, + pkgs, + lib, + ... + }: + { + treefmt.config = { + inherit (config.flake-root) projectRootFile; + package = pkgs.treefmt; + flakeFormatter = true; + flakeCheck = true; + programs = { + nixfmt.enable = true; + deadnix.enable = true; + prettier.enable = true; + statix.enable = true; + }; + settings.formatter.nixfmt.options = [ "--width=65536" ]; }; - }; - devshells.default.commands = [ - { - category = "tools"; - name = "fmt"; - help = "format the source tree"; - command = lib.getExe config.treefmt.build.wrapper; - } - ]; - }; + devshells.default.commands = [ + { + category = "tools"; + name = "fmt"; + help = "format the source tree"; + command = lib.getExe config.treefmt.build.wrapper; + } + ]; + }; } From 47f57549525032753f0aa371bef9a51fc5feed0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Mon, 18 Nov 2024 16:13:19 +0000 Subject: [PATCH 2/2] fmt --- checks/licenses.nix | 29 ++-- checks/run-vm-test.nix | 2 +- checks/vmTests.nix | 262 ++++++++++++++-------------- ci/default.nix | 28 +-- configurations/default.nix | 7 +- configurations/full.nix | 5 +- configurations/vm.nix | 56 +++++- docs/default.nix | 70 ++++---- docs/render.nix | 299 +++++++++++++++++--------------- flake.nix | 7 +- modules/blockfrost.nix | 18 +- modules/cardano.nix | 6 +- modules/cli.nix | 5 +- modules/db-sync.nix | 30 +++- modules/default.nix | 16 +- modules/http.nix | 10 +- modules/kupo.nix | 33 ++-- modules/monitoring.nix | 34 ++-- modules/node.nix | 31 ++-- modules/ogmios.nix | 21 +-- modules/oura.nix | 27 +-- modules/services/http-proxy.nix | 88 ++++++---- modules/services/kupo.nix | 100 ++++++++--- modules/services/ogmios.nix | 49 ++++-- modules/services/oura.nix | 30 ++-- packages/cardano.nix | 13 +- packages/default.nix | 11 +- packages/kupo.nix | 17 +- packages/ogmios.nix | 17 +- packages/oura.nix | 30 ++-- shell/default.nix | 67 +++---- templates/cluster/flake.nix | 127 ++++++++------ templates/cluster/preview.nix | 3 +- templates/cluster/proxy.nix | 8 +- templates/cluster/status.nix | 8 +- templates/cluster/vm.nix | 3 +- templates/default/flake.nix | 32 ++-- templates/default/vm.nix | 3 +- tests/blockfrost.nix | 55 +++--- tests/db-sync.nix | 74 ++++---- tests/http.nix | 46 ++--- tests/kupo.nix | 49 +++--- tests/load-balancer.nix | 56 +++--- tests/monitoring.nix | 21 ++- tests/node.nix | 40 +++-- tests/ogmios.nix | 49 +++--- tests/oura.nix | 121 +++++++------ 47 files changed, 1225 insertions(+), 888 deletions(-) mode change 120000 => 100644 configurations/vm.nix diff --git a/checks/licenses.nix b/checks/licenses.nix index 55ad124..43b8288 100644 --- a/checks/licenses.nix +++ b/checks/licenses.nix @@ -1,14 +1,19 @@ -{self, ...}: { - perSystem = {pkgs, ...}: { - checks = { - reuse = - pkgs.runCommandLocal "reuse-lint" { - buildInputs = [pkgs.reuse]; - } '' - cd ${self} - reuse --suppress-deprecation lint - touch $out - ''; +{ self, ... }: +{ + perSystem = + { pkgs, ... }: + { + checks = { + reuse = + pkgs.runCommandLocal "reuse-lint" + { + buildInputs = [ pkgs.reuse ]; + } + '' + cd ${self} + reuse --suppress-deprecation lint + touch $out + ''; + }; }; - }; } diff --git a/checks/run-vm-test.nix b/checks/run-vm-test.nix index e18b510..e3d00f9 100644 --- a/checks/run-vm-test.nix +++ b/checks/run-vm-test.nix @@ -8,7 +8,7 @@ writeShellApplication { name = "run-vm-test"; - runtimeInputs = []; + runtimeInputs = [ ]; text = '' cmd_name=$(basename "$0") diff --git a/checks/vmTests.nix b/checks/vmTests.nix index 67f41c4..51b7275 100644 --- a/checks/vmTests.nix +++ b/checks/vmTests.nix @@ -4,145 +4,139 @@ config, withSystem, ... -}: let - inherit (lib) mkOption types mapAttrs' nameValuePair; +}: +let + inherit (lib) + mkOption + types + mapAttrs' + nameValuePair + ; inherit (config.flake) nixosModules; -in { - perSystem = { - config, - lib, - system, - pkgs, - ... - }: let - cfg = config.vmTests; - in { - options.vmTests = { - tests = mkOption { - description = "Run integration tests in networks of virtual machines."; - type = types.lazyAttrsOf (types.submodule ({config, ...}: { - options = { - name = mkOption { - description = "The name of the test. Defaults to attribute name."; - internal = true; - type = types.str; - default = config._module.args.name; - }; - systems = mkOption { - description = "The systems to run the test on."; - type = types.listOf types.str; - default = ["x86_64-linux"]; - }; - module = mkOption { - description = "The NixOS test module. Required. See https://nixos.org/manual/nixos/stable/#sec-nixos-tests ."; - type = types.deferredModule; - }; - impure = mkOption { - description = "Wether the test requires internet access and should be run as an effect instead of a nix build."; - type = types.bool; - default = false; - }; - check = mkOption { - description = "The test derivation. Result of calling `_mkCheck` with this test."; - type = types.package; - default = cfg._mkCheck config; - }; - effect = mkOption { - description = "The test hercules-ci-effect. Result of calling `_mkEffect` with this test."; - type = types.package; - default = cfg._mkEffect config; - }; - }; - })); - }; - runVmTestScript = mkOption { - description = "Script that lists and runs integration tests on networks of virtual machines."; - type = types.package; - default = pkgs.callPackage ./run-vm-test.nix {inherit (cfg) tests;}; - }; - _nixosLib = mkOption { - description = "Convenience access to `nixpkgs/nixos/lib`."; - internal = true; - type = types.anything; - default = import (inputs.nixpkgs.outPath + "/nixos/lib") {}; - }; - _mkCheck = mkOption { - description = "Function that takes a test `module` and returns a derivation that runs the test when built."; - internal = true; - type = types.functionTo types.package; - default = test: - (cfg._nixosLib.runTest { - name = lib.mkDefault test.name; - imports = [test.module]; - hostPkgs = pkgs; - defaults = { - imports = [ - # Import all of our NixOS modules by default. - nixosModules.default - # Fix missing `pkgs.system` in tests. - {nixpkgs.overlays = [(_: _: {inherit system;})];} - ]; - documentation.enable = lib.mkDefault false; - }; - }) - .config - .result; - }; - _mkEffect = mkOption { - description = "Function that takes a test `module` and returns a Hercules CI effect that runs the test."; - internal = true; - type = types.functionTo types.package; - default = testModule: - withSystem system ({hci-effects, ...}: - hci-effects.modularEffect { - mounts."/dev/kvm" = "kvm"; - effectScript = '' - ${testModule.check.driver}/bin/nixos-test-driver - ''; - }); +in +{ + perSystem = + { + config, + lib, + system, + pkgs, + ... + }: + let + cfg = config.vmTests; + in + { + options.vmTests = { + tests = mkOption { + description = "Run integration tests in networks of virtual machines."; + type = types.lazyAttrsOf ( + types.submodule ( + { config, ... }: + { + options = { + name = mkOption { + description = "The name of the test. Defaults to attribute name."; + internal = true; + type = types.str; + default = config._module.args.name; + }; + systems = mkOption { + description = "The systems to run the test on."; + type = types.listOf types.str; + default = [ "x86_64-linux" ]; + }; + module = mkOption { + description = "The NixOS test module. Required. See https://nixos.org/manual/nixos/stable/#sec-nixos-tests ."; + type = types.deferredModule; + }; + impure = mkOption { + description = "Wether the test requires internet access and should be run as an effect instead of a nix build."; + type = types.bool; + default = false; + }; + check = mkOption { + description = "The test derivation. Result of calling `_mkCheck` with this test."; + type = types.package; + default = cfg._mkCheck config; + }; + effect = mkOption { + description = "The test hercules-ci-effect. Result of calling `_mkEffect` with this test."; + type = types.package; + default = cfg._mkEffect config; + }; + }; + } + ) + ); + }; + runVmTestScript = mkOption { + description = "Script that lists and runs integration tests on networks of virtual machines."; + type = types.package; + default = pkgs.callPackage ./run-vm-test.nix { inherit (cfg) tests; }; + }; + _nixosLib = mkOption { + description = "Convenience access to `nixpkgs/nixos/lib`."; + internal = true; + type = types.anything; + default = import (inputs.nixpkgs.outPath + "/nixos/lib") { }; + }; + _mkCheck = mkOption { + description = "Function that takes a test `module` and returns a derivation that runs the test when built."; + internal = true; + type = types.functionTo types.package; + default = + test: + (cfg._nixosLib.runTest { + name = lib.mkDefault test.name; + imports = [ test.module ]; + hostPkgs = pkgs; + defaults = { + imports = [ + # Import all of our NixOS modules by default. + nixosModules.default + # Fix missing `pkgs.system` in tests. + { nixpkgs.overlays = [ (_: _: { inherit system; }) ]; } + ]; + documentation.enable = lib.mkDefault false; + }; + }).config.result; + }; + _mkEffect = mkOption { + description = "Function that takes a test `module` and returns a Hercules CI effect that runs the test."; + internal = true; + type = types.functionTo types.package; + default = + testModule: + withSystem system ( + { hci-effects, ... }: + hci-effects.modularEffect { + mounts."/dev/kvm" = "kvm"; + effectScript = '' + ${testModule.check.driver}/bin/nixos-test-driver + ''; + } + ); + }; }; - }; - config = { - checks = - mapAttrs' - (name: test: - nameValuePair - "vmTests-${test.name}" - test.check) - (lib.filterAttrs - (_: v: lib.elem system v.systems && !v.impure) - cfg.tests); + config = { + checks = mapAttrs' (name: test: nameValuePair "vmTests-${test.name}" test.check) (lib.filterAttrs (_: v: lib.elem system v.systems && !v.impure) cfg.tests); - apps = - {run-vm-tests.program = lib.getExe cfg.runVmTestScript;} - // mapAttrs' - (name: test: - nameValuePair - "vmTests-${test.name}" - {program = "${test.check.driver}/bin/nixos-test-driver";}) - (lib.filterAttrs - (_: v: lib.elem system v.systems) - cfg.tests); + apps = { + run-vm-tests.program = lib.getExe cfg.runVmTestScript; + } // mapAttrs' (name: test: nameValuePair "vmTests-${test.name}" { program = "${test.check.driver}/bin/nixos-test-driver"; }) (lib.filterAttrs (_: v: lib.elem system v.systems) cfg.tests); - devshells.default.commands = [ - { - name = "run-vm-test"; - category = "tests"; - help = "list and run virtual machine integration tests"; - command = "${lib.getExe cfg.runVmTestScript} $@"; - } - ]; + devshells.default.commands = [ + { + name = "run-vm-test"; + category = "tests"; + help = "list and run virtual machine integration tests"; + command = "${lib.getExe cfg.runVmTestScript} $@"; + } + ]; + }; }; - }; - herculesCI.onPush.default.outputs.effects = - mapAttrs' - (name: test: - nameValuePair - "vmTests-${test.name}" - test.effect) - (lib.filterAttrs - (_: v: lib.elem config.defaultEffectSystem v.systems && v.impure) - (config.perSystem config.defaultEffectSystem).vmTests.tests); + herculesCI.onPush.default.outputs.effects = mapAttrs' (name: test: nameValuePair "vmTests-${test.name}" test.effect) (lib.filterAttrs (_: v: lib.elem config.defaultEffectSystem v.systems && v.impure) (config.perSystem config.defaultEffectSystem).vmTests.tests); } diff --git a/ci/default.nix b/ci/default.nix index 6dfa934..8708bd9 100644 --- a/ci/default.nix +++ b/ci/default.nix @@ -3,7 +3,8 @@ inputs, lib, ... -}: { +}: +{ imports = [ inputs.hercules-ci-effects.flakeModule "${inputs.hercules-ci-effects}/effects/push-cache/default.nix" @@ -19,9 +20,11 @@ }; }; - perSystem = {config, ...}: { - hercules-ci.github-pages.settings.contents = config.packages.docs; - }; + perSystem = + { config, ... }: + { + hercules-ci.github-pages.settings.contents = config.packages.docs; + }; push-cache-effect = { enable = true; @@ -29,16 +32,15 @@ mlabs-cardano-nix = { type = "attic"; secretName = "cardano-nix-cache-push-token"; - packages = with lib; + packages = + with lib; flatten [ - (forEach ["apps" "devShells" "packages"] - (attr: - forEach config.systems - (system: - collect isDerivation (config.flake.${attr}.${system} or {})))) - (forEach (attrValues config.flake.nixosConfigurations) - (os: - os.config.system.build.toplevel)) + (forEach [ + "apps" + "devShells" + "packages" + ] (attr: forEach config.systems (system: collect isDerivation (config.flake.${attr}.${system} or { })))) + (forEach (attrValues config.flake.nixosConfigurations) (os: os.config.system.build.toplevel)) ]; }; }; diff --git a/configurations/default.nix b/configurations/default.nix index 25959c6..1958f3c 100644 --- a/configurations/default.nix +++ b/configurations/default.nix @@ -2,14 +2,15 @@ self, inputs, ... -}: { +}: +{ flake.nixosConfigurations = { vm-preview = inputs.nixpkgs.lib.nixosSystem { modules = [ self.nixosModules.default ./preview.nix ./vm.nix - {nixpkgs.hostPlatform = "x86_64-linux";} + { nixpkgs.hostPlatform = "x86_64-linux"; } ]; }; vm-full = inputs.nixpkgs.lib.nixosSystem { @@ -17,7 +18,7 @@ self.nixosModules.default ./full.nix ./vm.nix - {nixpkgs.hostPlatform = "x86_64-linux";} + { nixpkgs.hostPlatform = "x86_64-linux"; } ]; }; }; diff --git a/configurations/full.nix b/configurations/full.nix index 2e5d8e0..15f176c 100644 --- a/configurations/full.nix +++ b/configurations/full.nix @@ -12,7 +12,10 @@ # monitoring.hosts = [ "localhost" ]; }; - networking.firewall.allowedTCPPorts = [3000 9090]; + networking.firewall.allowedTCPPorts = [ + 3000 + 9090 + ]; virtualisation.memorySize = 8192; diff --git a/configurations/vm.nix b/configurations/vm.nix deleted file mode 120000 index c7902da..0000000 --- a/configurations/vm.nix +++ /dev/null @@ -1 +0,0 @@ -../templates/default/vm.nix \ No newline at end of file diff --git a/configurations/vm.nix b/configurations/vm.nix new file mode 100644 index 0000000..c6cc1fb --- /dev/null +++ b/configurations/vm.nix @@ -0,0 +1,55 @@ +{ + lib, + modulesPath, + ... +}: +{ + imports = [ + "${modulesPath}/virtualisation/qemu-vm.nix" + "${modulesPath}/profiles/qemu-guest.nix" + ]; + + swapDevices = [ + { + device = "/swapfile"; + size = 4 * 1024; + } + ]; + + # WARNING: don't use this in production + # Allow root login without password, auto login + users.users.root.password = ""; + services.getty.autologinUser = "root"; + + virtualisation = { + cores = 2; + memorySize = lib.mkDefault 4096; + diskSize = lib.mkDefault (100 * 1024); + forwardPorts = [ + { + # http + from = "host"; + host.port = 8080; + guest.port = 80; + } + { + # cardano-node + from = "host"; + host.port = 3001; + guest.port = 3001; + } + { + # ogmios + from = "host"; + host.port = 1337; + guest.port = 1337; + } + { + # kupo + from = "host"; + host.port = 1442; + guest.port = 1442; + } + ]; + }; +} diff --git a/docs/default.nix b/docs/default.nix index eec5cad..35f5e32 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -3,7 +3,8 @@ inputs, self, ... -}: { +}: +{ imports = [ ./render.nix ]; @@ -15,83 +16,86 @@ sidebarOptions = [ { anchor = "cardano"; - modules = [config.flake.nixosModules.cardano]; - namespaces = ["cardano"]; + modules = [ config.flake.nixosModules.cardano ]; + namespaces = [ "cardano" ]; } { anchor = "cardano.cli"; - modules = [config.flake.nixosModules.cli]; - namespaces = ["cardano.cli"]; + modules = [ config.flake.nixosModules.cli ]; + namespaces = [ "cardano.cli" ]; } { anchor = "cardano.node"; - modules = [config.flake.nixosModules.node]; - namespaces = ["cardano.node"]; + modules = [ config.flake.nixosModules.node ]; + namespaces = [ "cardano.node" ]; } { anchor = "services.cardano-node"; - modules = [config.flake.nixosModules.node {services.cardano-node.environment = "mainnet";}]; - namespaces = ["services.cardano-node"]; + modules = [ + config.flake.nixosModules.node + { services.cardano-node.environment = "mainnet"; } + ]; + namespaces = [ "services.cardano-node" ]; } { anchor = "cardano.ogmios"; - modules = [config.flake.nixosModules.ogmios]; - namespaces = ["cardano.ogmios"]; + modules = [ config.flake.nixosModules.ogmios ]; + namespaces = [ "cardano.ogmios" ]; } { anchor = "services.ogmios"; - modules = [config.flake.nixosModules.ogmios]; - namespaces = ["services.ogmios"]; + modules = [ config.flake.nixosModules.ogmios ]; + namespaces = [ "services.ogmios" ]; } { anchor = "cardano.kupo"; - modules = [config.flake.nixosModules.kupo]; - namespaces = ["cardano.kupo"]; + modules = [ config.flake.nixosModules.kupo ]; + namespaces = [ "cardano.kupo" ]; } { anchor = "services.kupo"; - modules = [config.flake.nixosModules.kupo]; - namespaces = ["services.kupo"]; + modules = [ config.flake.nixosModules.kupo ]; + namespaces = [ "services.kupo" ]; } { anchor = "cardano.db-sync"; - modules = [config.flake.nixosModules.db-sync]; - namespaces = ["cardano.db-sync"]; + modules = [ config.flake.nixosModules.db-sync ]; + namespaces = [ "cardano.db-sync" ]; } { anchor = "services.cardano-db-sync"; - modules = [(config.flake.nixosModules.db-sync // {config.services.cardano-db-sync.cluster = "mainnet";})]; - namespaces = ["services.cardano-db-sync"]; + modules = [ (config.flake.nixosModules.db-sync // { config.services.cardano-db-sync.cluster = "mainnet"; }) ]; + namespaces = [ "services.cardano-db-sync" ]; } { anchor = "cardano.http"; - modules = [config.flake.nixosModules.http]; - namespaces = ["cardano.http"]; + modules = [ config.flake.nixosModules.http ]; + namespaces = [ "cardano.http" ]; } { anchor = "services.http-proxy"; - modules = [config.flake.nixosModules.http]; - namespaces = ["services.http-proxy"]; + modules = [ config.flake.nixosModules.http ]; + namespaces = [ "services.http-proxy" ]; } { anchor = "cardano.blockfrost"; - modules = [config.flake.nixosModules.blockfrost]; - namespaces = ["cardano.blockfrost"]; + modules = [ config.flake.nixosModules.blockfrost ]; + namespaces = [ "cardano.blockfrost" ]; } { anchor = "services.blockfrost"; - modules = [config.flake.nixosModules.blockfrost]; - namespaces = ["services.blockfrost"]; + modules = [ config.flake.nixosModules.blockfrost ]; + namespaces = [ "services.blockfrost" ]; } { anchor = "cardano.oura"; - modules = [config.flake.nixosModules.oura]; - namespaces = ["cardano.oura"]; + modules = [ config.flake.nixosModules.oura ]; + namespaces = [ "cardano.oura" ]; } { anchor = "services.oura"; - modules = [config.flake.nixosModules.oura]; - namespaces = ["services.oura"]; + modules = [ config.flake.nixosModules.oura ]; + namespaces = [ "services.oura" ]; } ]; diff --git a/docs/render.nix b/docs/render.nix index 911bf87..1d91c94 100644 --- a/docs/render.nix +++ b/docs/render.nix @@ -4,11 +4,24 @@ lib, self, ... -}: let +}: +let cfg = config.renderDocs; - inherit (lib) mkOption mkEnableOption mkIf mkMerge; - inherit (lib.types) bool str listOf deferredModule submodule path; + inherit (lib) + mkOption + mkEnableOption + mkIf + mkMerge + ; + inherit (lib.types) + bool + str + listOf + deferredModule + submodule + path + ; sidebarType = submodule { options = { @@ -51,7 +64,8 @@ }; }; }; -in { +in +{ options.renderDocs = { enable = mkEnableOption "Document rendering"; @@ -88,7 +102,7 @@ in { devshells = mkOption { type = listOf str; - default = ["default"]; + default = [ "default" ]; description = '' Names of the devshells to add `docs-serve` and `docs-build` commands to ''; @@ -96,7 +110,7 @@ in { sidebarOptions = mkOption { type = listOf sidebarType; - default = []; + default = [ ]; description = '' List of reference sections ''; @@ -104,7 +118,7 @@ in { fixups = mkOption { type = listOf fixupType; - default = []; + default = [ ]; }; invisible = mkOption { @@ -117,138 +131,147 @@ in { }; config = mkIf cfg.enable { - perSystem = { - config, - lib, - pkgs, - system, - ... - }: let - inherit (pkgs) stdenv mkdocs python312Packages; - - my-mkdocs = - pkgs.runCommand "my-mkdocs" - { - buildInputs = [ - mkdocs - python312Packages.mkdocs-material - ]; - } '' - mkdir -p $out/bin - - cat < $out/bin/mkdocs - #!${pkgs.bash}/bin/bash - set -euo pipefail - export PYTHONPATH=$PYTHONPATH - exec ${mkdocs}/bin/mkdocs "\$@" - MKDOCS - - chmod +x $out/bin/mkdocs - ''; - - eachOptionsDoc = builtins.listToAttrs (builtins.map ( - { - anchor, - modules, - namespaces, - ... - }: - lib.nameValuePair - anchor - (pkgs.nixosOptionsDoc { - # By default `nixosOptionsDoc` will ignore internal options but we want to show them - # This hack will make all the options not internal and visible and optionally append to the - # description a new field which is then corrected rendered as it was a native field - transformOptions = opt: - opt - // lib.optionalAttrs cfg.invisible { - internal = false; - visible = true; - } - // { - description = '' - ${lib.optionalString (opt.description != null) opt.description} - ${lib.optionalString (opt.internal && cfg.invisible) "*Internal:* true"} - ''; - } - // ( - if (lib.length (lib.splitString "\n" opt.default.text or "") > 20) - then { - default._type = "literalMD"; - default.text = '' -
This value is long. Click to expand. - ```nix - ${opt.default.text} - ``` -
+ perSystem = + { + config, + lib, + pkgs, + system, + ... + }: + let + inherit (pkgs) stdenv mkdocs python312Packages; + + my-mkdocs = + pkgs.runCommand "my-mkdocs" + { + buildInputs = [ + mkdocs + python312Packages.mkdocs-material + ]; + } + '' + mkdir -p $out/bin + + cat < $out/bin/mkdocs + #!${pkgs.bash}/bin/bash + set -euo pipefail + export PYTHONPATH=$PYTHONPATH + exec ${mkdocs}/bin/mkdocs "\$@" + MKDOCS + + chmod +x $out/bin/mkdocs + ''; + + eachOptionsDoc = builtins.listToAttrs ( + builtins.map ( + { + anchor, + modules, + namespaces, + ... + }: + lib.nameValuePair anchor ( + pkgs.nixosOptionsDoc { + # By default `nixosOptionsDoc` will ignore internal options but we want to show them + # This hack will make all the options not internal and visible and optionally append to the + # description a new field which is then corrected rendered as it was a native field + transformOptions = + opt: + opt + // lib.optionalAttrs cfg.invisible { + internal = false; + visible = true; + } + // { + description = '' + ${lib.optionalString (opt.description != null) opt.description} + ${lib.optionalString (opt.internal && cfg.invisible) "*Internal:* true"} ''; } - else {} - ); - options = let - evaluated = lib.evalModules { - modules = - modules - ++ [ + // ( + if (lib.length (lib.splitString "\n" opt.default.text or "") > 20) then { - imports = builtins.import "${inputs.nixpkgs}/nixos/modules/module-list.nix"; - nixpkgs.system = system; + default._type = "literalMD"; + default.text = '' +
This value is long. Click to expand. + ```nix + ${opt.default.text} + ``` +
+ ''; } - ]; - }; - in - lib.foldr (path: acc: lib.recursiveUpdate acc (lib.attrByPath (lib.splitString "." path) {} evaluated.options)) {} namespaces; - }) - ) - cfg.sidebarOptions); - - statements = - lib.concatStringsSep "\n" - (lib.mapAttrsToList (n: v: '' + else + { } + ); + options = + let + evaluated = lib.evalModules { + modules = modules ++ [ + { + imports = builtins.import "${inputs.nixpkgs}/nixos/modules/module-list.nix"; + nixpkgs.system = system; + } + ]; + }; + in + lib.foldr (path: acc: lib.recursiveUpdate acc (lib.attrByPath (lib.splitString "." path) { } evaluated.options)) { } namespaces; + } + ) + ) cfg.sidebarOptions + ); + + statements = lib.concatStringsSep "\n" ( + lib.mapAttrsToList (n: v: '' path=$out/${n}.md cat ${v.optionsCommonMark} | sed 's/\\> $path - '') - eachOptionsDoc); - - options-doc = pkgs.runCommand "nixos-options" {} '' - mkdir $out - ${statements} - # Replace `/nix/store` related paths with public urls - find $out -type f | xargs -n1 sed -i ${lib.concatMapStrings (x: " -e 's,${x.storePath},${x.githubUrl},g'") cfg.fixups} -e "s,file://https://,https://,g" - ''; - - docsPath = "./docs/reference/module-options"; - - index = { - nav = [ - { - "NixOS Module Reference" = lib.mapAttrsToList (n: _: {${n} = "reference/module-options/${n}.md";}) eachOptionsDoc; - } - ]; - }; - - indexYAML = - pkgs.runCommand "index.yaml" { - nativeBuildInputs = [pkgs.yq-go]; - index = builtins.toFile "index.json" (builtins.unsafeDiscardStringContext (builtins.toJSON index)); - } '' - yq -o yaml $index >$out + '') eachOptionsDoc + ); + + options-doc = pkgs.runCommand "nixos-options" { } '' + mkdir $out + ${statements} + # Replace `/nix/store` related paths with public urls + find $out -type f | xargs -n1 sed -i ${lib.concatMapStrings (x: " -e 's,${x.storePath},${x.githubUrl},g'") cfg.fixups} -e "s,file://https://,https://,g" ''; - mergedMkdocsYaml = - pkgs.runCommand "mkdocs.yaml" { - nativeBuildInputs = [pkgs.yq-go]; - } '' - yq '. *+ load("${indexYAML}")' ${cfg.mkdocsYamlFile} -o yaml >$out - ''; - in - mkMerge ([ + docsPath = "./docs/reference/module-options"; + + index = { + nav = [ + { + "NixOS Module Reference" = lib.mapAttrsToList (n: _: { ${n} = "reference/module-options/${n}.md"; }) eachOptionsDoc; + } + ]; + }; + + indexYAML = + pkgs.runCommand "index.yaml" + { + nativeBuildInputs = [ pkgs.yq-go ]; + index = builtins.toFile "index.json" (builtins.unsafeDiscardStringContext (builtins.toJSON index)); + } + '' + yq -o yaml $index >$out + ''; + + mergedMkdocsYaml = + pkgs.runCommand "mkdocs.yaml" + { + nativeBuildInputs = [ pkgs.yq-go ]; + } + '' + yq '. *+ load("${indexYAML}")' ${cfg.mkdocsYamlFile} -o yaml >$out + ''; + in + mkMerge ( + [ { packages.${cfg.packageName} = stdenv.mkDerivation { src = cfg.directory; inherit (cfg) name; - nativeBuildInputs = [my-mkdocs]; + nativeBuildInputs = [ my-mkdocs ]; unpackPhase = '' cp -r $src docs @@ -291,12 +314,13 @@ in { packages."${cfg.packageName}-serve" = config.packages.${cfg.packageName}.serve; } ] - ++ ( - builtins.map (devshell: { - devshells."${devshell}" = { - commands = let + ++ (builtins.map (devshell: { + devshells."${devshell}" = { + commands = + let category = "documentation"; - in [ + in + [ { inherit category; name = "docs-serve"; @@ -310,12 +334,11 @@ in { command = "nix build .#${cfg.packageName}"; } ]; - packages = [ - my-mkdocs - ]; - }; - }) - cfg.devshells - )); + packages = [ + my-mkdocs + ]; + }; + }) cfg.devshells) + ); }; } diff --git a/flake.nix b/flake.nix index 5e58470..49be907 100644 --- a/flake.nix +++ b/flake.nix @@ -54,10 +54,9 @@ inputs.nixpkgs.follows = "nixpkgs"; }; }; - outputs = inputs @ {flake-parts, ...}: - flake-parts.lib.mkFlake - {inherit inputs;} - { + outputs = + inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { imports = [ ./checks ./ci diff --git a/modules/blockfrost.nix b/modules/blockfrost.nix index 0a99fad..deb6fc1 100644 --- a/modules/blockfrost.nix +++ b/modules/blockfrost.nix @@ -2,11 +2,13 @@ config, lib, ... -}: let +}: +let cfg = config.cardano.blockfrost; dbsync-cfg = config.services.cardano-db-sync or null; inherit (lib) mkIf mkMerge mkEnableOption; -in { +in +{ options.cardano.blockfrost = { enable = mkEnableOption '' Blockfrost.io backend is an API service providing abstraction between you and Cardano blockchain data @@ -26,7 +28,9 @@ in { or enable the default postgresql service with `cardano.blockfrost.postgres.enable` ''; - postgres.enable = mkEnableOption "Connect blockfrost to local postgresql." // {default = true;}; + postgres.enable = mkEnableOption "Connect blockfrost to local postgresql." // { + default = true; + }; }; config = mkIf cfg.enable (mkMerge [ @@ -89,14 +93,14 @@ in { }) (mkIf (config.cardano.node.enable or false) { systemd.services.blockfrost-backend-ryo = { - after = ["cardano-node-socket.service"]; - requires = ["cardano-node-socket.service"]; + after = [ "cardano-node-socket.service" ]; + requires = [ "cardano-node-socket.service" ]; }; }) (mkIf (config.cardano.db-sync.enable or false) { systemd.services.blockfrost-backend-ryo = { - after = ["cardano-db-sync.service"]; - requires = ["cardano-db-sync.service"]; + after = [ "cardano-db-sync.service" ]; + requires = [ "cardano-db-sync.service" ]; }; }) ]); diff --git a/modules/cardano.nix b/modules/cardano.nix index 35302ad..fbbdbb1 100644 --- a/modules/cardano.nix +++ b/modules/cardano.nix @@ -2,10 +2,12 @@ lib, config, ... -}: let +}: +let cfg = config.cardano; inherit (lib) types; -in { +in +{ options.cardano = { network = lib.mkOption { description = "Cardano network to operate on."; diff --git a/modules/cli.nix b/modules/cli.nix index 94f26f5..331b913 100644 --- a/modules/cli.nix +++ b/modules/cli.nix @@ -3,7 +3,8 @@ lib, pkgs, ... -}: { +}: +{ options.cardano.cli.enable = lib.mkOption { description = "Add cardano-cli to 'environment.systemPackages'."; type = lib.types.bool; @@ -11,6 +12,6 @@ }; config = lib.mkIf config.cardano.cli.enable { - environment.systemPackages = [pkgs.cardano-cli]; + environment.systemPackages = [ pkgs.cardano-cli ]; }; } diff --git a/modules/db-sync.nix b/modules/db-sync.nix index 57997d0..bf181b6 100644 --- a/modules/db-sync.nix +++ b/modules/db-sync.nix @@ -2,11 +2,18 @@ config, lib, ... -}: let +}: +let cfg = config.cardano.db-sync; dbsync-cfg = config.services.cardano-db-sync; - inherit (lib) mkEnableOption mkIf mkMerge mkOptionDefault; -in { + inherit (lib) + mkEnableOption + mkIf + mkMerge + mkOptionDefault + ; +in +{ options.cardano.db-sync = { enable = mkEnableOption '' Cardano DB Sync provides a way to query local cardano node. @@ -25,7 +32,9 @@ in { or enable the default postgresql service with `services.cardano-db-sync.postgres.enable` and possibly overwrite the `services.postgresql` options for your need. ''; - postgres.enable = mkEnableOption "Run postgres and connect dbsync to it." // {default = true;}; + postgres.enable = mkEnableOption "Run postgres and connect dbsync to it." // { + default = true; + }; }; config = mkMerge [ @@ -41,7 +50,7 @@ in { postgres = { user = "cardano-db-sync"; # use first socket from postgresql settings or default to /run/postgresql - socketdir = builtins.head ((config.services.postgresql.settings.unix_socket_directories or []) ++ ["/run/postgresql"]); + socketdir = builtins.head ((config.services.postgresql.settings.unix_socket_directories or [ ]) ++ [ "/run/postgresql" ]); port = config.services.postgresql.settings.port or 5432; database = "cardano-db-sync"; }; @@ -63,7 +72,10 @@ in { ProtectHostname = true; ProtectKernelTunables = true; RestrictRealtime = true; - SystemCallFilter = ["@system-service" "~@privileged"]; + SystemCallFilter = [ + "@system-service" + "~@privileged" + ]; PrivateDevices = true; RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; ProtectHome = true; @@ -80,15 +92,15 @@ in { }) (mkIf (cfg.enable && config.cardano.node.enable or false) { systemd.services.cardano-db-sync = { - after = ["cardano-node-socket.service"]; - requires = ["cardano-node-socket.service"]; + after = [ "cardano-node-socket.service" ]; + requires = [ "cardano-node-socket.service" ]; }; }) (mkIf (cfg.enable && cfg.postgres.enable) { services.postgresql = { enable = true; # see warnings: this should be same as user name - ensureDatabases = [dbsync-cfg.postgres.database]; + ensureDatabases = [ dbsync-cfg.postgres.database ]; ensureUsers = [ { name = "${dbsync-cfg.postgres.database}"; diff --git a/modules/default.nix b/modules/default.nix index 3d8907a..4d14e9e 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -2,7 +2,8 @@ inputs, config, ... -}: { +}: +{ flake.flakeModules.docs = ../docs/render.nix; flake.nixosModules = { @@ -65,14 +66,11 @@ }; # the default module imports all modules default = { - imports = - [ - { - nixpkgs.overlays = [config.flake.overlays.default]; - } - ] - ++ (with builtins; - attrValues (removeAttrs config.flake.nixosModules ["default"])); + imports = [ + { + nixpkgs.overlays = [ config.flake.overlays.default ]; + } + ] ++ (with builtins; attrValues (removeAttrs config.flake.nixosModules [ "default" ])); }; }; } diff --git a/modules/http.nix b/modules/http.nix index 720df62..1d3f90d 100644 --- a/modules/http.nix +++ b/modules/http.nix @@ -2,10 +2,12 @@ config, lib, ... -}: let +}: +let cfg = config.cardano.http; inherit (lib) mkIf mkDefault mkEnableOption; -in { +in +{ options.cardano.http = { enable = mkEnableOption '' HTTP SSL proxy and load balancer for cardano services @@ -21,7 +23,7 @@ in { config = mkIf cfg.enable { services.http-proxy = { enable = true; - servers = mkIf (config.cardano.ogmios.enable || config.cardano.kupo.enable) (mkDefault ["127.0.0.1"]); + servers = mkIf (config.cardano.ogmios.enable || config.cardano.kupo.enable) (mkDefault [ "127.0.0.1" ]); services = { cardano-node = { inherit (config.services.cardano-node.package.passthru.identifier) version; @@ -37,7 +39,7 @@ in { grafana = { port = 3000; inherit (config.services.grafana.package) version; - servers = mkDefault []; + servers = mkDefault [ ]; }; }; }; diff --git a/modules/kupo.nix b/modules/kupo.nix index b1ab141..9a030ac 100644 --- a/modules/kupo.nix +++ b/modules/kupo.nix @@ -2,38 +2,27 @@ config, lib, ... -}: let +}: +let cfg = config.cardano.kupo; -in { +in +{ options.cardano.kupo = { - enable = - lib.mkEnableOption "Kupo chain-indexer"; + enable = lib.mkEnableOption "Kupo chain-indexer"; }; config = lib.mkIf cfg.enable { services.kupo = { enable = true; - nodeSocketPath = - lib.mkIf (config.cardano.node.enable or false) - config.cardano.node.socketPath; - nodeConfigPath = - lib.mkIf (config.cardano.node.enable or false) - config.cardano.node.configPath; - ogmiosHost = - lib.mkIf (config.cardano.ogmios.enable or false) - "127.0.0.1"; - ogmiosPort = - lib.mkIf (config.cardano.ogmios.enable or false) - config.services.ogmios.port; + nodeSocketPath = lib.mkIf (config.cardano.node.enable or false) config.cardano.node.socketPath; + nodeConfigPath = lib.mkIf (config.cardano.node.enable or false) config.cardano.node.configPath; + ogmiosHost = lib.mkIf (config.cardano.ogmios.enable or false) "127.0.0.1"; + ogmiosPort = lib.mkIf (config.cardano.ogmios.enable or false) config.services.ogmios.port; }; systemd.services.kupo = { - after = - lib.optional (config.cardano.node.enable or false) "cardano-node-socket.service" - ++ lib.optional (config.cardano.ogmios.enable or false) "ogmios.service"; - requires = - lib.optional (config.cardano.node.enable or false) "cardano-node-socket.service" - ++ lib.optional (config.cardano.ogmios.enable or false) "ogmios.service"; + after = lib.optional (config.cardano.node.enable or false) "cardano-node-socket.service" ++ lib.optional (config.cardano.ogmios.enable or false) "ogmios.service"; + requires = lib.optional (config.cardano.node.enable or false) "cardano-node-socket.service" ++ lib.optional (config.cardano.ogmios.enable or false) "ogmios.service"; }; }; } diff --git a/modules/monitoring.nix b/modules/monitoring.nix index a50f176..c140886 100644 --- a/modules/monitoring.nix +++ b/modules/monitoring.nix @@ -3,17 +3,25 @@ lib, pkgs, ... -}: let +}: +let cfg = config.cardano.monitoring; - inherit (lib) mkIf mkEnableOption mkMerge mkOption types; -in { + inherit (lib) + mkIf + mkEnableOption + mkMerge + mkOption + types + ; +in +{ options.cardano.monitoring = { enable = mkEnableOption '' monitoring services Prometheus and Grafana ''; targets = mkOption { type = with types; listOf string; - default = ["localhost"]; + default = [ "localhost" ]; description = '' List of hosts to to scrape prometheus metrics from. ''; @@ -58,40 +66,40 @@ in { scrapeConfigs = [ { job_name = "blockfrost"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.services.blockfrost.settings.server.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.services.blockfrost.settings.server.port}") cfg.targets; } ]; } { job_name = "db_sync"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.services.cardano-db-sync.explorerConfig.PrometheusPort}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.services.cardano-db-sync.explorerConfig.PrometheusPort}") cfg.targets; } ]; } { job_name = "cardano-node"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.cardano.node.prometheusExporter.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.cardano.node.prometheusExporter.port}") cfg.targets; } ]; } { job_name = "kupo"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.services.kupo.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.services.kupo.port}") cfg.targets; } ]; metrics_path = "/health"; } { job_name = "nginx"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.services.prometheus.exporters.nginx.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.services.prometheus.exporters.nginx.port}") cfg.targets; } ]; } { job_name = "node"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.services.prometheus.exporters.node.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.services.prometheus.exporters.node.port}") cfg.targets; } ]; } { job_name = "ogmios"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.services.ogmios.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.services.ogmios.port}") cfg.targets; } ]; } { job_name = "oura"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.cardano.oura.prometheusExporter.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.cardano.oura.prometheusExporter.port}") cfg.targets; } ]; } { job_name = "postgres"; - static_configs = [{targets = map (target: "${target}:${builtins.toString config.services.prometheus.exporters.postgres.port}") cfg.targets;}]; + static_configs = [ { targets = map (target: "${target}:${builtins.toString config.services.prometheus.exporters.postgres.port}") cfg.targets; } ]; } ]; }; diff --git a/modules/node.nix b/modules/node.nix index 3d8d2fd..427853d 100644 --- a/modules/node.nix +++ b/modules/node.nix @@ -3,10 +3,17 @@ lib, pkgs, ... -}: let +}: +let cfg = config.cardano.node; - inherit (builtins) elemAt match replaceStrings readFile; -in { + inherit (builtins) + elemAt + match + replaceStrings + readFile + ; +in +{ options.cardano.node = { enable = lib.mkEnableOption "cardano-node service"; @@ -22,8 +29,7 @@ in { default = "/etc/cardano-node/config.json"; }; - prometheusExporter.enable = - lib.mkEnableOption "prometheus exporter"; + prometheusExporter.enable = lib.mkEnableOption "prometheus exporter"; prometheusExporter.port = lib.mkOption { description = "Port where Prometheus exporter is exposed."; @@ -35,7 +41,7 @@ in { config = lib.mkIf cfg.enable { environment.etc."cardano-node/config.json" = { # hack to get config file path - text = readFile (elemAt (match ".* --config ([^ ]+) .*" (replaceStrings ["\n"] [" "] config.services.cardano-node.script)) 0); + text = readFile (elemAt (match ".* --config ([^ ]+) .*" (replaceStrings [ "\n" ] [ " " ] config.services.cardano-node.script)) 0); user = "cardano-node"; group = "cardano-node"; }; @@ -52,7 +58,10 @@ in { environment = config.cardano.network; extraNodeConfig = lib.mkIf cfg.prometheusExporter.enable { - hasPrometheus = ["0.0.0.0" config.cardano.node.prometheusExporter.port]; + hasPrometheus = [ + "0.0.0.0" + config.cardano.node.prometheusExporter.port + ]; }; # Listen on all interfaces. @@ -66,10 +75,10 @@ in { # Socket created by cardano-node is not writable by group . So we wait until it appears and set the permissions. systemd.services.cardano-node-socket = { description = "Wait for cardano-node socket to appear and set permissions to allow group read and write."; - after = ["cardano-node.service"]; - requires = ["cardano-node.service"]; - bindsTo = ["cardano-node.service"]; - requiredBy = ["cardano-node.service"]; + after = [ "cardano-node.service" ]; + requires = [ "cardano-node.service" ]; + bindsTo = [ "cardano-node.service" ]; + requiredBy = [ "cardano-node.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; diff --git a/modules/ogmios.nix b/modules/ogmios.nix index 1574b8e..5dd6e11 100644 --- a/modules/ogmios.nix +++ b/modules/ogmios.nix @@ -2,28 +2,25 @@ config, lib, ... -}: let +}: +let cfg = config.cardano.ogmios; -in { +in +{ options.cardano.ogmios = { - enable = - lib.mkEnableOption "Ogmios bridge interface for cardano-node"; + enable = lib.mkEnableOption "Ogmios bridge interface for cardano-node"; }; config = lib.mkIf cfg.enable { services.ogmios = { enable = true; - nodeSocketPath = - lib.mkIf (config.cardano.node.enable or false) - config.cardano.node.socketPath or null; - nodeConfigPath = - lib.mkIf (config.cardano.node.enable or false) - config.cardano.node.configPath or null; + nodeSocketPath = lib.mkIf (config.cardano.node.enable or false) config.cardano.node.socketPath or null; + nodeConfigPath = lib.mkIf (config.cardano.node.enable or false) config.cardano.node.configPath or null; }; systemd.services.ogmios = lib.mkIf (config.cardano.node.enable or false) { - after = ["cardano-node-socket.service"]; - requires = ["cardano-node-socket.service"]; + after = [ "cardano-node-socket.service" ]; + requires = [ "cardano-node-socket.service" ]; }; }; } diff --git a/modules/oura.nix b/modules/oura.nix index 581c71c..f4e3b41 100644 --- a/modules/oura.nix +++ b/modules/oura.nix @@ -2,19 +2,19 @@ config, lib, ... -}: let +}: +let cfg = config.cardano.oura; -in { +in +{ options.cardano.oura = { - enable = - lib.mkEnableOption "Oura event processing pipeline for Cardano"; + enable = lib.mkEnableOption "Oura event processing pipeline for Cardano"; - integrate = - lib.mkEnableOption ''connect oura to local cardano-node via N2C'' - // {default = config.cardano.node.enable or false;}; + integrate = lib.mkEnableOption ''connect oura to local cardano-node via N2C'' // { + default = config.cardano.node.enable or false; + }; - prometheusExporter.enable = - lib.mkEnableOption "prometheus exporter"; + prometheusExporter.enable = lib.mkEnableOption "prometheus exporter"; prometheusExporter.port = lib.mkOption { description = "Port where Prometheus exporter is exposed."; @@ -29,7 +29,10 @@ in { settings = { source = lib.mkIf cfg.integrate { type = "N2C"; - address = ["Unix" config.cardano.node.socketPath]; + address = [ + "Unix" + config.cardano.node.socketPath + ]; magic = config.cardano.network; }; metrics.address = lib.mkIf cfg.prometheusExporter.enable "0.0.0.0:${builtins.toString cfg.prometheusExporter.port}"; @@ -37,8 +40,8 @@ in { }; systemd.services.oura = lib.mkIf (config.cardano.node.enable or false) { - after = ["cardano-node-socket.service"]; - requires = ["cardano-node-socket.service"]; + after = [ "cardano-node-socket.service" ]; + requires = [ "cardano-node-socket.service" ]; }; }; } diff --git a/modules/services/http-proxy.nix b/modules/services/http-proxy.nix index 7bd0ba3..ab042e7 100644 --- a/modules/services/http-proxy.nix +++ b/modules/services/http-proxy.nix @@ -2,10 +2,21 @@ config, lib, ... -}: let +}: +let cfg = config.services.http-proxy; - inherit (lib) types listToAttrs mkOption mkEnableOption mapAttrs mkIf optional optionalString; -in { + inherit (lib) + types + listToAttrs + mkOption + mkEnableOption + mapAttrs + mkIf + optional + optionalString + ; +in +{ options.services.http-proxy = { enable = mkEnableOption "HTTP reverse proxy, TLS endpoint and load balancer"; openFirewall = mkOption { @@ -31,45 +42,50 @@ in { servers = mkOption { description = "List of upstream server host names used for all services."; type = types.listOf types.str; - default = []; + default = [ ]; }; services = mkOption { description = "Configuraiton for each upstream service."; - type = types.attrsOf (types.submodule ({name, ...}: { - options = { - name = mkOption { - description = "Name of the service."; - type = types.str; - default = name; - }; - servers = mkOption { - description = "List of upstream server host names."; - type = types.listOf types.str; - default = cfg.servers; - }; - port = mkOption { - description = "Upstream server port."; - type = types.nullOr types.port; - default = null; - }; - version = mkOption { - description = "This string will be served at path '/version'."; - type = types.nullOr types.str; - default = null; - }; - }; - })); + type = types.attrsOf ( + types.submodule ( + { name, ... }: + { + options = { + name = mkOption { + description = "Name of the service."; + type = types.str; + default = name; + }; + servers = mkOption { + description = "List of upstream server host names."; + type = types.listOf types.str; + default = cfg.servers; + }; + port = mkOption { + description = "Upstream server port."; + type = types.nullOr types.port; + default = null; + }; + version = mkOption { + description = "This string will be served at path '/version'."; + type = types.nullOr types.str; + default = null; + }; + }; + } + ) + ); }; _mkUpstream = mkOption { type = types.functionTo types.attrs; internal = true; default = service: { - servers = listToAttrs (map - (server: { + servers = listToAttrs ( + map (server: { name = "${server}:${toString service.port}"; - value = {}; - }) - service.servers); + value = { }; + }) service.servers + ); }; }; _mkVirtualHost = mkOption { @@ -84,7 +100,7 @@ in { return = "200 ${service.version}"; extraConfig = "add_header Content-Type text/plain;"; }; - "/" = mkIf (service.servers != [] && service.port != null) { + "/" = mkIf (service.servers != [ ] && service.port != null) { proxyWebsockets = true; proxyPass = "http://${service.name}"; }; @@ -101,7 +117,7 @@ in { }; }; config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall ([80] ++ optional cfg.https.enable 443); + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall ([ 80 ] ++ optional cfg.https.enable 443); services.nginx = { enable = true; @@ -113,7 +129,7 @@ in { statusPage = true; - upstreams = mapAttrs (_: cfg._mkUpstream) (lib.filterAttrs (_: s: s.servers != [] && s.port != null) cfg.services); + upstreams = mapAttrs (_: cfg._mkUpstream) (lib.filterAttrs (_: s: s.servers != [ ] && s.port != null) cfg.services); virtualHosts = mapAttrs (_: cfg._mkVirtualHost) cfg.services; }; }; diff --git a/modules/services/kupo.nix b/modules/services/kupo.nix index 35144fc..9e33269 100644 --- a/modules/services/kupo.nix +++ b/modules/services/kupo.nix @@ -3,10 +3,20 @@ lib, pkgs, ... -}: let +}: +let cfg = config.services.kupo; - inherit (lib) escapeShellArgs flatten types mkOption mkEnableOption mkIf optional; -in { + inherit (lib) + escapeShellArgs + flatten + types + mkOption + mkEnableOption + mkIf + optional + ; +in +{ options.services.kupo = { enable = mkEnableOption "Kupo Cardano chain-indexer"; @@ -84,7 +94,7 @@ in { matches = mkOption { description = "The list of addresses to watch."; type = types.listOf types.nonEmptyStr; - default = ["*"]; + default = [ "*" ]; }; since = mkOption { @@ -102,7 +112,7 @@ in { extraArgs = mkOption { description = "Extra arguments to kupo command."; type = types.listOf types.str; - default = []; + default = [ ]; }; }; @@ -117,34 +127,70 @@ in { users.users.kupo = mkIf (cfg.user == "kupo") { isSystemUser = true; inherit (cfg) group; - extraGroups = ["cardano-node"]; + extraGroups = [ "cardano-node" ]; }; - users.groups.kupo = mkIf (cfg.group == "kupo") {}; + users.groups.kupo = mkIf (cfg.group == "kupo") { }; systemd.services.kupo = { enable = true; - after = ["cardano-node.service" "ogmios.service"]; - wantedBy = ["multi-user.target"]; + after = [ + "cardano-node.service" + "ogmios.service" + ]; + wantedBy = [ "multi-user.target" ]; script = escapeShellArgs (flatten [ - ["${cfg.package}/bin/kupo"] - ["--workdir" cfg.workDir] - ["--host" cfg.host] - ["--port" cfg.port] + [ "${cfg.package}/bin/kupo" ] + [ + "--workdir" + cfg.workDir + ] + [ + "--host" + cfg.host + ] + [ + "--port" + cfg.port + ] (optional (cfg.ogmiosHost == null) [ - ["--node-socket" cfg.nodeSocketPath] - ["--node-config" cfg.nodeConfigPath] + [ + "--node-socket" + cfg.nodeSocketPath + ] + [ + "--node-config" + cfg.nodeConfigPath + ] ]) (optional (cfg.ogmiosHost != null) [ - ["--ogmios-host" cfg.ogmiosHost] - ["--ogmios-port" cfg.ogmiosPort] + [ + "--ogmios-host" + cfg.ogmiosHost + ] + [ + "--ogmios-port" + cfg.ogmiosPort + ] ]) (optional (cfg.hydraHost != null) [ - ["--hydra-host" cfg.hydraHost] - ["--hydra-port" cfg.hydraPort] + [ + "--hydra-host" + cfg.hydraHost + ] + [ + "--hydra-port" + cfg.hydraPort + ] ]) - ["--since" cfg.since] - (map (m: ["--match" m]) cfg.matches) + [ + "--since" + cfg.since + ] + (map (m: [ + "--match" + m + ]) cfg.matches) (optional cfg.pruneUtxo "--prune-utxo") cfg.extraArgs ]); @@ -156,8 +202,8 @@ in { StateDirectory = lib.removePrefix "/var/lib/" cfg.workDir; # Security UMask = "0077"; - AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; - CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; DevicePolicy = "closed"; LockPersonality = true; MemoryDenyWriteExecute = true; @@ -177,12 +223,16 @@ in { ProtectProc = "invisible"; ProtectSystem = "strict"; RemoveIPC = true; - RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; SystemCallArchitectures = "native"; - SystemCallFilter = ["~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid"]; + SystemCallFilter = [ "~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid" ]; }; }; }; diff --git a/modules/services/ogmios.nix b/modules/services/ogmios.nix index 123f2dd..180fb9e 100644 --- a/modules/services/ogmios.nix +++ b/modules/services/ogmios.nix @@ -5,9 +5,11 @@ pkgs, ... }: -with lib; let +with lib; +let cfg = config.services.ogmios; -in { +in +{ options.services.ogmios = with types; { enable = mkEnableOption "Ogmios bridge interface for cardano-node"; @@ -55,7 +57,7 @@ in { extraArgs = mkOption { description = "Extra arguments to ogmios command."; type = listOf str; - default = []; + default = [ ]; }; }; @@ -63,21 +65,33 @@ in { users.users.ogmios = mkIf (cfg.user == "ogmios") { isSystemUser = true; inherit (cfg) group; - extraGroups = ["cardano-node"]; + extraGroups = [ "cardano-node" ]; }; - users.groups.ogmios = mkIf (cfg.group == "ogmios") {}; + users.groups.ogmios = mkIf (cfg.group == "ogmios") { }; systemd.services.ogmios = { enable = true; - after = ["cardano-node.service"]; - wantedBy = ["multi-user.target"]; + after = [ "cardano-node.service" ]; + wantedBy = [ "multi-user.target" ]; script = escapeShellArgs (concatLists [ - ["${cfg.package}/bin/ogmios"] - ["--node-socket" cfg.nodeSocketPath] - ["--node-config" cfg.nodeConfigPath] - ["--host" cfg.host] - ["--port" cfg.port] + [ "${cfg.package}/bin/ogmios" ] + [ + "--node-socket" + cfg.nodeSocketPath + ] + [ + "--node-config" + cfg.nodeConfigPath + ] + [ + "--host" + cfg.host + ] + [ + "--port" + cfg.port + ] cfg.extraArgs ]); @@ -102,7 +116,11 @@ in { ProtectKernelModules = true; ProtectKernelLogs = true; ProtectControlGroups = true; - RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; RestrictNamespaces = true; LockPersonality = true; RestrictRealtime = true; @@ -110,7 +128,10 @@ in { RemoveIPC = true; PrivateMounts = true; SystemCallArchitectures = "native"; - SystemCallFilter = ["@system-service" "~@privileged"]; + SystemCallFilter = [ + "@system-service" + "~@privileged" + ]; MemoryDenyWriteExecute = true; }; }; diff --git a/modules/services/oura.nix b/modules/services/oura.nix index 8ebcaa3..01ee6a2 100644 --- a/modules/services/oura.nix +++ b/modules/services/oura.nix @@ -3,15 +3,17 @@ pkgs, lib, ... -}: let +}: +let cfg = config.services.oura; - settingsFormat = pkgs.formats.toml {}; -in { + settingsFormat = pkgs.formats.toml { }; +in +{ options = { services.oura = { enable = lib.mkEnableOption "oura"; - package = lib.mkPackageOption pkgs "oura" {}; + package = lib.mkPackageOption pkgs "oura" { }; stateDir = lib.mkOption { description = "State directory for oura service"; @@ -34,9 +36,9 @@ in { settings = lib.mkOption { type = lib.types.submodule { freeformType = settingsFormat.type; - options = {}; + options = { }; }; - default = {}; + default = { }; description = '' Freeform attrset that generates the TOML configuration file used by Oura. ''; @@ -58,12 +60,12 @@ in { isSystemUser = true; inherit (cfg) group; home = cfg.stateDir; - extraGroups = ["cardano-node"]; + extraGroups = [ "cardano-node" ]; }; - users.groups.oura = lib.mkIf (cfg.group == "oura") {}; + users.groups.oura = lib.mkIf (cfg.group == "oura") { }; systemd.services.oura = { - wantedBy = ["multi-user.target"]; + wantedBy = [ "multi-user.target" ]; serviceConfig = { ExecStart = "${cfg.package}/bin/oura daemon --config ${cfg.configFile}"; Group = cfg.group; @@ -72,7 +74,7 @@ in { WorkingDirectory = cfg.stateDir; # Security UMask = "0077"; - AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; DevicePolicy = "closed"; LockPersonality = true; MemoryDenyWriteExecute = true; @@ -90,12 +92,16 @@ in { ProtectKernelTunables = true; ProtectProc = "invisible"; RemoveIPC = true; - RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; SystemCallArchitectures = "native"; - SystemCallFilter = ["~@cpu-emulation @resources @debug @keyring @mount @obsolete @privileged @setuid"]; + SystemCallFilter = [ "~@cpu-emulation @resources @debug @keyring @mount @obsolete @privileged @setuid" ]; }; }; }; diff --git a/packages/cardano.nix b/packages/cardano.nix index bbbe244..070f49f 100644 --- a/packages/cardano.nix +++ b/packages/cardano.nix @@ -1,7 +1,10 @@ -{inputs, ...}: { - perSystem = {system, ...}: { - packages = { - inherit (inputs.cardano-node.packages.${system}) cardano-cli cardano-node; +{ inputs, ... }: +{ + perSystem = + { system, ... }: + { + packages = { + inherit (inputs.cardano-node.packages.${system}) cardano-cli cardano-node; + }; }; - }; } diff --git a/packages/default.nix b/packages/default.nix index 647b5a6..0131145 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -1,4 +1,5 @@ -{config, ...}: { +{ config, ... }: +{ imports = [ ./cardano.nix ./ogmios.nix @@ -7,7 +8,13 @@ ]; flake.overlays = { default = final: _prev: { - inherit ((config.perSystem final.system).packages) cardano-cli cardano-node ogmios kupo oura; + inherit ((config.perSystem final.system).packages) + cardano-cli + cardano-node + ogmios + kupo + oura + ; }; }; } diff --git a/packages/kupo.nix b/packages/kupo.nix index ce1678f..18ba9d1 100644 --- a/packages/kupo.nix +++ b/packages/kupo.nix @@ -1,9 +1,9 @@ let truncateVersion = version: builtins.head (builtins.match "v?([0-9]+\\.[0-9]+).*" version); mkUrl = system: version: "https://github.com/CardanoSolutions/kupo/releases/download/v${truncateVersion version}/kupo-${version}-${system}.zip"; - mkPackage = pkgs: version: hash: - pkgs.fetchzip - { + mkPackage = + pkgs: version: hash: + pkgs.fetchzip { url = mkUrl pkgs.system version; inherit hash; stripRoot = false; @@ -14,8 +14,11 @@ let inherit version; inherit mkPackage; }; -in { - perSystem = {pkgs, ...}: { - packages.kupo = mkPackage pkgs "2.9.0" "sha256-sEfaFPph1qBuPrxQzFeTKU/9i9w0KF/v7GpxxmorPWQ="; - }; +in +{ + perSystem = + { pkgs, ... }: + { + packages.kupo = mkPackage pkgs "2.9.0" "sha256-sEfaFPph1qBuPrxQzFeTKU/9i9w0KF/v7GpxxmorPWQ="; + }; } diff --git a/packages/ogmios.nix b/packages/ogmios.nix index d66e0d8..9729274 100644 --- a/packages/ogmios.nix +++ b/packages/ogmios.nix @@ -1,8 +1,8 @@ let mkUrl = system: version: "https://github.com/CardanoSolutions/ogmios/releases/download/v${version}/ogmios-v${version}-${system}.zip"; - mkPackage = pkgs: version: hash: - pkgs.fetchzip - { + mkPackage = + pkgs: version: hash: + pkgs.fetchzip { name = "ogmios-${version}"; url = mkUrl pkgs.system version; inherit hash; @@ -13,8 +13,11 @@ let inherit version; inherit mkPackage; }; -in { - perSystem = {pkgs, ...}: { - packages.ogmios = mkPackage pkgs "6.8.0" "sha256-PM3tB6YdFsXRxGptDuxOvLke0m/08ySy4oV1WfIu//g="; - }; +in +{ + perSystem = + { pkgs, ... }: + { + packages.ogmios = mkPackage pkgs "6.8.0" "sha256-PM3tB6YdFsXRxGptDuxOvLke0m/08ySy4oV1WfIu//g="; + }; } diff --git a/packages/oura.nix b/packages/oura.nix index cf8fb08..0229540 100644 --- a/packages/oura.nix +++ b/packages/oura.nix @@ -1,16 +1,20 @@ -{inputs, ...}: { - perSystem = {pkgs, ...}: let - craneLib = inputs.crane.mkLib pkgs; - oura = craneLib.buildPackage { - cargoExtraArgs = "--all-features"; # Enable all bundled plugins - env = { - OPENSSL_NO_VENDOR = "1"; # Use system openssl +{ inputs, ... }: +{ + perSystem = + { pkgs, ... }: + let + craneLib = inputs.crane.mkLib pkgs; + oura = craneLib.buildPackage { + cargoExtraArgs = "--all-features"; # Enable all bundled plugins + env = { + OPENSSL_NO_VENDOR = "1"; # Use system openssl + }; + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = [ pkgs.openssl ]; + src = craneLib.cleanCargoSource inputs.oura; }; - nativeBuildInputs = [pkgs.pkg-config]; - buildInputs = [pkgs.openssl]; - src = craneLib.cleanCargoSource inputs.oura; + in + { + packages.oura = oura; }; - in { - packages.oura = oura; - }; } diff --git a/shell/default.nix b/shell/default.nix index dfbb3ba..c5a10fc 100644 --- a/shell/default.nix +++ b/shell/default.nix @@ -1,40 +1,43 @@ -{inputs, ...}: { +{ inputs, ... }: +{ imports = [ inputs.devshell.flakeModule inputs.pre-commit-hooks-nix.flakeModule ]; - perSystem = { - pkgs, - config, - ... - }: { - devshells.default = { - devshell = { - name = "cardano.nix"; - motd = '' - ❄️ Welcome to the {14}{bold}cardano.nix{reset} devshell ❄️ - $(type -p menu &>/dev/null && menu) - $(type -p update-pre-commit-hooks &>/dev/null && update-pre-commit-hooks) - ''; + perSystem = + { + pkgs, + config, + ... + }: + { + devshells.default = { + devshell = { + name = "cardano.nix"; + motd = '' + ❄️ Welcome to the {14}{bold}cardano.nix{reset} devshell ❄️ + $(type -p menu &>/dev/null && menu) + $(type -p update-pre-commit-hooks &>/dev/null && update-pre-commit-hooks) + ''; + }; + packages = with pkgs; [ + statix + config.treefmt.build.wrapper + reuse + ]; + commands = [ + { + name = "update-pre-commit-hooks"; + command = config.pre-commit.installationScript; + category = "tools"; + help = "update git pre-commit hooks"; + } + ]; + }; + pre-commit.settings = { + hooks.treefmt.enable = true; + settings.treefmt.package = config.treefmt.build.wrapper; }; - packages = with pkgs; [ - statix - config.treefmt.build.wrapper - reuse - ]; - commands = [ - { - name = "update-pre-commit-hooks"; - command = config.pre-commit.installationScript; - category = "tools"; - help = "update git pre-commit hooks"; - } - ]; - }; - pre-commit.settings = { - hooks.treefmt.enable = true; - settings.treefmt.package = config.treefmt.build.wrapper; }; - }; } diff --git a/templates/cluster/flake.nix b/templates/cluster/flake.nix index feffdbd..990b524 100644 --- a/templates/cluster/flake.nix +++ b/templates/cluster/flake.nix @@ -4,63 +4,80 @@ cardano-nix.url = "github:mlabs-haskell/cardano.nix/main"; nixpkgs.follows = "cardano-nix/nixpkgs"; }; - outputs = { - cardano-nix, - nixpkgs, - ... - }: { - nixosConfigurations = { - node1 = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [{networking.hostName = "node1";} ./preview.nix cardano-nix.nixosModules.default]; - }; - node2 = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [{networking.hostName = "node2";} ./preview.nix cardano-nix.nixosModules.default]; - }; - node3 = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [{networking.hostName = "node3";} ./preview.nix cardano-nix.nixosModules.default]; - }; - status = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [./status.nix cardano-nix.nixosModules.default]; - }; - proxy = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [./proxy.nix cardano-nix.nixosModules.default]; - }; - }; - packages.x86_64-linux = { - vms = - ((import (nixpkgs.outPath + "/nixos/lib") {}).runTest { - name = "cluster"; - imports = [ - { - nodes.node1 = ./preview.nix; - nodes.node2 = ./preview.nix; - nodes.node3 = ./preview.nix; - nodes.status = ./status.nix; - nodes.proxy = ./proxy.nix; - testScript = _: '' - start_all() - join_all() - while True: - proxy.sleep(60) - ''; - } + outputs = + { + cardano-nix, + nixpkgs, + ... + }: + { + nixosConfigurations = { + node1 = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + { networking.hostName = "node1"; } + ./preview.nix + cardano-nix.nixosModules.default + ]; + }; + node2 = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + { networking.hostName = "node2"; } + ./preview.nix + cardano-nix.nixosModules.default + ]; + }; + node3 = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + { networking.hostName = "node3"; } + ./preview.nix + cardano-nix.nixosModules.default + ]; + }; + status = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./status.nix + cardano-nix.nixosModules.default ]; - hostPkgs = nixpkgs.legacyPackages.x86_64-linux; - defaults.imports = [ - ./vm.nix + }; + proxy = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./proxy.nix cardano-nix.nixosModules.default - # Fix missing `pkgs.system` in tests. - {nixpkgs.overlays = [(_: _: {inherit (nixpkgs.legacyPackages.x86_64-linux) system;})];} ]; - }) - .config - .result - .driver; + }; + }; + packages.x86_64-linux = { + vms = + ((import (nixpkgs.outPath + "/nixos/lib") { }).runTest { + name = "cluster"; + imports = [ + { + nodes.node1 = ./preview.nix; + nodes.node2 = ./preview.nix; + nodes.node3 = ./preview.nix; + nodes.status = ./status.nix; + nodes.proxy = ./proxy.nix; + testScript = _: '' + start_all() + join_all() + while True: + proxy.sleep(60) + ''; + } + ]; + hostPkgs = nixpkgs.legacyPackages.x86_64-linux; + defaults.imports = [ + ./vm.nix + cardano-nix.nixosModules.default + # Fix missing `pkgs.system` in tests. + { nixpkgs.overlays = [ (_: _: { inherit (nixpkgs.legacyPackages.x86_64-linux) system; }) ]; } + ]; + }).config.result.driver; + }; }; - }; } diff --git a/templates/cluster/preview.nix b/templates/cluster/preview.nix index a467191..cbb3f22 100644 --- a/templates/cluster/preview.nix +++ b/templates/cluster/preview.nix @@ -1,4 +1,5 @@ -{config, ...}: { +{ config, ... }: +{ cardano = { network = "preview"; node.enable = true; diff --git a/templates/cluster/proxy.nix b/templates/cluster/proxy.nix index 1ec5792..64ea24f 100644 --- a/templates/cluster/proxy.nix +++ b/templates/cluster/proxy.nix @@ -22,14 +22,18 @@ "node3" ]; - services.http-proxy.services.grafana.servers = ["status"]; + services.http-proxy.services.grafana.servers = [ "status" ]; }; # Enable Prometheus exporters and open firewall. Make sure not to expose these ports publicly when running in the cloud. cardano.monitoring.exporters.enable = true; # Configure services on separate ports, for easier forwarding from VM. Remove this if DNS is configured. - networking.firewall.allowedTCPPorts = [81 82 88]; + networking.firewall.allowedTCPPorts = [ + 81 + 82 + 88 + ]; services.nginx.virtualHosts.ogmios.listen = [ { addr = "0.0.0.0"; diff --git a/templates/cluster/status.nix b/templates/cluster/status.nix index eb7c206..1686fdd 100644 --- a/templates/cluster/status.nix +++ b/templates/cluster/status.nix @@ -1,7 +1,13 @@ { cardano.monitoring = { enable = true; - targets = ["proxy" "status" "node1" "node2" "node3"]; + targets = [ + "proxy" + "status" + "node1" + "node2" + "node3" + ]; }; # Grafana listen address. Do not expose this service publicly when running in the cloud, instead use the load balancer to proxy with HTTPS. diff --git a/templates/cluster/vm.nix b/templates/cluster/vm.nix index 80505b3..5d24e81 100644 --- a/templates/cluster/vm.nix +++ b/templates/cluster/vm.nix @@ -2,7 +2,8 @@ lib, modulesPath, ... -}: { +}: +{ imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") (modulesPath + "/profiles/qemu-guest.nix") diff --git a/templates/default/flake.nix b/templates/default/flake.nix index 20c6e95..3e5b4a0 100644 --- a/templates/default/flake.nix +++ b/templates/default/flake.nix @@ -4,22 +4,24 @@ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; cardano-nix.url = "github:mlabs-haskell/cardano.nix/main"; }; - outputs = inputs @ {self, ...}: { - nixosConfigurations = { - vm = inputs.nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - inputs.cardano-nix.nixosModules.default - ./preview.nix - ./vm.nix - ]; + outputs = + inputs@{ self, ... }: + { + nixosConfigurations = { + vm = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + inputs.cardano-nix.nixosModules.default + ./preview.nix + ./vm.nix + ]; + }; }; - }; - apps.x86_64-linux = { - vm = { - type = "app"; - program = "${self.nixosConfigurations.vm.config.system.build.vm}/bin/run-nixos-vm"; + apps.x86_64-linux = { + vm = { + type = "app"; + program = "${self.nixosConfigurations.vm.config.system.build.vm}/bin/run-nixos-vm"; + }; }; }; - }; } diff --git a/templates/default/vm.nix b/templates/default/vm.nix index a0f42eb..c6cc1fb 100644 --- a/templates/default/vm.nix +++ b/templates/default/vm.nix @@ -2,7 +2,8 @@ lib, modulesPath, ... -}: { +}: +{ imports = [ "${modulesPath}/virtualisation/qemu-vm.nix" "${modulesPath}/profiles/qemu-guest.nix" diff --git a/tests/blockfrost.nix b/tests/blockfrost.nix index 6408c98..8733ecb 100644 --- a/tests/blockfrost.nix +++ b/tests/blockfrost.nix @@ -2,32 +2,41 @@ perSystem.vmTests.tests.blockfrost = { impure = true; module = { - nodes.machine = {pkgs, ...}: { - cardano = { - network = "preview"; - cli.enable = true; - node.enable = true; - db-sync.enable = true; - db-sync.postgres.enable = true; - blockfrost.enable = true; - }; + nodes.machine = + { pkgs, ... }: + { + cardano = { + network = "preview"; + cli.enable = true; + node.enable = true; + db-sync.enable = true; + db-sync.postgres.enable = true; + blockfrost.enable = true; + }; - # We want to see what happens, if test failed - services.blockfrost.settings.server.debug = true; + # We want to see what happens, if test failed + services.blockfrost.settings.server.debug = true; - environment.systemPackages = with pkgs; [jq bc curl]; - }; + environment.systemPackages = with pkgs; [ + jq + bc + curl + ]; + }; - testScript = {nodes, ...}: let - magic = toString nodes.machine.config.cardano.networkNumber; - in '' - machine.wait_for_unit("cardano-node") - machine.wait_for_unit("cardano-node-socket") - machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") - machine.wait_for_unit("blockfrost-backend-ryo") - machine.wait_until_succeeds("curl --fail http://localhost:3000/health", timeout=60) - print(machine.succeed("systemd-analyze security blockfrost-backend-ryo")) - ''; + testScript = + { nodes, ... }: + let + magic = toString nodes.machine.config.cardano.networkNumber; + in + '' + machine.wait_for_unit("cardano-node") + machine.wait_for_unit("cardano-node-socket") + machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") + machine.wait_for_unit("blockfrost-backend-ryo") + machine.wait_until_succeeds("curl --fail http://localhost:3000/health", timeout=60) + print(machine.succeed("systemd-analyze security blockfrost-backend-ryo")) + ''; }; }; } diff --git a/tests/db-sync.nix b/tests/db-sync.nix index 3238aae..7f7b785 100644 --- a/tests/db-sync.nix +++ b/tests/db-sync.nix @@ -5,40 +5,50 @@ # Test runs impure to access the "preview" network. impure = true; module = { - nodes.machine = {pkgs, ...}: { - cardano = { - network = "preview"; - cli.enable = true; - node.enable = true; - db-sync.enable = true; + nodes.machine = + { pkgs, ... }: + { + cardano = { + network = "preview"; + cli.enable = true; + node.enable = true; + db-sync.enable = true; + }; + environment.systemPackages = with pkgs; [ + jq + bc + curl + postgresql + ]; }; - environment.systemPackages = with pkgs; [jq bc curl postgresql]; - }; - testScript = {nodes, ...}: let - cfg = nodes.machine; - inherit (cfg.services.cardano-db-sync.postgres) socketdir; - name = cfg.services.cardano-db-sync.postgres.database; - # get sync percentage, return true if it's above 0.000000001 - sql = "select (100 * (extract (epoch from (max (time) at time zone 'UTC')) - extract (epoch from (min (time) at time zone 'UTC'))) / (extract (epoch from (now () at time zone 'UTC')) - extract (epoch from (min (time) at time zone 'UTC')))) > 0.000000001 from block limit 1;"; - output = " ?column? \\n----------\\n t\\n(1 row)\\n\\n"; # postgres "true" result - in '' - import time - machine.wait_for_unit("cardano-db-sync") - i = 0 - timeout = 420 - while True: - (status, output) = machine.execute(r"""sudo -u postgres psql --no-password "host=${socketdir} user=postgres dbname=${name}" -c "${sql}" """) - if i >= timeout: - print("Can't wait forever for the dbsync to reach 0.000000001. Exiting - dbsync doesn't seem to sync.") - raise Exception("Timeout") - elif status == 0 and output == "${output}": - print("DbSync started syncing. Success.") - break - i += 1 - time.sleep(3) - print(machine.succeed("systemd-analyze security cardano-db-sync")) - ''; + testScript = + { nodes, ... }: + let + cfg = nodes.machine; + inherit (cfg.services.cardano-db-sync.postgres) socketdir; + name = cfg.services.cardano-db-sync.postgres.database; + # get sync percentage, return true if it's above 0.000000001 + sql = "select (100 * (extract (epoch from (max (time) at time zone 'UTC')) - extract (epoch from (min (time) at time zone 'UTC'))) / (extract (epoch from (now () at time zone 'UTC')) - extract (epoch from (min (time) at time zone 'UTC')))) > 0.000000001 from block limit 1;"; + output = " ?column? \\n----------\\n t\\n(1 row)\\n\\n"; # postgres "true" result + in + '' + import time + machine.wait_for_unit("cardano-db-sync") + i = 0 + timeout = 420 + while True: + (status, output) = machine.execute(r"""sudo -u postgres psql --no-password "host=${socketdir} user=postgres dbname=${name}" -c "${sql}" """) + if i >= timeout: + print("Can't wait forever for the dbsync to reach 0.000000001. Exiting - dbsync doesn't seem to sync.") + raise Exception("Timeout") + elif status == 0 and output == "${output}": + print("DbSync started syncing. Success.") + break + i += 1 + time.sleep(3) + print(machine.succeed("systemd-analyze security cardano-db-sync")) + ''; }; }; } diff --git a/tests/http.nix b/tests/http.nix index 801930c..cc66bb6 100644 --- a/tests/http.nix +++ b/tests/http.nix @@ -2,35 +2,41 @@ perSystem.vmTests.tests.http = { impure = true; module = { - nodes.node = {config, ...}: { - cardano = { - network = "preview"; - node.enable = true; - ogmios.enable = true; + nodes.node = + { config, ... }: + { + cardano = { + network = "preview"; + node.enable = true; + ogmios.enable = true; + }; + services.ogmios.host = "0.0.0.0"; + networking.firewall.allowedTCPPorts = [ config.services.ogmios.port ]; }; - services.ogmios.host = "0.0.0.0"; - networking.firewall.allowedTCPPorts = [config.services.ogmios.port]; - }; nodes.proxy = { cardano = { http.enable = true; }; - services.http-proxy.servers = ["node"]; + services.http-proxy.servers = [ "node" ]; }; - nodes.client = {pkgs, ...}: { - environment.systemPackages = [pkgs.curl]; - }; + nodes.client = + { pkgs, ... }: + { + environment.systemPackages = [ pkgs.curl ]; + }; - testScript = {nodes, ...}: '' - start_all() - node.wait_for_unit("ogmios") - node.wait_until_succeeds('curl --silent --fail http://127.0.0.1:1337/health') - proxy.wait_for_unit("nginx") - client.wait_until_succeeds('curl --silent --fail -H "Host: ogmios" http://proxy/health') - client.succeed('[ "${nodes.node.services.ogmios.package.version}" == "$(curl --silent --fail -H "Host: ogmios" http://proxy/version)" ]') - ''; + testScript = + { nodes, ... }: + '' + start_all() + node.wait_for_unit("ogmios") + node.wait_until_succeeds('curl --silent --fail http://127.0.0.1:1337/health') + proxy.wait_for_unit("nginx") + client.wait_until_succeeds('curl --silent --fail -H "Host: ogmios" http://proxy/health') + client.succeed('[ "${nodes.node.services.ogmios.package.version}" == "$(curl --silent --fail -H "Host: ogmios" http://proxy/version)" ]') + ''; }; }; } diff --git a/tests/kupo.nix b/tests/kupo.nix index 2d0f275..ccd55df 100644 --- a/tests/kupo.nix +++ b/tests/kupo.nix @@ -2,28 +2,37 @@ perSystem.vmTests.tests.kupo = { impure = true; module = { - nodes .machine = {pkgs, ...}: { - cardano = { - network = "preview"; - cli.enable = true; - node.enable = true; - ogmios.enable = true; - kupo.enable = true; - }; + nodes.machine = + { pkgs, ... }: + { + cardano = { + network = "preview"; + cli.enable = true; + node.enable = true; + ogmios.enable = true; + kupo.enable = true; + }; - environment.systemPackages = with pkgs; [jq bc curl]; - }; + environment.systemPackages = with pkgs; [ + jq + bc + curl + ]; + }; - testScript = {nodes, ...}: let - magic = toString nodes.machine.config.cardano.networkNumber; - in '' - machine.wait_for_unit("cardano-node") - machine.wait_for_unit("cardano-node-socket") - machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") - machine.wait_for_unit("kupo") - machine.succeed("curl --silent --fail http://localhost:1442/health") - print(machine.succeed("systemd-analyze security kupo")) - ''; + testScript = + { nodes, ... }: + let + magic = toString nodes.machine.config.cardano.networkNumber; + in + '' + machine.wait_for_unit("cardano-node") + machine.wait_for_unit("cardano-node-socket") + machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") + machine.wait_for_unit("kupo") + machine.succeed("curl --silent --fail http://localhost:1442/health") + print(machine.succeed("systemd-analyze security kupo")) + ''; }; }; } diff --git a/tests/load-balancer.nix b/tests/load-balancer.nix index 842d0b6..e5f6652 100644 --- a/tests/load-balancer.nix +++ b/tests/load-balancer.nix @@ -1,14 +1,17 @@ let - node = {config, ...}: { - cardano = { - network = "preview"; - node.enable = true; - ogmios.enable = true; + node = + { config, ... }: + { + cardano = { + network = "preview"; + node.enable = true; + ogmios.enable = true; + }; + services.ogmios.host = "0.0.0.0"; + networking.firewall.allowedTCPPorts = [ config.services.ogmios.port ]; }; - services.ogmios.host = "0.0.0.0"; - networking.firewall.allowedTCPPorts = [config.services.ogmios.port]; - }; -in { +in +{ perSystem.vmTests.tests.load-balancer = { impure = true; module = { @@ -20,7 +23,11 @@ in { nodes.proxy = { cardano.http.enable = true; - services.http-proxy.servers = ["node1" "node2" "node3"]; + services.http-proxy.servers = [ + "node1" + "node2" + "node3" + ]; virtualisation.forwardPorts = [ { @@ -31,18 +38,25 @@ in { ]; }; - nodes.client = {pkgs, ...}: { - environment.systemPackages = [pkgs.curl pkgs.iproute2]; - }; + nodes.client = + { pkgs, ... }: + { + environment.systemPackages = [ + pkgs.curl + pkgs.iproute2 + ]; + }; - testScript = {nodes, ...}: '' - start_all() - node1.wait_for_unit("ogmios") - node1.wait_until_succeeds('curl --silent --fail http://127.0.0.1:1337/health') - proxy.wait_for_unit("nginx") - client.wait_until_succeeds('curl --silent --fail -H "Host: ogmios" http://proxy/health') - client.succeed('[ "${nodes.node1.services.ogmios.package.version}" == "$(curl --silent --fail -H "Host: ogmios" http://proxy/version)" ]') - ''; + testScript = + { nodes, ... }: + '' + start_all() + node1.wait_for_unit("ogmios") + node1.wait_until_succeeds('curl --silent --fail http://127.0.0.1:1337/health') + proxy.wait_for_unit("nginx") + client.wait_until_succeeds('curl --silent --fail -H "Host: ogmios" http://proxy/health') + client.succeed('[ "${nodes.node1.services.ogmios.package.version}" == "$(curl --silent --fail -H "Host: ogmios" http://proxy/version)" ]') + ''; }; }; } diff --git a/tests/monitoring.nix b/tests/monitoring.nix index 2075ab0..6954144 100644 --- a/tests/monitoring.nix +++ b/tests/monitoring.nix @@ -2,15 +2,20 @@ perSystem.vmTests.tests.monitoring = { impure = true; module = { - nodes.machine = {pkgs, ...}: { - cardano = { - network = "preview"; - node.enable = true; - monitoring.enable = true; - }; + nodes.machine = + { pkgs, ... }: + { + cardano = { + network = "preview"; + node.enable = true; + monitoring.enable = true; + }; - environment.systemPackages = with pkgs; [jq bc]; - }; + environment.systemPackages = with pkgs; [ + jq + bc + ]; + }; testScript = '' machine.wait_for_unit("cardano-node") diff --git a/tests/node.nix b/tests/node.nix index d220c5e..8699e3f 100644 --- a/tests/node.nix +++ b/tests/node.nix @@ -2,24 +2,32 @@ perSystem.vmTests.tests.cardano-node = { impure = true; module = { - nodes.machine = {pkgs, ...}: { - cardano = { - network = "preview"; - cli.enable = true; - node.enable = true; - }; + nodes.machine = + { pkgs, ... }: + { + cardano = { + network = "preview"; + cli.enable = true; + node.enable = true; + }; - environment.systemPackages = with pkgs; [jq bc]; - }; + environment.systemPackages = with pkgs; [ + jq + bc + ]; + }; - testScript = {nodes, ...}: let - magic = toString nodes.machine.config.cardano.networkNumber; - in '' - machine.wait_for_unit("cardano-node") - machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") - print(machine.succeed("systemd-analyze security cardano-node")) - print('\nVM Test Succeeded.') - ''; + testScript = + { nodes, ... }: + let + magic = toString nodes.machine.config.cardano.networkNumber; + in + '' + machine.wait_for_unit("cardano-node") + machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") + print(machine.succeed("systemd-analyze security cardano-node")) + print('\nVM Test Succeeded.') + ''; }; }; } diff --git a/tests/ogmios.nix b/tests/ogmios.nix index 46cfb3e..c02d600 100644 --- a/tests/ogmios.nix +++ b/tests/ogmios.nix @@ -2,28 +2,37 @@ perSystem.vmTests.tests.ogmios = { impure = true; module = { - nodes.machine = {pkgs, ...}: { - cardano = { - network = "preview"; - cli.enable = true; - node.enable = true; - ogmios.enable = true; - }; + nodes.machine = + { pkgs, ... }: + { + cardano = { + network = "preview"; + cli.enable = true; + node.enable = true; + ogmios.enable = true; + }; - environment.systemPackages = with pkgs; [jq bc curl]; - }; + environment.systemPackages = with pkgs; [ + jq + bc + curl + ]; + }; - testScript = {nodes, ...}: let - magic = toString nodes.machine.config.cardano.networkNumber; - in '' - machine.wait_for_unit("cardano-node") - machine.wait_for_unit("cardano-node-socket") - machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") - machine.wait_for_unit("ogmios") - machine.succeed("curl --silent --fail http://localhost:1337/health") - machine.wait_until_succeeds("""[[ $(echo "$(curl --silent --fail http://localhost:1337/health | jq '.networkSynchronization' --raw-output) > 0.00001" | bc) == "1" ]]""") - print(machine.succeed("systemd-analyze security ogmios")) - ''; + testScript = + { nodes, ... }: + let + magic = toString nodes.machine.config.cardano.networkNumber; + in + '' + machine.wait_for_unit("cardano-node") + machine.wait_for_unit("cardano-node-socket") + machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") + machine.wait_for_unit("ogmios") + machine.succeed("curl --silent --fail http://localhost:1337/health") + machine.wait_until_succeeds("""[[ $(echo "$(curl --silent --fail http://localhost:1337/health | jq '.networkSynchronization' --raw-output) > 0.00001" | bc) == "1" ]]""") + print(machine.succeed("systemd-analyze security ogmios")) + ''; }; }; } diff --git a/tests/oura.nix b/tests/oura.nix index 7ecc80c..3b0335f 100644 --- a/tests/oura.nix +++ b/tests/oura.nix @@ -2,68 +2,77 @@ perSystem.vmTests.tests.oura = { impure = true; module = { - nodes.machine = {pkgs, ...}: { - cardano = { - network = "preview"; - cli.enable = true; - node.enable = true; - oura.enable = true; - oura.integrate = true; - }; + nodes.machine = + { pkgs, ... }: + { + cardano = { + network = "preview"; + cli.enable = true; + node.enable = true; + oura.enable = true; + oura.integrate = true; + }; - # Suppress excessive output from cardano-node, - # we assume that node works as it's ensured by other tests - services.cardano-node.extraServiceConfig = _: { - serviceConfig = { - StandardOutput = "null"; - StandardError = "null"; + # Suppress excessive output from cardano-node, + # we assume that node works as it's ensured by other tests + services.cardano-node.extraServiceConfig = _: { + serviceConfig = { + StandardOutput = "null"; + StandardError = "null"; + }; }; - }; - services.oura.settings = { - sink = { - type = "Logs"; - output_path = "/var/log/oura/oura.jsonl"; - output_format = "JSONL"; - max_bytes_per_file = 1000000; - max_total_files = 10; - compress_files = false; + services.oura.settings = { + sink = { + type = "Logs"; + output_path = "/var/log/oura/oura.jsonl"; + output_format = "JSONL"; + max_bytes_per_file = 1000000; + max_total_files = 10; + compress_files = false; + }; }; + # Writeable place for a "testing log file" + systemd.tmpfiles.rules = [ "d /var/log/oura 755 oura oura" ]; + environment.systemPackages = with pkgs; [ + jq + bc + curl + ]; }; - # Writeable place for a "testing log file" - systemd.tmpfiles.rules = ["d /var/log/oura 755 oura oura"]; - environment.systemPackages = with pkgs; [jq bc curl]; - }; - testScript = {nodes, ...}: let - magic = toString nodes.machine.config.cardano.networkNumber; - in '' - import json - machine.wait_for_unit("cardano-node") - machine.wait_for_unit("cardano-node-socket") - machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") - machine.wait_for_unit("oura") - lines = machine.succeed("tail /var/log/oura/oura.jsonl") - print(lines) - # Ensure that block/slot numbers monotonicaly grow - block_max = 0 - slot_max = 0 - for each in lines.strip().split("\n"): - each = each.strip() - js = json.loads(each) - # Very first record haven't block record - if not 'block' in js: - continue - slot = int(js["block"]["slot"]) - block = int(js["context"]["slot"]) - assert block > block_max - assert slot > slot_max - block_max, slot_max = block, slot - # Ensure that we seen few blocks - assert block_max > 0 - assert slot_max > 0 + testScript = + { nodes, ... }: + let + magic = toString nodes.machine.config.cardano.networkNumber; + in + '' + import json + machine.wait_for_unit("cardano-node") + machine.wait_for_unit("cardano-node-socket") + machine.wait_until_succeeds("""[[ $(echo "$(cardano-cli query tip --testnet-magic ${magic} | jq '.syncProgress' --raw-output) > 0.001" | bc) == "1" ]]""") + machine.wait_for_unit("oura") + lines = machine.succeed("tail /var/log/oura/oura.jsonl") + print(lines) + # Ensure that block/slot numbers monotonicaly grow + block_max = 0 + slot_max = 0 + for each in lines.strip().split("\n"): + each = each.strip() + js = json.loads(each) + # Very first record haven't block record + if not 'block' in js: + continue + slot = int(js["block"]["slot"]) + block = int(js["context"]["slot"]) + assert block > block_max + assert slot > slot_max + block_max, slot_max = block, slot + # Ensure that we seen few blocks + assert block_max > 0 + assert slot_max > 0 - print(machine.succeed("systemd-analyze security oura")) - ''; + print(machine.succeed("systemd-analyze security oura")) + ''; }; }; }