1{ pkgs, lib, config, options, ... }:
2
3with lib;
4
5let
6 cfg = config.services.openntpd;
7
8 package = pkgs.openntpd_nixos;
9
10 cfgFile = pkgs.writeText "openntpd.conf" ''
11 ${concatStringsSep "\n" (map (s: "server ${s}") cfg.servers)}
12 ${cfg.extraConfig}
13 '';
14
15 pidFile = "/run/openntpd.pid";
16
17in
18{
19 ###### interface
20
21 options.services.openntpd = {
22 enable = mkEnableOption "OpenNTP time synchronization server";
23
24 servers = mkOption {
25 default = config.services.ntp.servers;
26 type = types.listOf types.str;
27 inherit (options.services.ntp.servers) description;
28 };
29
30 extraConfig = mkOption {
31 type = with types; lines;
32 default = "";
33 example = ''
34 listen on 127.0.0.1
35 listen on ::1
36 '';
37 description = ''
38 Additional text appended to <filename>openntpd.conf</filename>.
39 '';
40 };
41
42 extraOptions = mkOption {
43 type = with types; string;
44 default = "";
45 example = "-s";
46 description = ''
47 Extra options used when launching openntpd.
48 '';
49 };
50 };
51
52 ###### implementation
53
54 config = mkIf cfg.enable {
55 services.timesyncd.enable = mkForce false;
56
57 # Add ntpctl to the environment for status checking
58 environment.systemPackages = [ package ];
59
60 users.extraUsers = singleton {
61 name = "ntp";
62 uid = config.ids.uids.ntp;
63 description = "OpenNTP daemon user";
64 home = "/var/empty";
65 };
66
67 systemd.services.openntpd = {
68 description = "OpenNTP Server";
69 wantedBy = [ "multi-user.target" ];
70 wants = [ "network-online.target" "time-sync.target" ];
71 before = [ "time-sync.target" ];
72 after = [ "dnsmasq.service" "bind.service" "network-online.target" ];
73 serviceConfig = {
74 ExecStart = "${package}/sbin/ntpd -f ${cfgFile} -p ${pidFile} ${cfg.extraOptions}";
75 Type = "forking";
76 PIDFile = pidFile;
77 };
78 };
79 };
80}