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