1{ lib, pkgs, ... }:
2let
3 oldNetbox = "netbox_4_2";
4 newNetbox = "netbox_4_3";
5
6 apiVersion =
7 version:
8 lib.pipe version [
9 (lib.splitString ".")
10 (lib.take 2)
11 (lib.concatStringsSep ".")
12 ];
13 oldApiVersion = apiVersion pkgs.${oldNetbox}.version;
14 newApiVersion = apiVersion pkgs.${newNetbox}.version;
15in
16{
17 name = "netbox-upgrade";
18
19 meta.maintainers = with lib.maintainers; [
20 minijackson
21 raitobezarius
22 ];
23
24 node.pkgsReadOnly = false;
25
26 nodes.machine =
27 let
28 pkgs' = pkgs;
29 in
30 { config, pkgs, ... }:
31 {
32 virtualisation.memorySize = 2048;
33 services.netbox = {
34 enable = true;
35 # Pick the NetBox package from this config's "pkgs" argument,
36 # so that `nixpkgs.config.permittedInsecurePackages` works
37 package = pkgs.${oldNetbox};
38 secretKeyFile = pkgs.writeText "secret" ''
39 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
40 '';
41 };
42
43 services.nginx = {
44 enable = true;
45
46 recommendedProxySettings = true;
47
48 virtualHosts.netbox = {
49 default = true;
50 locations."/".proxyPass = "http://localhost:${toString config.services.netbox.port}";
51 locations."/static/".alias = "/var/lib/netbox/static/";
52 };
53 };
54
55 users.users.nginx.extraGroups = [ "netbox" ];
56
57 networking.firewall.allowedTCPPorts = [ 80 ];
58
59 nixpkgs.config.permittedInsecurePackages = [ pkgs'.${oldNetbox}.name ];
60
61 specialisation.upgrade.configuration.services.netbox.package = lib.mkForce pkgs.${newNetbox};
62 };
63
64 testScript =
65 { nodes, ... }:
66 ''
67 start_all()
68 machine.wait_for_unit("netbox.target")
69 machine.wait_for_unit("nginx.service")
70 machine.wait_until_succeeds("journalctl --since -1m --unit netbox --grep Listening")
71
72 def api_version(headers):
73 header = [header for header in headers.splitlines() if header.startswith("API-Version:")][0]
74 return header.split()[1]
75
76 def check_api_version(version):
77 # Returns 403 with NetBox >= 4.0,
78 # but we still get the API version in the headers
79 headers = machine.succeed(
80 "curl -sSL http://localhost/api/ --head -H 'Content-Type: application/json'"
81 )
82 assert api_version(headers) == version
83
84 with subtest("NetBox version is the old one"):
85 check_api_version("${oldApiVersion}")
86
87 # Somehow, even though netbox-housekeeping.service has After=netbox.service,
88 # netbox-housekeeping.service and netbox.service still get started at the
89 # same time, making netbox-housekeeping fail (can't really do some house
90 # keeping job if the database is not correctly formed).
91 #
92 # So we don't check that the upgrade went well, we just check that
93 # netbox.service is active, and that netbox-housekeeping can be run
94 # successfully afterwards.
95 #
96 # This is not good UX, but the system should be working nonetheless.
97 machine.execute("${nodes.machine.system.build.toplevel}/specialisation/upgrade/bin/switch-to-configuration test >&2")
98
99 machine.wait_for_unit("netbox.service")
100 machine.succeed("systemctl start netbox-housekeeping.service")
101
102 with subtest("NetBox version is the new one"):
103 check_api_version("${newApiVersion}")
104 '';
105}