1{ lib, ... }:
2{
3 name = "ntpd-rs";
4
5 meta = {
6 maintainers = with lib.maintainers; [ fpletz ];
7 };
8
9 nodes = {
10 client = {
11 services.ntpd-rs = {
12 enable = true;
13 metrics.enable = false;
14 useNetworkingTimeServers = false;
15 settings = {
16 source = [
17 {
18 mode = "server";
19 address = "server";
20 }
21 ];
22 synchronization = {
23 minimum-agreeing-sources = 1;
24 };
25 };
26 };
27 };
28 server = {
29 networking.firewall = {
30 allowedTCPPorts = [
31 9975
32 ];
33 allowedUDPPorts = [
34 123
35 ];
36 };
37
38 services.ntpd-rs = {
39 enable = true;
40 metrics.enable = true;
41 settings = {
42 observability = {
43 metrics-exporter-listen = "[::]:9975";
44 };
45 server = [
46 { listen = "[::]:123"; }
47 ];
48 };
49 };
50 };
51 };
52
53 testScript =
54 { nodes, ... }:
55 ''
56 start_all()
57
58 for machine in (server, client):
59 machine.wait_for_unit('multi-user.target')
60 machine.succeed('systemctl is-active ntpd-rs.service')
61
62 client.fail('systemctl is-active ntpd-rs-metrics.service')
63 server.succeed('systemctl is-active ntpd-rs-metrics.service')
64
65 server.wait_for_open_port(9975)
66 client.succeed('curl http://server:9975/metrics | grep ntp_uptime_seconds')
67 server.fail('curl --fail --connect-timeout 2 http://client:9975/metrics | grep ntp_uptime_seconds')
68
69 client.succeed("ntp-ctl status | grep server:123")
70 server.succeed("ntp-ctl status | grep '\[::\]:123'")
71
72 client.succeed("grep '^mode = \"server\"' $(systemctl status ntpd-rs | grep -oE '/nix/store[^ ]*ntpd-rs.toml')")
73 server.succeed("grep '^mode = \"pool\"' $(systemctl status ntpd-rs | grep -oE '/nix/store[^ ]*ntpd-rs.toml')")
74 '';
75}