From 8bf1cade680e69b6468569fd7ec24feaa80d3913 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 5 Feb 2008 16:25:07 +0000 Subject: [PATCH] * New-style Subversion server configuration. svn path=/nixos/trunk/; revision=10508 --- upstart-jobs/apache-httpd/default.nix | 63 ++++++- upstart-jobs/apache-httpd/subversion.nix | 213 +++++++++++++++++++++++ 2 files changed, 273 insertions(+), 3 deletions(-) create mode 100644 upstart-jobs/apache-httpd/subversion.nix diff --git a/upstart-jobs/apache-httpd/default.nix b/upstart-jobs/apache-httpd/default.nix index 0273497d912..0aa8d622cf4 100644 --- a/upstart-jobs/apache-httpd/default.nix +++ b/upstart-jobs/apache-httpd/default.nix @@ -9,6 +9,15 @@ let httpd = pkgs.apacheHttpd; + subservices = [ + (import ./subversion.nix {inherit config pkgs;}) + ]; + + + writeTextInDir = name: text: + pkgs.runCommand name {inherit text;} "ensureDir $out; echo -n \"$text\" > $out/$name"; + + documentRoot = if cfg.documentRoot != null then cfg.documentRoot else pkgs.runCommand "empty" {} "ensureDir $out"; @@ -93,6 +102,7 @@ let AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl + AddType application/x-httpd-php .php .phtml MIMEMagicFile ${httpd}/conf/magic @@ -114,6 +124,20 @@ let ''; + + robotsTxt = writeTextInDir "robots.txt" '' + ${pkgs.lib.concatStrings (map (svc: svc.robotsEntries) subservices)} + ''; + + robotsConf = '' + Alias /robots.txt ${robotsTxt}/robots.txt + + + Order allow,deny + Allow from all + + ''; + httpdConf = pkgs.writeText "httpd.conf" '' @@ -135,8 +159,13 @@ let User ${cfg.user} Group ${cfg.group} - ${let f = name: "LoadModule ${name}_module ${httpd}/modules/mod_${name}.so\n"; - in pkgs.lib.concatStrings (map f apacheModules) + ${let + load = {name, path}: "LoadModule ${name}_module ${path}\n"; + allModules = + pkgs.lib.concatMap (svc: svc.extraModulesPre) subservices ++ + map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules ++ + pkgs.lib.concatMap (svc: svc.extraModules) subservices; + in pkgs.lib.concatStrings (map load allModules) } ${if cfg.enableUserDir then '' @@ -176,9 +205,13 @@ let ${if cfg.enableSSL then sslConf else ""} + # Fascist default - deny access to everything. + # !!! Options FollowSymLinks AllowOverride None +# Order deny,allow +# Deny from all ${documentRootConf} @@ -194,6 +227,10 @@ let ''; in pkgs.lib.concatStrings (map makeDirConf cfg.servedDirs) } + + ${pkgs.lib.concatStrings (map (svc: svc.extraConfig) subservices)} + + ${robotsConf} ''; @@ -216,7 +253,11 @@ in # Statically verify the syntactic correctness of the generated # httpd.conf. - buildHook = "${httpd}/bin/httpd -f ${httpdConf} -t"; + buildHook = '' + echo + echo '=== Checking the generated Apache configuration file ===' + ${httpd}/bin/httpd -f ${httpdConf} -t + ''; job = '' description "Apache HTTPD" @@ -227,8 +268,24 @@ in start script mkdir -m 0700 -p ${cfg.stateDir} mkdir -m 0700 -p ${cfg.logDir} + + # Get rid of old semaphores. These tend to accumulate across + # server restarts, eventually preventing it from restarting + # succesfully. + for i in $(${pkgs.utillinux}/bin/ipcs -s | grep ' wwwrun ' | cut -f2 -d ' '); do + ${pkgs.utillinux}/bin/ipcrm -s $i + done end script + ${ + let f = {name, value}: "env ${name}=${value}\n"; + in pkgs.lib.concatStrings (map f (pkgs.lib.concatMap (svc: svc.globalEnvVars) subservices)) + } + + env PATH=${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.lib.concatStringsSep ":" (pkgs.lib.concatMap (svc: svc.extraPath) subservices)} + + ${pkgs.diffutils}/bin:${pkgs.gnused}/bin + respawn ${httpd}/bin/httpd -f ${httpdConf} -DNO_DETACH ''; diff --git a/upstart-jobs/apache-httpd/subversion.nix b/upstart-jobs/apache-httpd/subversion.nix new file mode 100644 index 00000000000..cbfc9846ed2 --- /dev/null +++ b/upstart-jobs/apache-httpd/subversion.nix @@ -0,0 +1,213 @@ +{config, pkgs}: + +let + + prefix = "/svn"; + dbDir = "/tmp/svn/db"; + reposDir = "/tmp/svn/repos"; + backupsDir = "/tmp/svn/backup"; + tmpDir = "/tmp/svn/tmp"; + adminAddr = "eelco@cs.uu.nl"; + + + # Build a Subversion instance with Apache modules and Swig/Python bindings. + subversion = import ../../../nixpkgs/pkgs/applications/version-management/subversion-1.4.x { + inherit (pkgs) fetchurl stdenv apr aprutil neon expat swig zlib; + bdbSupport = true; + httpServer = true; + sslSupport = true; + compressionSupport = true; + pythonBindings = true; + httpd = pkgs.apacheHttpd; + }; + + + # Build our custom authentication modules. + authModules = import ../../../services/subversion/src/auth { + inherit (pkgs) stdenv apacheHttpd; + }; + + + # Access controls for /repos and /repos-xml. + reposConfig = dirName: '' + AuthType Basic + AuthName "Subversion repositories" + AuthBasicProvider auth-against-db + + AuthAllowNone on + + AuthzRepoPrefix ${prefix}/${dirName}/ + AuthzRepoDBType DB + AuthzRepoReaders ${dbDir}/svn-readers + AuthzRepoWriters ${dbDir}/svn-writers + + + Require repo-writer + + + + Require repo-reader + + + DAV svn + SVNParentPath ${reposDir} + #SVNAutoversioning @autoVersioning@ + ''; + + + # Build ViewVC. + viewvc = import ../../../services/subversion/src/viewvc { + inherit (pkgs) fetchurl stdenv python enscript; + inherit reposDir adminAddr subversion; + urlPrefix = prefix; + }; + + + viewerConfig = dirName: '' + AuthType Basic + AuthName "Subversion repositories" + AuthBasicProvider auth-against-db + AuthAllowNone on + AuthzRepoPrefix ${prefix}/${dirName}/ + AuthzRepoDBType DB + AuthzRepoReaders ${dbDir}/svn-readers + Require repo-reader + ''; + + + viewvcConfig = '' + ScriptAlias ${prefix}/viewvc ${viewvc}/viewvc/bin/mod_python/viewvc.py + + + AddHandler python-program .py + # Note: we write \" instead of ' to work around a lexer bug in Nix 0.11. + PythonPath "[\"${viewvc}/viewvc/bin/mod_python\", \"${subversion}/lib/python2.4/site-packages\"] + sys.path" + PythonHandler handler + ${viewerConfig "viewvc"} + + + Alias ${prefix}/viewvc-doc ${viewvc}/viewvc/templates/docroot + + #Redirect permanent /viewcvs @canonicalName@/viewvc + ''; + + + # Build WebSVN. + websvn = import ../../../services/subversion/src/websvn { + inherit (pkgs) fetchurl stdenv writeText enscript gnused diffutils; + inherit reposDir subversion; + cacheDir = tmpDir; + urlPrefix = prefix; + }; + + + websvnConfig = '' + Alias ${prefix}/websvn ${websvn}/wsvn.php + Alias ${prefix}/templates ${websvn}/templates + + + ${viewerConfig "websvn"} + + + + Order allow,deny + Allow from all + + ''; + + + # Build Repoman. + + repoman = pkgs.substituteAll { + src = ../../../services/subversion/src/repoman/repoman.pl.in; + dir = "/"; + name = "repoman.pl"; + isExecutable = true; + perl = "${pkgs.perl}/bin/perl"; + defaultPath = ""; + staticPrefix = prefix; + orgUrl = "http://example.org/"; + orgLogoUrl = "http://example.org/"; + orgName = "Example Org"; + canonicalName = "http://localhost/"; + userCreationDomain = "localhost"; + fsType = "fsfs"; + inherit adminAddr reposDir backupsDir dbDir subversion; + + # Urgh, most of these are dependencies of Email::Send, should figure them out automatically. + perlFlags = "-I${pkgs.perlBerkeleyDB}/lib/site_perl -I${pkgs.perlEmailSend}/lib/site_perl -I${pkgs.perlEmailSimple}/lib/site_perl -I${pkgs.perlModulePluggable}/lib/site_perl -I${pkgs.perlReturnValue}/lib/site_perl -I${pkgs.perlEmailAddress}/lib/site_perl"; + }; + + repomanConfig = '' + ScriptAlias ${prefix}/repoman ${repoman}/repoman.pl + ''; + + + # !!! + writeTextInDir = name: text: + pkgs.runCommand name {inherit text;} "ensureDir $out; echo -n \"$text\" > $out/$name"; + +in + +{ + + extraModulesPre = [ + # Allow anonymous access to repositories that are world-readable + # without prompting for a username/password. + { name = "authn_noauth"; path = "${authModules}/modules/mod_authn_noauth.so"; } + # Check whether the user is allowed read or write access to a + # repository. + { name = "authz_dyn"; path = "${authModules}/modules/mod_authz_dyn.so"; } + ]; + + extraModules = [ + { name = "python"; path = "${pkgs.mod_python}/modules/mod_python.so"; } + { name = "php5"; path = "${pkgs.php}/modules/libphp5.so"; } + { name = "dav_svn"; path = "${subversion}/modules/mod_dav_svn.so"; } + ]; + + extraConfig = '' + + + AuthDBMType DB + AuthDBMUserFile ${dbDir}/svn-users + + + + ${reposConfig "repos"} + + + + ${reposConfig "repos-xml"} + SVNIndexXSLT "@staticPrefix@/xsl/svnindex.xsl" + + + ${viewvcConfig} + + ${websvnConfig} + + ${repomanConfig} + + ''; + + robotsEntries = '' + User-agent: * + Disallow: ${prefix}/viewcvs/ + Disallow: ${prefix}/viewvc/ + Disallow: ${prefix}/websvn/ + Disallow: ${prefix}/repos-xml/ + ''; + + # mod_python's own Python modules must be in the initial Python + # path, they cannot be set through the PythonPath directive. + globalEnvVars = [ + { name = "PYTHONPATH"; value = "${pkgs.mod_python}/lib/python2.4/site-packages"; } + ]; + + extraPath = [ + # Needed for ViewVC. + "${pkgs.diffutils}/bin" + "${pkgs.gnused}/bin" + ]; + +}