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}