at 16.09-beta 13 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.tomcat; 8 tomcat = cfg.package; 9in 10 11{ 12 13 ###### interface 14 15 options = { 16 17 services.tomcat = { 18 19 enable = mkOption { 20 default = false; 21 description = "Whether to enable Apache Tomcat"; 22 }; 23 24 package = mkOption { 25 type = types.package; 26 default = pkgs.tomcat7; 27 defaultText = "pkgs.tomcat7"; 28 example = lib.literalExample "pkgs.tomcat8"; 29 description = '' 30 Which tomcat package to use. 31 ''; 32 }; 33 34 baseDir = mkOption { 35 default = "/var/tomcat"; 36 description = "Location where Tomcat stores configuration files, webapplications and logfiles"; 37 }; 38 39 extraGroups = mkOption { 40 default = []; 41 example = [ "users" ]; 42 description = "Defines extra groups to which the tomcat user belongs."; 43 }; 44 45 user = mkOption { 46 default = "tomcat"; 47 description = "User account under which Apache Tomcat runs."; 48 }; 49 50 group = mkOption { 51 default = "tomcat"; 52 description = "Group account under which Apache Tomcat runs."; 53 }; 54 55 javaOpts = mkOption { 56 default = ""; 57 description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat"; 58 }; 59 60 catalinaOpts = mkOption { 61 default = ""; 62 description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container"; 63 }; 64 65 sharedLibs = mkOption { 66 default = []; 67 description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications"; 68 }; 69 70 commonLibs = mkOption { 71 default = []; 72 description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications and the servlet container"; 73 }; 74 75 webapps = mkOption { 76 type = types.listOf types.package; 77 default = [ tomcat ]; 78 defaultText = "[ tomcat ]"; 79 description = "List containing WAR files or directories with WAR files which are web applications to be deployed on Tomcat"; 80 }; 81 82 virtualHosts = mkOption { 83 default = []; 84 description = "List consisting of a virtual host name and a list of web applications to deploy on each virtual host"; 85 }; 86 87 logPerVirtualHost = mkOption { 88 default = false; 89 description = "Whether to enable logging per virtual host."; 90 }; 91 92 jdk = mkOption { 93 type = types.package; 94 default = pkgs.jdk; 95 defaultText = "pkgs.jdk"; 96 description = "Which JDK to use."; 97 }; 98 99 axis2 = { 100 101 enable = mkOption { 102 default = false; 103 description = "Whether to enable an Apache Axis2 container"; 104 }; 105 106 services = mkOption { 107 default = []; 108 description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2"; 109 }; 110 111 }; 112 113 }; 114 115 }; 116 117 118 ###### implementation 119 120 config = mkIf config.services.tomcat.enable { 121 122 users.extraGroups = singleton 123 { name = "tomcat"; 124 gid = config.ids.gids.tomcat; 125 }; 126 127 users.extraUsers = singleton 128 { name = "tomcat"; 129 uid = config.ids.uids.tomcat; 130 description = "Tomcat user"; 131 home = "/homeless-shelter"; 132 extraGroups = cfg.extraGroups; 133 }; 134 135 systemd.services.tomcat = { 136 description = "Apache Tomcat server"; 137 wantedBy = [ "multi-user.target" ]; 138 after = [ "network-interfaces.target" ]; 139 serviceConfig.Type = "oneshot"; 140 serviceConfig.RemainAfterExit = true; 141 142 preStart = '' 143 # Create the base directory 144 mkdir -p ${cfg.baseDir} 145 146 # Create a symlink to the bin directory of the tomcat component 147 ln -sfn ${tomcat}/bin ${cfg.baseDir}/bin 148 149 # Create a conf/ directory 150 mkdir -p ${cfg.baseDir}/conf 151 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/conf 152 153 # Symlink the config files in the conf/ directory (except for catalina.properties and server.xml) 154 for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml) 155 do 156 ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i` 157 done 158 159 # Create subdirectory for virtual hosts 160 mkdir -p ${cfg.baseDir}/virtualhosts 161 162 # Create a modified catalina.properties file 163 # Change all references from CATALINA_HOME to CATALINA_BASE and add support for shared libraries 164 sed -e 's|''${catalina.home}|''${catalina.base}|g' \ 165 -e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \ 166 ${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties 167 168 # Create a modified server.xml which also includes all virtual hosts 169 sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${ 170 toString (map (virtualHost: ''<Host name=\"${virtualHost.name}\" appBase=\"virtualhosts/${virtualHost.name}/webapps\" unpackWARs=\"true\" autoDeploy=\"true\" xmlValidation=\"false\" xmlNamespaceAware=\"false\" >${if cfg.logPerVirtualHost then ''<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs/${virtualHost.name}\" prefix=\"${virtualHost.name}_access_log.\" pattern=\"combined\" resolveHosts=\"false\"/>'' else ""}</Host>'') cfg.virtualHosts)}" \ 171 ${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml 172 173 # Create a logs/ directory 174 mkdir -p ${cfg.baseDir}/logs 175 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs 176 ${if cfg.logPerVirtualHost then 177 toString (map (h: '' 178 mkdir -p ${cfg.baseDir}/logs/${h.name} 179 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name} 180 '') cfg.virtualHosts) else ''''} 181 182 # Create a temp/ directory 183 mkdir -p ${cfg.baseDir}/temp 184 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/temp 185 186 # Create a lib/ directory 187 mkdir -p ${cfg.baseDir}/lib 188 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/lib 189 190 # Create a shared/lib directory 191 mkdir -p ${cfg.baseDir}/shared/lib 192 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/shared/lib 193 194 # Create a webapps/ directory 195 mkdir -p ${cfg.baseDir}/webapps 196 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps 197 198 # Symlink all the given common libs files or paths into the lib/ directory 199 for i in ${tomcat} ${toString cfg.commonLibs} 200 do 201 if [ -f $i ] 202 then 203 # If the given web application is a file, symlink it into the common/lib/ directory 204 ln -sfn $i ${cfg.baseDir}/lib/`basename $i` 205 elif [ -d $i ] 206 then 207 # If the given web application is a directory, then iterate over the files 208 # in the special purpose directories and symlink them into the tomcat tree 209 210 for j in $i/lib/* 211 do 212 ln -sfn $j ${cfg.baseDir}/lib/`basename $j` 213 done 214 fi 215 done 216 217 # Symlink all the given shared libs files or paths into the shared/lib/ directory 218 for i in ${toString cfg.sharedLibs} 219 do 220 if [ -f $i ] 221 then 222 # If the given web application is a file, symlink it into the common/lib/ directory 223 ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i` 224 elif [ -d $i ] 225 then 226 # If the given web application is a directory, then iterate over the files 227 # in the special purpose directories and symlink them into the tomcat tree 228 229 for j in $i/shared/lib/* 230 do 231 ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j` 232 done 233 fi 234 done 235 236 # Symlink all the given web applications files or paths into the webapps/ directory 237 for i in ${toString cfg.webapps} 238 do 239 if [ -f $i ] 240 then 241 # If the given web application is a file, symlink it into the webapps/ directory 242 ln -sfn $i ${cfg.baseDir}/webapps/`basename $i` 243 elif [ -d $i ] 244 then 245 # If the given web application is a directory, then iterate over the files 246 # in the special purpose directories and symlink them into the tomcat tree 247 248 for j in $i/webapps/* 249 do 250 ln -sfn $j ${cfg.baseDir}/webapps/`basename $j` 251 done 252 253 # Also symlink the configuration files if they are included 254 if [ -d $i/conf/Catalina ] 255 then 256 for j in $i/conf/Catalina/* 257 do 258 mkdir -p ${cfg.baseDir}/conf/Catalina/localhost 259 ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` 260 done 261 fi 262 fi 263 done 264 265 ${toString (map (virtualHost: '' 266 # Create webapps directory for the virtual host 267 mkdir -p ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps 268 269 # Modify ownership 270 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps 271 272 # Symlink all the given web applications files or paths into the webapps/ directory 273 # of this virtual host 274 for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}" 275 do 276 if [ -f $i ] 277 then 278 # If the given web application is a file, symlink it into the webapps/ directory 279 ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i` 280 elif [ -d $i ] 281 then 282 # If the given web application is a directory, then iterate over the files 283 # in the special purpose directories and symlink them into the tomcat tree 284 285 for j in $i/webapps/* 286 do 287 ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j` 288 done 289 290 # Also symlink the configuration files if they are included 291 if [ -d $i/conf/Catalina ] 292 then 293 for j in $i/conf/Catalina/* 294 do 295 mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name} 296 ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j` 297 done 298 fi 299 fi 300 done 301 302 '' 303 ) cfg.virtualHosts) } 304 305 # Create a work/ directory 306 mkdir -p ${cfg.baseDir}/work 307 chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/work 308 309 ${if cfg.axis2.enable then 310 '' 311 # Copy the Axis2 web application 312 cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps 313 314 # Turn off addressing, which causes many errors 315 sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml 316 317 # Modify permissions on the Axis2 application 318 chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2 319 320 # Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory 321 for i in ${toString cfg.axis2.services} 322 do 323 if [ -f $i ] 324 then 325 # If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services 326 ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i` 327 elif [ -d $i ] 328 then 329 # If the given web application is a directory, then iterate over the files 330 # in the special purpose directories and symlink them into the tomcat tree 331 332 for j in $i/webapps/axis2/WEB-INF/services/* 333 do 334 ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j` 335 done 336 337 # Also symlink the configuration files if they are included 338 if [ -d $i/conf/Catalina ] 339 then 340 for j in $i/conf/Catalina/* 341 do 342 ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` 343 done 344 fi 345 fi 346 done 347 '' 348 else ""} 349 ''; 350 351 script = '' 352 ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${tomcat}/bin/startup.sh' 353 ''; 354 355 postStop = '' 356 echo "Stopping tomcat..." 357 CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${tomcat}/bin/shutdown.sh 358 ''; 359 360 }; 361 362 }; 363 364}