diff options
Diffstat (limited to 'nixos/modules/services/web-servers/tomcat.nix')
-rw-r--r-- | nixos/modules/services/web-servers/tomcat.nix | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/nixos/modules/services/web-servers/tomcat.nix b/nixos/modules/services/web-servers/tomcat.nix new file mode 100644 index 000000000000..a68828de5d8e --- /dev/null +++ b/nixos/modules/services/web-servers/tomcat.nix @@ -0,0 +1,344 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.services.tomcat; + tomcat = pkgs.tomcat6; +in + +{ + + ###### interface + + options = { + + services.tomcat = { + + enable = mkOption { + default = false; + description = "Whether to enable Apache Tomcat"; + }; + + baseDir = mkOption { + default = "/var/tomcat"; + description = "Location where Tomcat stores configuration files, webapplications and logfiles"; + }; + + extraGroups = mkOption { + default = []; + example = [ "users" ]; + description = "Defines extra groups to which the tomcat user belongs."; + }; + + user = mkOption { + default = "tomcat"; + description = "User account under which Apache Tomcat runs."; + }; + + group = mkOption { + default = "tomcat"; + description = "Group account under which Apache Tomcat runs."; + }; + + javaOpts = mkOption { + default = ""; + description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat"; + }; + + catalinaOpts = mkOption { + default = ""; + description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container"; + }; + + sharedLibs = mkOption { + default = []; + description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications"; + }; + + commonLibs = mkOption { + default = []; + description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications and the servlet container"; + }; + + webapps = mkOption { + default = [ tomcat ]; + description = "List containing WAR files or directories with WAR files which are web applications to be deployed on Tomcat"; + }; + + virtualHosts = mkOption { + default = []; + description = "List consisting of a virtual host name and a list of web applications to deploy on each virtual host"; + }; + + logPerVirtualHost = mkOption { + default = false; + description = "Whether to enable logging per virtual host."; + }; + + axis2 = { + + enable = mkOption { + default = false; + description = "Whether to enable an Apache Axis2 container"; + }; + + services = mkOption { + default = []; + description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2"; + }; + + }; + + }; + + }; + + + ###### implementation + + config = mkIf config.services.tomcat.enable { + + users.extraGroups = singleton + { name = "tomcat"; + gid = config.ids.gids.tomcat; + }; + + users.extraUsers = singleton + { name = "tomcat"; + uid = config.ids.uids.tomcat; + description = "Tomcat user"; + home = "/homeless-shelter"; + extraGroups = cfg.extraGroups; + }; + + jobs.tomcat = + { description = "Apache Tomcat server"; + + startOn = "started network-interfaces"; + stopOn = "stopping network-interfaces"; + + preStart = + '' + # Create the base directory + mkdir -p ${cfg.baseDir} + + # Create a symlink to the bin directory of the tomcat component + ln -sfn ${tomcat}/bin ${cfg.baseDir}/bin + + # Create a conf/ directory + mkdir -p ${cfg.baseDir}/conf + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/conf + + # Symlink the config files in the conf/ directory (except for catalina.properties and server.xml) + for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml) + do + ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i` + done + + # Create subdirectory for virtual hosts + mkdir -p ${cfg.baseDir}/virtualhosts + + # Create a modified catalina.properties file + # Change all references from CATALINA_HOME to CATALINA_BASE and add support for shared libraries + sed -e 's|''${catalina.home}|''${catalina.base}|g' \ + -e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \ + ${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties + + # Create a modified server.xml which also includes all virtual hosts + sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${ + 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)}" \ + ${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml + + # Create a logs/ directory + mkdir -p ${cfg.baseDir}/logs + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs + ${if cfg.logPerVirtualHost then + toString (map (h: '' + mkdir -p ${cfg.baseDir}/logs/${h.name} + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name} + '') cfg.virtualHosts) else ''''} + + # Create a temp/ directory + mkdir -p ${cfg.baseDir}/temp + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/temp + + # Create a lib/ directory + mkdir -p ${cfg.baseDir}/lib + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/lib + + # Create a shared/lib directory + mkdir -p ${cfg.baseDir}/shared/lib + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/shared/lib + + # Create a webapps/ directory + mkdir -p ${cfg.baseDir}/webapps + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps + + # Symlink all the given common libs files or paths into the lib/ directory + for i in ${tomcat} ${toString cfg.commonLibs} + do + if [ -f $i ] + then + # If the given web application is a file, symlink it into the common/lib/ directory + ln -sfn $i ${cfg.baseDir}/lib/`basename $i` + elif [ -d $i ] + then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/lib/* + do + ln -sfn $j ${cfg.baseDir}/lib/`basename $j` + done + fi + done + + # Symlink all the given shared libs files or paths into the shared/lib/ directory + for i in ${toString cfg.sharedLibs} + do + if [ -f $i ] + then + # If the given web application is a file, symlink it into the common/lib/ directory + ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i` + elif [ -d $i ] + then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/shared/lib/* + do + ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j` + done + fi + done + + # Symlink all the given web applications files or paths into the webapps/ directory + for i in ${toString cfg.webapps} + do + if [ -f $i ] + then + # If the given web application is a file, symlink it into the webapps/ directory + ln -sfn $i ${cfg.baseDir}/webapps/`basename $i` + elif [ -d $i ] + then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/webapps/* + do + ln -sfn $j ${cfg.baseDir}/webapps/`basename $j` + done + + # Also symlink the configuration files if they are included + if [ -d $i/conf/Catalina ] + then + for j in $i/conf/Catalina/* + do + mkdir -p ${cfg.baseDir}/conf/Catalina/localhost + ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` + done + fi + fi + done + + ${toString (map (virtualHost: '' + # Create webapps directory for the virtual host + mkdir -p ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps + + # Modify ownership + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps + + # Symlink all the given web applications files or paths into the webapps/ directory + # of this virtual host + for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}" + do + if [ -f $i ] + then + # If the given web application is a file, symlink it into the webapps/ directory + ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i` + elif [ -d $i ] + then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/webapps/* + do + ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j` + done + + # Also symlink the configuration files if they are included + if [ -d $i/conf/Catalina ] + then + for j in $i/conf/Catalina/* + do + mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name} + ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j` + done + fi + fi + done + + '' + ) cfg.virtualHosts) } + + # Create a work/ directory + mkdir -p ${cfg.baseDir}/work + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/work + + ${if cfg.axis2.enable then + '' + # Copy the Axis2 web application + cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps + + # Turn off addressing, which causes many errors + sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml + + # Modify permissions on the Axis2 application + chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2 + + # Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory + for i in ${toString cfg.axis2.services} + do + if [ -f $i ] + then + # If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services + ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i` + elif [ -d $i ] + then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/webapps/axis2/WEB-INF/services/* + do + ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j` + done + + # Also symlink the configuration files if they are included + if [ -d $i/conf/Catalina ] + then + for j in $i/conf/Catalina/* + do + ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` + done + fi + fi + done + '' + else ""} + + ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${tomcat}/bin/startup.sh' + ''; + + postStop = + '' + echo "Stopping tomcat..." + CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${tomcat}/bin/shutdown.sh + ''; + + }; + + }; + +} |