From 01f21083a897b86bf148f1d2bb9c8edca4d3786a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Fri, 25 Jan 2019 23:15:08 +0100 Subject: Rename virtual folder to nixops Fixes https://git.immae.eu/mantisbt/view.php?id=82 --- nixops/modules/websites/commons/adminer.nix | 65 +++++ nixops/modules/websites/commons/composer-env.nix | 280 +++++++++++++++++++++ .../websites/commons/spip/spip_ldap_patch.patch | 60 +++++ .../websites/commons/spip/spip_mes_options.php | 18 ++ nixops/modules/websites/commons/stats.nix | 67 +++++ 5 files changed, 490 insertions(+) create mode 100644 nixops/modules/websites/commons/adminer.nix create mode 100644 nixops/modules/websites/commons/composer-env.nix create mode 100644 nixops/modules/websites/commons/spip/spip_ldap_patch.patch create mode 100644 nixops/modules/websites/commons/spip/spip_mes_options.php create mode 100644 nixops/modules/websites/commons/stats.nix (limited to 'nixops/modules/websites/commons') diff --git a/nixops/modules/websites/commons/adminer.nix b/nixops/modules/websites/commons/adminer.nix new file mode 100644 index 0000000..891046f --- /dev/null +++ b/nixops/modules/websites/commons/adminer.nix @@ -0,0 +1,65 @@ +{ stdenv, fetchurl, nginx }: +let + adminer = rec { + webRoot = stdenv.mkDerivation rec { + version = "4.7.0"; + name = "adminer-${version}"; + src = fetchurl { + url = "https://www.adminer.org/static/download/${version}/${name}.php"; + sha256 = "1qq2g7rbfh2vrqfm3g0bz0qs057b049n0mhabnsbd1sgnpvnc5z7"; + }; + phases = "installPhase"; + installPhase = '' + mkdir -p $out + cp $src $out/index.php + ''; + }; + phpFpm = rec { + socket = "/var/run/phpfpm/adminer.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 5 + pm.process_idle_timeout = 60 + ;php_admin_flag[log_errors] = on + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = AdminerPHPSESSID + php_admin_value[open_basedir] = "${webRoot}:/tmp" + php_admin_value[session.save_path] = "/var/lib/php/sessions/adminer" + ''; + }; + apache = { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + vhostConf = '' + Alias /adminer ${webRoot} + + DirectoryIndex index.php + Require all granted + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + ''; + }; + nginxConf = { + alias = webRoot; + index = "index.php"; + extraConfig = '' + include ${nginx}/conf/fastcgi.conf; + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + fastcgi_param HTTP_PROXY ""; + fastcgi_param SCRIPT_FILENAME ${webRoot}/index.php; + fastcgi_pass unix:${phpFpm.socket}; + fastcgi_index index.php; + fastcgi_intercept_errors on; + ''; + }; + }; +in + adminer diff --git a/nixops/modules/websites/commons/composer-env.nix b/nixops/modules/websites/commons/composer-env.nix new file mode 100644 index 0000000..416a61c --- /dev/null +++ b/nixops/modules/websites/commons/composer-env.nix @@ -0,0 +1,280 @@ +# This file originates from composer2nix + +{ stdenv, writeTextFile, fetchurl, php, unzip }: + +let + composer = stdenv.mkDerivation { + name = "composer-1.8.0"; + src = fetchurl { + url = https://github.com/composer/composer/releases/download/1.8.0/composer.phar; + sha256 = "19pg9ip2mpyf5cyq34fld7qwl77mshqw3c4nif7sxmpnar6sh089"; + }; + buildInputs = [ php ]; + + # We must wrap the composer.phar because of the impure shebang. + # We cannot use patchShebangs because the executable verifies its own integrity and will detect that somebody has tampered with it. + + buildCommand = '' + # Copy phar file + mkdir -p $out/share/php + cp $src $out/share/php/composer.phar + chmod 755 $out/share/php/composer.phar + + # Create wrapper executable + mkdir -p $out/bin + cat > $out/bin/composer < + ''; + }; + + constructBin = writeTextFile { + name = "constructbin.php"; + executable = true; + text = '' + #! ${php}/bin/php + + ''; + }; + + bundleDependencies = dependencies: + stdenv.lib.concatMapStrings (dependencyName: + let + dependency = dependencies.${dependencyName}; + in + '' + ${if dependency.targetDir == "" then '' + vendorDir="$(dirname ${dependencyName})" + mkdir -p "$vendorDir" + ${if symlinkDependencies then + ''ln -s "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"'' + else + ''cp -a "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"'' + }${if dependency.needsModifyRights or false then "\n" + '' + chmod -R u+rwx "$vendorDir/$(basename "${dependencyName}")" + '' else ""} + '' else '' + namespaceDir="${dependencyName}/$(dirname "${dependency.targetDir}")" + mkdir -p "$namespaceDir" + ${if symlinkDependencies then + ''ln -s "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"'' + else + ''cp -a "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"'' + }${if dependency.needsModifyRights or false then "\n" + '' + chmod -R u+rwx "$namespaceDir/$(basename "${dependency.targetDir}")" + '' else ""} + ''} + '') (builtins.attrNames dependencies); + + extraArgs = removeAttrs args [ "name" "packages" "devPackages" "buildInputs" ]; + in + stdenv.mkDerivation ({ + name = "composer-${name}"; + buildInputs = [ php composer ] ++ buildInputs; + + inherit unpackPhase buildPhase; + + installPhase = '' + ${if executable then '' + mkdir -p $out/share/php + cp -a $src $out/share/php/$name + chmod -R u+w $out/share/php/$name + cd $out/share/php/$name + '' else '' + cp -a $src $out + chmod -R u+w $out + cd $out + ''} + + # Execute pre install hook + runHook preInstall + + # Remove unwanted files + rm -f *.nix + + export HOME=$TMPDIR + + ${if doRemoveVendor then '' + # Remove the provided vendor folder if it exists + rm -Rf vendor + '' else ""} + # If there is no composer.lock file, compose a dummy file. + # Otherwise, composer attempts to download the package.json file from + # the registry which we do not want. + if [ ! -f composer.lock ] + then + cat > composer.lock < vendor/composer/installed.json + + # Copy or symlink the provided dependencies + cd vendor + ${bundleDependencies packages} + ${stdenv.lib.optionalString (!noDev) (bundleDependencies devPackages)} + cd .. + + # Reconstruct autoload scripts + # We use the optimize feature because Nix packages cannot change after they have been built + # Using the dynamic loader for a Nix package is useless since there is nothing to dynamically reload. + composer dump-autoload --optimize ${stdenv.lib.optionalString noDev "--no-dev"} + + # Run the install step as a validation to confirm that everything works out as expected + composer install --optimize-autoloader ${stdenv.lib.optionalString noDev "--no-dev"} + + ${stdenv.lib.optionalString executable '' + # Reconstruct the bin/ folder if we deploy an executable project + ${constructBin} composer.json + ln -s $(pwd)/vendor/bin $out/bin + ''} + + ${stdenv.lib.optionalString (!symlinkDependencies) '' + # Patch the shebangs if possible + if [ -d $(pwd)/vendor/bin ] + then + # Look for all executables in bin/ + for i in $(pwd)/vendor/bin/* + do + # Look for their location + realFile=$(readlink -f "$i") + + # Restore write permissions + chmod u+wx "$(dirname "$realFile")" + chmod u+w "$realFile" + + # Patch shebang + sed -e "s|#!/usr/bin/php|#!${php}/bin/php|" \ + -e "s|#!/usr/bin/env php|#!${php}/bin/php|" \ + "$realFile" > tmp + mv tmp "$realFile" + chmod u+x "$realFile" + done + fi + ''} + + if [ "$removeComposerArtifacts" = "1" ] + then + # Remove composer stuff + rm -f composer.json composer.lock + fi + + # Execute post install hook + runHook postInstall + ''; + } // extraArgs); +in +{ + composer = stdenv.lib.makeOverridable composer; + buildZipPackage = stdenv.lib.makeOverridable buildZipPackage; + buildPackage = stdenv.lib.makeOverridable buildPackage; +} diff --git a/nixops/modules/websites/commons/spip/spip_ldap_patch.patch b/nixops/modules/websites/commons/spip/spip_ldap_patch.patch new file mode 100644 index 0000000..653c909 --- /dev/null +++ b/nixops/modules/websites/commons/spip/spip_ldap_patch.patch @@ -0,0 +1,60 @@ +--- old/ecrire/auth/ldap.php 2017-06-08 21:58:17.000000000 +0200 ++++ new/ecrire/auth/ldap.php 2017-06-10 02:54:02.687954143 +0200 +@@ -171,24 +171,41 @@ + $desc = isset($ldap['attributes']) && $ldap['attributes'] ? $ldap['attributes'] : $GLOBALS['ldap_attributes'] ; + + $logins = is_array($desc['login']) ? $desc['login'] : array($desc['login']); ++ if (isset($GLOBALS['ldap_search'])) { ++ $search_query = str_replace("%user%", $login_search, $GLOBALS['ldap_search']); ++ $result = @ldap_search($ldap_link, $ldap_base, $search_query, array("dn")); ++ $info = @ldap_get_entries($ldap_link, $result); ++ // Ne pas accepter les resultats si plus d'une entree ++ // (on veut un attribut unique) + +- // Tenter une recherche pour essayer de retrouver le DN +- foreach ($logins as $att) { +- $result = @ldap_search($ldap_link, $ldap_base, "$att=$login_search", array("dn")); +- $info = @ldap_get_entries($ldap_link, $result); +- // Ne pas accepter les resultats si plus d'une entree +- // (on veut un attribut unique) ++ if (is_array($info) and $info['count'] == 1) { ++ $dn = $info[0]['dn']; ++ if (!$checkpass) { ++ return $dn; ++ } ++ if (@ldap_bind($ldap_link, $dn, $pass)) { ++ return $dn; ++ } ++ } ++ } else { ++ // Tenter une recherche pour essayer de retrouver le DN ++ foreach ($logins as $att) { ++ $result = @ldap_search($ldap_link, $ldap_base, "$att=$login_search", array("dn")); ++ $info = @ldap_get_entries($ldap_link, $result); ++ // Ne pas accepter les resultats si plus d'une entree ++ // (on veut un attribut unique) + +- if (is_array($info) and $info['count'] == 1) { +- $dn = $info[0]['dn']; +- if (!$checkpass) { +- return $dn; +- } +- if (@ldap_bind($ldap_link, $dn, $pass)) { +- return $dn; +- } +- } +- } ++ if (is_array($info) and $info['count'] == 1) { ++ $dn = $info[0]['dn']; ++ if (!$checkpass) { ++ return $dn; ++ } ++ if (@ldap_bind($ldap_link, $dn, $pass)) { ++ return $dn; ++ } ++ } ++ } ++ } + + if ($checkpass and !isset($dn)) { + // Si echec, essayer de deviner le DN diff --git a/nixops/modules/websites/commons/spip/spip_mes_options.php b/nixops/modules/websites/commons/spip/spip_mes_options.php new file mode 100644 index 0000000..8db8389 --- /dev/null +++ b/nixops/modules/websites/commons/spip/spip_mes_options.php @@ -0,0 +1,18 @@ + diff --git a/nixops/modules/websites/commons/stats.nix b/nixops/modules/websites/commons/stats.nix new file mode 100644 index 0000000..b5bf0e0 --- /dev/null +++ b/nixops/modules/websites/commons/stats.nix @@ -0,0 +1,67 @@ +{ lib, pkgs, config, mylibs, ... }: +let + cfg = config.services.myWebsites.commons.stats; +in { + options = { + services.myWebsites.commons.stats = { + enable = lib.mkEnableOption "enable statistics"; + sites = lib.mkOption { + type = lib.types.listOf (lib.types.submodule { + options = { + conf = lib.mkOption { type = lib.types.path; }; + name = lib.mkOption { type = lib.types.string; }; + }; + }); + default = []; + description = "Sites to generate stats"; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.goaccess + ]; + + nixpkgs.config.packageOverrides = oldpkgs: rec { + goaccess = oldpkgs.goaccess.overrideAttrs(old: rec { + name = "goaccess-${version}"; + version = "1.3"; + src = pkgs.fetchurl { + url = "https://tar.goaccess.io/${name}.tar.gz"; + sha256 = "16vv3pj7pbraq173wlxa89jjsd279004j4kgzlrsk1dz4if5qxwc"; + }; + configureFlags = old.configureFlags ++ [ "--enable-tcb=btree" ]; + buildInputs = old.buildInputs ++ [ pkgs.tokyocabinet pkgs.bzip2 ]; + }); + }; + + services.cron = { + enable = true; + systemCronJobs = let + stats = domain: conf: let + d = pkgs.writeScriptBin "stats-${domain}" '' + #!${pkgs.stdenv.shell} + set -e + shopt -s nullglob + date_regex=$(LC_ALL=C date -d yesterday +'%d\/%b\/%Y') + TMPFILE=$(mktemp) + trap "rm -f $TMPFILE" EXIT + + cat /var/log/httpd/access_log-${domain} | sed -n "/\\[$date_regex/ p" > $TMPFILE + for i in /var/log/httpd/access_log-${domain}*.gz; do + zcat "$i" | sed -n "/\\[$date_regex/ p" >> $TMPFILE + done + goaccess $TMPFILE --no-progress -o /var/lib/goaccess/${domain}/index.html -p ${conf} + ''; + in "${d}/bin/stats-${domain}"; + in + pkgs.lib.lists.imap0 (i: v: "${toString (i+5)} 0 * * * root ${stats v.name v.conf}") cfg.sites; + }; + + system.activationScripts.goaccess = '' + mkdir -p /var/lib/goaccess + '' + + builtins.concatStringsSep "\n" (map (v: "mkdir -p /var/lib/goaccess/${v.name}") cfg.sites); + }; +} -- cgit v1.2.3