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