From 8355348aae080da8eefac7c089a5c91480bd1888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Becker?= Date: Wed, 20 Jan 2021 15:52:26 +0100 Subject: [PATCH 01/10] Etherpad documentation --- README.md | 2 ++ docs/configuring-playbook-etherpad.md | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 docs/configuring-playbook-etherpad.md diff --git a/README.md b/README.md index 93c022d9..26e059af 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ Using this playbook, you can get the following services configured on your serve - (optional) [Dimension](https://github.com/turt2live/matrix-dimension), an open source integrations manager for matrix clients - see [docs/configuring-playbook-dimension.md](docs/configuring-playbook-dimension.md) for setup documentation +- (optional) [Etherpad](https://etherpad.org), an open source collaborative text editor - see [docs/configuring-playbook-etherpad.md](docs/configuring-playbook-etherpad.md) for setup documentation + - (optional) [Jitsi](https://jitsi.org/), an open source video-conferencing platform - see [docs/configuring-playbook-jitsi.md](docs/configuring-playbook-jitsi.md) for setup documentation - (optional) [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) for scheduling one-off & recurring reminders and alarms - see [docs/configuring-playbook-bot-matrix-reminder-bot.md](docs/configuring-playbook-bot-matrix-reminder-bot.md) for setup documentation diff --git a/docs/configuring-playbook-etherpad.md b/docs/configuring-playbook-etherpad.md new file mode 100644 index 00000000..9ec24d33 --- /dev/null +++ b/docs/configuring-playbook-etherpad.md @@ -0,0 +1,26 @@ +# Setting up Etherpad (optional) + +[Etherpad](https://etherpad.org) is is an open source collaborative text editor that can be embedded in a Matrix chat room using the [Dimension integrations manager](https://dimension.t2bot.io) + +When enabled together with Jitsi, it will be made available as an option during the conferences. + +## Prerequisites + +For the self-hosted Etherpad instance to be available to your users, you must first enable and configure the **Dimension integrations manager** as described in [the playbook documentation](configuring-playbook-dimension.md) + +## Enable + +[Etherpad](https://etherpad.org) installation is disabled by default. You can enable it in your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_etherpad_enabled: true +``` + +## Set Dimension default to the self-hosted Etherpad + +The Dimension administrator users can configure the default URL template. The Dimension configuration menu can be accessed with the sprocket icon as you begin to add a widget to a room in Element. There you will find the Etherpad Widget Configuration action beneath the _Widgets_ tab. Replace `scalar.vector.im` with your own Dimension domain. + +### Removing the integrated Etherpad chat + +If you wish to disable the Etherpad chat button, you can do it by appending `?showChat=false` to the end of the pad URL, or the template. +Example: `https://dimension./etherpad/p/$roomId_$padName?showChat=false` From 4b451ff782000d49c1c5b601447bc240369a3f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Becker?= Date: Thu, 21 Jan 2021 00:06:35 +0100 Subject: [PATCH 02/10] Etherpad role --- group_vars/matrix_servers | 29 +++++ roles/matrix-etherpad/defaults/main.yml | 93 +++++++++++++++ roles/matrix-etherpad/tasks/init.yml | 3 + roles/matrix-etherpad/tasks/main.yml | 15 +++ roles/matrix-etherpad/tasks/setup_install.yml | 36 ++++++ .../matrix-etherpad/tasks/setup_uninstall.yml | 35 ++++++ .../matrix-etherpad/tasks/validate_config.yml | 7 ++ .../templates/settings.json.j2 | 106 ++++++++++++++++++ .../systemd/matrix-etherpad.service.j2 | 49 ++++++++ setup.yml | 1 + 10 files changed, 374 insertions(+) create mode 100644 roles/matrix-etherpad/defaults/main.yml create mode 100644 roles/matrix-etherpad/tasks/init.yml create mode 100644 roles/matrix-etherpad/tasks/main.yml create mode 100644 roles/matrix-etherpad/tasks/setup_install.yml create mode 100644 roles/matrix-etherpad/tasks/setup_uninstall.yml create mode 100644 roles/matrix-etherpad/tasks/validate_config.yml create mode 100644 roles/matrix-etherpad/templates/settings.json.j2 create mode 100644 roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 7c736ba4..50d34bcc 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -757,7 +757,30 @@ matrix_dimension_database_password: "{{ matrix_synapse_macaroon_secret_key | pas # ###################################################################### +###################################################################### +# +# matrix-etherpad +# +###################################################################### + +matrix_etherpad_enabled: false +matrix_etherpad_systemd_required_services_list: | + {{ + ['docker.service'] + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + }} + +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_etherpad_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_etherpad_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'etherpad.db') | to_uuid }}" + +###################################################################### +# +# /matrix-etherpad +# +###################################################################### ###################################################################### # @@ -1146,6 +1169,12 @@ matrix_postgres_additional_databases: | 'username': matrix_dimension_database_username, 'password': matrix_dimension_database_password, }] if (matrix_dimension_enabled and matrix_dimension_database_engine == 'postgres' and matrix_dimension_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_etherpad_database_name, + 'username': matrix_etherpad_database_username, + 'password': matrix_etherpad_database_password, + }] if (matrix_etherpad_enabled and matrix_etherpad_database_engine == 'postgres' and matrix_etherpad_database_hostname == 'matrix-postgres') else []) }} matrix_postgres_import_roles_to_ignore: | diff --git a/roles/matrix-etherpad/defaults/main.yml b/roles/matrix-etherpad/defaults/main.yml new file mode 100644 index 00000000..353adac7 --- /dev/null +++ b/roles/matrix-etherpad/defaults/main.yml @@ -0,0 +1,93 @@ +matrix_etherpad_enabled: false + +matrix_etherpad_base_path: "{{ matrix_base_data_path }}/etherpad" + +matrix_etherpad_docker_image: "docker.io/etherpad/etherpad:latest" +matrix_etherpad_docker_image_force_pull: "{{ matrix_etherpad_docker_image.endswith(':latest') }}" + +# List of systemd services that matrix-etherpad.service depends on. +matrix_etherpad_systemd_required_services_list: ['docker.service'] + +# List of systemd services that matrix-etherpad.service wants +matrix_etherpad_systemd_wanted_services_list: [] + +# Container user has to be able to write to the source file directories until this bug is fixed: +# https://github.com/ether/etherpad-lite/issues/2683 +matrix_etherpad_user_uid: '5001' +matrix_etherpad_user_gid: '5001' + +# Controls whether the matrix-etherpad container exposes its HTTP port (tcp/9001 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:9001"), or empty string to not expose. +matrix_etherpad_container_http_host_bind_port: '9001' + +# A list of extra arguments to pass to the container +matrix_etherpad_container_extra_arguments: [] + +matrix_etherpad_public_endpoint: '/etherpad' + +# By default, the Etherpad app can be accessed within the Dimension domain +matrix_etherpad_base_url: "https://{{ matrix_server_fqn_dimension }}{{ matrix_etherpad_public_endpoint }}" + +# Database-related configuration fields. +# +# Etherpad recommends using a dedicated database, and supports Sqliite only for development +# +# To use Postgres: +# - change the engine (`matrix_etherpad_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_etherpad_postgres_*` variables +matrix_etherpad_database_engine: 'sqlite' + +matrix_etherpad_sqlite_database_path_local: "{{ matrix_etherpad_base_path }}/etherpad.db" +matrix_etherpad_sqlite_database_path_in_container: "/data/etherpad.db" + +matrix_etherpad_database_username: 'matrix_etherpad' +matrix_etherpad_database_password: 'some-password' +matrix_etherpad_database_hostname: 'matrix-postgres' +matrix_etherpad_database_port: 5432 +matrix_etherpad_database_name: 'matrix_etherpad' + +matrix_etherpad_database_connection_string: 'postgres://{{ matrix_etherpad_database_username }}:{{ matrix_etherpad_database_password }}@{{ matrix_etherpad_database_hostname }}:{{ matrix_etherpad_database_port }}/{{ matrix_etherpad_database_name }}' + +# Variables configuring the etherpad +matrix_etherpad_title: 'Etherpad' +matrix_etherpad_default_pad_text: | + Welcome to Etherpad! + + This 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! + + Get involved with Etherpad at https://etherpad.org + +# Default Etherpad configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_etherpad_configuration_extension_json`) +# or completely replace this variable with your own template. +matrix_etherpad_configuration_default: "{{ lookup('template', 'templates/settings.json.j2') }}" + +# Your custom JSON configuration for Etherpad goes here. +# This configuration extends the default starting configuration (`matrix_etherpad_configuration_json`). +# +# You can override individual variables from the default configuration, or introduce new ones. +# +# If you need something more special, you can take full control by +# completely redefining `matrix_etherpad_configuration_json`. +# +# Example configuration extension follows: +# +# matrix_etherpad_configuration_extension_json: | +# { +# "loadTest": true, +# "commitRateLimiting": { +# "duration": 1, +# "points": 10 +# } +# } +# +matrix_etherpad_configuration_extension_json: '{}' + +matrix_etherpad_configuration_extension: "{{ matrix_etherpad_configuration_extension_json|from_json if matrix_etherpad_configuration_extension_json|from_json is mapping else {} }}" + +# Holds the final Etherpad configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_etherpad_configuration_json`. +matrix_etherpad_configuration: "{{ matrix_etherpad_configuration_default|combine(matrix_etherpad_configuration_extension, recursive=True) }}" diff --git a/roles/matrix-etherpad/tasks/init.yml b/roles/matrix-etherpad/tasks/init.yml new file mode 100644 index 00000000..7496d4b4 --- /dev/null +++ b/roles/matrix-etherpad/tasks/init.yml @@ -0,0 +1,3 @@ +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-etherpad.service'] }}" + when: matrix_etherpad_enabled|bool diff --git a/roles/matrix-etherpad/tasks/main.yml b/roles/matrix-etherpad/tasks/main.yml new file mode 100644 index 00000000..09ead973 --- /dev/null +++ b/roles/matrix-etherpad/tasks/main.yml @@ -0,0 +1,15 @@ +- import_tasks: "{{ role_path }}/tasks/init.yml" + tags: + - always + +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: run_setup|bool and matrix_etherpad_enabled|bool + tags: + - setup-all + - setup-etherpad + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: run_setup|bool and not matrix_etherpad_enabled|bool + tags: + - setup-all + - setup-etherpad diff --git a/roles/matrix-etherpad/tasks/setup_install.yml b/roles/matrix-etherpad/tasks/setup_install.yml new file mode 100644 index 00000000..a93c28de --- /dev/null +++ b/roles/matrix-etherpad/tasks/setup_install.yml @@ -0,0 +1,36 @@ +--- + +- name: Ensure Etherpad base path exists + file: + path: "{{ matrix_etherpad_base_path }}" + state: directory + mode: 0770 + owner: "{{ matrix_etherpad_user_uid }}" + group: "{{ matrix_etherpad_user_gid }}" + +- name: Ensure Etherpad config installed + copy: + content: "{{ matrix_etherpad_configuration|to_nice_json }}" + dest: "{{ matrix_etherpad_base_path }}/settings.json" + mode: 0640 + owner: "{{ matrix_etherpad_user_uid }}" + group: "{{ matrix_etherpad_user_gid }}" + +- name: Ensure Etherpad image is pulled + docker_image: + name: "{{ matrix_etherpad_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_etherpad_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" + force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_etherpad_docker_image_force_pull }}" + +- name: Ensure matrix-etherpad.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-etherpad.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-etherpad.service" + mode: 0644 + register: matrix_etherpad_systemd_service_result + +- name: Ensure systemd reloaded after matrix-etherpad.service installation + service: + daemon_reload: yes + when: "matrix_etherpad_systemd_service_result.changed|bool" diff --git a/roles/matrix-etherpad/tasks/setup_uninstall.yml b/roles/matrix-etherpad/tasks/setup_uninstall.yml new file mode 100644 index 00000000..865389f2 --- /dev/null +++ b/roles/matrix-etherpad/tasks/setup_uninstall.yml @@ -0,0 +1,35 @@ +--- + +- name: Check existence of matrix-etherpad service + stat: + path: "{{ matrix_systemd_path }}/matrix-etherpad.service" + register: matrix_etherpad_service_stat + +- name: Ensure matrix-etherpad is stopped + service: + name: matrix-etherpad + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_etherpad_service_stat.stat.exists|bool" + +- name: Ensure matrix-etherpad.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-etherpad.service" + state: absent + when: "matrix_etherpad_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-etherpad.service removal + service: + daemon_reload: yes + when: "matrix_etherpad_service_stat.stat.exists|bool" + +- name: Ensure Etherpad base directory doesn't exist + file: + path: "{{ matrix_etherpad_base_path }}" + state: absent + +- name: Ensure Dimension Docker image doesn't exist + docker_image: + name: "{{ matrix_etherpad_docker_image }}" + state: absent diff --git a/roles/matrix-etherpad/tasks/validate_config.yml b/roles/matrix-etherpad/tasks/validate_config.yml new file mode 100644 index 00000000..e5621a07 --- /dev/null +++ b/roles/matrix-etherpad/tasks/validate_config.yml @@ -0,0 +1,7 @@ +- name: Fail if required Etherpad settings not defined + fail: + msg: >- + You need to define a required configuration setting (`{{ item }}`) for using Etherpad. + with_items: + - + when: "matrix_etherpad_enabled and vars[item] == ''" diff --git a/roles/matrix-etherpad/templates/settings.json.j2 b/roles/matrix-etherpad/templates/settings.json.j2 new file mode 100644 index 00000000..6435cf6d --- /dev/null +++ b/roles/matrix-etherpad/templates/settings.json.j2 @@ -0,0 +1,106 @@ +{ + "title": {{ matrix_etherpad_title|to_json }}, + "favicon": "favicon.ico", + "skinName": "colibris", + "skinVariants": "super-light-toolbar super-light-editor light-background", + "ip": "::", + "port": 9001, + "showSettingsInAdminPage": true, + "dbType": {{ matrix_etherpad_database_engine|to_json }}, + "dbSettings": { + {% if matrix_etherpad_database_engine == 'sqlite' %} + "filename": {{ matrix_etherpad_sqlite_database_path_in_container|to_json }} + {% elif matrix_etherpad_database_engine == 'postgres' %} + "database": {{ matrix_etherpad_database_name|to_json }}, + "host": {{ matrix_etherpad_database_hostname|to_json }}, + "password": {{ matrix_etherpad_database_password|to_json }}, + "port": {{ matrix_etherpad_database_port|to_json }}, + "user": {{ matrix_etherpad_database_username|to_json }} + {% endif %} + }, + "defaultPadText" : {{ matrix_etherpad_default_pad_text|to_json }}, + "suppressErrorsInPadText": false, + "requireSession": false, + "editOnly": false, + "minify": true, + "maxAge": 21600, + "abiword": null, + "soffice": null, + "tidyHtml": null, + "allowUnknownFileEnds": true, + "requireAuthentication": false, + "requireAuthorization": false, + "trustProxy": true, + "cookie": { + "sameSite": "Lax" + }, + "disableIPlogging": true, + "automaticReconnectionTimeout": 0, + "scrollWhenFocusLineIsOutOfViewport": { + "percentage": { + "editionAboveViewport": 0, + "editionBelowViewport": 0 + }, + "duration": 0, + "scrollWhenCaretIsInTheLastLineOfViewport": false, + "percentageToScrollWhenUserPressesArrowUp": 0 + }, + "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], + "loadTest": false, + "importExportRateLimiting": { + "windowMs": 90000, + "max": 10 + }, + "importMaxFileSize": 52428800, + "commitRateLimiting": { + "duration": 1, + "points": 10 + }, + "exposeVersion": false, + "padOptions": { + "noColors": false, + "showControls": true, + "showChat": false, + "showLineNumbers": true, + "useMonospaceFont": false, + "userName": false, + "userColor": false, + "rtl": false, + "alwaysShowChat": false, + "chatAndUsers": false, + "lang": "en-gb" + }, + "padShortcutEnabled" : { + "altF9": true, + "altC": true, + "cmdShift2": true, + "delete": true, + "return": true, + "esc": true, + "cmdS": true, + "tab": true, + "cmdZ": true, + "cmdY": true, + "cmdI": true, + "cmdB": true, + "cmdU": true, + "cmd5": true, + "cmdShiftL": true, + "cmdShiftN": true, + "cmdShift1": true, + "cmdShiftC": true, + "cmdH": true, + "ctrlHome": true, + "pageUp": true, + "pageDown": true + }, + "loglevel": "INFO", + "logconfig" : + { "appenders": [ + { "type": "console", + "layout": {"type": "messagePassThrough"} + } + ] + }, + "customLocaleStrings": {} +} diff --git a/roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 b/roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 new file mode 100644 index 00000000..6f662aa7 --- /dev/null +++ b/roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 @@ -0,0 +1,49 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix Etherpad +{% for service in matrix_etherpad_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_etherpad_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ matrix_systemd_unit_home_path }}" +ExecStartPre=-{{ matrix_host_command_docker }} kill matrix-etherpad +ExecStartPre=-{{ matrix_host_command_docker }} rm matrix-etherpad + +# Fixup database ownership if it got changed somehow (during a server migration, etc.) +{% if matrix_etherpad_database_engine == 'sqlite' %} +ExecStartPre=-{{ matrix_host_command_chown }} {{ matrix_etherpad_user_uid }} {{ matrix_etherpad_sqlite_database_path_local }} +{% endif %} + +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-etherpad \ + --log-driver=none \ + --user={{ matrix_etherpad_user_uid }}:{{ matrix_etherpad_user_gid }} \ + --cap-drop=ALL \ + --network={{ matrix_docker_network }} \ + {% if matrix_etherpad_container_http_host_bind_port %} + -p {{ matrix_etherpad_container_http_host_bind_port }}:9001 \ + {% endif %} + --mount type=bind,src={{ matrix_etherpad_base_path }},dst=/data \ + {% for arg in matrix_etherpad_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_etherpad_docker_image }} \ + node --experimental-worker /opt/etherpad-lite/node_modules/ep_etherpad-lite/node/server.js \ + --settings /data/settings.json --credentials /data/credentials.json \ + --sessionkey /data/sessionkey.json --apikey /data/apijey.json + + +ExecStop=-{{ matrix_host_command_docker }} kill matrix-etherpad +ExecStop=-{{ matrix_host_command_docker }} rm matrix-etherpad +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-etherpad + +[Install] +WantedBy=multi-user.target diff --git a/setup.yml b/setup.yml index d070bcae..9bb1788f 100755 --- a/setup.yml +++ b/setup.yml @@ -33,6 +33,7 @@ - matrix-jitsi - matrix-ma1sd - matrix-dimension + - matrix-etherpad - matrix-email2matrix - matrix-nginx-proxy - matrix-coturn From 38bf1eda7026b75ddf0993910e50f8b0ecb6467b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Becker?= Date: Thu, 21 Jan 2021 00:06:59 +0100 Subject: [PATCH 03/10] Etherpad Jitsi integration --- group_vars/matrix_servers | 7 +++++++ roles/matrix-jitsi/defaults/main.yml | 3 +++ roles/matrix-jitsi/templates/web/custom-config.js.j2 | 3 +++ roles/matrix-jitsi/templates/web/env.j2 | 2 ++ 4 files changed, 15 insertions(+) diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 50d34bcc..5d76a60c 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -843,6 +843,13 @@ matrix_jitsi_web_stun_servers: | else [ 'stun:meet-jit-si-turnrelay.jitsi.net:443'] }} +# If the self-hosted Etherpad instance is available, it will also show up in Jitsi conferences, +# unless explicitly disabled by setting `matrix_jitsi_etherpad_enabled` to false. +# Falls back to the scalar.vector.im etherpad in case someone sets `matrix_jitsi_etherpad_enabled` to true, +# while also setting `matrix_etherpad_enabled` to false. +matrix_jitsi_etherpad_enabled: "{{ matrix_etherpad_enabled }}" +matrix_jitsi_etherpad_base: "{{ matrix_etherpad_base_url if matrix_etherpad_enabled else 'https://scalar.vector.im/etherpad' }}" + ###################################################################### # # /matrix-jitsi diff --git a/roles/matrix-jitsi/defaults/main.yml b/roles/matrix-jitsi/defaults/main.yml index 924198b4..028d9c19 100644 --- a/roles/matrix-jitsi/defaults/main.yml +++ b/roles/matrix-jitsi/defaults/main.yml @@ -67,6 +67,9 @@ matrix_jitsi_web_public_url: "https://{{ matrix_server_fqn_jitsi }}" # Addresses need to be prefixed with one of `stun:`, `turn:` or `turns:`. matrix_jitsi_web_stun_servers: ['stun:meet-jit-si-turnrelay.jitsi.net:443'] +# Controls whether Etherpad will be available within Jitsi +matrix_jitsi_etherpad_enabled: false + # Controls whether the matrix-jitsi-web container exposes its HTTP port (tcp/80 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:12080"), or empty string to not expose. diff --git a/roles/matrix-jitsi/templates/web/custom-config.js.j2 b/roles/matrix-jitsi/templates/web/custom-config.js.j2 index 02316ca0..bbe85798 100644 --- a/roles/matrix-jitsi/templates/web/custom-config.js.j2 +++ b/roles/matrix-jitsi/templates/web/custom-config.js.j2 @@ -11,5 +11,8 @@ config.p2p.stunServers = [ ]; {% endif %} +{% if matrix_jitsi_etherpad_enabled %} +config.etherpad_base = {{ (matrix_jitsi_etherpad_base + '/p/') |to_json }} +{% endif %} {{ matrix_jitsi_web_custom_config_extension }} diff --git a/roles/matrix-jitsi/templates/web/env.j2 b/roles/matrix-jitsi/templates/web/env.j2 index 353a3d14..7b763a3c 100644 --- a/roles/matrix-jitsi/templates/web/env.j2 +++ b/roles/matrix-jitsi/templates/web/env.j2 @@ -37,4 +37,6 @@ RESOLUTION_WIDTH_MIN={{ matrix_jitsi_web_config_resolution_width_min }} START_AUDIO_MUTED={{ matrix_jitsi_web_config_start_audio_muted_after_nth_participant }} START_VIDEO_MUTED={{ matrix_jitsi_web_config_start_video_muted_after_nth_participant }} +ETHERPAD_URL_BASE={{ (matrix_jitsi_etherpad_base + '/') if matrix_jitsi_etherpad_enabled else ''}} + {{ matrix_jitsi_web_environment_variables_extension }} From 7bc9be95cb2225b3ccdd8db2ff6e604e345157ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Becker?= Date: Thu, 21 Jan 2021 13:32:25 +0100 Subject: [PATCH 04/10] Add map directive to the base of nginx.conf This needs to be added for WebSocket upgrades to work properly (see doc: http://nginx.org/en/docs/http/websocket.html) --- roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 index 975c8b4f..facb0901 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 @@ -45,6 +45,11 @@ http { keepalive_timeout 65; #gzip on; + {# Map directive needed for proxied WebSocket upgrades #} + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } include /etc/nginx/conf.d/*.conf; } From 42f338016ba87480a948d89e224901dd8215673e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Becker?= Date: Thu, 21 Jan 2021 15:27:29 +0100 Subject: [PATCH 05/10] Etherpad matrix-nginx-proxy configuration --- roles/matrix-etherpad/tasks/init.yml | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/roles/matrix-etherpad/tasks/init.yml b/roles/matrix-etherpad/tasks/init.yml index 7496d4b4..081d4c23 100644 --- a/roles/matrix-etherpad/tasks/init.yml +++ b/roles/matrix-etherpad/tasks/init.yml @@ -1,3 +1,62 @@ - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-etherpad.service'] }}" when: matrix_etherpad_enabled|bool + +- block: + - name: Fail if matrix-nginx-proxy role already executed + fail: + msg: >- + Trying to append Etherpad's reverse-proxying configuration to matrix-nginx-proxy, + but it's pointless since the matrix-nginx-proxy role had already executed. + To fix this, please change the order of roles in your plabook, + so that the matrix-nginx-proxy role would run after the matrix-etherpad role. + when: matrix_nginx_proxy_role_executed|default(False)|bool + + - name: Generate Etherpad proxying configuration for matrix-nginx-proxy + set_fact: + matrix_etherpad_matrix_nginx_proxy_configuration: | + rewrite ^{{ matrix_etherpad_public_endpoint }}$ $scheme://$server_name{{ matrix_etherpad_public_endpoint }}/ permanent; + + location {{ matrix_etherpad_public_endpoint }}/ { + {% if matrix_nginx_proxy_enabled|default(False) %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver 127.0.0.11 valid=5s; + proxy_pass http://matrix-etherpad:9001/; + {# These are proxy directives needed specifically by Etherpad #} + proxy_buffering off; + proxy_http_version 1.1; # recommended with keepalive connections + proxy_pass_header Server; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; # for EP to set secure cookie flag when https is used + # WebSocket proxying - from http://nginx.org/en/docs/http/websocket.html + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + {% else %} + {# Generic configuration for use outside of our container setup #} + # A good guide for setting up your Etherpad behind nginx: + # https://docs.gandi.net/en/cloud/tutorials/etherpad_lite.html + proxy_pass http://127.0.0.1:9001/; + {% endif %} + } + + - name: Register Etherpad proxying configuration with matrix-nginx-proxy + set_fact: + matrix_nginx_proxy_proxy_dimension_additional_server_configuration_blocks: | + {{ + matrix_nginx_proxy_proxy_dimension_additional_server_configuration_blocks|default([]) + + + [matrix_etherpad_matrix_nginx_proxy_configuration] + }} + tags: + - always + when: matrix_etherpad_enabled|bool + +- name: Warn about reverse-proxying if matrix-nginx-proxy not used + debug: + msg: >- + NOTE: You've enabled the Etherpad tool but are not using the matrix-nginx-proxy + reverse proxy. + Please make sure that you're proxying the `{{ matrix_etherpad_public_endpoint }}` + URL endpoint to the matrix-etherpad container. + You can expose the container's port using the `matrix_etherpad_container_http_host_bind_port` variable. + when: "matrix_etherpad_enabled|bool and matrix_nginx_proxy_enabled is not defined" From 346f8b347536575b84e020860d08d255009317d2 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Tue, 26 Jan 2021 10:13:08 +0200 Subject: [PATCH 06/10] Fix typo --- roles/matrix-etherpad/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/matrix-etherpad/defaults/main.yml b/roles/matrix-etherpad/defaults/main.yml index 353adac7..19a79bd1 100644 --- a/roles/matrix-etherpad/defaults/main.yml +++ b/roles/matrix-etherpad/defaults/main.yml @@ -31,7 +31,7 @@ matrix_etherpad_base_url: "https://{{ matrix_server_fqn_dimension }}{{ matrix_et # Database-related configuration fields. # -# Etherpad recommends using a dedicated database, and supports Sqliite only for development +# Etherpad recommends using a dedicated database, and supports Sqlite only for development # # To use Postgres: # - change the engine (`matrix_etherpad_database_engine: 'postgres'`) From b7261dc09878de3b14a9a784ea8178a58261db84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Becker?= Date: Thu, 28 Jan 2021 15:11:22 +0100 Subject: [PATCH 07/10] Etherpad role: Etherpad needs Dimension The default scalar.vector.im integrations manager doesn't support custom URL's for etherpad, therefore Dimension needs to be enabled. --- roles/matrix-etherpad/tasks/main.yml | 6 ++++++ roles/matrix-etherpad/tasks/validate_config.yml | 8 +++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/roles/matrix-etherpad/tasks/main.yml b/roles/matrix-etherpad/tasks/main.yml index 09ead973..27548aaf 100644 --- a/roles/matrix-etherpad/tasks/main.yml +++ b/roles/matrix-etherpad/tasks/main.yml @@ -13,3 +13,9 @@ tags: - setup-all - setup-etherpad + +- import_tasks: "{{ role_path }}/tasks/validate_config.yml" + when: run_setup|bool and matrix_etherpad_enabled|bool + tags: + - setup-all + - setup-etherpad diff --git a/roles/matrix-etherpad/tasks/validate_config.yml b/roles/matrix-etherpad/tasks/validate_config.yml index e5621a07..77623558 100644 --- a/roles/matrix-etherpad/tasks/validate_config.yml +++ b/roles/matrix-etherpad/tasks/validate_config.yml @@ -1,7 +1,5 @@ -- name: Fail if required Etherpad settings not defined +- name: Fail if Etherpad is enabled without the Dimension integrations manager fail: msg: >- - You need to define a required configuration setting (`{{ item }}`) for using Etherpad. - with_items: - - - when: "matrix_etherpad_enabled and vars[item] == ''" + To integrate Etherpad notes with Matrix rooms you need to set "matrix_dimension_enabled" to true + when: "not matrix_dimension_enabled|bool" From efbffa26bf79139043f6c0c0e1ca69fb03c93616 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sat, 30 Jan 2021 11:37:08 +0200 Subject: [PATCH 08/10] Fix typo --- roles/matrix-etherpad/tasks/setup_uninstall.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/matrix-etherpad/tasks/setup_uninstall.yml b/roles/matrix-etherpad/tasks/setup_uninstall.yml index 865389f2..8f40f420 100644 --- a/roles/matrix-etherpad/tasks/setup_uninstall.yml +++ b/roles/matrix-etherpad/tasks/setup_uninstall.yml @@ -29,7 +29,7 @@ path: "{{ matrix_etherpad_base_path }}" state: absent -- name: Ensure Dimension Docker image doesn't exist +- name: Ensure Etherpad Docker image doesn't exist docker_image: name: "{{ matrix_etherpad_docker_image }}" state: absent From 7804060eee3a7b6437c767980d2edd605799ced7 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sun, 31 Jan 2021 09:47:47 +0200 Subject: [PATCH 09/10] Use Etherpad 1.8.7, not :latest --- roles/matrix-etherpad/defaults/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/matrix-etherpad/defaults/main.yml b/roles/matrix-etherpad/defaults/main.yml index 19a79bd1..28bb0c8d 100644 --- a/roles/matrix-etherpad/defaults/main.yml +++ b/roles/matrix-etherpad/defaults/main.yml @@ -2,7 +2,7 @@ matrix_etherpad_enabled: false matrix_etherpad_base_path: "{{ matrix_base_data_path }}/etherpad" -matrix_etherpad_docker_image: "docker.io/etherpad/etherpad:latest" +matrix_etherpad_docker_image: "docker.io/etherpad/etherpad:1.8.7" matrix_etherpad_docker_image_force_pull: "{{ matrix_etherpad_docker_image.endswith(':latest') }}" # List of systemd services that matrix-etherpad.service depends on. @@ -53,9 +53,9 @@ matrix_etherpad_database_connection_string: 'postgres://{{ matrix_etherpad_datab matrix_etherpad_title: 'Etherpad' matrix_etherpad_default_pad_text: | Welcome to Etherpad! - + This 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! - + Get involved with Etherpad at https://etherpad.org # Default Etherpad configuration template which covers the generic use case. From 5df2f6cdd1ff9a79d9998ca57cf320ea2f43d30b Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sun, 31 Jan 2021 09:54:12 +0200 Subject: [PATCH 10/10] Update docs and changelog --- CHANGELOG.md | 9 +++++++++ docs/configuring-playbook-etherpad.md | 4 ++-- docs/container-images.md | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ce03e79..1e23e58d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 2021-01-31 + +## Etherpad support + +Thanks to [@pushytoxin](https://github.com/pushytoxin), the playbook can now install the [Etherpad](https://etherpad.org) realtime collaborative text editor. It can be used in a [Jitsi](https://jitsi.org/) audio/video call or integrated as a widget into Matrix chat rooms via the [Dimension](https://dimension.t2bot.io) integration manager. + +To get it installed, follow [our Etherpad docs page](docs/configuring-playbook-etherpad.md). + + # 2021-01-22 ## (Breaking Change) Postgres changes that require manual intervention diff --git a/docs/configuring-playbook-etherpad.md b/docs/configuring-playbook-etherpad.md index 9ec24d33..af1a9c7d 100644 --- a/docs/configuring-playbook-etherpad.md +++ b/docs/configuring-playbook-etherpad.md @@ -2,13 +2,13 @@ [Etherpad](https://etherpad.org) is is an open source collaborative text editor that can be embedded in a Matrix chat room using the [Dimension integrations manager](https://dimension.t2bot.io) -When enabled together with Jitsi, it will be made available as an option during the conferences. +When enabled together with the Jitsi audio/video conferencing system (see [our docs on Jitsi](configuring-playbook-jitsi.md)), it will be made available as an option during the conferences. ## Prerequisites For the self-hosted Etherpad instance to be available to your users, you must first enable and configure the **Dimension integrations manager** as described in [the playbook documentation](configuring-playbook-dimension.md) -## Enable +## Installing [Etherpad](https://etherpad.org) installation is disabled by default. You can enable it in your configuration file (`inventory/host_vars/matrix./vars.yml`): diff --git a/docs/container-images.md b/docs/container-images.md index 33cfa727..aee24b04 100644 --- a/docs/container-images.md +++ b/docs/container-images.md @@ -32,6 +32,8 @@ These services are not part of our default installation, but can be enabled by [ - [ewoutp/goofys](https://hub.docker.com/r/ewoutp/goofys/) - the [Goofys](https://github.com/kahing/goofys) Amazon [S3](https://aws.amazon.com/s3/) file-system-mounting program (optional) +- [etherpad/etherpad](https://hub.docker.com/r/etherpad/etherpad/) - the [Etherpad](https://etherpad.org) realtime collaborative text editor that can be used in a Jitsi audio/video call or integrated as a widget into Matrix chat rooms via the Dimension integration manager (optional) + - [devture/email2matrix](https://hub.docker.com/r/devture/email2matrix/) - the [Email2Matrix](https://github.com/devture/email2matrix) email server, which can relay email messages to Matrix rooms (optional) - [devture/matrix-corporal](https://hub.docker.com/r/devture/matrix-corporal/) - [Matrix Corporal](https://github.com/devture/matrix-corporal): reconciliator and gateway for a managed Matrix server (optional)