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