summaryrefslogtreecommitdiffstats
path: root/nixos
diff options
context:
space:
mode:
authorFélix Baylac-Jacqué <felix@alternativebit.fr>2020-11-08 15:10:14 +0100
committerFélix Baylac-Jacqué <felix@alternativebit.fr>2021-01-26 18:11:38 +0100
commit60b730fd944b6e42bc185dd92ed8cb71e48d795b (patch)
tree3e62bdea054d1ec1b0084a710f09ef2a0371d3d6 /nixos
parent231c5a576a95391d5e4cd5b8948bfa8a6224bed1 (diff)
nixos/pleroma: add NixOS VM test.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/pleroma.nix265
2 files changed, 266 insertions, 0 deletions
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 902c3bbc65e9..22629042ae5c 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -301,6 +301,7 @@ in
php = handleTest ./php {};
pinnwand = handleTest ./pinnwand.nix {};
plasma5 = handleTest ./plasma5.nix {};
+ pleroma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./pleroma.nix {};
plotinus = handleTest ./plotinus.nix {};
podman = handleTestOn ["x86_64-linux"] ./podman.nix {};
postfix = handleTest ./postfix.nix {};
diff --git a/nixos/tests/pleroma.nix b/nixos/tests/pleroma.nix
new file mode 100644
index 000000000000..797cac44f956
--- /dev/null
+++ b/nixos/tests/pleroma.nix
@@ -0,0 +1,265 @@
+/*
+ Pleroma E2E VM test.
+
+ Abstract:
+ =========
+ Using pleroma, postgresql, a local CA cert, a nginx reverse proxy
+ and a toot-based client, we're going to:
+
+ 1. Provision a pleroma service from scratch (pleroma config + postgres db).
+ 2. Create a "jamy" admin user.
+ 3. Send a toot from this user.
+ 4. Send a upload from this user.
+ 5. Check the toot is part of the server public timeline
+
+ Notes:
+ - We need a fully functional TLS setup without having any access to
+ the internet. We do that by issuing a self-signed cert, add this
+ self-cert to the hosts pki trust store and finally spoof the
+ hostnames using /etc/hosts.
+ - For this NixOS test, we *had* to store some DB-related and
+ pleroma-related secrets to the store. Keep in mind the store is
+ world-readable, it's the worst place possible to store *any*
+ secret. **DO NOT DO THIS IN A REAL WORLD DEPLOYMENT**.
+*/
+
+import ./make-test-python.nix ({ pkgs, ... }:
+ let
+ send-toot = pkgs.writeScriptBin "send-toot" ''
+ set -eux
+ # toot is using the requests library internally. This library
+ # sadly embed its own certificate store instead of relying on the
+ # system one. Overriding this pretty bad default behaviour.
+ export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
+
+ export TOOT_LOGIN_CLI_PASSWORD="jamy-password"
+ toot login_cli -i "pleroma.nixos.test" -e "jamy@nixos.test"
+ echo "Login OK"
+
+ # Send a toot then verify it's part of the public timeline
+ echo "y" | toot post "hello world Jamy here"
+ echo "Send toot OK"
+ echo "y" | toot timeline | grep -c "hello world Jamy here"
+ echo "Get toot from timeline OK"
+
+ # Test file upload
+ echo "y" | toot upload ${db-seed} | grep -c "https://pleroma.nixos.test/media"
+ echo "File upload OK"
+
+ echo "====================================================="
+ echo "= SUCCESS ="
+ echo "= ="
+ echo "= We were able to sent a toot + a upload and ="
+ echo "= retrieve both of them in the public timeline. ="
+ echo "====================================================="
+ '';
+
+ provision-db = pkgs.writeScriptBin "provision-db" ''
+ set -eux
+ sudo -u postgres psql -f ${db-seed}
+ '';
+
+ test-db-passwd = "SccZOvTGM//BMrpoQj68JJkjDkMGb4pHv2cECWiI+XhVe3uGJTLI0vFV/gDlZ5jJ";
+
+ /* For this NixOS test, we *had* to store this secret to the store.
+ Keep in mind the store is world-readable, it's the worst place
+ possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+ DEPLOYMENT**.*/
+ db-seed = pkgs.writeText "provision.psql" ''
+ CREATE USER pleroma WITH ENCRYPTED PASSWORD '${test-db-passwd}';
+ CREATE DATABASE pleroma OWNER pleroma;
+ \c pleroma;
+ --Extensions made by ecto.migrate that need superuser access
+ CREATE EXTENSION IF NOT EXISTS citext;
+ CREATE EXTENSION IF NOT EXISTS pg_trgm;
+ CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
+ '';
+
+ pleroma-conf = ''
+ import Config
+
+ config :pleroma, Pleroma.Web.Endpoint,
+ url: [host: "pleroma.nixos.test", scheme: "https", port: 443],
+ http: [ip: {127, 0, 0, 1}, port: 4000]
+
+ config :pleroma, :instance,
+ name: "NixOS test pleroma server",
+ email: "pleroma@nixos.test",
+ notify_email: "pleroma@nixos.test",
+ limit: 5000,
+ registrations_open: true
+
+ config :pleroma, :media_proxy,
+ enabled: false,
+ redirect_on_failure: true
+ #base_url: "https://cache.pleroma.social"
+
+ config :pleroma, Pleroma.Repo,
+ adapter: Ecto.Adapters.Postgres,
+ username: "pleroma",
+ password: "${test-db-passwd}",
+ database: "pleroma",
+ hostname: "localhost",
+ pool_size: 10,
+ prepare: :named,
+ parameters: [
+ plan_cache_mode: "force_custom_plan"
+ ]
+
+ config :pleroma, :database, rum_enabled: false
+ config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
+ config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
+ config :pleroma, configurable_from_database: false
+ '';
+
+ /* For this NixOS test, we *had* to store this secret to the store.
+ Keep in mind the store is world-readable, it's the worst place
+ possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+ DEPLOYMENT**.
+ In a real-word deployment, you'd handle this either by:
+ - manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
+ - use a deployment tool such as morph or NixOps to deploy your secrets.
+ */
+ pleroma-conf-secret = pkgs.writeText "secrets.exs" ''
+ import Config
+
+ config :joken, default_signer: "PS69/wMW7X6FIQPABt9lwvlZvgrJIncfiAMrK9J5mjVus/7/NJJi1DsDA1OghBE5"
+
+ config :pleroma, Pleroma.Web.Endpoint,
+ secret_key_base: "NvfmU7lYaQrmmxt4NACm0AaAfN9t6WxsrX0NCB4awkGHvr1S7jyshlEmrjaPFhhq",
+ signing_salt: "3L41+BuJ"
+
+ config :web_push_encryption, :vapid_details,
+ subject: "mailto:pleroma@nixos.test",
+ public_key: "BKjfNX9-UqAcncaNqERQtF7n9pKrB0-MO-juv6U5E5XQr_Tg5D-f8AlRjduAguDpyAngeDzG8MdrTejMSL4VF30",
+ private_key: "k7o9onKMQrgMjMb6l4fsxSaXO0BTNAer5MVSje3q60k"
+ '';
+
+ /* For this NixOS test, we *had* to store this secret to the store.
+ Keep in mind the store is world-readable, it's the worst place
+ possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+ DEPLOYMENT**.
+ In a real-word deployment, you'd handle this either by:
+ - manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
+ - use a deployment tool such as morph or NixOps to deploy your secrets.
+ */
+ provision-secrets = pkgs.writeScriptBin "provision-secrets" ''
+ set -eux
+ cp "${pleroma-conf-secret}" "/var/lib/pleroma/secrets.exs"
+ chown pleroma:pleroma /var/lib/pleroma/secrets.exs
+ '';
+
+ /* For this NixOS test, we *had* to store this secret to the store.
+ Keep in mind the store is world-readable, it's the worst place
+ possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+ DEPLOYMENT**.
+ */
+ provision-user = pkgs.writeScriptBin "provision-user" ''
+ set -eux
+
+ # Waiting for pleroma to be up.
+ timeout 5m bash -c 'while [[ "$(curl -s -o /dev/null -w '%{http_code}' https://pleroma.nixos.test/api/v1/instance)" != "200" ]]; do sleep 2; done'
+ pleroma_ctl user new jamy jamy@nixos.test --password 'jamy-password' --moderator --admin -y
+ '';
+
+ tls-cert = pkgs.runCommandNoCC "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
+ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=pleroma.nixos.test'
+ mkdir -p $out
+ cp key.pem cert.pem $out
+ '';
+
+ /* Toot is preventing users from feeding login_cli a password non
+ interactively. While it makes sense most of the times, it's
+ preventing us to login in this non-interactive test. This patch
+ introduce a TOOT_LOGIN_CLI_PASSWORD env variable allowing us to
+ provide a password to toot login_cli
+
+ If https://github.com/ihabunek/toot/pull/180 gets merged at some
+ point, feel free to remove this patch. */
+ custom-toot = pkgs.toot.overrideAttrs(old:{
+ patches = [ (pkgs.fetchpatch {
+ url = "https://github.com/NinjaTrappeur/toot/commit/b4a4c30f41c0cb7e336714c2c4af9bc9bfa0c9f2.patch";
+ sha256 = "sha256-0xxNwjR/fStLjjUUhwzCCfrghRVts+fc+fvVJqVcaFg=";
+ }) ];
+ });
+
+ hosts = nodes: ''
+ ${nodes.pleroma.config.networking.primaryIPAddress} pleroma.nixos.test
+ ${nodes.client.config.networking.primaryIPAddress} client.nixos.test
+ '';
+ in {
+ name = "pleroma";
+ nodes = {
+ client = { nodes, pkgs, config, ... }: {
+ security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
+ networking.extraHosts = hosts nodes;
+ environment.systemPackages = with pkgs; [
+ custom-toot
+ send-toot
+ ];
+ };
+ pleroma = { nodes, pkgs, config, ... }: {
+ security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
+ networking.extraHosts = hosts nodes;
+ networking.firewall.enable = false;
+ environment.systemPackages = with pkgs; [
+ provision-db
+ provision-secrets
+ provision-user
+ ];
+ services = {
+ pleroma = {
+ enable = true;
+ configs = [
+ pleroma-conf
+ ];
+ };
+ postgresql = {
+ enable = true;
+ package = pkgs.postgresql_12;
+ };
+ nginx = {
+ enable = true;
+ virtualHosts."pleroma.nixos.test" = {
+ addSSL = true;
+ sslCertificate = "${tls-cert}/cert.pem";
+ sslCertificateKey = "${tls-cert}/key.pem";
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:4000";
+ extraConfig = ''
+ add_header 'Access-Control-Allow-Origin' '*' always;
+ add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
+ add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
+ add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
+ if ($request_method = OPTIONS) {
+ return 204;
+ }
+ add_header X-XSS-Protection "1; mode=block";
+ add_header X-Permitted-Cross-Domain-Policies none;
+ add_header X-Frame-Options DENY;
+ add_header X-Content-Type-Options nosniff;
+ add_header Referrer-Policy same-origin;
+ add_header X-Download-Options noopen;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header Host $host;
+ client_max_body_size 16m;
+ '';
+ };
+ };
+ };
+ };
+ };
+ };
+
+ testScript = { nodes, ... }: ''
+ pleroma.wait_for_unit("postgresql.service")
+ pleroma.succeed("provision-db")
+ pleroma.succeed("provision-secrets")
+ pleroma.systemctl("restart pleroma.service")
+ pleroma.wait_for_unit("pleroma.service")
+ pleroma.succeed("provision-user")
+ client.succeed("send-toot")
+ '';
+})