about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-01-25 18:01:20 +0000
committerGitHub <noreply@github.com>2022-01-25 18:01:20 +0000
commitbf793f213d8aa5607112cca7bff1639c76306e7a (patch)
tree7bfbdcc496449833680c58197d8c9bea684f7144 /nixos
parent48f17360d9eae59b5c8c56ff9dc2336f35cc27ae (diff)
parent12919b985b2e0ea65e7a31cb48a84647baf8152c (diff)
Merge master into staging-next
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/networking/bird.nix22
-rw-r--r--nixos/modules/services/security/tor.nix7
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/bird.nix205
4 files changed, 232 insertions, 3 deletions
diff --git a/nixos/modules/services/networking/bird.nix b/nixos/modules/services/networking/bird.nix
index c14adbda3c5ac..fc06cdaa6e58c 100644
--- a/nixos/modules/services/networking/bird.nix
+++ b/nixos/modules/services/networking/bird.nix
@@ -31,7 +31,23 @@ let
             default = true;
             description = ''
               Whether the config should be checked at build time.
-              Disabling this might become necessary if the config includes files not present during build time.
+              When the config can't be checked during build time, for example when it includes
+              other files, either disable this option or use <code>preCheckConfig</code> to create
+              the included files before checking.
+            '';
+          };
+          preCheckConfig = mkOption {
+            type = types.lines;
+            default = "";
+            example = ''
+              echo "cost 100;" > include.conf
+            '';
+            description = ''
+              Commands to execute before the config file check. The file to be checked will be
+              available as <code>${variant}.conf</code> in the current directory.
+
+              Files created with this option will not be available at service runtime, only during
+              build time checking.
             '';
           };
         };
@@ -45,7 +61,9 @@ let
           name = "${variant}.conf";
           text = cfg.config;
           checkPhase = optionalString cfg.checkConfig ''
-            ${pkg}/bin/${birdBin} -d -p -c $out
+            ln -s $out ${variant}.conf
+            ${cfg.preCheckConfig}
+            ${pkg}/bin/${birdBin} -d -p -c ${variant}.conf
           '';
         };
 
diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix
index f3ed1d160eed9..cafb44e124298 100644
--- a/nixos/modules/services/security/tor.nix
+++ b/nixos/modules/services/security/tor.nix
@@ -794,6 +794,11 @@ in
               };
             }));
           };
+          options.ShutdownWaitLength = mkOption {
+            type = types.int;
+            default = 30;
+            description = descriptionGeneric "ShutdownWaitLength";
+          };
           options.SocksPolicy = optionStrings "SocksPolicy" // {
             example = ["accept *:*"];
           };
@@ -977,7 +982,7 @@ in
         ExecStart = "${cfg.package}/bin/tor -f ${torrc}";
         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
         KillSignal = "SIGINT";
-        TimeoutSec = 30;
+        TimeoutSec = cfg.settings.ShutdownWaitLength + 30; # Wait a bit longer than ShutdownWaitLength before actually timing out
         Restart = "on-failure";
         LimitNOFILE = 32768;
         RuntimeDirectory = [
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 2f6e1dc9898f5..62bc8acef6063 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -46,6 +46,7 @@ in
   beanstalkd = handleTest ./beanstalkd.nix {};
   bees = handleTest ./bees.nix {};
   bind = handleTest ./bind.nix {};
+  bird = handleTest ./bird.nix {};
   bitcoind = handleTest ./bitcoind.nix {};
   bittorrent = handleTest ./bittorrent.nix {};
   blockbook-frontend = handleTest ./blockbook-frontend.nix {};
diff --git a/nixos/tests/bird.nix b/nixos/tests/bird.nix
new file mode 100644
index 0000000000000..50d397be14ee0
--- /dev/null
+++ b/nixos/tests/bird.nix
@@ -0,0 +1,205 @@
+# This test does a basic functionality check for all bird variants and demonstrates a use
+# of the preCheckConfig option.
+
+{ system ? builtins.currentSystem
+, pkgs ? import ../.. { inherit system; config = { }; }
+}:
+
+let
+  inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
+  inherit (pkgs.lib) optionalString;
+
+  hostShared = hostId: { pkgs, ... }: {
+    virtualisation.vlans = [ 1 ];
+
+    environment.systemPackages = with pkgs; [ jq ];
+
+    networking = {
+      useNetworkd = true;
+      useDHCP = false;
+      firewall.enable = false;
+    };
+
+    systemd.network.networks."01-eth1" = {
+      name = "eth1";
+      networkConfig.Address = "10.0.0.${hostId}/24";
+    };
+  };
+
+  birdTest = v4:
+    let variant = "bird${optionalString (!v4) "6"}"; in
+    makeTest {
+      name = variant;
+
+      nodes.host1 = makeBirdHost variant "1";
+      nodes.host2 = makeBirdHost variant "2";
+
+      testScript = makeTestScript variant v4 (!v4);
+    };
+
+  bird2Test = makeTest {
+    name = "bird2";
+
+    nodes.host1 = makeBird2Host "1";
+    nodes.host2 = makeBird2Host "2";
+
+    testScript = makeTestScript "bird2" true true;
+  };
+
+  makeTestScript = variant: v4: v6: ''
+    start_all()
+
+    host1.wait_for_unit("${variant}.service")
+    host2.wait_for_unit("${variant}.service")
+
+    ${optionalString v4 ''
+    with subtest("Waiting for advertised IPv4 routes"):
+      host1.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.2\")) | any'")
+      host2.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.1\")) | any'")
+    ''}
+    ${optionalString v6 ''
+    with subtest("Waiting for advertised IPv6 routes"):
+      host1.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::2\")) | any'")
+      host2.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::1\")) | any'")
+    ''}
+
+    with subtest("Check fake routes in preCheckConfig do not exists"):
+      ${optionalString v4 ''host1.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")''}
+      ${optionalString v4 ''host2.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")''}
+
+      ${optionalString v6 ''host1.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")''}
+      ${optionalString v6 ''host2.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")''}
+  '';
+
+  makeBirdHost = variant: hostId: { pkgs, ... }: {
+    imports = [ (hostShared hostId) ];
+
+    services.${variant} = {
+      enable = true;
+
+      config = ''
+        log syslog all;
+
+        debug protocols all;
+
+        router id 10.0.0.${hostId};
+
+        protocol device {
+        }
+
+        protocol kernel {
+          import none;
+          export all;
+        }
+
+        protocol static {
+          include "static.conf";
+        }
+
+        protocol ospf {
+          export all;
+          area 0 {
+            interface "eth1" {
+              hello 5;
+              wait 5;
+            };
+          };
+        }
+      '';
+
+      preCheckConfig =
+        let
+          route = { bird = "1.2.3.4/32"; bird6 = "fd00::/128"; }.${variant};
+        in
+        ''echo "route ${route} blackhole;" > static.conf'';
+    };
+
+    systemd.tmpfiles.rules =
+      let
+        route = { bird = "10.10.0.${hostId}/32"; bird6 = "fdff::${hostId}/128"; }.${variant};
+      in
+      [ "f /etc/bird/static.conf - - - - route ${route} blackhole;" ];
+  };
+
+  makeBird2Host = hostId: { pkgs, ... }: {
+    imports = [ (hostShared hostId) ];
+
+    services.bird2 = {
+      enable = true;
+
+      config = ''
+        log syslog all;
+
+        debug protocols all;
+
+        router id 10.0.0.${hostId};
+
+        protocol device {
+        }
+
+        protocol kernel kernel4 {
+          ipv4 {
+            import none;
+            export all;
+          };
+        }
+
+        protocol static static4 {
+          ipv4;
+          include "static4.conf";
+        }
+
+        protocol ospf v2 ospf4 {
+          ipv4 {
+            export all;
+          };
+          area 0 {
+            interface "eth1" {
+              hello 5;
+              wait 5;
+            };
+          };
+        }
+
+        protocol kernel kernel6 {
+          ipv6 {
+            import none;
+            export all;
+          };
+        }
+
+        protocol static static6 {
+          ipv6;
+          include "static6.conf";
+        }
+
+        protocol ospf v3 ospf6 {
+          ipv6 {
+            export all;
+          };
+          area 0 {
+            interface "eth1" {
+              hello 5;
+              wait 5;
+            };
+          };
+        }
+      '';
+
+      preCheckConfig = ''
+        echo "route 1.2.3.4/32 blackhole;" > static4.conf
+        echo "route fd00::/128 blackhole;" > static6.conf
+      '';
+    };
+
+    systemd.tmpfiles.rules = [
+      "f /etc/bird/static4.conf - - - - route 10.10.0.${hostId}/32 blackhole;"
+      "f /etc/bird/static6.conf - - - - route fdff::${hostId}/128 blackhole;"
+    ];
+  };
+in
+{
+  bird = birdTest true;
+  bird6 = birdTest false;
+  bird2 = bird2Test;
+}