at 25.11-pre 4.5 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 12 cfg = config.services.fcron; 13 14 queuelen = optionalString (cfg.queuelen != null) "-q ${toString cfg.queuelen}"; 15 16 # Duplicate code, also found in cron.nix. Needs deduplication. 17 systemCronJobs = '' 18 SHELL=${pkgs.bash}/bin/bash 19 PATH=${config.system.path}/bin:${config.system.path}/sbin 20 ${optionalString (config.services.cron.mailto != null) '' 21 MAILTO="${config.services.cron.mailto}" 22 ''} 23 NIX_CONF_DIR=/etc/nix 24 ${lib.concatStrings (map (job: job + "\n") config.services.cron.systemCronJobs)} 25 ''; 26 27 allowdeny = target: users: { 28 source = pkgs.writeText "fcron.${target}" (concatStringsSep "\n" users); 29 target = "fcron.${target}"; 30 mode = "644"; 31 gid = config.ids.gids.fcron; 32 }; 33 34in 35 36{ 37 38 ###### interface 39 40 options = { 41 42 services.fcron = { 43 44 enable = mkOption { 45 type = types.bool; 46 default = false; 47 description = "Whether to enable the {command}`fcron` daemon."; 48 }; 49 50 allow = mkOption { 51 type = types.listOf types.str; 52 default = [ "all" ]; 53 description = '' 54 Users allowed to use fcrontab and fcrondyn (one name per 55 line, `all` for everyone). 56 ''; 57 }; 58 59 deny = mkOption { 60 type = types.listOf types.str; 61 default = [ ]; 62 description = "Users forbidden from using fcron."; 63 }; 64 65 maxSerialJobs = mkOption { 66 type = types.int; 67 default = 1; 68 description = "Maximum number of serial jobs which can run simultaneously."; 69 }; 70 71 queuelen = mkOption { 72 type = types.nullOr types.int; 73 default = null; 74 description = "Number of jobs the serial queue and the lavg queue can contain."; 75 }; 76 77 systab = mkOption { 78 type = types.lines; 79 default = ""; 80 description = ''The "system" crontab contents.''; 81 }; 82 }; 83 84 }; 85 86 ###### implementation 87 88 config = mkIf cfg.enable { 89 90 services.fcron.systab = systemCronJobs; 91 92 environment.etc = listToAttrs ( 93 map 94 (x: { 95 name = x.target; 96 value = x; 97 }) 98 [ 99 (allowdeny "allow" (cfg.allow)) 100 (allowdeny "deny" cfg.deny) 101 # see man 5 fcron.conf 102 { 103 source = 104 let 105 isSendmailWrapped = lib.hasAttr "sendmail" config.security.wrappers; 106 sendmailPath = 107 if isSendmailWrapped then "/run/wrappers/bin/sendmail" else "${config.system.path}/bin/sendmail"; 108 in 109 pkgs.writeText "fcron.conf" '' 110 fcrontabs = /var/spool/fcron 111 pidfile = /run/fcron.pid 112 fifofile = /run/fcron.fifo 113 fcronallow = /etc/fcron.allow 114 fcrondeny = /etc/fcron.deny 115 shell = /bin/sh 116 sendmail = ${sendmailPath} 117 editor = ${pkgs.vim}/bin/vim 118 ''; 119 target = "fcron.conf"; 120 gid = config.ids.gids.fcron; 121 mode = "0644"; 122 } 123 ] 124 ); 125 126 environment.systemPackages = [ pkgs.fcron ]; 127 users.users.fcron = { 128 uid = config.ids.uids.fcron; 129 home = "/var/spool/fcron"; 130 group = "fcron"; 131 }; 132 users.groups.fcron.gid = config.ids.gids.fcron; 133 134 security.wrappers = { 135 fcrontab = { 136 source = "${pkgs.fcron}/bin/fcrontab"; 137 owner = "fcron"; 138 group = "fcron"; 139 setgid = true; 140 setuid = true; 141 }; 142 fcrondyn = { 143 source = "${pkgs.fcron}/bin/fcrondyn"; 144 owner = "fcron"; 145 group = "fcron"; 146 setgid = true; 147 setuid = false; 148 }; 149 fcronsighup = { 150 source = "${pkgs.fcron}/bin/fcronsighup"; 151 owner = "root"; 152 group = "fcron"; 153 setuid = true; 154 }; 155 }; 156 systemd.services.fcron = { 157 description = "fcron daemon"; 158 wantedBy = [ "multi-user.target" ]; 159 160 path = [ pkgs.fcron ]; 161 162 preStart = '' 163 install \ 164 --mode 0770 \ 165 --owner fcron \ 166 --group fcron \ 167 --directory /var/spool/fcron 168 # load system crontab file 169 /run/wrappers/bin/fcrontab -u systab - < ${pkgs.writeText "systab" cfg.systab} 170 ''; 171 172 serviceConfig = { 173 Type = "forking"; 174 ExecStart = "${pkgs.fcron}/sbin/fcron -m ${toString cfg.maxSerialJobs} ${queuelen}"; 175 }; 176 }; 177 }; 178}