Move all of NixOS to nixos/ in preparation of the repository merge
This commit is contained in:
662
nixos/modules/services/web-servers/apache-httpd/default.nix
Normal file
662
nixos/modules/services/web-servers/apache-httpd/default.nix
Normal file
@@ -0,0 +1,662 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
mainCfg = config.services.httpd;
|
||||
|
||||
httpd = mainCfg.package;
|
||||
|
||||
version24 = !versionOlder httpd.version "2.4";
|
||||
|
||||
httpdConf = mainCfg.configFile;
|
||||
|
||||
php = pkgs.php.override { apacheHttpd = httpd; };
|
||||
|
||||
getPort = cfg: if cfg.port != 0 then cfg.port else if cfg.enableSSL then 443 else 80;
|
||||
|
||||
extraModules = attrByPath ["extraModules"] [] mainCfg;
|
||||
extraForeignModules = filter builtins.isAttrs extraModules;
|
||||
extraApacheModules = filter (x: !(builtins.isAttrs x)) extraModules; # I'd prefer using builtins.isString here, but doesn't exist yet
|
||||
|
||||
|
||||
makeServerInfo = cfg: {
|
||||
# Canonical name must not include a trailing slash.
|
||||
canonicalName =
|
||||
(if cfg.enableSSL then "https" else "http") + "://" +
|
||||
cfg.hostName +
|
||||
(if getPort cfg != (if cfg.enableSSL then 443 else 80) then ":${toString (getPort cfg)}" else "");
|
||||
|
||||
# Admin address: inherit from the main server if not specified for
|
||||
# a virtual host.
|
||||
adminAddr = if cfg.adminAddr != "" then cfg.adminAddr else mainCfg.adminAddr;
|
||||
|
||||
vhostConfig = cfg;
|
||||
serverConfig = mainCfg;
|
||||
fullConfig = config; # machine config
|
||||
};
|
||||
|
||||
|
||||
vhostOptions = import ./per-server-options.nix {
|
||||
inherit mkOption;
|
||||
forMainServer = false;
|
||||
};
|
||||
|
||||
vhosts = let
|
||||
makeVirtualHost = cfgIn:
|
||||
let
|
||||
# Fill in defaults for missing options.
|
||||
cfg = addDefaultOptionValues vhostOptions cfgIn;
|
||||
in cfg;
|
||||
in map makeVirtualHost mainCfg.virtualHosts;
|
||||
|
||||
|
||||
allHosts = [mainCfg] ++ vhosts;
|
||||
|
||||
|
||||
callSubservices = serverInfo: defs:
|
||||
let f = svc:
|
||||
let
|
||||
svcFunction =
|
||||
if svc ? function then svc.function
|
||||
else import "${./.}/${if svc ? serviceType then svc.serviceType else svc.serviceName}.nix";
|
||||
config = addDefaultOptionValues res.options
|
||||
(if svc ? config then svc.config else svc);
|
||||
defaults = {
|
||||
extraConfig = "";
|
||||
extraModules = [];
|
||||
extraModulesPre = [];
|
||||
extraPath = [];
|
||||
extraServerPath = [];
|
||||
globalEnvVars = [];
|
||||
robotsEntries = "";
|
||||
startupScript = "";
|
||||
enablePHP = false;
|
||||
phpOptions = "";
|
||||
options = {};
|
||||
};
|
||||
res = defaults // svcFunction { inherit config pkgs serverInfo php; };
|
||||
in res;
|
||||
in map f defs;
|
||||
|
||||
|
||||
# !!! callSubservices is expensive
|
||||
subservicesFor = cfg: callSubservices (makeServerInfo cfg) cfg.extraSubservices;
|
||||
|
||||
mainSubservices = subservicesFor mainCfg;
|
||||
|
||||
allSubservices = mainSubservices ++ concatMap subservicesFor vhosts;
|
||||
|
||||
|
||||
# !!! should be in lib
|
||||
writeTextInDir = name: text:
|
||||
pkgs.runCommand name {inherit text;} "ensureDir $out; echo -n \"$text\" > $out/$name";
|
||||
|
||||
|
||||
enableSSL = any (vhost: vhost.enableSSL) allHosts;
|
||||
|
||||
|
||||
# Names of modules from ${httpd}/modules that we want to load.
|
||||
apacheModules =
|
||||
[ # HTTP authentication mechanisms: basic and digest.
|
||||
"auth_basic" "auth_digest"
|
||||
|
||||
# Authentication: is the user who he claims to be?
|
||||
"authn_file" "authn_dbm" "authn_anon"
|
||||
(if version24 then "authn_core" else "authn_alias")
|
||||
|
||||
# Authorization: is the user allowed access?
|
||||
"authz_user" "authz_groupfile" "authz_host"
|
||||
|
||||
# Other modules.
|
||||
"ext_filter" "include" "log_config" "env" "mime_magic"
|
||||
"cern_meta" "expires" "headers" "usertrack" /* "unique_id" */ "setenvif"
|
||||
"mime" "dav" "status" "autoindex" "asis" "info" "dav_fs"
|
||||
"vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling"
|
||||
"userdir" "alias" "rewrite" "proxy" "proxy_http"
|
||||
]
|
||||
++ optionals version24 [
|
||||
"mpm_${mainCfg.multiProcessingModule}"
|
||||
"authz_core"
|
||||
"unixd"
|
||||
]
|
||||
++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
|
||||
++ optional enableSSL "ssl"
|
||||
++ extraApacheModules;
|
||||
|
||||
|
||||
allDenied = if version24 then ''
|
||||
Require all denied
|
||||
'' else ''
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
'';
|
||||
|
||||
allGranted = if version24 then ''
|
||||
Require all granted
|
||||
'' else ''
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
'';
|
||||
|
||||
|
||||
loggingConf = ''
|
||||
ErrorLog ${mainCfg.logDir}/error_log
|
||||
|
||||
LogLevel notice
|
||||
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b" common
|
||||
LogFormat "%{Referer}i -> %U" referer
|
||||
LogFormat "%{User-agent}i" agent
|
||||
|
||||
CustomLog ${mainCfg.logDir}/access_log ${mainCfg.logFormat}
|
||||
'';
|
||||
|
||||
|
||||
browserHacks = ''
|
||||
BrowserMatch "Mozilla/2" nokeepalive
|
||||
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
|
||||
BrowserMatch "RealPlayer 4\.0" force-response-1.0
|
||||
BrowserMatch "Java/1\.0" force-response-1.0
|
||||
BrowserMatch "JDK/1\.0" force-response-1.0
|
||||
BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
|
||||
BrowserMatch "^WebDrive" redirect-carefully
|
||||
BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully
|
||||
BrowserMatch "^gnome-vfs" redirect-carefully
|
||||
'';
|
||||
|
||||
|
||||
sslConf = ''
|
||||
SSLSessionCache shm:${mainCfg.stateDir}/ssl_scache(512000)
|
||||
|
||||
SSLMutex posixsem
|
||||
|
||||
SSLRandomSeed startup builtin
|
||||
SSLRandomSeed connect builtin
|
||||
'';
|
||||
|
||||
|
||||
mimeConf = ''
|
||||
TypesConfig ${httpd}/conf/mime.types
|
||||
|
||||
AddType application/x-x509-ca-cert .crt
|
||||
AddType application/x-pkcs7-crl .crl
|
||||
AddType application/x-httpd-php .php .phtml
|
||||
|
||||
<IfModule mod_mime_magic.c>
|
||||
MIMEMagicFile ${httpd}/conf/magic
|
||||
</IfModule>
|
||||
|
||||
AddEncoding x-compress Z
|
||||
AddEncoding x-gzip gz tgz
|
||||
'';
|
||||
|
||||
|
||||
perServerConf = isMainServer: cfg: let
|
||||
|
||||
serverInfo = makeServerInfo cfg;
|
||||
|
||||
subservices = callSubservices serverInfo cfg.extraSubservices;
|
||||
|
||||
documentRoot = if cfg.documentRoot != null then cfg.documentRoot else
|
||||
pkgs.runCommand "empty" {} "ensureDir $out";
|
||||
|
||||
documentRootConf = ''
|
||||
DocumentRoot "${documentRoot}"
|
||||
|
||||
<Directory "${documentRoot}">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
${allGranted}
|
||||
</Directory>
|
||||
'';
|
||||
|
||||
robotsTxt = pkgs.writeText "robots.txt" ''
|
||||
${# If this is a vhost, the include the entries for the main server as well.
|
||||
if isMainServer then ""
|
||||
else concatMapStrings (svc: svc.robotsEntries) mainSubservices}
|
||||
${concatMapStrings (svc: svc.robotsEntries) subservices}
|
||||
'';
|
||||
|
||||
robotsConf = ''
|
||||
Alias /robots.txt ${robotsTxt}
|
||||
'';
|
||||
|
||||
in ''
|
||||
ServerName ${serverInfo.canonicalName}
|
||||
|
||||
${concatMapStrings (alias: "ServerAlias ${alias}\n") cfg.serverAliases}
|
||||
|
||||
${if cfg.sslServerCert != "" then ''
|
||||
SSLCertificateFile ${cfg.sslServerCert}
|
||||
SSLCertificateKeyFile ${cfg.sslServerKey}
|
||||
'' else ""}
|
||||
|
||||
${if cfg.enableSSL then ''
|
||||
SSLEngine on
|
||||
'' else if enableSSL then /* i.e., SSL is enabled for some host, but not this one */
|
||||
''
|
||||
SSLEngine off
|
||||
'' else ""}
|
||||
|
||||
${if isMainServer || cfg.adminAddr != "" then ''
|
||||
ServerAdmin ${cfg.adminAddr}
|
||||
'' else ""}
|
||||
|
||||
${if !isMainServer && mainCfg.logPerVirtualHost then ''
|
||||
ErrorLog ${mainCfg.logDir}/error_log-${cfg.hostName}
|
||||
CustomLog ${mainCfg.logDir}/access_log-${cfg.hostName} ${cfg.logFormat}
|
||||
'' else ""}
|
||||
|
||||
${robotsConf}
|
||||
|
||||
${if isMainServer || cfg.documentRoot != null then documentRootConf else ""}
|
||||
|
||||
${if cfg.enableUserDir then ''
|
||||
|
||||
UserDir public_html
|
||||
UserDir disabled root
|
||||
|
||||
<Directory "/home/*/public_html">
|
||||
AllowOverride FileInfo AuthConfig Limit Indexes
|
||||
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
|
||||
<Limit GET POST OPTIONS>
|
||||
${allGranted}
|
||||
</Limit>
|
||||
<LimitExcept GET POST OPTIONS>
|
||||
${allDenied}
|
||||
</LimitExcept>
|
||||
</Directory>
|
||||
|
||||
'' else ""}
|
||||
|
||||
${if cfg.globalRedirect != "" then ''
|
||||
RedirectPermanent / ${cfg.globalRedirect}
|
||||
'' else ""}
|
||||
|
||||
${
|
||||
let makeFileConf = elem: ''
|
||||
Alias ${elem.urlPath} ${elem.file}
|
||||
'';
|
||||
in concatMapStrings makeFileConf cfg.servedFiles
|
||||
}
|
||||
|
||||
${
|
||||
let makeDirConf = elem: ''
|
||||
Alias ${elem.urlPath} ${elem.dir}/
|
||||
<Directory ${elem.dir}>
|
||||
Options +Indexes
|
||||
${allGranted}
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
'';
|
||||
in concatMapStrings makeDirConf cfg.servedDirs
|
||||
}
|
||||
|
||||
${concatMapStrings (svc: svc.extraConfig) subservices}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
|
||||
confFile = pkgs.writeText "httpd.conf" ''
|
||||
|
||||
ServerRoot ${httpd}
|
||||
|
||||
${optionalString version24 ''
|
||||
DefaultRuntimeDir ${mainCfg.stateDir}/runtime
|
||||
''}
|
||||
|
||||
PidFile ${mainCfg.stateDir}/httpd.pid
|
||||
|
||||
${optionalString (mainCfg.multiProcessingModule != "prefork") ''
|
||||
# mod_cgid requires this.
|
||||
ScriptSock ${mainCfg.stateDir}/cgisock
|
||||
''}
|
||||
|
||||
<IfModule prefork.c>
|
||||
MaxClients ${toString mainCfg.maxClients}
|
||||
MaxRequestsPerChild ${toString mainCfg.maxRequestsPerChild}
|
||||
</IfModule>
|
||||
|
||||
${let
|
||||
ports = map getPort allHosts;
|
||||
uniquePorts = uniqList {inputList = ports;};
|
||||
in concatMapStrings (port: "Listen ${toString port}\n") uniquePorts
|
||||
}
|
||||
|
||||
User ${mainCfg.user}
|
||||
Group ${mainCfg.group}
|
||||
|
||||
${let
|
||||
load = {name, path}: "LoadModule ${name}_module ${path}\n";
|
||||
allModules =
|
||||
concatMap (svc: svc.extraModulesPre) allSubservices
|
||||
++ map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules
|
||||
++ optional enablePHP { name = "php5"; path = "${php}/modules/libphp5.so"; }
|
||||
++ concatMap (svc: svc.extraModules) allSubservices
|
||||
++ extraForeignModules;
|
||||
in concatMapStrings load allModules
|
||||
}
|
||||
|
||||
AddHandler type-map var
|
||||
|
||||
<Files ~ "^\.ht">
|
||||
${allDenied}
|
||||
</Files>
|
||||
|
||||
${mimeConf}
|
||||
${loggingConf}
|
||||
${browserHacks}
|
||||
|
||||
Include ${httpd}/conf/extra/httpd-default.conf
|
||||
Include ${httpd}/conf/extra/httpd-autoindex.conf
|
||||
Include ${httpd}/conf/extra/httpd-multilang-errordoc.conf
|
||||
Include ${httpd}/conf/extra/httpd-languages.conf
|
||||
|
||||
${if enableSSL then sslConf else ""}
|
||||
|
||||
# Fascist default - deny access to everything.
|
||||
<Directory />
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
${allDenied}
|
||||
</Directory>
|
||||
|
||||
# But do allow access to files in the store so that we don't have
|
||||
# to generate <Directory> clauses for every generated file that we
|
||||
# want to serve.
|
||||
<Directory /nix/store>
|
||||
${allGranted}
|
||||
</Directory>
|
||||
|
||||
# Generate directives for the main server.
|
||||
${perServerConf true mainCfg}
|
||||
|
||||
# Always enable virtual hosts; it doesn't seem to hurt.
|
||||
${let
|
||||
ports = map getPort allHosts;
|
||||
uniquePorts = uniqList {inputList = ports;};
|
||||
directives = concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts;
|
||||
in optionalString (!version24) directives
|
||||
}
|
||||
|
||||
${let
|
||||
makeVirtualHost = vhost: ''
|
||||
<VirtualHost *:${toString (getPort vhost)}>
|
||||
${perServerConf false vhost}
|
||||
</VirtualHost>
|
||||
'';
|
||||
in concatMapStrings makeVirtualHost vhosts
|
||||
}
|
||||
'';
|
||||
|
||||
|
||||
enablePHP = any (svc: svc.enablePHP) allSubservices;
|
||||
|
||||
|
||||
# Generate the PHP configuration file. Should probably be factored
|
||||
# out into a separate module.
|
||||
phpIni = pkgs.runCommand "php.ini"
|
||||
{ options = concatStringsSep "\n"
|
||||
([ mainCfg.phpOptions ] ++ (map (svc: svc.phpOptions) allSubservices));
|
||||
}
|
||||
''
|
||||
cat ${php}/etc/php-recommended.ini > $out
|
||||
echo "$options" >> $out
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.httpd = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable the Apache httpd server.
|
||||
";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.apacheHttpd.override { mpm = mainCfg.multiProcessingModule; };
|
||||
example = "pkgs.apacheHttpd_2_4";
|
||||
description = "
|
||||
Overridable attribute of the Apache HTTP Server package to use.
|
||||
";
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
default = confFile;
|
||||
example = ''pkgs.writeText "httpd.conf" "# my custom config file ...";'';
|
||||
description = "
|
||||
Overridable config file to use for Apache. By default, use the
|
||||
file automatically generated by nixos.
|
||||
";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
description = "
|
||||
These configuration lines will be appended to the Apache config
|
||||
file. Note that this mechanism may not work when <option>configFile</option>
|
||||
is overridden.
|
||||
";
|
||||
};
|
||||
|
||||
extraModules = mkOption {
|
||||
default = [];
|
||||
example = [ "proxy_connect" { name = "php5"; path = "${php}/modules/libphp5.so"; } ];
|
||||
description = ''
|
||||
Specifies additional Apache modules. These can be specified
|
||||
as a string in the case of modules distributed with Apache,
|
||||
or as an attribute set specifying the
|
||||
<varname>name</varname> and <varname>path</varname> of the
|
||||
module.
|
||||
'';
|
||||
};
|
||||
|
||||
logPerVirtualHost = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
If enabled, each virtual host gets its own
|
||||
<filename>access_log</filename> and
|
||||
<filename>error_log</filename>, namely suffixed by the
|
||||
<option>hostName</option> of the virtual host.
|
||||
";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "wwwrun";
|
||||
description = "
|
||||
User account under which httpd runs. The account is created
|
||||
automatically if it doesn't exist.
|
||||
";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
default = "wwwrun";
|
||||
description = "
|
||||
Group under which httpd runs. The account is created
|
||||
automatically if it doesn't exist.
|
||||
";
|
||||
};
|
||||
|
||||
logDir = mkOption {
|
||||
default = "/var/log/httpd";
|
||||
description = "
|
||||
Directory for Apache's log files. It is created automatically.
|
||||
";
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
default = "/var/run/httpd";
|
||||
description = "
|
||||
Directory for Apache's transient runtime state (such as PID
|
||||
files). It is created automatically. Note that the default,
|
||||
<filename>/var/run/httpd</filename>, is deleted at boot time.
|
||||
";
|
||||
};
|
||||
|
||||
virtualHosts = mkOption {
|
||||
default = [];
|
||||
example = [
|
||||
{ hostName = "foo";
|
||||
documentRoot = "/data/webroot-foo";
|
||||
}
|
||||
{ hostName = "bar";
|
||||
documentRoot = "/data/webroot-bar";
|
||||
}
|
||||
];
|
||||
description = ''
|
||||
Specification of the virtual hosts served by Apache. Each
|
||||
element should be an attribute set specifying the
|
||||
configuration of the virtual host. The available options
|
||||
are the non-global options permissible for the main host.
|
||||
'';
|
||||
};
|
||||
|
||||
phpOptions = mkOption {
|
||||
default = "";
|
||||
example =
|
||||
''
|
||||
date.timezone = "CET"
|
||||
'';
|
||||
description =
|
||||
"Options appended to the PHP configuration file <filename>php.ini</filename>.";
|
||||
};
|
||||
|
||||
multiProcessingModule = mkOption {
|
||||
default = "prefork";
|
||||
example = "worker";
|
||||
type = types.uniq types.string;
|
||||
description =
|
||||
''
|
||||
Multi-processing module to be used by Apache. Available
|
||||
modules are <literal>prefork</literal> (the default;
|
||||
handles each request in a separate child process),
|
||||
<literal>worker</literal> (hybrid approach that starts a
|
||||
number of child processes each running a number of
|
||||
threads) and <literal>event</literal> (a recent variant of
|
||||
<literal>worker</literal> that handles persistent
|
||||
connections more efficiently).
|
||||
'';
|
||||
};
|
||||
|
||||
maxClients = mkOption {
|
||||
default = 150;
|
||||
example = 8;
|
||||
description = "Maximum number of httpd processes (prefork)";
|
||||
};
|
||||
|
||||
maxRequestsPerChild = mkOption {
|
||||
default = 0;
|
||||
example = 500;
|
||||
description =
|
||||
"Maximum number of httpd requests answered per httpd child (prefork), 0 means unlimited";
|
||||
};
|
||||
}
|
||||
|
||||
# Include the options shared between the main server and virtual hosts.
|
||||
// (import ./per-server-options.nix {
|
||||
inherit mkOption;
|
||||
forMainServer = true;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.httpd.enable {
|
||||
|
||||
users.extraUsers = optionalAttrs (mainCfg.user == "wwwrun") singleton
|
||||
{ name = "wwwrun";
|
||||
group = "wwwrun";
|
||||
description = "Apache httpd user";
|
||||
uid = config.ids.uids.wwwrun;
|
||||
};
|
||||
|
||||
users.extraGroups = optionalAttrs (mainCfg.group == "wwwrun") singleton
|
||||
{ name = "wwwrun";
|
||||
gid = config.ids.gids.wwwrun;
|
||||
};
|
||||
|
||||
environment.systemPackages = [httpd] ++ concatMap (svc: svc.extraPath) allSubservices;
|
||||
|
||||
services.httpd.phpOptions =
|
||||
''
|
||||
; Needed for PHP's mail() function.
|
||||
sendmail_path = sendmail -t -i
|
||||
|
||||
; Apparently PHP doesn't use $TZ.
|
||||
date.timezone = "${config.time.timeZone}"
|
||||
'';
|
||||
|
||||
systemd.services.httpd =
|
||||
{ description = "Apache HTTPD";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "keys.target" ];
|
||||
after = [ "network.target" "fs.target" "postgresql.service" "keys.target" ];
|
||||
|
||||
path =
|
||||
[ httpd pkgs.coreutils pkgs.gnugrep ]
|
||||
++ # Needed for PHP's mail() function. !!! Probably the
|
||||
# ssmtp module should export the path to sendmail in
|
||||
# some way.
|
||||
optional config.networking.defaultMailServer.directDelivery pkgs.ssmtp
|
||||
++ concatMap (svc: svc.extraServerPath) allSubservices;
|
||||
|
||||
environment =
|
||||
{ PHPRC = if enablePHP then phpIni else "";
|
||||
} // (listToAttrs (concatMap (svc: svc.globalEnvVars) allSubservices));
|
||||
|
||||
preStart =
|
||||
''
|
||||
mkdir -m 0750 -p ${mainCfg.stateDir}
|
||||
chown root.${mainCfg.group} ${mainCfg.stateDir}
|
||||
${optionalString version24 ''
|
||||
mkdir -m 0750 -p "${mainCfg.stateDir}/runtime"
|
||||
chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime"
|
||||
''}
|
||||
mkdir -m 0700 -p ${mainCfg.logDir}
|
||||
|
||||
${optionalString (mainCfg.documentRoot != null)
|
||||
''
|
||||
# Create the document root directory if does not exists yet
|
||||
mkdir -p ${mainCfg.documentRoot}
|
||||
''
|
||||
}
|
||||
|
||||
# Get rid of old semaphores. These tend to accumulate across
|
||||
# server restarts, eventually preventing it from restarting
|
||||
# successfully.
|
||||
for i in $(${pkgs.utillinux}/bin/ipcs -s | grep ' ${mainCfg.user} ' | cut -f2 -d ' '); do
|
||||
${pkgs.utillinux}/bin/ipcrm -s $i
|
||||
done
|
||||
|
||||
# Run the startup hooks for the subservices.
|
||||
for i in ${toString (map (svn: svn.startupScript) allSubservices)}; do
|
||||
echo Running Apache startup hook $i...
|
||||
$i
|
||||
done
|
||||
'';
|
||||
|
||||
serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}";
|
||||
serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop";
|
||||
serviceConfig.Type = "forking";
|
||||
serviceConfig.Restart = "always";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
303
nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
Normal file
303
nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
Normal file
@@ -0,0 +1,303 @@
|
||||
{ config, pkgs, serverInfo, php, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
mediawikiConfig = pkgs.writeText "LocalSettings.php"
|
||||
''
|
||||
<?php
|
||||
# Copied verbatim from the default (generated) LocalSettings.php.
|
||||
if( defined( 'MW_INSTALL_PATH' ) ) {
|
||||
$IP = MW_INSTALL_PATH;
|
||||
} else {
|
||||
$IP = dirname( __FILE__ );
|
||||
}
|
||||
|
||||
$path = array( $IP, "$IP/includes", "$IP/languages" );
|
||||
set_include_path( implode( PATH_SEPARATOR, $path ) . PATH_SEPARATOR . get_include_path() );
|
||||
|
||||
require_once( "$IP/includes/DefaultSettings.php" );
|
||||
|
||||
if ( $wgCommandLineMode ) {
|
||||
if ( isset( $_SERVER ) && array_key_exists( 'REQUEST_METHOD', $_SERVER ) ) {
|
||||
die( "This script must be run from the command line\n" );
|
||||
}
|
||||
}
|
||||
|
||||
$wgScriptPath = "${config.urlPrefix}";
|
||||
|
||||
# We probably need to set $wgSecretKey and $wgCacheEpoch.
|
||||
|
||||
# Paths to external programs.
|
||||
$wgDiff3 = "${pkgs.diffutils}/bin/diff3";
|
||||
$wgDiff = "${pkgs.diffutils}/bin/diff";
|
||||
$wgImageMagickConvertCommand = "${pkgs.imagemagick}/bin/convert";
|
||||
|
||||
#$wgDebugLogFile = "/tmp/mediawiki_debug_log.txt";
|
||||
|
||||
# Database configuration.
|
||||
$wgDBtype = "${config.dbType}";
|
||||
$wgDBserver = "${config.dbServer}";
|
||||
$wgDBuser = "${config.dbUser}";
|
||||
$wgDBpassword = "${config.dbPassword}";
|
||||
$wgDBname = "${config.dbName}";
|
||||
|
||||
# E-mail.
|
||||
$wgEmergencyContact = "${config.emergencyContact}";
|
||||
$wgPasswordSender = "${config.passwordSender}";
|
||||
|
||||
$wgSitename = "${config.siteName}";
|
||||
|
||||
${optionalString (config.logo != "") ''
|
||||
$wgLogo = "${config.logo}";
|
||||
''}
|
||||
|
||||
${optionalString (config.articleUrlPrefix != "") ''
|
||||
$wgArticlePath = "${config.articleUrlPrefix}/$1";
|
||||
''}
|
||||
|
||||
${optionalString config.enableUploads ''
|
||||
$wgEnableUploads = true;
|
||||
$wgUploadDirectory = "${config.uploadDir}";
|
||||
''}
|
||||
|
||||
${optionalString (config.defaultSkin != "") ''
|
||||
$wgDefaultSkin = "${config.defaultSkin}";
|
||||
''}
|
||||
|
||||
${config.extraConfig}
|
||||
?>
|
||||
'';
|
||||
|
||||
# Unpack Mediawiki and put the config file in its root directory.
|
||||
mediawikiRoot = pkgs.stdenv.mkDerivation rec {
|
||||
name= "mediawiki-1.20.5";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "http://download.wikimedia.org/mediawiki/1.20/${name}.tar.gz";
|
||||
sha256 = "0ix6khrilfdncjqnh41xjs0bd49i1q0rywycjaixjfpwj6vjbqbl";
|
||||
};
|
||||
|
||||
skins = config.skins;
|
||||
|
||||
buildPhase =
|
||||
''
|
||||
for skin in $skins; do
|
||||
cp -prvd $skin/* skins/
|
||||
done
|
||||
''; # */
|
||||
|
||||
installPhase =
|
||||
''
|
||||
ensureDir $out
|
||||
cp -r * $out
|
||||
cp ${mediawikiConfig} $out/LocalSettings.php
|
||||
'';
|
||||
};
|
||||
|
||||
mediawikiScripts = pkgs.runCommand "mediawiki-${config.id}-scripts"
|
||||
{ buildInputs = [ pkgs.makeWrapper ]; }
|
||||
''
|
||||
ensureDir $out/bin
|
||||
for i in changePassword.php createAndPromote.php userOptions.php edit.php nukePage.php update.php; do
|
||||
makeWrapper ${php}/bin/php $out/bin/mediawiki-${config.id}-$(basename $i .php) \
|
||||
--add-flags ${mediawikiRoot}/maintenance/$i
|
||||
done
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
extraConfig =
|
||||
''
|
||||
${optionalString config.enableUploads ''
|
||||
Alias ${config.urlPrefix}/images ${config.uploadDir}
|
||||
|
||||
<Directory ${config.uploadDir}>
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
Options -Indexes
|
||||
</Directory>
|
||||
''}
|
||||
|
||||
Alias ${config.urlPrefix} ${mediawikiRoot}
|
||||
|
||||
<Directory ${mediawikiRoot}>
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
DirectoryIndex index.php
|
||||
</Directory>
|
||||
|
||||
${optionalString (config.articleUrlPrefix != "") ''
|
||||
Alias ${config.articleUrlPrefix} ${mediawikiRoot}/index.php
|
||||
''}
|
||||
'';
|
||||
|
||||
enablePHP = true;
|
||||
|
||||
options = {
|
||||
|
||||
id = mkOption {
|
||||
default = "main";
|
||||
description = ''
|
||||
A unique identifier necessary to keep multiple MediaWiki server
|
||||
instances on the same machine apart. This is used to
|
||||
disambiguate the administrative scripts, which get names like
|
||||
mediawiki-$id-change-password.
|
||||
'';
|
||||
};
|
||||
|
||||
dbType = mkOption {
|
||||
default = "postgres";
|
||||
example = "mysql";
|
||||
description = "Database type.";
|
||||
};
|
||||
|
||||
dbName = mkOption {
|
||||
default = "mediawiki";
|
||||
description = "Name of the database that holds the MediaWiki data.";
|
||||
};
|
||||
|
||||
dbServer = mkOption {
|
||||
default = ""; # use a Unix domain socket
|
||||
example = "10.0.2.2";
|
||||
description = ''
|
||||
The location of the database server. Leave empty to use a
|
||||
database server running on the same machine through a Unix
|
||||
domain socket.
|
||||
'';
|
||||
};
|
||||
|
||||
dbUser = mkOption {
|
||||
default = "mediawiki";
|
||||
description = "The user name for accessing the database.";
|
||||
};
|
||||
|
||||
dbPassword = mkOption {
|
||||
default = "";
|
||||
example = "foobar";
|
||||
description = ''
|
||||
The password of the database user. Warning: this is stored in
|
||||
cleartext in the Nix store!
|
||||
'';
|
||||
};
|
||||
|
||||
emergencyContact = mkOption {
|
||||
default = serverInfo.serverConfig.adminAddr;
|
||||
example = "admin@example.com";
|
||||
description = ''
|
||||
Emergency contact e-mail address. Defaults to the Apache
|
||||
admin address.
|
||||
'';
|
||||
};
|
||||
|
||||
passwordSender = mkOption {
|
||||
default = serverInfo.serverConfig.adminAddr;
|
||||
example = "password@example.com";
|
||||
description = ''
|
||||
E-mail address from which password confirmations originate.
|
||||
Defaults to the Apache admin address.
|
||||
'';
|
||||
};
|
||||
|
||||
siteName = mkOption {
|
||||
default = "MediaWiki";
|
||||
example = "Foobar Wiki";
|
||||
description = "Name of the wiki";
|
||||
};
|
||||
|
||||
logo = mkOption {
|
||||
default = "";
|
||||
example = "/images/logo.png";
|
||||
description = "The URL of the site's logo (which should be a 135x135px image).";
|
||||
};
|
||||
|
||||
urlPrefix = mkOption {
|
||||
default = "/w";
|
||||
description = ''
|
||||
The URL prefix under which the Mediawiki service appears.
|
||||
'';
|
||||
};
|
||||
|
||||
articleUrlPrefix = mkOption {
|
||||
default = "/wiki";
|
||||
example = "";
|
||||
description = ''
|
||||
The URL prefix under which article pages appear,
|
||||
e.g. http://server/wiki/Page. Leave empty to use the main URL
|
||||
prefix, e.g. http://server/w/index.php?title=Page.
|
||||
'';
|
||||
};
|
||||
|
||||
enableUploads = mkOption {
|
||||
default = false;
|
||||
description = "Whether to enable file uploads.";
|
||||
};
|
||||
|
||||
uploadDir = mkOption {
|
||||
default = throw "You must specify `uploadDir'.";
|
||||
example = "/data/mediawiki-upload";
|
||||
description = "The directory that stores uploaded files.";
|
||||
};
|
||||
|
||||
defaultSkin = mkOption {
|
||||
default = "";
|
||||
example = "nostalgia";
|
||||
description = "Set this value to change the default skin used by MediaWiki.";
|
||||
};
|
||||
|
||||
skins = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.path;
|
||||
description =
|
||||
''
|
||||
List of paths whose content is copied to the ‘skins’
|
||||
subdirectory of the MediaWiki installation.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
example =
|
||||
''
|
||||
$wgEnableEmail = false;
|
||||
'';
|
||||
description = ''
|
||||
Any additional text to be appended to MediaWiki's
|
||||
configuration file. This is a PHP script. For configuration
|
||||
settings, see <link xlink:href='http://www.mediawiki.org/wiki/Manual:Configuration_settings'/>.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
extraPath = [ mediawikiScripts ];
|
||||
|
||||
# !!! Need to specify that Apache has a dependency on PostgreSQL!
|
||||
|
||||
startupScript = pkgs.writeScript "mediawiki_startup.sh"
|
||||
# Initialise the database automagically if we're using a Postgres
|
||||
# server on localhost.
|
||||
(optionalString (config.dbType == "postgres" && config.dbServer == "") ''
|
||||
if ! ${pkgs.postgresql}/bin/psql -l | grep -q ' ${config.dbName} ' ; then
|
||||
${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true
|
||||
${pkgs.postgresql}/bin/createdb "${config.dbName}" -O "${config.dbUser}"
|
||||
( echo 'CREATE LANGUAGE plpgsql;'
|
||||
cat ${mediawikiRoot}/maintenance/postgres/tables.sql
|
||||
echo 'CREATE TEXT SEARCH CONFIGURATION public.default ( COPY = pg_catalog.english );'
|
||||
echo COMMIT
|
||||
) | ${pkgs.postgresql}/bin/psql -U "${config.dbUser}" "${config.dbName}"
|
||||
fi
|
||||
'');
|
||||
|
||||
robotsEntries = optionalString (config.articleUrlPrefix != "")
|
||||
''
|
||||
User-agent: *
|
||||
Disallow: ${config.urlPrefix}/
|
||||
Disallow: ${config.articleUrlPrefix}/Special:Search
|
||||
Disallow: ${config.articleUrlPrefix}/Special:Random
|
||||
'';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
{ config, pkgs, serverInfo, ... }:
|
||||
|
||||
let
|
||||
inherit (pkgs) mercurial;
|
||||
inherit (pkgs.lib) mkOption;
|
||||
|
||||
urlPrefix = config.urlPrefix;
|
||||
|
||||
cgi = pkgs.stdenv.mkDerivation {
|
||||
name = "mercurial-cgi";
|
||||
buildCommand = ''
|
||||
ensureDir $out
|
||||
cp -v ${mercurial}/share/cgi-bin/hgweb.cgi $out
|
||||
sed -i "s|/path/to/repo/or/config|$out/hgweb.config|" $out/hgweb.cgi
|
||||
echo "
|
||||
[collections]
|
||||
${config.dataDir} = ${config.dataDir}
|
||||
[web]
|
||||
style = gitweb
|
||||
allow_push = *
|
||||
" > $out/hgweb.config
|
||||
'';
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
extraConfig = ''
|
||||
RewriteEngine on
|
||||
RewriteRule /(.*) ${cgi}/hgweb.cgi/$1
|
||||
|
||||
<Location "${urlPrefix}">
|
||||
AuthType Basic
|
||||
AuthName "Mercurial repositories"
|
||||
AuthUserFile ${config.dataDir}/hgusers
|
||||
<LimitExcept GET>
|
||||
Require valid-user
|
||||
</LimitExcept>
|
||||
</Location>
|
||||
<Directory "${cgi}">
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
AllowOverride All
|
||||
Options ExecCGI
|
||||
AddHandler cgi-script .cgi
|
||||
PassEnv PYTHONPATH
|
||||
</Directory>
|
||||
'';
|
||||
|
||||
robotsEntries = ''
|
||||
User-agent: *
|
||||
Disallow: ${urlPrefix}
|
||||
'';
|
||||
|
||||
extraServerPath = [ pkgs.python ];
|
||||
|
||||
globalEnvVars = [ { name = "PYTHONPATH"; value = "${mercurial}/lib/${pkgs.python.libPrefix}/site-packages"; } ];
|
||||
|
||||
options = {
|
||||
urlPrefix = mkOption {
|
||||
default = "/hg";
|
||||
description = "
|
||||
The URL prefix under which the Mercurial service appears.
|
||||
Use the empty string to have it appear in the server root.
|
||||
";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
example = "/data/mercurial";
|
||||
description = "
|
||||
Path to the directory that holds the repositories.
|
||||
";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
# This file defines the options that can be used both for the Apache
|
||||
# main server configuration, and for the virtual hosts. (The latter
|
||||
# has additional options that affect the web server as a whole, like
|
||||
# the user/group to run under.)
|
||||
|
||||
{forMainServer, mkOption}:
|
||||
|
||||
{
|
||||
|
||||
hostName = mkOption {
|
||||
default = "localhost";
|
||||
description = "
|
||||
Canonical hostname for the server.
|
||||
";
|
||||
};
|
||||
|
||||
serverAliases = mkOption {
|
||||
default = [];
|
||||
example = ["www.example.org" "www.example.org:8080" "example.org"];
|
||||
description = "
|
||||
Additional names of virtual hosts served by this virtual host configuration.
|
||||
";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = 0;
|
||||
description = "
|
||||
Port for the server. 0 means use the default port: 80 for http
|
||||
and 443 for https (i.e. when enableSSL is set).
|
||||
";
|
||||
};
|
||||
|
||||
enableSSL = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable SSL (https) support.
|
||||
";
|
||||
};
|
||||
|
||||
# Note: sslServerCert and sslServerKey can be left empty, but this
|
||||
# only makes sense for virtual hosts (they will inherit from the
|
||||
# main server).
|
||||
|
||||
sslServerCert = mkOption {
|
||||
default = "";
|
||||
example = "/var/host.cert";
|
||||
description = "
|
||||
Path to server SSL certificate.
|
||||
";
|
||||
};
|
||||
|
||||
sslServerKey = mkOption {
|
||||
default = "";
|
||||
example = "/var/host.key";
|
||||
description = "
|
||||
Path to server SSL certificate key.
|
||||
";
|
||||
};
|
||||
|
||||
adminAddr = mkOption ({
|
||||
example = "admin@example.org";
|
||||
description = "
|
||||
E-mail address of the server administrator.
|
||||
";
|
||||
} // (if forMainServer then {} else {default = "";}));
|
||||
|
||||
documentRoot = mkOption {
|
||||
default = null;
|
||||
example = "/data/webserver/docs";
|
||||
description = "
|
||||
The path of Apache's document root directory. If left undefined,
|
||||
an empty directory in the Nix store will be used as root.
|
||||
";
|
||||
};
|
||||
|
||||
servedDirs = mkOption {
|
||||
default = [];
|
||||
example = [
|
||||
{ urlPath = "/nix";
|
||||
dir = "/home/eelco/Dev/nix-homepage";
|
||||
}
|
||||
];
|
||||
description = "
|
||||
This option provides a simple way to serve static directories.
|
||||
";
|
||||
};
|
||||
|
||||
servedFiles = mkOption {
|
||||
default = [];
|
||||
example = [
|
||||
{ urlPath = "/foo/bar.png";
|
||||
dir = "/home/eelco/some-file.png";
|
||||
}
|
||||
];
|
||||
description = "
|
||||
This option provides a simple way to serve individual, static files.
|
||||
";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
example = ''
|
||||
<Directory /home>
|
||||
Options FollowSymlinks
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
'';
|
||||
description = "
|
||||
These lines go to httpd.conf verbatim. They will go after
|
||||
directories and directory aliases defined by default.
|
||||
";
|
||||
};
|
||||
|
||||
extraSubservices = mkOption {
|
||||
default = [];
|
||||
description = "
|
||||
Extra subservices to enable in the webserver.
|
||||
";
|
||||
};
|
||||
|
||||
enableUserDir = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable serving <filename>~/public_html</filename> as
|
||||
<literal>/~<replaceable>username</replaceable></literal>.
|
||||
";
|
||||
};
|
||||
|
||||
globalRedirect = mkOption {
|
||||
default = "";
|
||||
example = http://newserver.example.org/;
|
||||
description = "
|
||||
If set, all requests for this host are redirected permanently to
|
||||
the given URL.
|
||||
";
|
||||
};
|
||||
|
||||
logFormat = mkOption {
|
||||
default = "common";
|
||||
example = "combined";
|
||||
description = "
|
||||
Log format for Apache's log files. Possible values are: combined, common, referer, agent.
|
||||
";
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
{ config, pkgs, serverInfo, ... }:
|
||||
|
||||
let
|
||||
extraWorkersProperties = pkgs.lib.optionalString (config ? extraWorkersProperties) config.extraWorkersProperties;
|
||||
|
||||
workersProperties = pkgs.writeText "workers.properties" ''
|
||||
# Define list of workers that will be used
|
||||
# for mapping requests
|
||||
# The configuration directives are valid
|
||||
# for the mod_jk version 1.2.18 and later
|
||||
#
|
||||
worker.list=loadbalancer,status
|
||||
|
||||
# Define Node1
|
||||
# modify the host as your host IP or DNS name.
|
||||
worker.node1.port=8009
|
||||
worker.node1.host=localhost
|
||||
worker.node1.type=ajp13
|
||||
worker.node1.lbfactor=1
|
||||
|
||||
# Load-balancing behaviour
|
||||
worker.loadbalancer.type=lb
|
||||
worker.loadbalancer.balance_workers=node1
|
||||
|
||||
# Status worker for managing load balancer
|
||||
worker.status.type=status
|
||||
|
||||
${extraWorkersProperties}
|
||||
'';
|
||||
in
|
||||
{
|
||||
extraModules = [
|
||||
{ name = "jk"; path = "${pkgs.tomcat_connectors}/modules/mod_jk.so"; }
|
||||
];
|
||||
|
||||
extraConfig = ''
|
||||
# Where to find workers.properties
|
||||
JkWorkersFile ${workersProperties}
|
||||
|
||||
# Where to put jk logs
|
||||
JkLogFile ${config.logDir}/mod_jk.log
|
||||
|
||||
# Set the jk log level [debug/error/info]
|
||||
JkLogLevel info
|
||||
|
||||
# Select the log format
|
||||
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
|
||||
|
||||
# JkOptions indicates to send SSK KEY SIZE
|
||||
# Note: Changed from +ForwardURICompat.
|
||||
# See http://tomcat.apache.org/security-jk.html
|
||||
JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories
|
||||
|
||||
# JkRequestLogFormat
|
||||
JkRequestLogFormat "%w %V %T"
|
||||
|
||||
# Mount your applications
|
||||
JkMount /__application__/* loadbalancer
|
||||
|
||||
# You can use external file for mount points.
|
||||
# It will be checked for updates each 60 seconds.
|
||||
# The format of the file is: /url=worker
|
||||
# /examples/*=loadbalancer
|
||||
#JkMountFile uriworkermap.properties
|
||||
|
||||
# Add shared memory.
|
||||
# This directive is present with 1.2.10 and
|
||||
# later versions of mod_jk, and is needed for
|
||||
# for load balancing to work properly
|
||||
# Note: Replaced JkShmFile logs/jk.shm due to SELinux issues. Refer to
|
||||
# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=225452
|
||||
JkShmFile ${config.stateDir}/jk.shm
|
||||
|
||||
# Static files in all Tomcat webapp context directories are served by apache
|
||||
JkAutoAlias /var/tomcat/webapps
|
||||
|
||||
# All requests go to worker by default
|
||||
JkMount /* loadbalancer
|
||||
# Serve some static files using httpd
|
||||
#JkUnMount /*.html loadbalancer
|
||||
#JkUnMount /*.jpg loadbalancer
|
||||
#JkUnMount /*.gif loadbalancer
|
||||
#JkUnMount /*.css loadbalancer
|
||||
#JkUnMount /*.png loadbalancer
|
||||
#JkUnMount /*.js loadbalancer
|
||||
|
||||
# Add jkstatus for managing runtime data
|
||||
<Location /jkstatus/>
|
||||
JkMount status
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
Allow from 127.0.0.1
|
||||
</Location>
|
||||
'';
|
||||
}
|
||||
121
nixos/modules/services/web-servers/apache-httpd/trac.nix
Normal file
121
nixos/modules/services/web-servers/apache-httpd/trac.nix
Normal file
@@ -0,0 +1,121 @@
|
||||
{ config, pkgs, serverInfo, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
# Build a Subversion instance with Apache modules and Swig/Python bindings.
|
||||
subversion = pkgs.subversion.override (origArgs: {
|
||||
bdbSupport = true;
|
||||
httpServer = true;
|
||||
sslSupport = true;
|
||||
compressionSupport = true;
|
||||
pythonBindings = true;
|
||||
});
|
||||
|
||||
pythonLib = p: "${p}/";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
projectsLocation = mkOption {
|
||||
description = "URL path in which Trac projects can be accessed";
|
||||
default = "/projects";
|
||||
};
|
||||
|
||||
projects = mkOption {
|
||||
description = "List of projects that should be provided by Trac. If they are not defined yet empty projects are created.";
|
||||
default = [];
|
||||
example =
|
||||
[ { identifier = "myproject";
|
||||
name = "My Project";
|
||||
databaseURL="postgres://root:password@/tracdb";
|
||||
subversionRepository="/data/subversion/myproject";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "wwwrun";
|
||||
description = "User account under which Trac runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
default = "wwwrun";
|
||||
description = "Group under which Trac runs.";
|
||||
};
|
||||
|
||||
ldapAuthentication = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Enable the ldap authentication in trac";
|
||||
};
|
||||
|
||||
url = mkOption {
|
||||
default = "ldap://127.0.0.1/dc=example,dc=co,dc=ke?uid?sub?(objectClass=inetOrgPerson)";
|
||||
description = "URL of the LDAP authentication";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
default = "Trac server";
|
||||
description = "AuthName";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
extraModules = singleton
|
||||
{ name = "python"; path = "${pkgs.mod_python}/modules/mod_python.so"; };
|
||||
|
||||
extraConfig = ''
|
||||
<Location ${config.projectsLocation}>
|
||||
SetHandler mod_python
|
||||
PythonHandler trac.web.modpython_frontend
|
||||
PythonOption TracEnvParentDir /var/trac/projects
|
||||
PythonOption TracUriRoot ${config.projectsLocation}
|
||||
PythonOption PYTHON_EGG_CACHE /var/trac/egg-cache
|
||||
</Location>
|
||||
${if config.ldapAuthentication.enable then ''
|
||||
<LocationMatch "^${config.projectsLocation}[^/]+/login$">
|
||||
AuthType Basic
|
||||
AuthName "${config.ldapAuthentication.name}"
|
||||
AuthBasicProvider "ldap"
|
||||
AuthLDAPURL "${config.ldapAuthentication.url}"
|
||||
authzldapauthoritative Off
|
||||
require valid-user
|
||||
</LocationMatch>
|
||||
'' else ""}
|
||||
'';
|
||||
|
||||
globalEnvVars = singleton
|
||||
{ name = "PYTHONPATH";
|
||||
value =
|
||||
makeSearchPath "lib/${pkgs.python.libPrefix}/site-packages"
|
||||
[ pkgs.mod_python
|
||||
pkgs.pythonPackages.trac
|
||||
pkgs.setuptools
|
||||
pkgs.pythonPackages.genshi
|
||||
pkgs.pythonPackages.psycopg2
|
||||
pkgs.python.modules.sqlite3
|
||||
subversion
|
||||
];
|
||||
};
|
||||
|
||||
startupScript = pkgs.writeScript "activateTrac" ''
|
||||
mkdir -p /var/trac
|
||||
chown ${config.user}:${config.group} /var/trac
|
||||
|
||||
${concatMapStrings (project:
|
||||
''
|
||||
if [ ! -d /var/trac/${project.identifier} ]
|
||||
then
|
||||
export PYTHONPATH=${pkgs.pythonPackages.psycopg2}/lib/${pkgs.python.libPrefix}/site-packages
|
||||
${pkgs.pythonPackages.trac}/bin/trac-admin /var/trac/${project.identifier} initenv "${project.name}" "${project.databaseURL}" svn "${project.subversionRepository}"
|
||||
fi
|
||||
'' ) (config.projects)}
|
||||
'';
|
||||
|
||||
}
|
||||
82
nixos/modules/services/web-servers/apache-httpd/zabbix.nix
Normal file
82
nixos/modules/services/web-servers/apache-httpd/zabbix.nix
Normal file
@@ -0,0 +1,82 @@
|
||||
{ config, pkgs, serverInfo, ... }:
|
||||
|
||||
let
|
||||
|
||||
# The Zabbix PHP frontend needs to be able to write its
|
||||
# configuration settings (the connection info to the database) to
|
||||
# the "conf" subdirectory. So symlink $out/conf to some directory
|
||||
# outside of the Nix store where we want to keep this stateful info.
|
||||
# Note that different instances of the frontend will therefore end
|
||||
# up with their own copies of the PHP sources. !!! Alternatively,
|
||||
# we could generate zabbix.conf.php declaratively.
|
||||
zabbixPHP = pkgs.runCommand "${pkgs.zabbix.server.name}-php" {}
|
||||
''
|
||||
cp -rs ${pkgs.zabbix.server}/share/zabbix/php "$out"
|
||||
chmod -R u+w $out
|
||||
ln -s "${if config.configFile == null
|
||||
then "${config.stateDir}/zabbix.conf.php"
|
||||
else config.configFile}" "$out/conf/zabbix.conf.php"
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
enablePHP = true;
|
||||
|
||||
phpOptions =
|
||||
''
|
||||
post_max_size = 32M
|
||||
max_execution_time = 300
|
||||
max_input_time = 300
|
||||
'';
|
||||
|
||||
extraConfig = ''
|
||||
Alias ${config.urlPrefix}/ ${zabbixPHP}/
|
||||
|
||||
<Directory ${zabbixPHP}>
|
||||
DirectoryIndex index.php
|
||||
Order deny,allow
|
||||
Allow from *
|
||||
</Directory>
|
||||
'';
|
||||
|
||||
startupScript = pkgs.writeScript "zabbix-startup-hook" ''
|
||||
mkdir -p ${config.stateDir}
|
||||
chown -R ${serverInfo.serverConfig.user} ${config.stateDir}
|
||||
'';
|
||||
|
||||
# The frontend needs "ps" to find out whether zabbix_server is running.
|
||||
extraServerPath = [ pkgs.procps ];
|
||||
|
||||
options = {
|
||||
|
||||
urlPrefix = pkgs.lib.mkOption {
|
||||
default = "/zabbix";
|
||||
description = "
|
||||
The URL prefix under which the Zabbix service appears.
|
||||
Use the empty string to have it appear in the server root.
|
||||
";
|
||||
};
|
||||
|
||||
configFile = pkgs.lib.mkOption {
|
||||
default = null;
|
||||
type = with pkgs.lib.types; nullOr path;
|
||||
description = ''
|
||||
The configuration file (zabbix.conf.php) which contains the database
|
||||
connection settings. If not set, the configuration settings will created
|
||||
by the web installer.
|
||||
'';
|
||||
};
|
||||
|
||||
stateDir = pkgs.lib.mkOption {
|
||||
default = "/var/lib/zabbix/frontend";
|
||||
description = "
|
||||
Directory where the dynamically generated configuration data
|
||||
of the PHP frontend will be stored.
|
||||
";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user