at 21.11-pre 5.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.firefox.syncserver; 7 8 defaultDbLocation = "/var/db/firefox-sync-server/firefox-sync-server.db"; 9 defaultSqlUri = "sqlite:///${defaultDbLocation}"; 10 11 syncServerIni = pkgs.writeText "syncserver.ini" '' 12 [DEFAULT] 13 overrides = ${cfg.privateConfig} 14 15 [server:main] 16 use = egg:gunicorn 17 host = ${cfg.listen.address} 18 port = ${toString cfg.listen.port} 19 20 [app:main] 21 use = egg:syncserver 22 23 [syncserver] 24 public_url = ${cfg.publicUrl} 25 ${optionalString (cfg.sqlUri != "") "sqluri = ${cfg.sqlUri}"} 26 allow_new_users = ${boolToString cfg.allowNewUsers} 27 28 [browserid] 29 backend = tokenserver.verifiers.LocalVerifier 30 audiences = ${removeSuffix "/" cfg.publicUrl} 31 ''; 32 33 user = "syncserver"; 34 group = "syncserver"; 35in 36 37{ 38 meta.maintainers = with lib.maintainers; [ nadrieril ]; 39 40 options = { 41 services.firefox.syncserver = { 42 enable = mkOption { 43 type = types.bool; 44 default = false; 45 description = '' 46 Whether to enable a Firefox Sync Server, this give the opportunity to 47 Firefox users to store all synchronized data on their own server. To use this 48 server, Firefox users should visit the <option>about:config</option>, and 49 replicate the following change 50 51 <screen> 52 services.sync.tokenServerURI: http://localhost:5000/token/1.0/sync/1.5 53 </screen> 54 55 where <option>http://localhost:5000/</option> corresponds to the 56 public url of the server. 57 ''; 58 }; 59 60 listen.address = mkOption { 61 type = types.str; 62 default = "127.0.0.1"; 63 example = "0.0.0.0"; 64 description = '' 65 Address on which the sync server listen to. 66 ''; 67 }; 68 69 listen.port = mkOption { 70 type = types.int; 71 default = 5000; 72 description = '' 73 Port on which the sync server listen to. 74 ''; 75 }; 76 77 publicUrl = mkOption { 78 type = types.str; 79 default = "http://localhost:5000/"; 80 example = "http://sync.example.com/"; 81 description = '' 82 Public URL with which firefox users can use to access the sync server. 83 ''; 84 }; 85 86 allowNewUsers = mkOption { 87 type = types.bool; 88 default = true; 89 description = '' 90 Whether to allow new-user signups on the server. Only request by 91 existing accounts will be honored. 92 ''; 93 }; 94 95 sqlUri = mkOption { 96 type = types.str; 97 default = defaultSqlUri; 98 example = "postgresql://scott:tiger@localhost/test"; 99 description = '' 100 The location of the database. This URL is composed of 101 <option>dialect[+driver]://user:password@host/dbname[?key=value..]</option>, 102 where <option>dialect</option> is a database name such as 103 <option>mysql</option>, <option>oracle</option>, <option>postgresql</option>, 104 etc., and <option>driver</option> the name of a DBAPI, such as 105 <option>psycopg2</option>, <option>pyodbc</option>, <option>cx_oracle</option>, 106 etc. The <link 107 xlink:href="http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#database-urls"> 108 SQLAlchemy documentation</link> provides more examples and describe the syntax of 109 the expected URL. 110 ''; 111 }; 112 113 privateConfig = mkOption { 114 type = types.str; 115 default = "/etc/firefox/syncserver-secret.ini"; 116 description = '' 117 The private config file is used to extend the generated config with confidential 118 information, such as the <option>syncserver.sqlUri</option> setting if it contains a 119 password, and the <option>syncserver.secret</option> setting is used by the server to 120 generate cryptographically-signed authentication tokens. 121 122 If this file does not exists, then it is created with a generated 123 <option>syncserver.secret</option> settings. 124 ''; 125 }; 126 }; 127 }; 128 129 config = mkIf cfg.enable { 130 131 systemd.services.syncserver = { 132 after = [ "network.target" ]; 133 description = "Firefox Sync Server"; 134 wantedBy = [ "multi-user.target" ]; 135 path = [ 136 pkgs.coreutils 137 (pkgs.python.withPackages (ps: [ pkgs.syncserver ps.gunicorn ])) 138 ]; 139 140 serviceConfig = { 141 User = user; 142 Group = group; 143 PermissionsStartOnly = true; 144 }; 145 146 preStart = '' 147 if ! test -e ${cfg.privateConfig}; then 148 mkdir -p $(dirname ${cfg.privateConfig}) 149 echo > ${cfg.privateConfig} '[syncserver]' 150 chmod 600 ${cfg.privateConfig} 151 echo >> ${cfg.privateConfig} "secret = $(head -c 20 /dev/urandom | sha1sum | tr -d ' -')" 152 fi 153 chmod 600 ${cfg.privateConfig} 154 chmod 755 $(dirname ${cfg.privateConfig}) 155 chown ${user}:${group} ${cfg.privateConfig} 156 157 '' + optionalString (cfg.sqlUri == defaultSqlUri) '' 158 if ! test -e $(dirname ${defaultDbLocation}); then 159 mkdir -m 700 -p $(dirname ${defaultDbLocation}) 160 chown ${user}:${group} $(dirname ${defaultDbLocation}) 161 fi 162 163 # Move previous database file if it exists 164 oldDb="/var/db/firefox-sync-server.db" 165 if test -f $oldDb; then 166 mv $oldDb ${defaultDbLocation} 167 chown ${user}:${group} ${defaultDbLocation} 168 fi 169 ''; 170 171 script = '' 172 gunicorn --paste ${syncServerIni} 173 ''; 174 }; 175 176 users.users.${user} = { 177 inherit group; 178 isSystemUser = true; 179 }; 180 181 users.groups.${group} = {}; 182 }; 183}