at 17.09-beta 5.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4let 5 gunicorn = pkgs.pythonPackages.gunicorn; 6 bepasty = pkgs.bepasty; 7 gevent = pkgs.pythonPackages.gevent; 8 python = pkgs.pythonPackages.python; 9 cfg = config.services.bepasty; 10 user = "bepasty"; 11 group = "bepasty"; 12 default_home = "/var/lib/bepasty"; 13in 14{ 15 options.services.bepasty = { 16 enable = mkEnableOption "Bepasty servers"; 17 18 servers = mkOption { 19 default = {}; 20 description = '' 21 configure a number of bepasty servers which will be started with 22 gunicorn. 23 ''; 24 type = with types ; attrsOf (submodule ({ config, ... } : { 25 26 options = { 27 28 bind = mkOption { 29 type = types.str; 30 description = '' 31 Bind address to be used for this server. 32 ''; 33 example = "0.0.0.0:8000"; 34 default = "127.0.0.1:8000"; 35 }; 36 37 dataDir = mkOption { 38 type = types.str; 39 description = '' 40 Path to the directory where the pastes will be saved to 41 ''; 42 default = default_home+"/data"; 43 }; 44 45 defaultPermissions = mkOption { 46 type = types.str; 47 description = '' 48 default permissions for all unauthenticated accesses. 49 ''; 50 example = "read,create,delete"; 51 default = "read"; 52 }; 53 54 extraConfig = mkOption { 55 type = types.lines; 56 description = '' 57 Extra configuration for bepasty server to be appended on the 58 configuration. 59 see https://bepasty-server.readthedocs.org/en/latest/quickstart.html#configuring-bepasty 60 for all options. 61 ''; 62 default = ""; 63 example = '' 64 PERMISSIONS = { 65 'myadminsecret': 'admin,list,create,read,delete', 66 } 67 MAX_ALLOWED_FILE_SIZE = 5 * 1000 * 1000 68 ''; 69 }; 70 71 secretKey = mkOption { 72 type = types.str; 73 description = '' 74 server secret for safe session cookies, must be set. 75 76 Warning: this secret is stored in the WORLD-READABLE Nix store! 77 78 It's recommended to use <option>secretKeyFile</option> 79 which takes precedence over <option>secretKey</option>. 80 ''; 81 default = ""; 82 }; 83 84 secretKeyFile = mkOption { 85 type = types.nullOr types.str; 86 default = null; 87 description = '' 88 A file that contains the server secret for safe session cookies, must be set. 89 90 <option>secretKeyFile</option> takes precedence over <option>secretKey</option>. 91 92 Warning: when <option>secretKey</option> is non-empty <option>secretKeyFile</option> 93 defaults to a file in the WORLD-READABLE Nix store containing that secret. 94 ''; 95 }; 96 97 workDir = mkOption { 98 type = types.str; 99 description = '' 100 Path to the working directory (used for config and pidfile). 101 Defaults to the users home directory. 102 ''; 103 default = default_home; 104 }; 105 106 }; 107 config = { 108 secretKeyFile = mkDefault ( 109 if config.secretKey != "" 110 then toString (pkgs.writeTextFile { 111 name = "bepasty-secret-key"; 112 text = config.secretKey; 113 }) 114 else null 115 ); 116 }; 117 })); 118 }; 119 }; 120 121 config = mkIf cfg.enable { 122 123 environment.systemPackages = [ bepasty ]; 124 125 # creates gunicorn systemd service for each configured server 126 systemd.services = mapAttrs' (name: server: 127 nameValuePair ("bepasty-server-${name}-gunicorn") 128 ({ 129 description = "Bepasty Server ${name}"; 130 wantedBy = [ "multi-user.target" ]; 131 after = [ "network.target" ]; 132 restartIfChanged = true; 133 134 environment = let 135 penv = python.buildEnv.override { 136 extraLibs = [ bepasty gevent ]; 137 }; 138 in { 139 BEPASTY_CONFIG = "${server.workDir}/bepasty-${name}.conf"; 140 PYTHONPATH= "${penv}/${python.sitePackages}/"; 141 }; 142 143 serviceConfig = { 144 Type = "simple"; 145 PrivateTmp = true; 146 ExecStartPre = assert !isNull server.secretKeyFile; pkgs.writeScript "bepasty-server.${name}-init" '' 147 #!/bin/sh 148 mkdir -p "${server.workDir}" 149 mkdir -p "${server.dataDir}" 150 chown ${user}:${group} "${server.workDir}" "${server.dataDir}" 151 cat > ${server.workDir}/bepasty-${name}.conf <<EOF 152 SITENAME="${name}" 153 STORAGE_FILESYSTEM_DIRECTORY="${server.dataDir}" 154 SECRET_KEY="$(cat "${server.secretKeyFile}")" 155 DEFAULT_PERMISSIONS="${server.defaultPermissions}" 156 ${server.extraConfig} 157 EOF 158 ''; 159 ExecStart = ''${gunicorn}/bin/gunicorn bepasty.wsgi --name ${name} \ 160 -u ${user} \ 161 -g ${group} \ 162 --workers 3 --log-level=info \ 163 --bind=${server.bind} \ 164 --pid ${server.workDir}/gunicorn-${name}.pid \ 165 -k gevent 166 ''; 167 }; 168 }) 169 ) cfg.servers; 170 171 users.extraUsers = [{ 172 uid = config.ids.uids.bepasty; 173 name = user; 174 group = group; 175 home = default_home; 176 }]; 177 178 users.extraGroups = [{ 179 name = group; 180 gid = config.ids.gids.bepasty; 181 }]; 182 }; 183}