]> git.immae.eu Git - perso/Immae/Config/Nix.git/commitdiff
Add etherpad lite tool
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Thu, 24 Jan 2019 23:58:26 +0000 (00:58 +0100)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Fri, 25 Jan 2019 00:22:28 +0000 (01:22 +0100)
Fixes https://git.immae.eu/mantisbt/view.php?id=72

virtual/modules/websites/default.nix
virtual/modules/websites/tools/ether/default.nix [new file with mode: 0644]
virtual/modules/websites/tools/ether/etherpad-lite.json [new file with mode: 0644]
virtual/modules/websites/tools/ether/etherpad_lite.nix [new file with mode: 0644]
virtual/modules/websites/tools/ether/libreoffice_patch.diff [new file with mode: 0644]

index 06f51ff935752dd2d9a7c2926069c4c1c98bd52e..4d5ae23d3564f83403dfca8332c0125917f94ada 100644 (file)
@@ -99,6 +99,7 @@ in
     ./tools/mastodon
     ./tools/mediagoblin
     ./tools/diaspora
+    ./tools/ether
     # built using:
     # sed -e "s/services\.httpd/services\.httpdProd/g" .nix-defexpr/channels/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
     # Removed allGranted
@@ -179,6 +180,7 @@ in
     services.myWebsites.tools.mastodon.enable = true;
     services.myWebsites.tools.mediagoblin.enable = true;
     services.myWebsites.tools.diaspora.enable = true;
+    services.myWebsites.tools.etherpad-lite.enable = true;
 
     services.myWebsites.Chloe.production.enable = cfg.production.enable;
     services.myWebsites.Ludivine.production.enable = cfg.production.enable;
diff --git a/virtual/modules/websites/tools/ether/default.nix b/virtual/modules/websites/tools/ether/default.nix
new file mode 100644 (file)
index 0000000..5ee3433
--- /dev/null
@@ -0,0 +1,89 @@
+{ lib, pkgs, config, myconfig, mylibs, ... }:
+let
+  etherpad = pkgs.callPackage ./etherpad_lite.nix {
+    inherit (mylibs) fetchedGithub;
+    env = myconfig.env.tools.etherpad-lite;
+  };
+
+  cfg = config.services.myWebsites.tools.etherpad-lite;
+in {
+  options.services.myWebsites.tools.etherpad-lite = {
+    enable = lib.mkEnableOption "enable etherpad's website";
+  };
+
+  config = lib.mkIf cfg.enable {
+    systemd.services.etherpad-lite = {
+      description = "Etherpad-lite";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" "postgresql.service" ];
+      wants = [ "postgresql.service" ];
+
+      environment.NODE_ENV = "production";
+      environment.HOME = etherpad.webappDir;
+
+      path = [ pkgs.nodejs ];
+
+      script = ''
+        exec ${pkgs.nodejs}/bin/node ${etherpad.webappDir}/src/node/server.js \
+          --settings ${etherpad.config}
+      '';
+
+      serviceConfig = {
+        DynamicUser = true;
+        User = "etherpad-lite";
+        Group = "etherpad-lite";
+        WorkingDirectory = etherpad.webappDir;
+        PrivateTmp = true;
+        NoNewPrivileges = true;
+        PrivateDevices = true;
+        ProtectHome = true;
+        ProtectControlGroups = true;
+        ProtectKernelModules = true;
+        Restart = "always";
+        Type = "simple";
+        TimeoutSec = 60;
+      };
+    };
+
+    services.myWebsites.tools.modules = [
+      "headers" "proxy" "proxy_http" "proxy_wstunnel"
+    ];
+    security.acme.certs."eldiron".extraDomains."ether.immae.eu" = null;
+    services.myWebsites.tools.vhostConfs.etherpad-lite = {
+      certName    = "eldiron";
+      hosts       = [ "ether.immae.eu" ];
+      root        = null;
+      extraConfig = [ ''
+        Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
+        RequestHeader set X-Forwarded-Proto "https"
+
+        RewriteEngine On
+
+        RewriteMap  redirects "txt:${pkgs.writeText "redirects.txt" myconfig.env.tools.etherpad-lite.redirects}"
+        RewriteCond %{QUERY_STRING}         "!noredirect"
+        RewriteCond %{REQUEST_URI}          "^(.*)$"
+        RewriteCond ''${redirects:$1|Unknown} "!Unknown"
+        RewriteRule "^(.*)$"                ''${redirects:$1}  [L,NE,R=301,QSD]
+
+        RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
+        RewriteCond %{QUERY_STRING} transport=websocket    [NC]
+        RewriteRule /(.*)           ws://localhost:${etherpad.listenPort}/$1 [P,L]
+
+        <IfModule mod_proxy.c>
+          ProxyVia On
+          ProxyRequests Off
+          ProxyPreserveHost On
+          ProxyPass         / http://localhost:${etherpad.listenPort}/
+          ProxyPassReverse  / http://localhost:${etherpad.listenPort}/
+          ProxyPass         /socket.io ws://localhost:${etherpad.listenPort}/socket.io
+          ProxyPassReverse  /socket.io ws://localhost:${etherpad.listenPort}/socket.io
+          <Proxy *>
+            Options FollowSymLinks MultiViews
+            AllowOverride None
+            Require all granted
+          </Proxy>
+        </IfModule>
+      '' ];
+    };
+  };
+}
diff --git a/virtual/modules/websites/tools/ether/etherpad-lite.json b/virtual/modules/websites/tools/ether/etherpad-lite.json
new file mode 100644 (file)
index 0000000..81369c4
--- /dev/null
@@ -0,0 +1,15 @@
+{
+  "tag": "1.7.0",
+  "meta": {
+    "name": "etherpad-lite",
+    "url": "https://github.com/ether/etherpad-lite",
+    "branch": "refs/tags/1.7.0"
+  },
+  "github": {
+    "owner": "ether",
+    "repo": "etherpad-lite",
+    "rev": "96ac381afb9ea731dad48968f15d77dc6488bd0d",
+    "sha256": "03k6bwlm9ch9kssy9jipfg8ij7rpbzd89xq4mvg4grg1q6ivnzk9",
+    "fetchSubmodules": true
+  }
+}
diff --git a/virtual/modules/websites/tools/ether/etherpad_lite.nix b/virtual/modules/websites/tools/ether/etherpad_lite.nix
new file mode 100644 (file)
index 0000000..f5f05b7
--- /dev/null
@@ -0,0 +1,183 @@
+{ env, fetchedGithub, fetchurl, stdenv, writeText, pkgs, cacert }:
+let
+  listenPort = "18001";
+  sessionkey = writeText "SESSIONKEY.txt" env.session_key;
+  apikey = writeText "APIKEY.txt" env.api_key;
+  jquery = fetchurl {
+    url = https://code.jquery.com/jquery-1.9.1.js;
+    sha256 = "0h4dk67yc9d0kadqxb6b33585f3x3559p6qmp70l00qwq030vn3v";
+  };
+  etherpad_modules = [
+    "ep_aa_file_menu_toolbar"
+    "ep_adminpads"
+    "ep_align"
+    "ep_bookmark"
+    "ep_clear_formatting"
+    "ep_colors"
+    "ep_copy_paste_select_all"
+    "ep_cursortrace"
+    "ep_embedmedia"
+    "ep_font_family"
+    "ep_font_size"
+    "ep_headings2"
+    "ep_ldapauth"
+    "ep_line_height"
+    "ep_markdown"
+    "ep_previewimages"
+    "ep_ruler"
+    "ep_scrollto"
+    "ep_set_title_on_pad"
+    "ep_subscript_and_superscript"
+    "ep_timesliderdiff"
+    ];
+  config =
+    # Make sure we’re not rebuilding whole libreoffice just because of a
+    # dependency
+    let libreoffice = (import <nixpkgs> {}).libreoffice-fresh;
+    in
+    writeText "settings.json" ''
+      {
+        "title": "Etherpad",
+        "favicon": "favicon.ico",
+
+        "ip": "127.0.0.1",
+        "port" : ${listenPort},
+        "showSettingsInAdminPage" : false,
+        "dbType" : "postgres",
+        "dbSettings" : {
+          "user"    : "${env.postgresql.user}",
+          "host"    : "${env.postgresql.socket}",
+          "password": "${env.postgresql.password}",
+          "database": "${env.postgresql.database}",
+          "charset" : "utf8mb4"
+        },
+
+        "defaultPadText" : "Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nGet involved with Etherpad at http:\/\/etherpad.org\n",
+        "padOptions": {
+          "noColors": false,
+          "showControls": true,
+          "showChat": true,
+          "showLineNumbers": true,
+          "useMonospaceFont": false,
+          "userName": false,
+          "userColor": false,
+          "rtl": false,
+          "alwaysShowChat": false,
+          "chatAndUsers": false,
+          "lang": "en-gb"
+        },
+
+        "suppressErrorsInPadText" : false,
+        "requireSession" : false,
+        "editOnly" : false,
+        "sessionNoPassword" : false,
+        "minify" : true,
+        "maxAge" : 21600,
+        "abiword" : null,
+        "soffice" : "${libreoffice}/bin/soffice",
+        "tidyHtml" : "${pkgs.html-tidy}/bin/tidy",
+        "allowUnknownFileEnds" : true,
+        "requireAuthentication" : false,
+        "requireAuthorization" : false,
+        "trustProxy" : false,
+        "disableIPlogging" : false,
+        "automaticReconnectionTimeout" : 0,
+        "scrollWhenFocusLineIsOutOfViewport": {
+          "percentage": {
+            "editionAboveViewport": 0,
+            "editionBelowViewport": 0
+          },
+          "duration": 0,
+          "scrollWhenCaretIsInTheLastLineOfViewport": false,
+          "percentageToScrollWhenUserPressesArrowUp": 0
+        },
+        "users": {
+          "ldapauth": {
+            "url": "ldaps://${env.ldap.host}",
+            "accountBase": "${env.ldap.base}",
+            "accountPattern": "(&(memberOf=cn=users,cn=etherpad,ou=services,dc=immae,dc=eu)(uid={{username}}))",
+            "displayNameAttribute": "cn",
+            "searchDN": "cn=etherpad,ou=services,dc=immae,dc=eu",
+            "searchPWD": "${env.ldap.password}",
+            "groupSearchBase": "${env.ldap.base}",
+            "groupAttribute": "member",
+            "groupAttributeIsDN": true,
+            "searchScope": "sub",
+            "groupSearch": "(memberOf=cn=groups,cn=etherpad,ou=services,dc=immae,dc=eu)",
+            "anonymousReadonly": false
+          }
+        },
+        "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"],
+        "loadTest": false,
+        "indentationOnNewLine": false,
+        "toolbar": {
+          "left": [
+            ["bold", "italic", "underline", "strikethrough"],
+            ["orderedlist", "unorderedlist", "indent", "outdent"],
+            ["undo", "redo"],
+            ["clearauthorship"]
+          ],
+          "right": [
+            ["importexport", "timeslider", "savedrevision"],
+            ["settings", "embed"],
+            ["showusers"]
+          ],
+          "timeslider": [
+            ["timeslider_export", "timeslider_returnToPad"]
+          ]
+        },
+        "loglevel": "INFO",
+        "logconfig" : { "appenders": [ { "type": "console" } ] }
+      }
+    '';
+  webappDir = stdenv.mkDerivation (fetchedGithub ./etherpad-lite.json // rec {
+    __noChroot = true;
+    patches = [ ./libreoffice_patch.diff ];
+    buildPhase = ''
+      export GIT_SSL_CAINFO=${cacert}/etc/ssl/certs/ca-bundle.crt
+      export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
+      export HOME=$PWD
+
+      touch src/.ep_initialized
+      cp -v src/static/custom/js.template src/static/custom/index.js
+      cp -v src/static/custom/js.template src/static/custom/pad.js
+      cp -v src/static/custom/js.template src/static/custom/timeslider.js
+      cp -v src/static/custom/css.template src/static/custom/index.css
+      cp -v src/static/custom/css.template src/static/custom/pad.css
+      cp -v src/static/custom/css.template src/static/custom/timeslider.css
+
+      sed -i 's/var\/dirty.db/\/var\/lib\/etherpad-lite\/dirty.db/g' \
+        settings.json.template
+
+      mkdir -v node_modules
+      ln -s ../src node_modules/ep_etherpad-lite
+
+      node bin/doc/generate doc/index.md --format=html \
+        --template=doc/template.html > documentation.html
+
+      cd src
+      npm install
+      cd ..
+      ${builtins.concatStringsSep "\n"
+        (map (n: "npm install ${n}; touch node_modules/${n}/.ep_initialized") etherpad_modules)}
+      '';
+    installPhase = ''
+      mkdir -p $out
+      install -t $out/src/ -vDm 644 src/.ep_initialized
+      cp -a node_modules $out/
+      cp -a src/* $out/src/
+      ln -sf ${sessionkey} $out/SESSIONKEY.txt
+      ln -sf ${apikey} $out/APIKEY.txt
+      cp ${jquery} $out/src/static/js/jquery.js
+
+      mkdir $out/doc
+      install -t "$out/doc/" \
+        -vDm 644 {CHANGELOG,CONTRIBUTING,README}.md \
+        -vDm 644 documentation.html
+    '';
+    buildInputs = [ pkgs.nodejs pkgs.python ];
+  });
+in
+  {
+    inherit webappDir config listenPort;
+  }
diff --git a/virtual/modules/websites/tools/ether/libreoffice_patch.diff b/virtual/modules/websites/tools/ether/libreoffice_patch.diff
new file mode 100644 (file)
index 0000000..d9e3dfc
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/src/node/utils/LibreOffice.js      2018-06-18 09:54:15.087161212 +0200
++++ b/src/node/utils/LibreOffice.js    2018-06-18 10:33:27.534055021 +0200
+@@ -63,6 +63,7 @@
+         '--invisible',
+         '--nologo',
+         '--nolockcheck',
++        '-env:UserInstallation=file:///tmp/',
+         '--convert-to', task.type,
+         task.srcFile,
+         '--outdir', tmpDir
+