29027fd1e1
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.
345 lines
13 KiB
Nix
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
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|