nixpkgs/nixos/modules/services/web-servers/tomcat.nix
Eelco Dolstra 29027fd1e1 Rewrite ‘with pkgs.lib’ -> ‘with lib’
Using pkgs.lib on the spine of module evaluation is problematic
because the pkgs argument depends on the result of module
evaluation. To prevent an infinite recursion, pkgs and some of the
modules are evaluated twice, which is inefficient. Using ‘with lib’
prevents this problem.
2014-04-14 16:26:48 +02:00

345 lines
13 KiB
Nix

{ config, lib, pkgs, ... }:
with 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
'';
};
};
}