1{ lib, config, pkgs, ... }:
2
3let
4 cfg = config.services.ntpd-rs;
5 format = pkgs.formats.toml { };
6 configFile = format.generate "ntpd-rs.toml" cfg.settings;
7in
8{
9 options.services.ntpd-rs = {
10 enable = lib.mkEnableOption "Network Time Service (ntpd-rs)";
11 metrics.enable = lib.mkEnableOption "ntpd-rs Prometheus Metrics Exporter";
12
13 package = lib.mkPackageOption pkgs "ntpd-rs" { };
14
15 useNetworkingTimeServers = lib.mkOption {
16 type = lib.types.bool;
17 default = true;
18 description = ''
19 Use source time servers from {var}`networking.timeServers` in config.
20 '';
21 };
22
23 settings = lib.mkOption {
24 type = lib.types.submodule {
25 freeformType = format.type;
26 };
27 default = { };
28 description = ''
29 Settings to write to {file}`ntp.toml`
30
31 See <https://docs.ntpd-rs.pendulum-project.org/man/ntp.toml.5>
32 for more information about available options.
33 '';
34 };
35 };
36
37 config = lib.mkIf cfg.enable {
38 assertions = [
39 {
40 assertion = !config.services.timesyncd.enable;
41 message = ''
42 `ntpd-rs` is not compatible with `services.timesyncd`. Please disable one of them.
43 '';
44 }
45 ];
46
47 environment.systemPackages = [ cfg.package ];
48 systemd.packages = [ cfg.package ];
49
50 services.timesyncd.enable = false;
51 systemd.services.systemd-timedated.environment = {
52 SYSTEMD_TIMEDATED_NTP_SERVICES = "ntpd-rs.service";
53 };
54
55 services.ntpd-rs.settings = {
56 observability = {
57 observation-path = lib.mkDefault "/var/run/ntpd-rs/observe";
58 };
59 source = lib.mkIf cfg.useNetworkingTimeServers (map
60 (ts: {
61 mode = "server";
62 address = ts;
63 })
64 config.networking.timeServers);
65 };
66
67 systemd.services.ntpd-rs = {
68 wantedBy = [ "multi-user.target" ];
69 serviceConfig = {
70 User = "";
71 Group = "";
72 DynamicUser = true;
73 ExecStart = [ "" "${lib.makeBinPath [ cfg.package ]}/ntp-daemon --config=${configFile}" ];
74 };
75 };
76
77 systemd.services.ntpd-rs-metrics = lib.mkIf cfg.metrics.enable {
78 wantedBy = [ "multi-user.target" ];
79 serviceConfig = {
80 User = "";
81 Group = "";
82 DynamicUser = true;
83 ExecStart = [ "" "${lib.makeBinPath [ cfg.package ]}/ntp-metrics-exporter --config=${configFile}" ];
84 };
85 };
86 };
87
88 meta.maintainers = with lib.maintainers; [ fpletz ];
89}