1{ config, pkgs, lib, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.rsyncd;
8
9 motdFile = builtins.toFile "rsyncd-motd" cfg.motd;
10
11 foreach = attrs: f:
12 concatStringsSep "\n" (mapAttrsToList f attrs);
13
14 cfgFile = ''
15 ${optionalString (cfg.motd != "") "motd file = ${motdFile}"}
16 ${optionalString (cfg.address != "") "address = ${cfg.address}"}
17 ${optionalString (cfg.port != 873) "port = ${toString cfg.port}"}
18 ${cfg.extraConfig}
19 ${foreach cfg.modules (name: module: ''
20 [${name}]
21 ${foreach module (k: v:
22 "${k} = ${v}"
23 )}
24 '')}
25 '';
26in
27
28{
29 options = {
30 services.rsyncd = {
31
32 enable = mkOption {
33 default = false;
34 description = "Whether to enable the rsync daemon.";
35 };
36
37 motd = mkOption {
38 type = types.string;
39 default = "";
40 description = ''
41 Message of the day to display to clients on each connect.
42 This usually contains site information and any legal notices.
43 '';
44 };
45
46 port = mkOption {
47 default = 873;
48 type = types.int;
49 description = "TCP port the daemon will listen on.";
50 };
51
52 address = mkOption {
53 default = "";
54 example = "192.168.1.2";
55 description = ''
56 IP address the daemon will listen on; rsyncd will listen on
57 all addresses if this is not specified.
58 '';
59 };
60
61 extraConfig = mkOption {
62 type = types.lines;
63 default = "";
64 description = ''
65 Lines of configuration to add to rsyncd globally.
66 See <command>man rsyncd.conf</command> for options.
67 '';
68 };
69
70 modules = mkOption {
71 default = {};
72 description = ''
73 A set describing exported directories.
74 See <command>man rsyncd.conf</command> for options.
75 '';
76 type = types.attrsOf (types.attrsOf types.str);
77 example =
78 { srv =
79 { path = "/srv";
80 "read only" = "yes";
81 comment = "Public rsync share.";
82 };
83 };
84 };
85
86 user = mkOption {
87 type = types.str;
88 default = "root";
89 description = ''
90 The user to run the daemon as.
91 By default the daemon runs as root.
92 '';
93 };
94
95 group = mkOption {
96 type = types.str;
97 default = "root";
98 description = ''
99 The group to run the daemon as.
100 By default the daemon runs as root.
101 '';
102 };
103
104 };
105 };
106
107 ###### implementation
108
109 config = mkIf cfg.enable {
110
111 environment.etc."rsyncd.conf".text = cfgFile;
112
113 systemd.services.rsyncd = {
114 description = "Rsync daemon";
115 wantedBy = [ "multi-user.target" ];
116 restartTriggers = [ config.environment.etc."rsyncd.conf".source ];
117 serviceConfig = {
118 ExecStart = "${pkgs.rsync}/bin/rsync --daemon --no-detach";
119 User = cfg.user;
120 Group = cfg.group;
121 };
122 };
123 };
124}