diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..bc3c8e75 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +# https://liberapay.com/s.pantaleev/ +liberapay: s.pantaleev diff --git a/CHANGELOG.md b/CHANGELOG.md index 247e4e14..c4a586e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,151 @@ +# 2020-12-23 + +## The big move to all-on-Postgres (potentially dangerous) + +**TLDR**: all your bridges (and other services) will likely be auto-migrated from SQLite/nedb to Postgres, hopefully without trouble. You can opt-out (see how below), if too worried about breakage. + +Until now, we've only used Postgres as a database for Synapse. All other services (bridges, bots, etc.) were kept simple and used a file-based database (SQLite or nedb). + +Since [this huge pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/740), **all of our services now use Postgres by default**. Thanks to [Johanna Dorothea Reichmann](https://github.com/jdreichmann) for starting the work on it and for providing great input! + +Moving all services to Postgres brings a few **benefits** to us: + +- **improved performance** +- **improved compatibility**. Most bridges are deprecating SQLite/nedb support or offer less features when not on Postgres. +- **easier backups**. It's still some effort to take a proper backup (Postgres dump + various files, keys), but a Postgres dump now takes you much further. +- we're now **more prepared to introduce other services** that need a Postgres database - [Dendrite](https://github.com/matrix-org/dendrite), the [mautrix-signal](https://github.com/tulir/mautrix-signal) bridge (existing [pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/686)), etc. + +### Key takeway + +- existing installations that use an [external Postgres](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-external-postgres.md) server should be unaffected (they remain on SQLite/nedb for all services, except Synapse) + +- for existing installations which use our integrated Postgres database server (`matrix-postgres`, which is the default), **we automatically migrate data** from SQLite/nedb to Postgres and **archive the database files** (`something.db` -> `something.db.backup`), so you can restore them if you need to go back (see how below). + +### Opting-out of the Postgres migration + +This is a **very large and somewhat untested change** (potentially dangerous), so **if you're not feeling confident/experimental, opt-out** of it for now. Still, it's the new default and what we (and various bridges) will focus on going forward, so don't stick to old ways for too long. + +You can remain on SQLite/nedb (at least for now) by adding a variable like this to your `vars.yml` file for each service you use: `matrix_COMPONENT_database_engine: sqlite` (e.g. `matrix_mautrix_facebook_database_engine: sqlite`). + +Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them. + +### Going back to SQLite/nedb if things went wrong + +If you went with the Postgres migration and it went badly for you (some bridge not working as expected or not working at all), do this: + +- stop all services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`) +- SSH into the server and rename the old database files (`something.db.backup` -> `something.db`). Example: `mv /matrix/mautrix-facebook/data/mautrix-facebook.db.backup /matrix/mautrix-facebook/data/mautrix-facebook.db` +- switch the affected service back to SQLite (e.g. `matrix_mautrix_facebook_database_engine: sqlite`). Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them. +- re-run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`) +- [get in touch](README.md#support) with us + + +# 2020-12-11 + +## synapse-janitor support removed + +We've removed support for the unmaintained [synapse-janitor](https://github.com/xwiki-labs/synapse_scripts) script. There's been past reports of it corrupting the Synapse database. Since there hasn't been any new development on it and it doesn't seem too useful nowadays, there's no point in including it in the playbook. + +If you need to clean up or compact your database, consider using the Synapse Admin APIs directly. See our [Synapse maintenance](docs/maintenance-synapse.md) and [Postgres maintenance](docs/maintenance-postgres.md) documentation pages for more details. + + +## Docker 20.10 is here + +(No need to do anything special in relation to this. Just something to keep in mind) + +Docker 20.10 got released recently and your server will likely get it the next time you update. + +This is the first major Docker update in a long time and it packs a lot of changes. +Some of them introduced some breakage for us initially (see [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/d08b27784f222effcbce2abf924bf07bbe0893be) and [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/7593d969e316cc0144bce378a5be58c76c2c37ee)), but it should be all good now. + + +# 2020-12-08 + +## openid APIs exposed by default on the federation port when federation disabled + +We've changed some defaults. People running with our default configuration (federation enabled), are not affected at all. + +If you are running an unfederated server (`matrix_synapse_federation_enabled: false`), this may be of interest to you. + +When federation is disabled, but ma1sd or Dimension are enabled, we'll now expose the `openid` APIs on the federation port. +These APIs are necessary for some ma1sd features to work. If you'd like to prevent this, you can: `matrix_synapse_federation_port_openid_resource_required: false`. + + +# 2020-11-27 + +## Recent Jitsi updates may require configuration changes + +We've recently [updated from Jitsi build 4857 to build 5142](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/719), which brings a lot of configuration changes. + +**If you use our default Jitsi settings, you won't have to do anything.** + +People who have [fine-tuned Jitsi](docs/configuring-playbook-jitsi.md#optional-fine-tune-jitsi) may find that some options got renamed now, others are gone and yet others still need to be defined in another way. + +The next time you run the playbook [installation](docs/installing.md) command, our validation logic will tell you if you're using some variables like that and will recommend a migration path for each one. + +Additionally, we've recently disabled transcriptions (`matrix_jitsi_enable_transcriptions: false`) and recording (`matrix_jitsi_enable_recording: false`) by default. These features did not work anyway, because we don't install the required dependencies for them (Jigasi and Jibri, respectively). If you've been somehow pointing your Jitsi installation to some manually installed Jigasi/Jibri service, you may need to toggle these flags back to enabled to have transcriptions and recordings working. + + +# 2020-11-23 + +## Breaking change matrix-sms-bridge + +Because of many problems using gammu as SMS provider, matrix-sms-bridge now uses (https://github.com/RebekkaMa/android-sms-gateway-server) by default. See (the docs)[./docs/configuring-playbook-bridge-matrix-bridge-sms.md] which new vars you need to add. + +If you are using this playbook to deploy matrix-sms-bridge and still really want to use gammu as SMS provider, we could possibly add support for both android-sms-gateway-server and gammu. + +# 2020-11-13 + +## Breaking change matrix-sms-bridge + +The new version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) changed its database from neo4j to h2. You need to sync the bridge at the first start. Note that this only will sync rooms where the @smsbot:yourServer is member. For rooms without @smsbot:yourServer you need to kick and invite the telephone number **or** invite @smsbot:yourServer. + +1. Add the following to your `vars.yml` file: `matrix_sms_bridge_container_extra_arguments=['--env SPRING_PROFILES_ACTIVE=initialsync']` +2. Login to your host shell and remove old systemd file from your host: `rm /etc/systemd/system/matrix-sms-bridge-database.service` +2. Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-matrix-sms-bridge,start` +3. Login to your host shell and check the logs with `journalctl -u matrix-sms-bridge` until the sync finished. +4. Remove the var from the first step. +5. Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`. + +# 2020-11-10 + +## Dynamic DNS support + +Thanks to [Scott Crossen](https://github.com/scottcrossen), the playbook can now manage Dynamic DNS for you using [ddclient](https://ddclient.net/). + +To learn more, follow our [Dynamic DNS docs page](docs/configuring-playbook-dynamic-dns.md). + + +# 2020-10-28 + +## (Compatibility Break) https://matrix.DOMAIN/ now redirects to https://element.DOMAIN/ + +Until now, we used to serve a static page coming from Synapse at `https://matrix.DOMAIN/`. This page was not very useful to anyone. + +Since `matrix.DOMAIN` may be accessed by regular users in certain conditions, it's probably better to redirect them to a better place (e.g. to the [Element](docs/configuring-playbook-client-element.md) client). + +If Element is installed (`matrix_client_element_enabled: true`, which it is by default), we now redirect people to it, instead of showing them a Synapse static page. + +If you'd like to control where the redirect goes, use the `matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain` variable. +To restore the old behavior of not redirecting anywhere and serving the Synapse static page, set it to an empty value (`matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: ""`). + + +# 2020-10-26 + +## (Compatibility Break) /_synapse/admin is no longer publicly exposed by default + +We used to expose the Synapse Admin APIs publicly (at `https://matrix.DOMAIN/_synapse/admin`). +These APIs require authentication with a valid access token, so it's not that big a deal to expose them. + +However, following [official Synapse's reverse-proxying recommendations](https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md#synapse-administration-endpoints), we're no longer exposing `/_synapse/admin` by default. + +If you'd like to restore restore the old behavior and expose `/_synapse/admin` publicly, you can use the following configuration (in your `vars.yml`): + +```yaml +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: true +``` + + # 2020-10-02 ## Minimum Ansible version raised to v2.7.0 diff --git a/README.md b/README.md index 72018115..ac2b7ca9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Support room on Matrix](https://img.shields.io/matrix/matrix-docker-ansible-deploy:devture.com.svg?label=%23matrix-docker-ansible-deploy%3Adevture.com&logo=matrix&style=for-the-badge&server_fqdn=matrix.devture.com)](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com) [![donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/s.pantaleev/donate) + # Matrix (An open network for secure, decentralized communication) server setup using Ansible and Docker ## Purpose @@ -128,7 +130,7 @@ This playbook sets up your server using the following Docker images: - [instrumentisto/coturn](https://hub.docker.com/r/instrumentisto/coturn/) - the [Coturn](https://github.com/coturn/coturn) STUN/TURN server (optional) -- [vectorim/riot-web](https://hub.docker.com/r/vectorim/riot-web/) - the [Element](https://element.io/) web client (optional) +- [vectorim/element-web](https://hub.docker.com/r/vectorim/element-web/) - the [Element](https://element.io/) web client (optional) - [ma1uta/ma1sd](https://hub.docker.com/r/ma1uta/ma1sd/) - the [ma1sd](https://github.com/ma1uta/ma1sd) Matrix Identity server (optional) diff --git a/docs/README.md b/docs/README.md index 8d22477e..8c95eff3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,13 +10,13 @@ - [Installing](installing.md) -- **Importing data from another Synapse server installation** +- **Importing data from another server installation** - - [Importing an existing SQLite database (from another installation)](importing-sqlite.md) (optional) + - [Importing an existing SQLite database (from another Synapse installation)](importing-synapse-sqlite.md) (optional) - [Importing an existing Postgres database (from another installation)](importing-postgres.md) (optional) - - [Importing `media_store` data files from an existing installation](importing-media-store.md) (optional) + - [Importing `media_store` data files from an existing Synapse installation](importing-synapse-media-store.md) (optional) - [Registering users](registering-users.md) diff --git a/docs/configuring-dns.md b/docs/configuring-dns.md index 08bc905e..9d738477 100644 --- a/docs/configuring-dns.md +++ b/docs/configuring-dns.md @@ -34,7 +34,7 @@ DNS records marked with `(*)` above are optional. They refer to services that wi As the table above illustrates, you need to create 2 subdomains (`matrix.` and `element.`) and point both of them to your new server's IP address (DNS `A` record or `CNAME` record is fine). -The `element.` subdomain is necessary, because this playbook installs the [Element](https://github.com/vector-im/riot-web) web client for you. +The `element.` subdomain is necessary, because this playbook installs the [Element](https://github.com/vector-im/element-web) web client for you. If you'd rather instruct the playbook not to install Element (`matrix_client_element_enabled: false` when [Configuring the playbook](configuring-playbook.md) later), feel free to skip the `element.` DNS record. The `dimension.` subdomain may be necessary, because this playbook could install the [Dimension integrations manager](http://dimension.t2bot.io/) for you. Dimension installation is disabled by default, because it's only possible to install it after the other Matrix services are working (see [Setting up Dimension](configuring-playbook-dimension.md) later). If you do not wish to set up Dimension, feel free to skip the `dimension.` DNS record. diff --git a/docs/configuring-playbook-bridge-appservice-discord.md b/docs/configuring-playbook-bridge-appservice-discord.md index 13a5174b..f3efc555 100644 --- a/docs/configuring-playbook-bridge-appservice-discord.md +++ b/docs/configuring-playbook-bridge-appservice-discord.md @@ -22,10 +22,10 @@ matrix_appservice_discord_client_id: "YOUR DISCORD APP CLIENT ID" matrix_appservice_discord_bot_token: "YOUR DISCORD APP BOT TOKEN" ``` -4. If you've already installed Matrix services using the playbook before, you'll need to re-run it (`--tags=setup-all,start`). If not, proceed with [configuring other playbook services](configuring-playbook.md) and then with [Installing](installing.md). Get back to this guide once ready. -5. Retrieve Discord invite link from the `{{ matrix_appservice_discord_config_path }}/invite_link` file on the server (this defaults to `/matrix/appservice-discord/config/invite_link`). You need to peek at the file on the server via SSH, etc., because it's not available via HTTP(S). -6. Invite the Bot to Discord servers you wish to bridge. Administrator permission is recommended. -7. Room addresses follow this syntax: `#_discord_guildid_channelid`. You can easily find the guild and channel ids by logging into Discord in a browser and opening the desired channel. The URL will have this format: `discordapp.com/channels/guild_id/channel_id`. Once you have figured out the appropriate room addrss, you can join by doing `/join #_discord_guildid_channelid` in your Matrix client. +5. If you've already installed Matrix services using the playbook before, you'll need to re-run it (`--tags=setup-all,start`). If not, proceed with [configuring other playbook services](configuring-playbook.md) and then with [Installing](installing.md). Get back to this guide once ready. +6. Retrieve Discord invite link from the `{{ matrix_appservice_discord_config_path }}/invite_link` file on the server (this defaults to `/matrix/appservice-discord/config/invite_link`). You need to peek at the file on the server via SSH, etc., because it's not available via HTTP(S). +7. Invite the Bot to Discord servers you wish to bridge. Administrator permission is recommended. +8. Room addresses follow this syntax: `#_discord_guildid_channelid`. You can easily find the guild and channel ids by logging into Discord in a browser and opening the desired channel. The URL will have this format: `discordapp.com/channels/guild_id/channel_id`. Once you have figured out the appropriate room addrss, you can join by doing `/join #_discord_guildid_channelid` in your Matrix client. Other configuration options are available via the `matrix_appservice_discord_configuration_extension_yaml` variable. diff --git a/docs/configuring-playbook-bridge-matrix-bridge-sms.md b/docs/configuring-playbook-bridge-matrix-bridge-sms.md index 99b4f6f0..86a95ab2 100644 --- a/docs/configuring-playbook-bridge-matrix-bridge-sms.md +++ b/docs/configuring-playbook-bridge-matrix-bridge-sms.md @@ -1,11 +1,10 @@ # Setting up matrix-sms-bridge (optional) -The playbook can install and configure -[matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) for you. +The playbook can install and configure [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) for you. See the project page to learn what it does and why it might be useful to you. -First you need to ensure, that the bridge has unix read and write rights to your modem. On debian based distributions there is nothing to do. On others distributions you either add a group `dialout` to your host and assign it to your modem or you give the matrix user or group access to your modem. +**The bridge uses [android-sms-gateway-server](https://github.com/RebekkaMa/android-sms-gateway-server). You need to configure it first.** To enable the bridge just use the following playbook configuration: @@ -13,16 +12,23 @@ playbook configuration: ```yaml matrix_sms_bridge_enabled: true -matrix_sms_bridge_gammu_modem: "/dev/serial/by-id/myDeviceId" -# generate a secret passwort e.g. with pwgen -s 64 1 -matrix_sms_bridge_database_password: "" -# (optional) a room id to a default room + +# (optional but recommended) a room id to a default room matrix_sms_bridge_default_room: "" -# (optional) gammu reset frequencies (see https://wammu.eu/docs/manual/smsd/config.html#option-ResetFrequency) -matrix_sms_bridge_gammu_reset_frequency: 3600 -matrix_sms_bridge_gammu_hard_reset_frequency: 0 -# (optional) group with unix read and write rights to modem -matrix_sms_bridge_modem_group: 'dialout' + +# (optional but recommended) configure your server location +matrix_sms_bridge_default_region: DE +matrix_sms_bridge_default_timezone: Europe/Berlin + +# Settings to connect to android-sms-gateway-server +matrix_sms_bridge_provider_android_baseurl: https://192.168.24.24:9090 +matrix_sms_bridge_provider_android_username: admin +matrix_sms_bridge_provider_android_password: supeSecretPassword + +# (optional) if your android-sms-gateway-server uses a self signed vertificate, the bridge needs a "truststore". This can be the certificate itself. +matrix_sms_bridge_provider_android_truststore_local_path: android-sms-gateway-server.p12 +matrix_sms_bridge_provider_android_truststore_password: 123 + ``` diff --git a/docs/configuring-playbook-client-element.md b/docs/configuring-playbook-client-element.md index 8b0eb331..45299c55 100644 --- a/docs/configuring-playbook-client-element.md +++ b/docs/configuring-playbook-client-element.md @@ -1,6 +1,6 @@ # Configuring Element (optional) -By default, this playbook installs the [Element](https://github.com/vector-im/riot-web) Matrix client web application. +By default, this playbook installs the [Element](https://github.com/vector-im/element-web) Matrix client web application. If that's okay, you can skip this document. diff --git a/docs/configuring-playbook-dimension.md b/docs/configuring-playbook-dimension.md index 604e6aa6..d5f0a9e6 100644 --- a/docs/configuring-playbook-dimension.md +++ b/docs/configuring-playbook-dimension.md @@ -3,6 +3,9 @@ **[Dimension](https://dimension.t2bot.io) can only be installed after Matrix services are installed and running.** If you're just installing Matrix services for the first time, please continue with the [Configuration](configuring-playbook.md) / [Installation](installing.md) flow and come back here later. +**Note**: enabling Dimension, means that the `openid` API endpoints will be exposed on the Matrix Federation port (usually `8448`), even if [federation](configuring-playbook-federation.md) is disabled. It's something to be aware of, especially in terms of firewall whitelisting (make sure port `8448` is accessible). + + ## Prerequisites This playbook now supports running [Dimension](https://dimension.t2bot.io) in both a federated and an [unfederated](https://github.com/turt2live/matrix-dimension/blob/master/docs/unfederated.md) environment. This is handled automatically based on the value of `matrix_synapse_federation_enabled`. @@ -48,7 +51,7 @@ To get an access token for the Dimension user, you can follow one of two options 3. Copy the highlighted text to your configuration. 4. Close the private browsing session. **Do not log out**. Logging out will invalidate the token, making it not work. -*With CURL* +*With CURL* ``` curl -X POST --header 'Content-Type: application/json' -d '{ diff --git a/docs/configuring-playbook-dynamic-dns.md b/docs/configuring-playbook-dynamic-dns.md new file mode 100644 index 00000000..bc58c273 --- /dev/null +++ b/docs/configuring-playbook-dynamic-dns.md @@ -0,0 +1,27 @@ +# Dynamic DNS + +## Setup + +Most cloud providers / ISPs will charge you extra for a static IP address. If you're +not hosting a highly reliable homeserver you can workaround this via dynamic DNS. To +set this up, you'll need to get the username/password from your DNS provider. For +google domains, this process is described [here](https://support.google.com/domains/answer/6147083). +After you've gotten the proper credentials you can add the following config to your `inventory/host_vars/matrix.DOMAIN/vars.yml`: + +```yaml +matrix_dynamic_dns_enabled: true + +matrix_dynamic_dns_domain_configurations: + - provider: domains.google.com + protocol: dyndn2 + username: XXXXXXXXXXXXXXXX + password: XXXXXXXXXXXXXXXX + domain: "{{ matrix_domain }}" +``` + + +## Additional Reading + +Additional resources: + +- https://matrix.org/docs/guides/free-small-matrix-server diff --git a/docs/configuring-playbook-federation.md b/docs/configuring-playbook-federation.md index 1e4ad61e..2e6410ec 100644 --- a/docs/configuring-playbook-federation.md +++ b/docs/configuring-playbook-federation.md @@ -37,3 +37,13 @@ matrix_synapse_federation_enabled: false ``` With that, your server's users will only be able to talk among themselves, but not to anyone who is on another server. + +**Disabling federation does not necessarily disable the federation port** (`8448`). Services like [Dimension](configuring-playbook-dimension.md) and [ma1sd](configuring-playbook-ma1sd.md) normally rely on `openid` APIs exposed on that port. Even if you disable federation and only if necessary, we may still be exposing the federation port and serving the `openid` APIs there. To override this and completely disable Synapse's federation port use: + +```yaml +# This stops the federation port on the Synapse side (normally `matrix-synapse:8048` on the container network). +matrix_synapse_federation_port_enabled: false + +# This removes the `8448` virtual host from the matrix-nginx-proxy reverse-proxy server. +matrix_nginx_proxy_proxy_matrix_federation_api_enabled: false +``` diff --git a/docs/configuring-playbook-jitsi.md b/docs/configuring-playbook-jitsi.md index 72402360..f72241e1 100644 --- a/docs/configuring-playbook-jitsi.md +++ b/docs/configuring-playbook-jitsi.md @@ -91,44 +91,33 @@ matrix_jitsi_jvb_container_extra_arguments: ## (Optional) Fine tune Jitsi -You may want to suspend unused video layers until they are requested again, to save up resources on both server and clients. +Sample **additional** `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration to save up resources (explained below): + +```yaml +matrix_jitsi_web_custom_config_extension: | + config.enableLayerSuspension = true; + + config.disableAudioLevels = true; + + // Limit the number of video feeds forwarded to each client + config.channelLastN = 4; + +matrix_jitsi_web_config_resolution_width_ideal_and_max: 480 +matrix_jitsi_web_config_resolution_height_ideal_and_max: 240 +``` + +You may want to **suspend unused video layers** until they are requested again, to save up resources on both server and clients. Read more on this feature [here](https://jitsi.org/blog/new-off-stage-layer-suppression-feature/) For this add this line to your `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration: -```yaml -matrix_jitsi_web_config_enableLayerSuspension: true -``` +You may wish to **disable audio levels** to avoid excessive refresh of the client-side page and decrease the CPU consumption involved. -You may wish to disable audio levels to avoid excessive refresh of the client-side page and decrease the CPU consumption involved. -For this add this line to your `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration: - -```yaml -matrix_jitsi_web_config_disableAudioLevels: true -``` - -You may want to limit the number of video feeds forwarded to each client, to save up resources on both server and clients. As clients’ bandwidth and CPU may not bear the load, use this setting to avoid lag and crashes. +You may want to **limit the number of video feeds forwarded to each client**, to save up resources on both server and clients. As clients’ bandwidth and CPU may not bear the load, use this setting to avoid lag and crashes. This feature is found by default in other webconference applications such as Office 365 Teams (limit is set to 4). -Read how it works [here](https://github.com/jitsi/jitsi-videobridge/blob/master/doc/last-n.md) and performance evaluation on this [study](https://jitsi.org/wp-content/uploads/2016/12/nossdav2015lastn.pdf) -For this add this line to your `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration: +Read how it works [here](https://github.com/jitsi/jitsi-videobridge/blob/master/doc/last-n.md) and performance evaluation on this [study](https://jitsi.org/wp-content/uploads/2016/12/nossdav2015lastn.pdf). -```yaml -matrix_jitsi_web_config_channelLastN: 4 -``` +You may want to **limit the maximum video resolution**, to save up resources on both server and clients. -To enable the variables that allow you to manage the video configuration you must add the following line to your `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration: - -```yaml -matrix_jitsi_web_config_constraints_enabled: true -``` - -You may want to limit the maximum video resolution, to save up resources on both server and clients. -For example, to set resolution to 480. -For this add this two lines to your `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration: - -```yaml -matrix_jitsi_web_config_constraints_video_height_ideal: 480 -matrix_jitsi_web_config_constraints_video_height_max: 480 -``` ## Apply changes diff --git a/docs/configuring-playbook-ma1sd.md b/docs/configuring-playbook-ma1sd.md index 03208337..70c507cb 100644 --- a/docs/configuring-playbook-ma1sd.md +++ b/docs/configuring-playbook-ma1sd.md @@ -4,7 +4,9 @@ By default, this playbook configures an [ma1sd](https://github.com/ma1uta/ma1sd) This server is private by default, potentially at the expense of user discoverability. -ma1sd is a fork of [mxisd](https://github.com/kamax-io/mxisd) which was pronounced end of life 2019-06-21. +*ma1sd is a fork of [mxisd](https://github.com/kamax-io/mxisd) which was pronounced end of life 2019-06-21.* + +**Note**: enabling ma1sd (which is also the default), means that the `openid` API endpoints will be exposed on the Matrix Federation port (usually `8448`), even if [federation](configuring-playbook-federation.md) is disabled. It's something to be aware of, especially in terms of firewall whitelisting (make sure port `8448` is accessible). ## Disabling ma1sd @@ -50,6 +52,9 @@ To use the [Registration](https://github.com/ma1uta/ma1sd/blob/master/docs/featu - `matrix_ma1sd_configuration_extension_yaml` - to configure ma1sd as required. See the [Registration feature's docs](https://github.com/ma1uta/ma1sd/blob/master/docs/features/registration.md) for inspiration. Also see the [Additional features](#additional-features) section below to learn more about how to use `matrix_ma1sd_configuration_extension_yaml`. +**Note**: For this to work, either the homeserver needs to [federate](configuring-playbook-federation.md) or the `openid` APIs need to exposed on the federation port. When federation is disabled and ma1sd is enabled, we automatically expose the `openid` APIs (only!) on the federation port. Make sure the federation port (usually `https://matrix.DOMAIN:8448`) is whitelisted in your firewall (even if you don't actually use/need federation). + + ## Authentication [Authentication](https://github.com/ma1uta/ma1sd/blob/master/docs/features/authentication.md) provides the possibility to use your own [Identity Stores](https://github.com/ma1uta/ma1sd/blob/master/docs/stores/README.md) (for example LDAP) to authenticate users on your Homeserver. The following configuration can be used to authenticate against an LDAP server: diff --git a/docs/configuring-playbook-nginx.md b/docs/configuring-playbook-nginx.md index e0b4911e..5693c569 100644 --- a/docs/configuring-playbook-nginx.md +++ b/docs/configuring-playbook-nginx.md @@ -23,3 +23,19 @@ matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses: - 8.8.8.8 - 1.1.1.1 ``` + +## Synapse + OpenID Connect for Single-Sign-On + +If you want to use OpenID Connect as an SSO provider (as per the [Synapse OpenID docs](https://github.com/matrix-org/synapse/blob/develop/docs/openid.md)), you need to use the following configuration (in your `vars.yml` file) to instruct nginx to forward `/_synapse/oidc` to Synapse: + +```yaml +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_oidc_api_enabled: true +``` + +## Disable Nginx access logs + +This will disable the access logging for nginx. + +```yaml +matrix_nginx_proxy_access_log_enabled: false +``` diff --git a/docs/configuring-playbook-own-webserver.md b/docs/configuring-playbook-own-webserver.md index 2c4b43a2..c930da40 100644 --- a/docs/configuring-playbook-own-webserver.md +++ b/docs/configuring-playbook-own-webserver.md @@ -113,7 +113,7 @@ With this, nginx would still be in use, but it would not bother with anything SS All services would be served locally on `127.0.0.1:81` and `127.0.0.1:8449` (as per the example configuration above). You can then set up another reverse-proxy server on ports 80/443/8448 for all of the expected domains and make traffic go to these local ports. -The expected domains vary depending on the services you have enabled (`matrix.DOMAIN` for sure; `element.DOMAIN` and `dimension.DOMAIN` are optional). +The expected domains vary depending on the services you have enabled (`matrix.DOMAIN` for sure; `element.DOMAIN`, `dimension.DOMAIN` and `jitsi.DOMAIN` are optional). ### Sample configuration for running behind Traefik 2.0 @@ -144,7 +144,7 @@ matrix_nginx_proxy_container_extra_arguments: - '--label "traefik.enable=true"' # The Nginx proxy container will receive traffic from these subdomains - - '--label "traefik.http.routers.matrix-nginx-proxy.rule=Host(`{{ matrix_server_fqn_matrix }}`,`{{ matrix_server_fqn_element }}`,`{{ matrix_server_fqn_dimension }}`)"' + - '--label "traefik.http.routers.matrix-nginx-proxy.rule=Host(`{{ matrix_server_fqn_matrix }}`,`{{ matrix_server_fqn_element }}`,`{{ matrix_server_fqn_dimension }}`,`{{ matrix_server_fqn_jitsi }}`)"' # (The 'web-secure' entrypoint must bind to port 443 in Traefik config) - '--label "traefik.http.routers.matrix-nginx-proxy.entrypoints=web-secure"' @@ -172,7 +172,7 @@ matrix_synapse_container_extra_arguments: - '--label "traefik.http.services.matrix-synapse.loadbalancer.server.port=8048"' ``` -This method uses labels attached to the Nginx and Synapse containers to provide the Traefik Docker provider with the information it needs to proxy `matrix.DOMAIN`, `element.DOMAIN`, and `dimension.DOMAIN`. Some [static configuration](https://docs.traefik.io/v2.0/reference/static-configuration/file/) is required in Traefik; namely, having endpoints on ports 443 and 8448 and having a certificate resolver. +This method uses labels attached to the Nginx and Synapse containers to provide the Traefik Docker provider with the information it needs to proxy `matrix.DOMAIN`, `element.DOMAIN`, `dimension.DOMAIN` and `jitsi.DOMAIN`. Some [static configuration](https://docs.traefik.io/v2.0/reference/static-configuration/file/) is required in Traefik; namely, having endpoints on ports 443 and 8448 and having a certificate resolver. Note that this configuration on its own does **not** redirect traffic on port 80 (plain HTTP) to port 443 for HTTPS, which may cause some issues, since the built-in Nginx proxy usually does this. If you are not already doing this in Traefik, it can be added to Traefik in a [file provider](https://docs.traefik.io/v2.0/providers/file/) as follows: @@ -193,3 +193,38 @@ Note that this configuration on its own does **not** redirect traffic on port 80 scheme = "https" permanent = true ``` + +You can use the following `docker-compose.yml` as example to launch Traefik. + +```yaml +version: "3.3" + +services: + + traefik: + image: "traefik:v2.3" + restart: always + container_name: "traefik" + networks: + - traefik + command: + - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.network=traefik" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web-secure.address=:443" + - "--entrypoints.synapse.address=:8448" + - "--certificatesresolvers.default.acme.tlschallenge=true" + - "--certificatesresolvers.default.acme.email=YOUR EMAIL" + - "--certificatesresolvers.default.acme.storage=/letsencrypt/acme.json" + ports: + - "443:443" + - "8080:8080" + volumes: + - "./letsencrypt:/letsencrypt" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + +networks: + traefik: + external: true +``` diff --git a/docs/configuring-playbook-ssl-certificates.md b/docs/configuring-playbook-ssl-certificates.md index 5b5c7cdc..7f05a5b2 100644 --- a/docs/configuring-playbook-ssl-certificates.md +++ b/docs/configuring-playbook-ssl-certificates.md @@ -67,6 +67,7 @@ By default, it obtains certificates for: - possibly for `element.`, unless you have disabled the [Element client component](configuring-playbook-client-element.md) using `matrix_client_element_enabled: false` - possibly for `riot.`, if you have explicitly enabled Riot to Element redirection (for background compatibility) using `matrix_nginx_proxy_proxy_riot_compat_redirect_enabled: true` - possibly for `dimension.`, if you have explicitly [set up Dimension](configuring-playbook-dimension.md). +- possibly for `jitsi.`, if you have explicitly [set up Jitsi](configuring-playbook-jitsi.md). - possibly for your base domain (``), if you have explicitly configured [Serving the base domain](configuring-playbook-base-domain-serving.md) If you are hosting other domains on the Matrix machine, you can make the playbook obtain and renew certificates for those other domains too. @@ -80,6 +81,7 @@ matrix_ssl_domains_to_obtain_certificates_for: - '{{ matrix_server_fqn_matrix }}' - '{{ matrix_server_fqn_element }}' - '{{ matrix_server_fqn_dimension }}' + - '{{ matrix_server_fqn_jitsi }}' - '{{ matrix_domain }}' ``` diff --git a/docs/configuring-playbook-synapse-admin.md b/docs/configuring-playbook-synapse-admin.md index b3eafaea..68d70305 100644 --- a/docs/configuring-playbook-synapse-admin.md +++ b/docs/configuring-playbook-synapse-admin.md @@ -15,6 +15,8 @@ Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars. matrix_synapse_admin_enabled: true ``` +**Note**: Synapse Admin requires Synapse's [Admin APIs](https://github.com/matrix-org/synapse/tree/master/docs/admin_api) to function. Access to them is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, for additional security, we normally leave them unexposed, following [official Synapse reverse-proxying recommendations](https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md#synapse-administration-endpoints). Because Synapse Admin needs these APIs to function, when installing Synapse Admin, we **automatically** exposes them publicly for you (equivalent to `matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: true`). + ## Installing diff --git a/docs/configuring-playbook-synapse.md b/docs/configuring-playbook-synapse.md index 019a651f..9ae1e903 100644 --- a/docs/configuring-playbook-synapse.md +++ b/docs/configuring-playbook-synapse.md @@ -21,3 +21,8 @@ Alternatively, **if there is no pre-defined variable** for a Synapse setting you ## Synapse Admin Certain Synapse administration tasks (managing users and rooms, etc.) can be performed via a web user-interace, if you install [Synapse Admin](configuring-playbook-synapse-admin.md). + + +## Synapse + OpenID Connect for Single-Sign-On + +If you'd like to use OpenID Connect authentication with Synapse, you'll need some additional reverse-proxy configuration (see [our nginx reverse-proxy doc page](configuring-playbook-nginx.md#synapse-openid-connect-for-single-sign-on)). diff --git a/docs/configuring-playbook.md b/docs/configuring-playbook.md index ad45eac7..3bb28c3f 100644 --- a/docs/configuring-playbook.md +++ b/docs/configuring-playbook.md @@ -33,6 +33,7 @@ When you're done with all the configuration you'd like to do, continue with [Ins - [Setting up the Jitsi video-conferencing platform](configuring-playbook-jitsi.md) (optional) +- [Setting Dynamic DNS](configuring-playbook-dynamic-dns.md) (optional) ### Core service adjustments diff --git a/docs/howto-server-delegation.md b/docs/howto-server-delegation.md index 5235b843..1ea1091a 100644 --- a/docs/howto-server-delegation.md +++ b/docs/howto-server-delegation.md @@ -89,7 +89,7 @@ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key: /matrix/ssl/ If your files are not in `/matrix/ssl` but in some other location, you would need to mount them into the container: ```yaml -matrix_synapse_container_extra_arguments: +matrix_nginx_proxy_container_extra_arguments: - "--mount type=bind,src=/some/path/on/the/host,dst=/some/path/inside/the/container,ro" ``` diff --git a/docs/importing-postgres.md b/docs/importing-postgres.md index a88067e1..0dd75cb2 100644 --- a/docs/importing-postgres.md +++ b/docs/importing-postgres.md @@ -1,7 +1,7 @@ # Importing an existing Postgres database from another installation (optional) -Run this if you'd like to import your database from a previous installation of Synapse. -(don't forget to import your `media_store` files as well - see [the importing-media-store guide](importing-media-store.md)). +Run this if you'd like to import your database from a previous installation. +(don't forget to import your Synapse `media_store` files as well - see [the importing-synape-media-store guide](importing-synapse-media-store.md)). ## Prerequisites diff --git a/docs/importing-media-store.md b/docs/importing-synapse-media-store.md similarity index 92% rename from docs/importing-media-store.md rename to docs/importing-synapse-media-store.md index 0d86370b..0ba7bacb 100644 --- a/docs/importing-media-store.md +++ b/docs/importing-synapse-media-store.md @@ -1,4 +1,4 @@ -# Importing `media_store` data files from an existing installation (optional) +# Importing `media_store` data files from an existing Synapse installation (optional) Run this if you'd like to import your `media_store` files from a previous installation of Synapse. @@ -17,6 +17,6 @@ As an alternative, you can perform a manual restore using the [AWS CLI tool](htt Run this command (make sure to replace `` with a path on your server): - ansible-playbook -i inventory/hosts setup.yml --extra-vars='server_path_media_store=' --tags=import-media-store + ansible-playbook -i inventory/hosts setup.yml --extra-vars='server_path_media_store=' --tags=import-synapse-media-store **Note**: `` must be a file path to a `media_store` directory on the server (not on your local machine!). diff --git a/docs/importing-sqlite.md b/docs/importing-synapse-sqlite.md similarity index 86% rename from docs/importing-sqlite.md rename to docs/importing-synapse-sqlite.md index 9e3a910d..aade2226 100644 --- a/docs/importing-sqlite.md +++ b/docs/importing-synapse-sqlite.md @@ -1,7 +1,7 @@ -# Importing an existing SQLite database from another installation (optional) +# Importing an existing SQLite database from another Synapse installation (optional) Run this if you'd like to import your database from a previous default installation of Synapse. -(don't forget to import your `media_store` files as well - see [the importing-media-store guide](importing-media-store.md)). +(don't forget to import your `media_store` files as well - see [the importing-synapse-media-store guide](importing-synapse-media-store.md)). While this playbook always sets up PostgreSQL, by default a Synapse installation would run using an SQLite database. @@ -18,7 +18,7 @@ Before doing the actual import, **you need to upload your SQLite database file t Run this command (make sure to replace `` with a file path on your server): - ansible-playbook -i inventory/hosts setup.yml --extra-vars='server_path_homeserver_db=' --tags=import-sqlite-db + ansible-playbook -i inventory/hosts setup.yml --extra-vars='server_path_homeserver_db=' --tags=import-synapse-sqlite-db **Notes**: diff --git a/docs/installing.md b/docs/installing.md index 43758ffb..a2ce1371 100644 --- a/docs/installing.md +++ b/docs/installing.md @@ -21,11 +21,11 @@ Feel free to **re-run this setup command any time** you think something is off w After installing, but before starting the services, you may want to do additional things like: -- [Importing an existing SQLite database (from another installation)](importing-sqlite.md) (optional) +- [Importing an existing SQLite database (from another Synapse installation)](importing-synapse-sqlite.md) (optional) - [Importing an existing Postgres database (from another installation)](importing-postgres.md) (optional) -- [Importing `media_store` data files from an existing installation](importing-media-store.md) (optional) +- [Importing `media_store` data files from an existing Synapse installation](importing-synapse-media-store.md) (optional) ## Starting the services diff --git a/docs/maintenance-synapse.md b/docs/maintenance-synapse.md index 79998299..143238c1 100644 --- a/docs/maintenance-synapse.md +++ b/docs/maintenance-synapse.md @@ -4,14 +4,11 @@ This document shows you how to perform various maintenance tasks related to the Table of contents: -- [Purging unused data with synapse-janitor](#purging-unused-data-with-synapse-janitor), for when you wish to delete unused data from the Synapse database - - [Purging old data with the Purge History API](#purging-old-data-with-the-purge-history-api), for when you wish to delete in-use (but old) data from the Synapse database - [Synapse maintenance](#synapse-maintenance) - [Purging old data with the Purge History API](#purging-old-data-with-the-purge-history-api) - [Compressing state with rust-synapse-compress-state](#compressing-state-with-rust-synapse-compress-state) - - [Purging unused data with synapse-janitor](#purging-unused-data-with-synapse-janitor) - [Browse and manipulate the database](#browse-and-manipulate-the-database) - [Browse and manipulate the database](#browse-and-manipulate-the-database), for when you really need to take matters into your own hands @@ -57,27 +54,6 @@ If you need to adjust this, pass: `--extra-vars='matrix_synapse_rust_synapse_com After state compression, you may wish to run a [`FULL` Postgres `VACUUM`](./maintenance-postgres.md#vacuuming-postgresql). -## Purging unused data with synapse-janitor - -**NOTE**: There are [reports](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/465) that **synapse-janitor is dangerous to use and causes database corruption**. You may wish to refrain from using it. - -When you **leave** and **forget** a room, Synapse can clean up its data, but currently doesn't. -This **unused and unreachable data** remains in your database forever. - -There are external tools (like [synapse-janitor](https://github.com/xwiki-labs/synapse_scripts)), which are meant to solve this problem. - -To ask the playbook to run synapse-janitor, execute: - -```bash -ansible-playbook -i inventory/hosts setup.yml --tags=run-postgres-synapse-janitor,start -``` - -**Note**: this will automatically stop Synapse temporarily and restart it later. - -Running synapse-janitor potentially deletes a lot of data from the Postgres database. -You may wish to run a [`FULL` Postgres `VACUUM`](./maintenance-postgres.md#vacuuming-postgresql) after that. - - ## Browse and manipulate the database When the [matrix admin API](https://github.com/matrix-org/synapse/tree/master/docs/admin_api) and the other tools do not provide a more convenient way, having a look at synapse's postgresql database can satisfy a lot of admins' needs. diff --git a/docs/prerequisites.md b/docs/prerequisites.md index 4356081b..488f6c6f 100644 --- a/docs/prerequisites.md +++ b/docs/prerequisites.md @@ -10,7 +10,7 @@ This playbook doesn't support running on ARM (see [this issue](https://github.co - `root` access to your server (or a user capable of elevating to `root` via `sudo`). -- [Python](https://www.python.org/) being installed on the server. Most distributions install Python by default, but some don't (e.g. Ubuntu 18.04) and require manual installation (something like `apt-get install python`). +- [Python](https://www.python.org/) being installed on the server. Most distributions install Python by default, but some don't (e.g. Ubuntu 18.04) and require manual installation (something like `apt-get install python3`). On some distros, Ansible may incorrectly [detect the Python version](https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html) (2 vs 3) and you may need to explicitly specify the interpreter path in `inventory/hosts` during installation (e.g. `ansible_python_interpreter=/usr/bin/python3`) - A `cron`-like tool installed on the server such as `cron` or `anacron` to automatically schedule the Let's Encrypt SSL certificates's renewal. *This can be ignored if you use your own SSL certificates.* @@ -22,6 +22,17 @@ This playbook doesn't support running on ARM (see [this issue](https://github.co - Properly configured DNS records for `` (details in [Configuring DNS](configuring-dns.md)). -- Some TCP/UDP ports open. This playbook configures the server's internal firewall for you. In most cases, you don't need to do anything special. But **if your server is running behind another firewall**, you'd need to open these ports: `80/tcp` (HTTP webserver), `443/tcp` (HTTPS webserver), `3478/tcp` (TURN over TCP), `3478/udp` (TURN over UDP), `5349/tcp` (TURN over TCP), `5349/udp` (TURN over UDP), `8448/tcp` (Matrix Federation API HTTPS webserver), the range `49152-49172/udp` (TURN over UDP), `4443/tcp` (Jitsi Harvester fallback), `10000/udp` (Jitsi video RTP). Depending on your firewall/NAT setup, incoming RTP packets on port 10000 may have the external IP of your firewall as destination address, due to the usage of STUN in JVB (see [`matrix_jitsi_jvb_stun_servers`](../roles/matrix-jitsi/defaults/main.yml)). +- Some TCP/UDP ports open. This playbook configures the server's internal firewall for you. In most cases, you don't need to do anything special. But **if your server is running behind another firewall**, you'd need to open these ports: + + - `80/tcp`: HTTP webserver + - `443/tcp`: HTTPS webserver + - `3478/tcp`: TURN over TCP (used by Coturn) + - `3478/udp`: TURN over UDP (used by Coturn) + - `5349/tcp`: TURN over TCP (used by Coturn) + - `5349/udp`: TURN over UDP (used by Coturn) + - `8448/tcp`: Matrix Federation API HTTPS webserver. In some cases, this **may necessary even with federation disabled**. Integration Servers (like Dimension) and Identity Servers (like ma1sd) may need to access `openid` APIs on the federation port. + - the range `49152-49172/udp`: TURN over UDP + - `4443/tcp`: Jitsi Harvester fallback + - `10000/udp`: Jitsi video RTP. Depending on your firewall/NAT setup, incoming RTP packets on port `10000` may have the external IP of your firewall as destination address, due to the usage of STUN in JVB (see [`matrix_jitsi_jvb_stun_servers`](../roles/matrix-jitsi/defaults/main.yml)). When ready to proceed, continue with [Configuring DNS](configuring-dns.md). diff --git a/docs/self-building.md b/docs/self-building.md index 169e4aa5..fa4db222 100644 --- a/docs/self-building.md +++ b/docs/self-building.md @@ -15,6 +15,7 @@ List of roles where self-building the Docker image is currently possible: - `matrix-client-element` - `matrix-registration` - `matrix-coturn` +- `matrix-corporal` - `matrix-ma1sd` - `matrix-mailer` - `matrix-bridge-mautrix-facebook` diff --git a/docs/uninstalling.md b/docs/uninstalling.md index 7acb9bcc..cb55a7b5 100644 --- a/docs/uninstalling.md +++ b/docs/uninstalling.md @@ -1,24 +1,40 @@ # Uninstalling -**Note**: If you have some trouble with your installation configuration, you can just [re-run the playbook](installing.md) and it will try to set things up again. You don't need to uninstall and install fresh. +**Warnings**: -However, if you've installed this on some server where you have other stuff you wish to preserve, and now want get rid of Matrix, it's enough to do these: +- If your server federates with others, make sure to **leave any federated rooms before nuking your Matrix server's data**. Otherwise, the next time you set up a Matrix server for this domain (regardless of the installation method you use), you'll encounter trouble federating. -- ensure all Matrix services are stopped (`systemctl stop 'matrix*'`) +- If you have some trouble with your installation, you can just [re-run the playbook](installing.md) and it will try to set things up again. **Uninstalling and then installing anew rarely solves anything**. -- delete the Matrix-related systemd .service files (`rm -f /etc/systemd/system/matrix*`) and reload systemd (`systemctl daemon-reload`) + +----------------- + + +## Uninstalling using a script + +Installing places a `/usr/local/bin/matrix-remove-all` script on the server. + +You can run it to to have it uninstall things for you automatically (see below). **Use with caution!** + + +## Uninstalling manually + +If you prefer to uninstall manually, run these commands (most are meant to be executed on the Matrix server itself): + +- ensure all Matrix services are stopped: `ansible-playbook -i inventory/hosts setup.yml --tags=stop` (if you can't get Ansible working to run this command, you can run `systemctl stop 'matrix*'` manually on the server) + +- delete the Matrix-related systemd `.service` files (`rm -f /etc/systemd/system/matrix*.service`) and reload systemd (`systemctl daemon-reload`) - delete all Matrix-related cronjobs (`rm -f /etc/cron.d/matrix*`) - delete some helper scripts (`rm -f /usr/local/bin/matrix*`) -- delete some cached Docker images (or just delete them all: `docker rmi $(docker images -aq)`) +- delete some cached Docker images (`docker system prune -a`) or just delete them all (`docker rmi $(docker images -aq)`) -- delete the Docker network: `docker network rm matrix` +- delete the Docker network: `docker network rm matrix` (might have been deleted already if you ran the `docker system prune` command) - uninstall Docker itself, if necessary - delete the `/matrix` directory (`rm -rf /matrix`) -The script `/usr/local/bin/matrix-remove-all` performs all these steps (**use with caution!**). diff --git a/docs/updating-users-passwords.md b/docs/updating-users-passwords.md index 785bc17c..7d2f2832 100644 --- a/docs/updating-users-passwords.md +++ b/docs/updating-users-passwords.md @@ -26,7 +26,7 @@ and then connecting to the postgres server and executing: ``` UPDATE users SET password_hash = '' WHERE name = '@someone:server.com' ``` -` + where `` is the hash returned by the docker command above. diff --git a/examples/apache/matrix-synapse.conf b/examples/apache/matrix-synapse.conf index 3e09121f..e4266b81 100644 --- a/examples/apache/matrix-synapse.conf +++ b/examples/apache/matrix-synapse.conf @@ -43,6 +43,8 @@ AllowEncodedSlashes NoDecode ProxyPass /_matrix http://127.0.0.1:8008/_matrix retry=0 nocanon ProxyPassReverse /_matrix http://127.0.0.1:8008/_matrix + ProxyPass /_synapse/client http://127.0.0.1:8008/_synapse/client retry=0 nocanon + ProxyPassReverse /_synapse/client http://127.0.0.1:8008/_synapse/client # Map /.well-known/matrix/client for client discovery Alias /.well-known/matrix/client /matrix/static-files/.well-known/matrix/client diff --git a/examples/caddy/matrix-synapse b/examples/caddy/matrix-synapse index 30f7c5a2..4202c759 100644 --- a/examples/caddy/matrix-synapse +++ b/examples/caddy/matrix-synapse @@ -21,9 +21,11 @@ https://matrix.DOMAIN { } # Synapse Client<>Server API - proxy / matrix-synapse:8008 { + proxy /_matrix matrix-synapse:8008 { + transparent + except /_matrix/identity/ /_matrix/client/r0/user_directory/search + } + proxy /_synapse/client matrix-synapse:8008 { transparent - except /.well-known/ /_matrix/identity/ /_matrix/client/r0/user_directory/search } - } diff --git a/examples/hosts b/examples/hosts index 3b14f09e..daf2cfc5 100644 --- a/examples/hosts +++ b/examples/hosts @@ -10,6 +10,9 @@ # # If you're running this Ansible playbook on the same server as the one you're installing to, # consider adding an additional `ansible_connection=local` argument below. +# +# Ansible may fail to discover which Python interpreter to use on the host for some distros (like Ubuntu 20.04). +# You may sometimes need to explicitly add `ansible_python_interpreter=/usr/bin/python3` to lines below. [matrix_servers] matrix. ansible_host= ansible_ssh_user=root diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 5252f7ad..09253dae 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -24,20 +24,6 @@ matrix_identity_server_url: "{{ ('https://' + matrix_server_fqn_matrix) if matri # ###################################################################### -###################################################################### -# -# matrix-architecture -# -###################################################################### - -matrix_architecture: "amd64" - -###################################################################### -# -# /matrix-architecture -# -###################################################################### - ###################################################################### # @@ -61,12 +47,19 @@ matrix_appservice_discord_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_appservice_discord_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'discord.as.token') | to_uuid }}" matrix_appservice_discord_homeserver_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'discord.hs.token') | to_uuid }}" +# We only make this use Postgres if our own Postgres server is enabled. +# It's only then (for now) that we can automatically create the necessary database and user for this service. +matrix_appservice_discord_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_appservice_discord_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'as.discord.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-appservice-discord @@ -135,6 +128,10 @@ matrix_appservice_slack_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) }} +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_appservice_slack_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_appservice_slack_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'as.slack.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-appservice-slack @@ -170,6 +167,10 @@ matrix_appservice_irc_appservice_token: "{{ matrix_synapse_macaroon_secret_key | matrix_appservice_irc_homeserver_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'irc.hs.token') | to_uuid }}" +matrix_appservice_irc_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'nedb' }}" +matrix_appservice_irc_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'as.irc.db') | to_uuid }}" + + ###################################################################### # # /matrix-bridge-appservice-irc @@ -193,6 +194,8 @@ matrix_mautrix_facebook_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mautrix_facebook_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'fb.as.token') | to_uuid }}" @@ -201,6 +204,12 @@ matrix_mautrix_facebook_homeserver_token: "{{ matrix_synapse_macaroon_secret_key matrix_mautrix_facebook_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +matrix_mautrix_facebook_bridge_presence: "{{ matrix_synapse_use_presence if matrix_synapse_enabled else true }}" + +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mautrix_facebook_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mautrix_facebook_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mau.fb.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mautrix-facebook @@ -224,6 +233,8 @@ matrix_mautrix_hangouts_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mautrix_hangouts_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'ho.as.token') | to_uuid }}" @@ -234,6 +245,10 @@ matrix_mautrix_hangouts_container_http_host_bind_port: "{{ '' if matrix_nginx_pr matrix_mautrix_hangouts_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mautrix_hangouts_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mautrix_hangouts_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mau.hangouts.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mautrix-hangouts @@ -294,6 +309,8 @@ matrix_mautrix_telegram_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mautrix_telegram_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'telegr.as.token') | to_uuid }}" @@ -306,6 +323,10 @@ matrix_mautrix_telegram_container_http_host_bind_port: "{{ '' if matrix_nginx_pr matrix_mautrix_telegram_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mautrix_telegram_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mautrix_telegram_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mau.telegram.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mautrix-telegram @@ -326,6 +347,8 @@ matrix_mautrix_whatsapp_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mautrix_whatsapp_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'whats.as.token') | to_uuid }}" @@ -334,6 +357,10 @@ matrix_mautrix_whatsapp_homeserver_token: "{{ matrix_synapse_macaroon_secret_key matrix_mautrix_whatsapp_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mautrix_whatsapp_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mautrix_whatsapp_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mauwhatsapp.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mautrix-whatsapp @@ -382,6 +409,8 @@ matrix_mx_puppet_skype_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mx_puppet_skype_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'skype.as.tok') | to_uuid }}" @@ -390,6 +419,10 @@ matrix_mx_puppet_skype_homeserver_token: "{{ matrix_synapse_macaroon_secret_key matrix_mx_puppet_skype_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mx_puppet_skype_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_skype_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxpup.skype.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mx-puppet-skype @@ -413,6 +446,8 @@ matrix_mx_puppet_slack_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mx_puppet_slack_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxslk.as.tok') | to_uuid }}" @@ -421,6 +456,10 @@ matrix_mx_puppet_slack_homeserver_token: "{{ matrix_synapse_macaroon_secret_key matrix_mx_puppet_slack_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mx_puppet_slack_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_slack_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxpup.slack.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mx-puppet-slack @@ -443,6 +482,8 @@ matrix_mx_puppet_twitter_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mx_puppet_twitter_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxtwt.as.tok') | to_uuid }}" @@ -453,6 +494,10 @@ matrix_mx_puppet_twitter_login_shared_secret: "{{ matrix_synapse_ext_password_pr matrix_mx_puppet_twitter_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else ('127.0.0.1:' ~ matrix_mx_puppet_twitter_appservice_port) }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mx_puppet_twitter_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_twitter_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxpup.twitter.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mx-puppet-twitter @@ -476,6 +521,8 @@ matrix_mx_puppet_instagram_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mx_puppet_instagram_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxig.as.tok') | to_uuid }}" @@ -484,6 +531,10 @@ matrix_mx_puppet_instagram_homeserver_token: "{{ matrix_synapse_macaroon_secret_ matrix_mx_puppet_instagram_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mx_puppet_instagram_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_instagram_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxpup.ig.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mx-puppet-instagram @@ -506,6 +557,8 @@ matrix_mx_puppet_discord_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mx_puppet_discord_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxdsc.as.tok') | to_uuid }}" @@ -514,6 +567,10 @@ matrix_mx_puppet_discord_homeserver_token: "{{ matrix_synapse_macaroon_secret_ke matrix_mx_puppet_discord_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mx_puppet_discord_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_discord_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxpup.dsc.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mx-puppet-discord @@ -536,6 +593,8 @@ matrix_mx_puppet_steam_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) }} matrix_mx_puppet_steam_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxste.as.tok') | to_uuid }}" @@ -544,6 +603,10 @@ matrix_mx_puppet_steam_homeserver_token: "{{ matrix_synapse_macaroon_secret_key matrix_mx_puppet_steam_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_mx_puppet_steam_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_steam_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxpup.steam.db') | to_uuid }}" + ###################################################################### # # /matrix-bridge-mx-puppet-steam @@ -560,6 +623,17 @@ matrix_mx_puppet_steam_login_shared_secret: "{{ matrix_synapse_ext_password_prov # We don't enable bots by default. matrix_bot_matrix_reminder_bot_enabled: false +matrix_bot_matrix_reminder_bot_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_bot_matrix_reminder_bot_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_bot_matrix_reminder_bot_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'reminder.bot.db') | to_uuid }}" + ###################################################################### # # /matrix-bot-matrix-reminder-bot @@ -575,6 +649,8 @@ matrix_bot_matrix_reminder_bot_enabled: false matrix_corporal_enabled: false +matrix_corporal_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + # Normally, matrix-nginx-proxy is enabled and nginx can reach matrix-corporal over the container network. # If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose # matrix-corporal's web-server ports to the local host. @@ -614,13 +690,19 @@ matrix_coturn_container_image_self_build: "{{ matrix_architecture != 'amd64'}}" matrix_coturn_turn_external_ip_address: "{{ ansible_host }}" -matrix_coturn_tls_enabled: true +matrix_coturn_tls_enabled: "{{ matrix_ssl_retrieval_method != 'none' }}" matrix_coturn_tls_cert_path: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_server_fqn_matrix }}/fullchain.pem" matrix_coturn_tls_key_path: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_server_fqn_matrix }}/privkey.pem" -matrix_coturn_container_additional_volumes: - - src: "{{ matrix_ssl_config_dir_path }}" - dst: "{{ matrix_ssl_config_dir_path }}" - options: ro +matrix_coturn_container_additional_volumes: | + {{ + ([] if matrix_ssl_retrieval_method == 'none' else [ + { + 'src': matrix_ssl_config_dir_path, + 'dst': matrix_ssl_config_dir_path, + 'options': 'ro', + } + ]) + }} ###################################################################### # @@ -646,7 +728,16 @@ matrix_dimension_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_ena matrix_integration_manager_rest_url: "{{ matrix_dimension_integrations_rest_url if matrix_dimension_enabled else None }}" matrix_integration_manager_ui_url: "{{ matrix_dimension_integrations_ui_url if matrix_dimension_enabled else None }}" -matrix_dimension_homeserver_federationUrl: "http://matrix-synapse:{{ 8048 if matrix_synapse_federation_enabled|bool else 8008 }}" +matrix_dimension_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_dimension_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_dimension_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'dimension.db') | to_uuid }}" ###################################################################### # @@ -655,6 +746,23 @@ matrix_dimension_homeserver_federationUrl: "http://matrix-synapse:{{ 8048 if mat ###################################################################### + +###################################################################### +# +# matrix-dynamic-dns +# +###################################################################### + +matrix_dynamic_dns_enabled: false + +###################################################################### +# +# /matrix-dynamic-dns +# +###################################################################### + + + ###################################################################### # # matrix-email2matrix @@ -684,6 +792,8 @@ matrix_jitsi_enabled: false # the Jitsi HTTP port to the local host. matrix_jitsi_web_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:12080' }}" +matrix_jitsi_jvb_container_colibri_ws_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:12090' }}" + matrix_jitsi_jibri_xmpp_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'jibri') | to_uuid }}" matrix_jitsi_jicofo_auth_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'jicofo') | to_uuid }}" matrix_jitsi_jvb_auth_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'jvb') | to_uuid }}" @@ -773,6 +883,11 @@ matrix_ma1sd_threepid_medium_email_connectors_smtp_tls: 0 matrix_ma1sd_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" +matrix_ma1sd_systemd_required_services_list: | + {{ + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + }} + matrix_ma1sd_systemd_wanted_services_list: | {{ (['matrix-corporal.service'] if matrix_corporal_enabled else ['matrix-synapse.service']) @@ -782,6 +897,10 @@ matrix_ma1sd_systemd_wanted_services_list: | (['matrix-mailer.service'] if matrix_mailer_enabled else []) }} +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_ma1sd_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_ma1sd_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'ma1sd.db') | to_uuid }}" + ###################################################################### # # /matrix-ma1sd @@ -805,6 +924,10 @@ matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "{{ 'matrix-corp matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "{{ '127.0.0.1:41080' if matrix_corporal_enabled else '127.0.0.1:8008' }}" matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: "{{ matrix_synapse_max_upload_size_mb }}" +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: "{{ matrix_synapse_admin_enabled }}" + +matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: "{{ matrix_server_fqn_element if matrix_client_element_enabled else '' }}" + matrix_nginx_proxy_proxy_matrix_enabled: true matrix_nginx_proxy_proxy_element_enabled: "{{ matrix_client_element_enabled }}" matrix_nginx_proxy_proxy_dimension_enabled: "{{ matrix_dimension_enabled }}" @@ -819,7 +942,8 @@ matrix_nginx_proxy_proxy_matrix_identity_api_addr_with_container: "matrix-ma1sd: matrix_nginx_proxy_proxy_matrix_identity_api_addr_sans_container: "127.0.0.1:8090" # By default, we do TLS termination for the Matrix Federation API (port 8448) at matrix-nginx-proxy. -matrix_nginx_proxy_proxy_matrix_federation_api_enabled: true +# Unless this is handled there OR Synapse's federation listener port is disabled, we'll reverse-proxy. +matrix_nginx_proxy_proxy_matrix_federation_api_enabled: "{{ matrix_synapse_federation_port_enabled and not matrix_synapse_tls_federation_listener_enabled }}" matrix_nginx_proxy_proxy_matrix_federation_api_addr_with_container: "matrix-synapse:8048" matrix_nginx_proxy_proxy_matrix_federation_api_addr_sans_container: "127.0.0.1:8048" @@ -869,6 +993,8 @@ matrix_ssl_architecture: "{{ }[matrix_architecture] }}" +matrix_ssl_pre_obtaining_required_service_name: "{{ 'matrix-dynamic-dns' if matrix_dynamic_dns_enabled else '' }}" + ###################################################################### # # /matrix-nginx-proxy @@ -887,9 +1013,137 @@ matrix_postgres_enabled: true matrix_postgres_connection_hostname: "matrix-postgres" matrix_postgres_connection_username: "synapse" +# Please note that the max length of the password is 99 characters matrix_postgres_connection_password: "synapse-password" matrix_postgres_db_name: "homeserver" +matrix_postgres_pgloader_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_postgres_additional_databases: | + {{ + ([{ + 'name': matrix_ma1sd_database_name, + 'username': matrix_ma1sd_database_username, + 'password': matrix_ma1sd_database_password, + }] if (matrix_ma1sd_enabled and matrix_ma1sd_database_engine == 'postgres' and matrix_ma1sd_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_bot_matrix_reminder_bot_database_name, + 'username': matrix_bot_matrix_reminder_bot_database_username, + 'password': matrix_bot_matrix_reminder_bot_database_password, + }] if (matrix_bot_matrix_reminder_bot_enabled and matrix_bot_matrix_reminder_bot_database_engine == 'postgres' and matrix_bot_matrix_reminder_bot_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_registration_database_name, + 'username': matrix_registration_database_username, + 'password': matrix_registration_database_password, + }] if (matrix_registration_enabled and matrix_registration_database_engine == 'postgres' and matrix_registration_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_appservice_discord_database_name, + 'username': matrix_appservice_discord_database_username, + 'password': matrix_appservice_discord_database_password, + }] if (matrix_appservice_discord_enabled and matrix_appservice_discord_database_engine == 'postgres' and matrix_appservice_discord_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_appservice_slack_database_name, + 'username': matrix_appservice_slack_database_username, + 'password': matrix_appservice_slack_database_password, + }] if (matrix_appservice_slack_enabled and matrix_appservice_slack_database_engine == 'postgres' and matrix_appservice_slack_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_appservice_irc_database_name, + 'username': matrix_appservice_irc_database_username, + 'password': matrix_appservice_irc_database_password, + }] if (matrix_appservice_irc_enabled and matrix_appservice_irc_database_engine == 'postgres' and matrix_appservice_irc_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mautrix_facebook_database_name, + 'username': matrix_mautrix_facebook_database_username, + 'password': matrix_mautrix_facebook_database_password, + }] if (matrix_mautrix_facebook_enabled and matrix_mautrix_facebook_database_engine == 'postgres' and matrix_mautrix_facebook_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mautrix_hangouts_database_name, + 'username': matrix_mautrix_hangouts_database_username, + 'password': matrix_mautrix_hangouts_database_password, + }] if (matrix_mautrix_hangouts_enabled and matrix_mautrix_hangouts_database_engine == 'postgres' and matrix_mautrix_hangouts_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mautrix_telegram_database_name, + 'username': matrix_mautrix_telegram_database_username, + 'password': matrix_mautrix_telegram_database_password, + }] if (matrix_mautrix_telegram_enabled and matrix_mautrix_telegram_database_engine == 'postgres' and matrix_mautrix_telegram_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mautrix_whatsapp_database_name, + 'username': matrix_mautrix_whatsapp_database_username, + 'password': matrix_mautrix_whatsapp_database_password, + }] if (matrix_mautrix_whatsapp_enabled and matrix_mautrix_whatsapp_database_engine == 'postgres' and matrix_mautrix_whatsapp_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': 'matrix_bridge_sms', + 'username': 'matrix_bridge_sms', + 'password': matrix_synapse_macaroon_secret_key | password_hash('sha512', 'bridge.sms.db') | to_uuid, + }] if matrix_sms_bridge_enabled else []) + + + ([{ + 'name': matrix_mx_puppet_skype_database_name, + 'username': matrix_mx_puppet_skype_database_username, + 'password': matrix_mx_puppet_skype_database_password, + }] if (matrix_mx_puppet_skype_enabled and matrix_mx_puppet_skype_database_engine == 'postgres' and matrix_mx_puppet_skype_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mx_puppet_slack_database_name, + 'username': matrix_mx_puppet_slack_database_username, + 'password': matrix_mx_puppet_slack_database_password, + }] if (matrix_mx_puppet_slack_enabled and matrix_mx_puppet_slack_database_engine == 'postgres' and matrix_mx_puppet_slack_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mx_puppet_twitter_database_name, + 'username': matrix_mx_puppet_twitter_database_username, + 'password': matrix_mx_puppet_twitter_database_password, + }] if (matrix_mx_puppet_twitter_enabled and matrix_mx_puppet_twitter_database_engine == 'postgres' and matrix_mx_puppet_twitter_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mx_puppet_instagram_database_name, + 'username': matrix_mx_puppet_instagram_database_username, + 'password': matrix_mx_puppet_instagram_database_password, + }] if (matrix_mx_puppet_instagram_enabled and matrix_mx_puppet_instagram_database_engine == 'postgres' and matrix_mx_puppet_instagram_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mx_puppet_discord_database_name, + 'username': matrix_mx_puppet_discord_database_username, + 'password': matrix_mx_puppet_discord_database_password, + }] if (matrix_mx_puppet_discord_enabled and matrix_mx_puppet_discord_database_engine == 'postgres' and matrix_mx_puppet_discord_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_mx_puppet_steam_database_name, + 'username': matrix_mx_puppet_steam_database_username, + 'password': matrix_mx_puppet_steam_database_password, + }] if (matrix_mx_puppet_steam_enabled and matrix_mx_puppet_steam_database_engine == 'postgres' and matrix_mx_puppet_steam_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_dimension_database_name, + '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 []) + }} + +matrix_postgres_import_roles_to_ignore: | + {{ + [matrix_postgres_connection_username] + + + matrix_postgres_additional_databases|map(attribute='username')|list + }} + +matrix_postgres_import_databases_to_ignore: | + {{ + [matrix_postgres_db_name] + + + matrix_postgres_additional_databases|map(attribute='name')|list + }} + ###################################################################### # # /matrix-postgres @@ -953,7 +1207,7 @@ matrix_client_element_jitsi_preferredDomain: "{{ matrix_server_fqn_jitsi if matr # ###################################################################### -matrix_synapse_container_image_self_build: "{{ matrix_architecture != 'amd64'}}" +matrix_synapse_container_image_self_build: "{{ matrix_architecture not in ['arm32', 'arm64', 'amd64'] }}" # When ma1sd is enabled, we can use it to validate email addresses and phone numbers. # Synapse can validate email addresses by itself as well, but it's probably not what we want by default when we have an identity server. @@ -990,12 +1244,7 @@ matrix_synapse_tls_federation_listener_enabled: false matrix_synapse_tls_certificate_path: ~ matrix_synapse_tls_private_key_path: ~ -matrix_synapse_http_listener_resource_names: | - {{ - ["client"] - + - ( ["openid"] if matrix_dimension_enabled and not matrix_synapse_federation_enabled else [] ) - }} +matrix_synapse_federation_port_openid_resource_required: "{{ not matrix_synapse_federation_enabled and (matrix_dimension_enabled or matrix_ma1sd_enabled) }}" matrix_synapse_email_enabled: "{{ matrix_mailer_enabled }}" matrix_synapse_email_smtp_host: "matrix-mailer" @@ -1091,6 +1340,17 @@ matrix_registration_api_validate_certs: "{{ false if matrix_ssl_retrieval_method matrix_registration_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" +matrix_registration_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_registration_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_registration_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mx.registr.db') | to_uuid }}" + ###################################################################### # # /matrix-registration diff --git a/roles/matrix-base/defaults/main.yml b/roles/matrix-base/defaults/main.yml index 164509b7..2cc4b42f 100644 --- a/roles/matrix-base/defaults/main.yml +++ b/roles/matrix-base/defaults/main.yml @@ -23,6 +23,17 @@ matrix_server_fqn_jitsi: "jitsi.{{ matrix_domain }}" matrix_federation_public_port: 8448 +# The architecture that your server runs. +# Recognized values by us are 'amd64', 'arm32' and 'arm64'. +# Not all architectures support all services, so your experience (on non-amd64) may vary. +# See docs/alternative-architectures.md +matrix_architecture: amd64 + +# The architecture for Debian packages. +# See: https://wiki.debian.org/SupportedArchitectures +# We just remap from our `matrix_architecture` values to what Debian and possibly other distros call things. +matrix_debian_arch: "{{ 'armhf' if matrix_architecture == 'arm32' else matrix_architecture }}" + matrix_user_username: "matrix" matrix_user_groupname: "matrix" @@ -106,7 +117,6 @@ matrix_docker_package_name: docker-ce run_postgres_import: true run_postgres_upgrade: true run_postgres_import_sqlite_db: true -run_postgres_synapse_janitor: true run_postgres_vacuum: true run_synapse_register_user: true run_synapse_update_user_password: true diff --git a/roles/matrix-base/files/yum.repos.d/docker-ce.repo b/roles/matrix-base/files/yum.repos.d/docker-ce.repo index 56242d98..1abdbe36 100644 --- a/roles/matrix-base/files/yum.repos.d/docker-ce.repo +++ b/roles/matrix-base/files/yum.repos.d/docker-ce.repo @@ -1,62 +1,62 @@ [docker-ce-stable] name=Docker CE Stable - $basearch -baseurl=https://download.docker.com/linux/centos/7/$basearch/stable +baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable enabled=1 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpg [docker-ce-stable-debuginfo] name=Docker CE Stable - Debuginfo $basearch -baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/stable +baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/stable enabled=0 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpg [docker-ce-stable-source] name=Docker CE Stable - Sources -baseurl=https://download.docker.com/linux/centos/7/source/stable -enabled=0 -gpgcheck=1 -gpgkey=https://download.docker.com/linux/centos/gpg - -[docker-ce-edge] -name=Docker CE Edge - $basearch -baseurl=https://download.docker.com/linux/centos/7/$basearch/edge -enabled=0 -gpgcheck=1 -gpgkey=https://download.docker.com/linux/centos/gpg - -[docker-ce-edge-debuginfo] -name=Docker CE Edge - Debuginfo $basearch -baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/edge -enabled=0 -gpgcheck=1 -gpgkey=https://download.docker.com/linux/centos/gpg - -[docker-ce-edge-source] -name=Docker CE Edge - Sources -baseurl=https://download.docker.com/linux/centos/7/source/edge +baseurl=https://download.docker.com/linux/centos/$releasever/source/stable enabled=0 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpg [docker-ce-test] name=Docker CE Test - $basearch -baseurl=https://download.docker.com/linux/centos/7/$basearch/test +baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/test enabled=0 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpg [docker-ce-test-debuginfo] name=Docker CE Test - Debuginfo $basearch -baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/test +baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/test enabled=0 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpg [docker-ce-test-source] name=Docker CE Test - Sources -baseurl=https://download.docker.com/linux/centos/7/source/test +baseurl=https://download.docker.com/linux/centos/$releasever/source/test +enabled=0 +gpgcheck=1 +gpgkey=https://download.docker.com/linux/centos/gpg + +[docker-ce-nightly] +name=Docker CE Nightly - $basearch +baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/nightly +enabled=0 +gpgcheck=1 +gpgkey=https://download.docker.com/linux/centos/gpg + +[docker-ce-nightly-debuginfo] +name=Docker CE Nightly - Debuginfo $basearch +baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/nightly +enabled=0 +gpgcheck=1 +gpgkey=https://download.docker.com/linux/centos/gpg + +[docker-ce-nightly-source] +name=Docker CE Nightly - Sources +baseurl=https://download.docker.com/linux/centos/$releasever/source/nightly enabled=0 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpg diff --git a/roles/matrix-base/tasks/server_base/setup_debian.yml b/roles/matrix-base/tasks/server_base/setup_debian.yml index 6d8d18fa..37706d1f 100644 --- a/roles/matrix-base/tasks/server_base/setup_debian.yml +++ b/roles/matrix-base/tasks/server_base/setup_debian.yml @@ -11,7 +11,7 @@ - name: Ensure Docker's APT key is trusted apt_key: - url: https://download.docker.com/linux/ubuntu/gpg + url: "https://download.docker.com/linux/{{ ansible_distribution|lower }}/gpg" id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 state: present register: add_repository_key @@ -20,7 +20,7 @@ - name: Ensure Docker repository is enabled apt_repository: - repo: "deb [arch=amd64] https://download.docker.com/linux/{{ ansible_distribution|lower }} {{ ansible_distribution_release }} stable" + repo: "deb [arch={{ matrix_debian_arch }}] https://download.docker.com/linux/{{ ansible_distribution|lower }} {{ ansible_distribution_release }} stable" state: present update_cache: yes when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce' diff --git a/roles/matrix-base/tasks/server_base/setup_raspbian.yml b/roles/matrix-base/tasks/server_base/setup_raspbian.yml index a9a5d20a..421905a0 100644 --- a/roles/matrix-base/tasks/server_base/setup_raspbian.yml +++ b/roles/matrix-base/tasks/server_base/setup_raspbian.yml @@ -5,6 +5,7 @@ name: - apt-transport-https - ca-certificates + - gnupg state: present update_cache: yes @@ -19,7 +20,7 @@ - name: Ensure Docker repository is enabled apt_repository: - repo: "deb [arch=armhf] https://download.docker.com/linux/raspbian {{ ansible_distribution_release }} stable" + repo: "deb [arch={{ matrix_debian_arch }}] https://download.docker.com/linux/raspbian {{ ansible_distribution_release }} stable" state: present update_cache: yes when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce' @@ -27,7 +28,6 @@ - name: Ensure APT packages are installed apt: name: - - python-docker - "{{ matrix_ntpd_package }}" - fuse state: latest @@ -37,5 +37,6 @@ apt: name: - "{{ matrix_docker_package_name }}" + - "python{{'3' if ansible_python.version.major == 3 else ''}}-docker" state: latest when: matrix_docker_installation_enabled|bool diff --git a/roles/matrix-base/templates/usr-local-bin/matrix-remove-all.j2 b/roles/matrix-base/templates/usr-local-bin/matrix-remove-all.j2 index 972919e3..2a2314a5 100644 --- a/roles/matrix-base/templates/usr-local-bin/matrix-remove-all.j2 +++ b/roles/matrix-base/templates/usr-local-bin/matrix-remove-all.j2 @@ -24,9 +24,9 @@ else find /etc/cron.d/ -name "matrix-*" -delete echo "Remove matrix scripts" find {{ matrix_local_bin_path }}/ -name "matrix-*" -delete - echo "Remove every docker images" - docker rmi $(docker images -aq) - echo "Remove docker matrix network" + echo "Remove unused Docker images and resources" + docker system prune -af + echo "Remove Docker matrix network (should be gone already, but ..)" docker network rm {{ matrix_docker_network }} echo "Remove {{ matrix_base_data_path }} directory" rm -fr "{{ matrix_base_data_path }}" diff --git a/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml b/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml index 8f4a2c2f..29bc8307 100644 --- a/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml +++ b/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml @@ -3,7 +3,7 @@ matrix_bot_matrix_reminder_bot_enabled: true -matrix_bot_matrix_reminder_bot_docker_image: "anoa/matrix-reminder-bot:release-v0.2.0" +matrix_bot_matrix_reminder_bot_docker_image: "docker.io/anoa/matrix-reminder-bot:release-v0.2.0" matrix_bot_matrix_reminder_bot_docker_image_force_pull: "{{ matrix_bot_matrix_reminder_bot_docker_image.endswith(':latest') }}" matrix_bot_matrix_reminder_bot_base_path: "{{ matrix_base_data_path }}/matrix-reminder-bot" @@ -21,6 +21,34 @@ matrix_bot_matrix_reminder_bot_systemd_required_services_list: ['docker.service' matrix_bot_matrix_reminder_bot_systemd_wanted_services_list: [] +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_bot_matrix_reminder_bot_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bot_matrix_reminder_bot_database_*` variables +matrix_bot_matrix_reminder_bot_database_engine: 'sqlite' + +matrix_bot_matrix_reminder_bot_sqlite_database_path_local: "{{ matrix_bot_matrix_reminder_bot_data_path }}/bot.db" +matrix_bot_matrix_reminder_bot_sqlite_database_path_in_container: "/data/bot.db" + +matrix_bot_matrix_reminder_bot_database_username: 'matrix_reminder_bot' +matrix_bot_matrix_reminder_bot_database_password: 'some-password' +matrix_bot_matrix_reminder_bot_database_hostname: 'matrix-postgres' +matrix_bot_matrix_reminder_bot_database_port: 5432 +matrix_bot_matrix_reminder_bot_database_name: 'matrix_reminder_bot' + +matrix_bot_matrix_reminder_bot_database_connection_string: 'postgres://{{ matrix_bot_matrix_reminder_bot_database_username }}:{{ matrix_bot_matrix_reminder_bot_database_password }}@{{ matrix_bot_matrix_reminder_bot_database_hostname }}:{{ matrix_bot_matrix_reminder_bot_database_port }}/{{ matrix_bot_matrix_reminder_bot_database_name }}' + +matrix_bot_matrix_reminder_bot_storage_database: "{{ + { + 'sqlite': ('sqlite://' + matrix_bot_matrix_reminder_bot_sqlite_database_path_in_container), + 'postgres': matrix_bot_matrix_reminder_bot_database_connection_string, + }[matrix_bot_matrix_reminder_bot_database_engine] +}}" + + # The bot's username. This user needs to be created manually beforehand. # Also see `matrix_bot_matrix_reminder_bot_user_password`. matrix_bot_matrix_reminder_bot_matrix_user_id_localpart: "bot.matrix-reminder-bot" diff --git a/roles/matrix-bot-matrix-reminder-bot/tasks/main.yml b/roles/matrix-bot-matrix-reminder-bot/tasks/main.yml index ade3d191..fc2afddb 100644 --- a/roles/matrix-bot-matrix-reminder-bot/tasks/main.yml +++ b/roles/matrix-bot-matrix-reminder-bot/tasks/main.yml @@ -8,7 +8,14 @@ - setup-all - setup-bot-matrix-reminder-bot -- import_tasks: "{{ role_path }}/tasks/setup.yml" +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: "run_setup|bool and matrix_bot_matrix_reminder_bot_enabled|bool" + tags: + - setup-all + - setup-bot-matrix-reminder-bot + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: "run_setup|bool and not matrix_bot_matrix_reminder_bot_enabled|bool" tags: - setup-all - setup-bot-matrix-reminder-bot diff --git a/roles/matrix-bot-matrix-reminder-bot/tasks/setup.yml b/roles/matrix-bot-matrix-reminder-bot/tasks/setup.yml deleted file mode 100644 index bc211e31..00000000 --- a/roles/matrix-bot-matrix-reminder-bot/tasks/setup.yml +++ /dev/null @@ -1,88 +0,0 @@ ---- - -# -# Tasks related to setting up matrix-reminder-bot -# - -- name: Ensure matrix-reminder-bot paths exist - file: - path: "{{ item.path }}" - state: directory - mode: 0750 - owner: "{{ matrix_user_username }}" - group: "{{ matrix_user_groupname }}" - with_items: - - { path: "{{ matrix_bot_matrix_reminder_bot_config_path }}", when: true } - - { path: "{{ matrix_bot_matrix_reminder_bot_data_path }}", when: true } - - { path: "{{ matrix_bot_matrix_reminder_bot_data_store_path }}", when: true } - when: matrix_bot_matrix_reminder_bot_enabled|bool and item.when - -- name: Ensure matrix-reminder-bot image is pulled - docker_image: - name: "{{ matrix_bot_matrix_reminder_bot_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_matrix_reminder_bot_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_bot_matrix_reminder_bot_docker_image_force_pull }}" - when: matrix_bot_matrix_reminder_bot_enabled|bool - -- name: Ensure matrix-reminder-bot config installed - copy: - content: "{{ matrix_bot_matrix_reminder_bot_configuration|to_nice_yaml }}" - dest: "{{ matrix_bot_matrix_reminder_bot_config_path }}/config.yaml" - mode: 0644 - owner: "{{ matrix_user_username }}" - group: "{{ matrix_user_groupname }}" - when: matrix_bot_matrix_reminder_bot_enabled|bool - -- name: Ensure matrix-matrix-reminder-bot.service installed - template: - src: "{{ role_path }}/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2" - dest: "{{ matrix_systemd_path }}/matrix-bot-matrix-reminder-bot.service" - mode: 0644 - register: matrix_bot_matrix_reminder_bot_systemd_service_result - when: matrix_bot_matrix_reminder_bot_enabled|bool - -- name: Ensure systemd reloaded after matrix-matrix-reminder-bot.service installation - service: - daemon_reload: yes - when: "matrix_bot_matrix_reminder_bot_enabled|bool and matrix_bot_matrix_reminder_bot_systemd_service_result.changed" - -# -# Tasks related to getting rid of matrix-reminder-bot (if it was previously enabled) -# - -- name: Check existence of matrix-matrix-reminder-bot service - stat: - path: "{{ matrix_systemd_path }}/matrix-matrix-reminder-bot.service" - register: matrix_bot_matrix_reminder_bot_service_stat - -- name: Ensure matrix-matrix-reminder-bot is stopped - service: - name: matrix-matrix-reminder-bot - state: stopped - daemon_reload: yes - register: stopping_result - when: "not matrix_bot_matrix_reminder_bot_enabled|bool and matrix_bot_matrix_reminder_bot_service_stat.stat.exists" - -- name: Ensure matrix-matrix-reminder-bot.service doesn't exist - file: - path: "{{ matrix_systemd_path }}/matrix-matrix-reminder-bot.service" - state: absent - when: "not matrix_bot_matrix_reminder_bot_enabled|bool and matrix_bot_matrix_reminder_bot_service_stat.stat.exists" - -- name: Ensure systemd reloaded after matrix-matrix-reminder-bot.service removal - service: - daemon_reload: yes - when: "not matrix_bot_matrix_reminder_bot_enabled|bool and matrix_bot_matrix_reminder_bot_service_stat.stat.exists" - -- name: Ensure Matrix matrix-reminder-bot paths don't exist - file: - path: "{{ matrix_bot_matrix_reminder_bot_base_path }}" - state: absent - when: "not matrix_bot_matrix_reminder_bot_enabled|bool" - -- name: Ensure matrix-reminder-bot Docker image doesn't exist - docker_image: - name: "{{ matrix_bot_matrix_reminder_bot_docker_image }}" - state: absent - when: "not matrix_bot_matrix_reminder_bot_enabled|bool" diff --git a/roles/matrix-bot-matrix-reminder-bot/tasks/setup_install.yml b/roles/matrix-bot-matrix-reminder-bot/tasks/setup_install.yml new file mode 100644 index 00000000..195485e4 --- /dev/null +++ b/roles/matrix-bot-matrix-reminder-bot/tasks/setup_install.yml @@ -0,0 +1,73 @@ +--- + +- set_fact: + matrix_bot_matrix_reminder_bot_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_bot_matrix_reminder_bot_sqlite_database_path_local }}" + register: matrix_bot_matrix_reminder_bot_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_bot_matrix_reminder_bot_sqlite_database_path_local }}" + dst: "{{ matrix_bot_matrix_reminder_bot_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_bot_matrix_reminder_bot_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-bot-matrix-reminder-bot.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_bot_matrix_reminder_bot_requires_restart: true + when: "matrix_bot_matrix_reminder_bot_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_bot_matrix_reminder_bot_database_engine == 'postgres'" + +- name: Ensure matrix-reminder-bot paths exist + file: + path: "{{ item.path }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - { path: "{{ matrix_bot_matrix_reminder_bot_config_path }}", when: true } + - { path: "{{ matrix_bot_matrix_reminder_bot_data_path }}", when: true } + - { path: "{{ matrix_bot_matrix_reminder_bot_data_store_path }}", when: true } + when: "item.when|bool" + +- name: Ensure matrix-reminder-bot image is pulled + docker_image: + name: "{{ matrix_bot_matrix_reminder_bot_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_bot_matrix_reminder_bot_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_bot_matrix_reminder_bot_docker_image_force_pull }}" + +- name: Ensure matrix-reminder-bot config installed + copy: + content: "{{ matrix_bot_matrix_reminder_bot_configuration|to_nice_yaml }}" + dest: "{{ matrix_bot_matrix_reminder_bot_config_path }}/config.yaml" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + +- name: Ensure matrix-bot-matrix-reminder-bot.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-bot-matrix-reminder-bot.service" + mode: 0644 + register: matrix_bot_matrix_reminder_bot_systemd_service_result + +- name: Ensure systemd reloaded after matrix-bot-matrix-reminder-bot.service installation + service: + daemon_reload: yes + when: "matrix_bot_matrix_reminder_bot_systemd_service_result.changed|bool" + +- name: Ensure matrix-bot-matrix-reminder-bot.service restarted, if necessary + service: + name: "matrix-bot-matrix-reminder-bot.service" + state: restarted + when: "matrix_bot_matrix_reminder_bot_requires_restart|bool" diff --git a/roles/matrix-bot-matrix-reminder-bot/tasks/setup_uninstall.yml b/roles/matrix-bot-matrix-reminder-bot/tasks/setup_uninstall.yml new file mode 100644 index 00000000..744f474d --- /dev/null +++ b/roles/matrix-bot-matrix-reminder-bot/tasks/setup_uninstall.yml @@ -0,0 +1,35 @@ +--- + +- name: Check existence of matrix-matrix-reminder-bot service + stat: + path: "{{ matrix_systemd_path }}/matrix-bot-matrix-reminder-bot.service" + register: matrix_bot_matrix_reminder_bot_service_stat + +- name: Ensure matrix-matrix-reminder-bot is stopped + service: + name: matrix-matrix-reminder-bot + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_bot_matrix_reminder_bot_service_stat.stat.exists|bool" + +- name: Ensure matrix-bot-matrix-reminder-bot.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-bot-matrix-reminder-bot.service" + state: absent + when: "matrix_bot_matrix_reminder_bot_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-bot-matrix-reminder-bot.service removal + service: + daemon_reload: yes + when: "matrix_bot_matrix_reminder_bot_service_stat.stat.exists|bool" + +- name: Ensure Matrix matrix-reminder-bot paths don't exist + file: + path: "{{ matrix_bot_matrix_reminder_bot_base_path }}" + state: absent + +- name: Ensure matrix-reminder-bot Docker image doesn't exist + docker_image: + name: "{{ matrix_bot_matrix_reminder_bot_docker_image }}" + state: absent diff --git a/roles/matrix-bot-matrix-reminder-bot/templates/config.yaml.j2 b/roles/matrix-bot-matrix-reminder-bot/templates/config.yaml.j2 index e5ba5651..59643958 100644 --- a/roles/matrix-bot-matrix-reminder-bot/templates/config.yaml.j2 +++ b/roles/matrix-bot-matrix-reminder-bot/templates/config.yaml.j2 @@ -23,7 +23,7 @@ storage: # For Postgres, this would look like: # database: "postgres://username:password@localhost/dbname?sslmode=disable" #database: "postgres://matrix-reminder-bot:remindme@localhost/matrix-reminder-bot?sslmode=disable" - database: "sqlite:///data/bot.db" + database: {{ matrix_bot_matrix_reminder_bot_storage_database|to_json }} # The path to a directory for internal bot storage # containing encryption keys, sync tokens, etc. store_path: "/data/store" diff --git a/roles/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 b/roles/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 index 0decac02..950242e5 100644 --- a/roles/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 +++ b/roles/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_bot_matrix_reminder_bot_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -21,8 +22,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-bot-matrix-rem --read-only \ --network={{ matrix_docker_network }} \ -e 'TZ={{ matrix_bot_matrix_reminder_bot_reminders_timezone }}' \ - -v {{ matrix_bot_matrix_reminder_bot_config_path }}:/config:ro \ - -v {{ matrix_bot_matrix_reminder_bot_data_path }}:/data:rw \ + --mount type=bind,src={{ matrix_bot_matrix_reminder_bot_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bot_matrix_reminder_bot_data_path }},dst=/data \ --entrypoint=/bin/sh \ {% for arg in matrix_bot_matrix_reminder_bot_container_extra_arguments %} {{ arg }} \ diff --git a/roles/matrix-bridge-appservice-discord/defaults/main.yml b/roles/matrix-bridge-appservice-discord/defaults/main.yml index 97ad8e89..c7cdddb6 100644 --- a/roles/matrix-bridge-appservice-discord/defaults/main.yml +++ b/roles/matrix-bridge-appservice-discord/defaults/main.yml @@ -3,7 +3,7 @@ matrix_appservice_discord_enabled: true -matrix_appservice_discord_docker_image: "halfshot/matrix-appservice-discord:latest" +matrix_appservice_discord_docker_image: "docker.io/halfshot/matrix-appservice-discord:v1.0.0" matrix_appservice_discord_docker_image_force_pull: "{{ matrix_appservice_discord_docker_image.endswith(':latest') }}" matrix_appservice_discord_base_path: "{{ matrix_base_data_path }}/appservice-discord" @@ -17,6 +17,8 @@ matrix_appservice_discord_bot_token: '' matrix_appservice_discord_appservice_token: '' matrix_appservice_discord_homeserver_token: '' +matrix_appservice_discord_homeserver_domain: "{{ matrix_domain }}" + # Controls whether the matrix-appservice-discord container exposes its HTTP port (tcp/9005 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:9005"), or empty string to not expose. @@ -39,6 +41,38 @@ matrix_appservice_discord_bridge_homeserverUrl: "{{ matrix_homeserver_url }}" matrix_appservice_discord_bridge_disablePresence: false matrix_appservice_discord_bridge_enableSelfServiceBridging: false +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_appservice_discord_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_appservice_discord_postgres_*` variables +matrix_appservice_discord_database_engine: 'sqlite' + +matrix_appservice_discord_sqlite_database_path_local: "{{ matrix_appservice_discord_data_path }}/discord.db" +matrix_appservice_discord_sqlite_database_path_in_container: "/data/discord.db" + +matrix_appservice_discord_database_username: 'matrix_appservice_discord' +matrix_appservice_discord_database_password: 'some-password' +matrix_appservice_discord_database_hostname: 'matrix-postgres' +matrix_appservice_discord_database_port: 5432 +matrix_appservice_discord_database_name: 'matrix_appservice_discord' + +# These 2 variables are what actually ends up in the bridge configuration. +# It's best if you don't change them directly, but rather redefine the sub-variables that constitute them. +matrix_appservice_discord_database_filename: "{{ matrix_appservice_discord_sqlite_database_path_in_container }}" +matrix_appservice_discord_database_connString: 'postgresql://{{ matrix_appservice_discord_database_username }}:{{ matrix_appservice_discord_database_password }}@{{ matrix_appservice_discord_database_hostname }}:{{ matrix_appservice_discord_database_port }}/{{ matrix_appservice_discord_database_name }}' + + +# Tells whether the bot should make use of "Privileged Gateway Intents". +# +# Enabling this means that you need to enable it for the bot (Discord application) as well, +# by triggering all Intent checkboxes on a page like this: `https://discord.com/developers/applications/694448564151123988/bot` +# +# Learn more: https://gist.github.com/advaith1/e69bcc1cdd6d0087322734451f15aa2f +matrix_appservice_discord_auth_usePrivilegedIntents: false + matrix_appservice_discord_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" matrix_appservice_discord_configuration_extension_yaml: | @@ -62,10 +96,10 @@ matrix_appservice_discord_registration_yaml: | namespaces: users: - exclusive: true - regex: '^@_discord_.*' + regex: '@_discord_.*:{{ matrix_appservice_discord_homeserver_domain|regex_escape }}' aliases: - exclusive: true - regex: '^#_discord_.*' + regex: '#_discord_.*:{{ matrix_appservice_discord_homeserver_domain|regex_escape }}' url: {{ matrix_appservice_discord_appservice_url }} sender_localpart: _discord_bot rate_limited: false diff --git a/roles/matrix-bridge-appservice-discord/tasks/setup_install.yml b/roles/matrix-bridge-appservice-discord/tasks/setup_install.yml index 3678b35b..6d3fdd0f 100644 --- a/roles/matrix-bridge-appservice-discord/tasks/setup_install.yml +++ b/roles/matrix-bridge-appservice-discord/tasks/setup_install.yml @@ -1,5 +1,31 @@ --- +- set_fact: + matrix_appservice_discord_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_appservice_discord_sqlite_database_path_local }}" + register: matrix_appservice_discord_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_appservice_discord_sqlite_database_path_local }}" + dst: "{{ matrix_appservice_discord_database_connString }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_appservice_discord_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-appservice-discord.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_appservice_discord_requires_restart: true + when: "matrix_appservice_discord_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_appservice_discord_database_engine == 'postgres'" + - name: Ensure Appservice Discord image is pulled docker_image: name: "{{ matrix_appservice_discord_docker_image }}" @@ -63,7 +89,7 @@ {{ matrix_host_command_docker }} run --rm --name matrix-appservice-discord-link-gen --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL - -v {{ matrix_appservice_discord_config_path }}:/cfg + --mount type=bind,src={{ matrix_appservice_discord_config_path }},dst=/cfg -w /cfg {{ matrix_appservice_discord_docker_image }} /bin/sh -c "node /build/tools/addbot.js > /cfg/invite_link" @@ -80,3 +106,9 @@ service: daemon_reload: yes when: "matrix_appservice_discord_systemd_service_result.changed" + +- name: Ensure matrix-appservice-discord.service restarted, if necessary + service: + name: "matrix-appservice-discord.service" + state: restarted + when: "matrix_appservice_discord_requires_restart|bool" diff --git a/roles/matrix-bridge-appservice-discord/tasks/validate_config.yml b/roles/matrix-bridge-appservice-discord/tasks/validate_config.yml index 46612ba5..73253ba0 100644 --- a/roles/matrix-bridge-appservice-discord/tasks/validate_config.yml +++ b/roles/matrix-bridge-appservice-discord/tasks/validate_config.yml @@ -10,6 +10,7 @@ - "matrix_appservice_discord_bot_token" - "matrix_appservice_discord_appservice_token" - "matrix_appservice_discord_homeserver_token" + - "matrix_appservice_discord_homeserver_domain" - name: (Deprecation) Catch and report renamed appservice-discord variables fail: @@ -19,3 +20,7 @@ when: "item.old in vars" with_items: - {'old': 'matrix_appservice_discord_container_expose_client_server_api_port', 'new': ''} + +- name: Require a valid database engine + fail: msg="`matrix_appservice_discord_database_engine` needs to be either 'sqlite' or 'postgres'" + when: "matrix_appservice_discord_database_engine not in ['sqlite', 'postgres']" diff --git a/roles/matrix-bridge-appservice-discord/templates/config.yaml.j2 b/roles/matrix-bridge-appservice-discord/templates/config.yaml.j2 index e91c60de..b2ecd198 100644 --- a/roles/matrix-bridge-appservice-discord/templates/config.yaml.j2 +++ b/roles/matrix-bridge-appservice-discord/templates/config.yaml.j2 @@ -26,10 +26,17 @@ bridge: disableReadReceipts: false # Disable Join Leave echos from matrix disableJoinLeaveNotifications: false + # Disable Invite echos from matrix + disableInviteNotifications: false + # Auto-determine the language of code blocks (this can be CPU-intensive) + determineCodeLanguage: false # Authentication configuration for the discord bot. auth: clientID: {{ matrix_appservice_discord_client_id|string|to_json }} botToken: {{ matrix_appservice_discord_bot_token }} + # You must enable "Privileged Gateway Intents" in your bot settings on discord.com (e.g. https://discord.com/developers/applications/12345/bot) + # for this to work + usePrivilegedIntents: {{ matrix_appservice_discord_auth_usePrivilegedIntents|to_json }} logging: # What level should the logger output to the console at. console: "warn" #silly, verbose, info, http, warn, error, silent @@ -45,16 +52,17 @@ logging: # enable: # - "DiscordBot" database: - userStorePath: "/data/user-store.db" - roomStorePath: "/data/room-store.db" # You may either use SQLite or Postgresql for the bridge database, which contains # important mappings for events and user puppeting configurations. # Use the filename option for SQLite, or connString for Postgresql. # If you are migrating, see https://github.com/Half-Shot/matrix-appservice-discord/blob/master/docs/howto.md#migrate-to-postgres-from-sqlite # WARNING: You will almost certainly be fine with sqlite unless your bridge # is in heavy demand and you suffer from IO slowness. - filename: "/data/discord.db" - # connString: "postgresql://user:password@localhost/database_name" + {% if matrix_appservice_discord_database_engine == 'sqlite' %} + filename: {{ matrix_appservice_discord_database_filename|to_json }} + {% else %} + connString: {{ matrix_appservice_discord_database_connString|to_json }} + {% endif %} room: # Set the default visibility of alias rooms, defaults to "public". # One of: "public", "private" @@ -82,10 +90,12 @@ channel: limits: # Delay in milliseconds between discord users joining a room. roomGhostJoinDelay: 6000 - # Delay in milliseconds before sending messages to discord to avoid echos. - # (Copies of a sent message may arrive from discord before we've + # Lock timeout in milliseconds before sending messages to discord to avoid + # echos. Default is rather high as the lock will most likely time out + # before anyways. + # echos = (Copies of a sent message may arrive from discord before we've # fininished handling it, causing us to echo it back to the room) - discordSendDelay: 750 + discordSendDelay: 1500 ghosts: # Pattern for the ghosts nick, available is :nick, :username, :tag and :id nickPattern: ":nick" diff --git a/roles/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 b/roles/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 index f2187ca3..7ec15752 100644 --- a/roles/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 +++ b/roles/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_appservice_discord_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -25,8 +26,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-appservice-dis {% if matrix_appservice_discord_container_http_host_bind_port %} -p {{ matrix_appservice_discord_container_http_host_bind_port }}:9005 \ {% endif %} - -v {{ matrix_appservice_discord_config_path }}:/cfg \ - -v {{ matrix_appservice_discord_data_path }}:/data \ + --mount type=bind,src={{ matrix_appservice_discord_config_path }},dst=/cfg \ + --mount type=bind,src={{ matrix_appservice_discord_data_path }},dst=/data \ {% for arg in matrix_appservice_discord_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-bridge-appservice-irc/defaults/main.yml b/roles/matrix-bridge-appservice-irc/defaults/main.yml index 2cbb3e5f..0b671e76 100644 --- a/roles/matrix-bridge-appservice-irc/defaults/main.yml +++ b/roles/matrix-bridge-appservice-irc/defaults/main.yml @@ -3,7 +3,7 @@ matrix_appservice_irc_enabled: true -matrix_appservice_irc_docker_image: "matrixdotorg/matrix-appservice-irc:release-0.17.1" +matrix_appservice_irc_docker_image: "docker.io/matrixdotorg/matrix-appservice-irc:release-0.17.1" matrix_appservice_irc_docker_image_force_pull: "{{ matrix_appservice_irc_docker_image.endswith(':latest') }}" matrix_appservice_irc_base_path: "{{ matrix_base_data_path }}/appservice-irc" @@ -16,6 +16,25 @@ matrix_appservice_irc_homeserver_domain: '{{ matrix_domain }}' matrix_appservice_irc_homeserver_enablePresence: true matrix_appservice_irc_appservice_address: 'http://matrix-appservice-irc:9999' +matrix_appservice_irc_database_engine: nedb +matrix_appservice_irc_database_username: matrix_appservice_irc +matrix_appservice_irc_database_password: ~ +matrix_appservice_irc_database_hostname: 'matrix-postgres' +matrix_appservice_irc_database_port: 5432 +matrix_appservice_irc_database_name: matrix_appservice_irc + +# This is just the Postgres connection string, if Postgres is used. +# Naming clashes with `matrix_appservice_irc_database_connectionString` somewhat. +matrix_appservice_irc_database_connection_string: 'postgresql://{{ matrix_appservice_irc_database_username }}:{{ matrix_appservice_irc_database_password }}@{{ matrix_appservice_irc_database_hostname }}:{{ matrix_appservice_irc_database_port }}/{{ matrix_appservice_irc_database_name }}?sslmode=disable' + +# This is what actually goes into `database.connectionString` for the bridge. +matrix_appservice_irc_database_connectionString: "{{ + { + 'nedb': 'nedb:///data', + 'postgres': matrix_appservice_irc_database_connection_string, + }[matrix_appservice_irc_database_engine] +}}" + matrix_appservice_irc_ircService_servers: [] # Example of `matrix_appservice_irc_ircService_servers` with one server (and all its options): diff --git a/roles/matrix-bridge-appservice-irc/tasks/migrate_nedb_to_postgres.yml b/roles/matrix-bridge-appservice-irc/tasks/migrate_nedb_to_postgres.yml new file mode 100644 index 00000000..3fab195a --- /dev/null +++ b/roles/matrix-bridge-appservice-irc/tasks/migrate_nedb_to_postgres.yml @@ -0,0 +1,64 @@ +- name: Fail if Postgres not enabled + fail: + msg: "Postgres via the matrix-postgres role is not enabled (`matrix_postgres_enabled`). Cannot migrate." + when: "not matrix_postgres_enabled|bool" + +# Defaults + +- name: Set postgres_start_wait_time, if not provided + set_fact: + postgres_start_wait_time: 15 + when: "postgres_start_wait_time|default('') == ''" + +# Actual import work + +- name: Ensure matrix-postgres is started + service: + name: matrix-postgres + state: started + daemon_reload: yes + register: matrix_postgres_service_start_result + +- name: Wait a bit, so that Postgres can start + wait_for: + timeout: "{{ postgres_start_wait_time }}" + delegate_to: 127.0.0.1 + become: false + when: "matrix_postgres_service_start_result.changed|bool" + +- name: Ensure matrix-appservice-irc is stopped + service: + name: matrix-appservice-irc + state: stopped + +- name: Import appservice-irc NeDB database into Postgres + command: + cmd: >- + {{ matrix_host_command_docker }} run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --network={{ matrix_docker_network }} + --mount type=bind,src={{ matrix_appservice_irc_data_path }},dst=/data + --entrypoint=/bin/sh + {{ matrix_appservice_irc_docker_image }} + -c + '/usr/local/bin/node /app/lib/scripts/migrate-db-to-pgres.js --dbdir /data --privateKey /data/passkey.pem --connectionString {{ matrix_appservice_irc_database_connection_string }}' + +- name: Archive NeDB database files + command: + cmd: "mv {{ matrix_appservice_irc_data_path }}/{{ item }} {{ matrix_appservice_irc_data_path }}/{{ item }}.backup" + with_items: + - rooms.db + - users.db + +- name: Inject result + set_fact: + matrix_playbook_runtime_results: | + {{ + matrix_playbook_runtime_results|default([]) + + + [ + "NOTE: Your appservice-irc database files have been imported into Postgres. The original database files have been moved from `{{ matrix_appservice_irc_data_path }}/*.db` to `{{ matrix_appservice_irc_data_path }}/*.db.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete these files." + ] + }} diff --git a/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml b/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml index 5e313347..00568c0d 100644 --- a/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml +++ b/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml @@ -1,12 +1,5 @@ --- -- name: Ensure Appservice IRC image is pulled - docker_image: - name: "{{ matrix_appservice_irc_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_appservice_irc_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_appservice_irc_docker_image_force_pull }}" - - name: Ensure Appservice IRC paths exist file: path: "{{ item }}" @@ -24,25 +17,48 @@ path: "{{ matrix_appservice_irc_base_path }}/passkey.pem" register: matrix_appservice_irc_stat_passkey -- name: (Data relocation) Ensure matrix-appservice-irc.service is stopped - service: - name: matrix-appservice-irc - state: stopped - daemon_reload: yes - failed_when: false +- block: + - name: (Data relocation) Ensure matrix-appservice-irc.service is stopped + service: + name: matrix-appservice-irc + state: stopped + daemon_reload: yes + failed_when: false + + - name: (Data relocation) Move AppService IRC passkey.pem file to ./data directory + command: "mv {{ matrix_appservice_irc_base_path }}/passkey.pem {{ matrix_appservice_irc_data_path }}/passkey.pem" + + - name: (Data relocation) Move AppService IRC database files to ./data directory + command: "mv {{ matrix_appservice_irc_base_path }}/{{ item }} {{ matrix_appservice_irc_data_path }}/{{ item }}" + with_items: + - rooms.db + - users.db + failed_when: false when: "matrix_appservice_irc_stat_passkey.stat.exists" -- name: (Data relocation) Move AppService IRC passkey.pem file to ./data directory - command: "mv {{ matrix_appservice_irc_base_path }}/passkey.pem {{ matrix_appservice_irc_data_path }}/passkey.pem" - when: "matrix_appservice_irc_stat_passkey.stat.exists" +- set_fact: + matrix_appservice_irc_requires_restart: false -- name: (Data relocation) Move AppService IRC database files to ./data directory - command: "mv {{ matrix_appservice_irc_base_path }}/{{ item }} {{ matrix_appservice_irc_data_path }}/{{ item }}" - with_items: - - rooms.db - - users.db - failed_when: false - when: "matrix_appservice_irc_stat_passkey.stat.exists" +- block: + - name: Check if a nedb database already exists + stat: + path: "{{ matrix_appservice_irc_data_path }}/users.db" + register: matrix_appservice_irc_nedb_database_path_local_stat_result + + - block: + - import_tasks: "{{ role_path }}/tasks/migrate_nedb_to_postgres.yml" + + - set_fact: + matrix_appservice_irc_requires_restart: true + when: "matrix_appservice_irc_nedb_database_path_local_stat_result.stat.exists|bool" + when: "matrix_appservice_irc_database_engine == 'postgres'" + +- name: Ensure Appservice IRC image is pulled + docker_image: + name: "{{ matrix_appservice_irc_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_appservice_irc_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_appservice_irc_docker_image_force_pull }}" - name: Ensure Matrix Appservice IRC config installed copy: @@ -147,3 +163,9 @@ service: daemon_reload: yes when: "matrix_appservice_irc_systemd_service_result.changed" + +- name: Ensure matrix-appservice-irc.service restarted, if necessary + service: + name: "matrix-appservice-irc.service" + state: restarted + when: "matrix_appservice_irc_requires_restart|bool" diff --git a/roles/matrix-bridge-appservice-irc/templates/config.yaml.j2 b/roles/matrix-bridge-appservice-irc/templates/config.yaml.j2 index 3daa1898..94bbda7b 100644 --- a/roles/matrix-bridge-appservice-irc/templates/config.yaml.j2 +++ b/roles/matrix-bridge-appservice-irc/templates/config.yaml.j2 @@ -127,8 +127,8 @@ advanced: # Use an external database to store bridge state. database: # database engine (must be 'postgres' or 'nedb'). Default: nedb - engine: "nedb" + engine: {{ matrix_appservice_irc_database_engine|to_json }} # Either a PostgreSQL connection string, or a path to the NeDB storage directory. # For postgres, it must start with postgres:// # For NeDB, it must start with nedb://. The path is relative to the project directory. - connectionString: "nedb:///data" + connectionString: {{ matrix_appservice_irc_database_connectionString|to_json }} diff --git a/roles/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 b/roles/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 index 95638612..c86eb835 100644 --- a/roles/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 +++ b/roles/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_appservice_irc_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-appservice-slack/defaults/main.yml b/roles/matrix-bridge-appservice-slack/defaults/main.yml index eef7d070..28646a3c 100644 --- a/roles/matrix-bridge-appservice-slack/defaults/main.yml +++ b/roles/matrix-bridge-appservice-slack/defaults/main.yml @@ -3,7 +3,7 @@ matrix_appservice_slack_enabled: true -matrix_appservice_slack_docker_image: "matrixdotorg/matrix-appservice-slack:release-1.5.0" +matrix_appservice_slack_docker_image: "docker.io/matrixdotorg/matrix-appservice-slack:release-1.5.0" matrix_appservice_slack_docker_image_force_pull: "{{ matrix_appservice_slack_docker_image.endswith(':latest') }}" matrix_appservice_slack_base_path: "{{ matrix_base_data_path }}/appservice-slack" @@ -45,6 +45,26 @@ matrix_appservice_slack_appservice_token: '' matrix_appservice_slack_homeserver_token: '' matrix_appservice_slack_id_token: '' +matrix_appservice_slack_database_engine: nedb +matrix_appservice_slack_database_username: matrix_appservice_slack +matrix_appservice_slack_database_password: ~ +matrix_appservice_slack_database_hostname: 'matrix-postgres' +matrix_appservice_slack_database_port: 5432 +matrix_appservice_slack_database_name: matrix_appservice_slack + +# This is just the Postgres connection string, if Postgres is used. +# Naming clashes with `matrix_appservice_slack_database_connectionString` somewhat. +matrix_appservice_slack_database_connection_string: 'postgresql://{{ matrix_appservice_slack_database_username }}:{{ matrix_appservice_slack_database_password }}@{{ matrix_appservice_slack_database_hostname }}:{{ matrix_appservice_slack_database_port }}/{{ matrix_appservice_slack_database_name }}?sslmode=disable' + +# This is what actually goes into `database.connectionString` for the bridge. +matrix_appservice_slack_database_connectionString: "{{ + { + 'nedb': 'nedb:///data', + 'postgres': matrix_appservice_slack_database_connection_string, + }[matrix_appservice_slack_database_engine] +}}" + + matrix_appservice_slack_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" matrix_appservice_slack_configuration_extension_yaml: | diff --git a/roles/matrix-bridge-appservice-slack/tasks/migrate_nedb_to_postgres.yml b/roles/matrix-bridge-appservice-slack/tasks/migrate_nedb_to_postgres.yml new file mode 100644 index 00000000..fedad977 --- /dev/null +++ b/roles/matrix-bridge-appservice-slack/tasks/migrate_nedb_to_postgres.yml @@ -0,0 +1,66 @@ +- name: Fail if Postgres not enabled + fail: + msg: "Postgres via the matrix-postgres role is not enabled (`matrix_postgres_enabled`). Cannot migrate." + when: "not matrix_postgres_enabled|bool" + +# Defaults + +- name: Set postgres_start_wait_time, if not provided + set_fact: + postgres_start_wait_time: 15 + when: "postgres_start_wait_time|default('') == ''" + +# Actual import work + +- name: Ensure matrix-postgres is started + service: + name: matrix-postgres + state: started + daemon_reload: yes + register: matrix_postgres_service_start_result + +- name: Wait a bit, so that Postgres can start + wait_for: + timeout: "{{ postgres_start_wait_time }}" + delegate_to: 127.0.0.1 + become: false + when: "matrix_postgres_service_start_result.changed|bool" + +- name: Ensure matrix-appservice-slack is stopped + service: + name: matrix-appservice-slack + state: stopped + +- name: Import appservice-slack NeDB database into Postgres + command: + cmd: >- + {{ matrix_host_command_docker }} run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --network={{ matrix_docker_network }} + --mount type=bind,src={{ matrix_appservice_slack_data_path }},dst=/data + --entrypoint=/bin/sh + {{ matrix_appservice_slack_docker_image }} + -c + '/usr/local/bin/node /usr/src/app/lib/scripts/migrateToPostgres.js --dbdir /data --connectionString {{ matrix_appservice_slack_database_connection_string }}' + +- name: Archive NeDB database files + command: + cmd: "mv {{ matrix_appservice_slack_data_path }}/{{ item }} {{ matrix_appservice_slack_data_path }}/{{ item }}.backup" + with_items: + - teams.db + - room-store.db + - user-store.db + - event-store.db + +- name: Inject result + set_fact: + matrix_playbook_runtime_results: | + {{ + matrix_playbook_runtime_results|default([]) + + + [ + "NOTE: Your appservice-slack database files have been imported into Postgres. The original database files have been moved from `{{ matrix_appservice_slack_data_path }}/*.db` to `{{ matrix_appservice_slack_data_path }}/*.db.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete these files." + ] + }} diff --git a/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml b/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml index 94e0fedf..29b0f39e 100644 --- a/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml +++ b/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml @@ -1,12 +1,5 @@ --- -- name: Ensure Appservice Slack image is pulled - docker_image: - name: "{{ matrix_appservice_slack_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_appservice_slack_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_appservice_slack_docker_image_force_pull }}" - - name: Ensure AppService Slack paths exist file: path: "{{ item }}" @@ -19,6 +12,30 @@ - "{{ matrix_appservice_slack_config_path }}" - "{{ matrix_appservice_slack_data_path }}" +- set_fact: + matrix_appservice_slack_requires_restart: false + +- block: + - name: Check if a nedb database already exists + stat: + path: "{{ matrix_appservice_slack_data_path }}/teams.db" + register: matrix_appservice_slack_nedb_database_path_local_stat_result + + - block: + - import_tasks: "{{ role_path }}/tasks/migrate_nedb_to_postgres.yml" + + - set_fact: + matrix_appservice_slack_requires_restart: true + when: "matrix_appservice_slack_nedb_database_path_local_stat_result.stat.exists|bool" + when: "matrix_appservice_slack_database_engine == 'postgres'" + +- name: Ensure Appservice Slack image is pulled + docker_image: + name: "{{ matrix_appservice_slack_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_appservice_slack_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_appservice_slack_docker_image_force_pull }}" + - name: Ensure Matrix Appservice Slack config installed copy: content: "{{ matrix_appservice_slack_configuration|to_nice_yaml }}" @@ -46,3 +63,9 @@ service: daemon_reload: yes when: "matrix_appservice_slack_systemd_service_result.changed" + +- name: Ensure matrix-appservice-slack.service restarted, if necessary + service: + name: "matrix-appservice-slack.service" + state: restarted + when: "matrix_appservice_slack_requires_restart|bool" diff --git a/roles/matrix-bridge-appservice-slack/tasks/validate_config.yml b/roles/matrix-bridge-appservice-slack/tasks/validate_config.yml index 5da5f947..8af10f2f 100644 --- a/roles/matrix-bridge-appservice-slack/tasks/validate_config.yml +++ b/roles/matrix-bridge-appservice-slack/tasks/validate_config.yml @@ -9,4 +9,4 @@ - "matrix_appservice_slack_control_room_id" - "matrix_appservice_slack_appservice_token" - "matrix_appservice_slack_homeserver_token" - - "matrix_appservice_slack_id_token" \ No newline at end of file + - "matrix_appservice_slack_id_token" diff --git a/roles/matrix-bridge-appservice-slack/templates/config.yaml.j2 b/roles/matrix-bridge-appservice-slack/templates/config.yaml.j2 index 8f48d317..bf8072c1 100644 --- a/roles/matrix-bridge-appservice-slack/templates/config.yaml.j2 +++ b/roles/matrix-bridge-appservice-slack/templates/config.yaml.j2 @@ -9,6 +9,12 @@ homeserver: url: "{{ matrix_appservice_slack_homeserver_url }}" server_name: "{{ matrix_domain }}" +{% if matrix_appservice_slack_database_engine == 'nedb' %} dbdir: "/data" +{% else %} +db: + engine: {{ matrix_appservice_slack_database_engine|to_json }} + connectionString: {{ matrix_appservice_slack_database_connectionString|to_json }} +{% endif %} matrix_admin_room: "{{ matrix_appservice_slack_control_room_id }}" diff --git a/roles/matrix-bridge-appservice-slack/templates/systemd/matrix-appservice-slack.service.j2 b/roles/matrix-bridge-appservice-slack/templates/systemd/matrix-appservice-slack.service.j2 index 1c68294f..b16b2fed 100644 --- a/roles/matrix-bridge-appservice-slack/templates/systemd/matrix-appservice-slack.service.j2 +++ b/roles/matrix-bridge-appservice-slack/templates/systemd/matrix-appservice-slack.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_appservice_slack_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-appservice-webhooks/defaults/main.yml b/roles/matrix-bridge-appservice-webhooks/defaults/main.yml index 0fb5abbc..e668f918 100644 --- a/roles/matrix-bridge-appservice-webhooks/defaults/main.yml +++ b/roles/matrix-bridge-appservice-webhooks/defaults/main.yml @@ -3,7 +3,7 @@ matrix_appservice_webhooks_enabled: true -matrix_appservice_webhooks_docker_image: "turt2live/matrix-appservice-webhooks:latest" +matrix_appservice_webhooks_docker_image: "docker.io/turt2live/matrix-appservice-webhooks:latest" matrix_appservice_webhooks_docker_image_force_pull: "{{ matrix_appservice_webhooks_docker_image.endswith(':latest') }}" matrix_appservice_webhooks_base_path: "{{ matrix_base_data_path }}/appservice-webhooks" diff --git a/roles/matrix-bridge-appservice-webhooks/templates/systemd/matrix-appservice-webhooks.service.j2 b/roles/matrix-bridge-appservice-webhooks/templates/systemd/matrix-appservice-webhooks.service.j2 index 08f5813f..2049ee65 100644 --- a/roles/matrix-bridge-appservice-webhooks/templates/systemd/matrix-appservice-webhooks.service.j2 +++ b/roles/matrix-bridge-appservice-webhooks/templates/systemd/matrix-appservice-webhooks.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_appservice_webhooks_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mautrix-facebook/defaults/main.yml b/roles/matrix-bridge-mautrix-facebook/defaults/main.yml index 610bcc11..da9b1889 100644 --- a/roles/matrix-bridge-mautrix-facebook/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-facebook/defaults/main.yml @@ -4,9 +4,11 @@ matrix_mautrix_facebook_enabled: true matrix_mautrix_facebook_container_image_self_build: false +matrix_mautrix_facebook_container_image_self_build_repo: "https://github.com/tulir/mautrix-facebook.git" # See: https://mau.dev/tulir/mautrix-facebook/container_registry -matrix_mautrix_facebook_docker_image: "dock.mau.dev/tulir/mautrix-facebook:latest" +matrix_mautrix_facebook_docker_image: "{{ matrix_mautrix_facebook_docker_image_name_prefix }}tulir/mautrix-facebook:latest" +matrix_mautrix_facebook_docker_image_name_prefix: "{{ 'localhost/' if matrix_mautrix_facebook_container_image_self_build else 'dock.mau.dev/' }}" matrix_mautrix_facebook_docker_image_force_pull: "{{ matrix_mautrix_facebook_docker_image.endswith(':latest') }}" matrix_mautrix_facebook_base_path: "{{ matrix_base_data_path }}/mautrix-facebook" @@ -30,9 +32,42 @@ matrix_mautrix_facebook_systemd_wanted_services_list: [] matrix_mautrix_facebook_appservice_token: '' matrix_mautrix_facebook_homeserver_token: '' + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_mautrix_facebook_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_mautrix_facebook_postgres_*` variables +matrix_mautrix_facebook_database_engine: 'sqlite' + +matrix_mautrix_facebook_sqlite_database_path_local: "{{ matrix_mautrix_facebook_data_path }}/mautrix-facebook.db" +matrix_mautrix_facebook_sqlite_database_path_in_container: "/data/mautrix-facebook.db" + +matrix_mautrix_facebook_database_username: 'matrix_mautrix_facebook' +matrix_mautrix_facebook_database_password: 'some-password' +matrix_mautrix_facebook_database_hostname: 'matrix-postgres' +matrix_mautrix_facebook_database_port: 5432 +matrix_mautrix_facebook_database_name: 'matrix_mautrix_facebook' + +matrix_mautrix_facebook_database_connection_string: 'postgres://{{ matrix_mautrix_facebook_database_username }}:{{ matrix_mautrix_facebook_database_password }}@{{ matrix_mautrix_facebook_database_hostname }}:{{ matrix_mautrix_facebook_database_port }}/{{ matrix_mautrix_facebook_database_name }}' + +matrix_mautrix_facebook_appservice_database: "{{ + { + 'sqlite': ('sqlite:///' + matrix_mautrix_facebook_sqlite_database_path_in_container), + 'postgres': matrix_mautrix_facebook_database_connection_string, + }[matrix_mautrix_facebook_database_engine] +}}" + + # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mautrix_facebook_login_shared_secret: '' +matrix_mautrix_facebook_bridge_login_shared_secret_map: "{{ {matrix_mautrix_facebook_homeserver_domain: matrix_mautrix_facebook_login_shared_secret} if matrix_mautrix_facebook_login_shared_secret else {} }}" + +matrix_mautrix_facebook_bridge_presence: true + # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml index a1131d8e..59998463 100644 --- a/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml @@ -8,6 +8,32 @@ The matrix-bridge-mautrix-facebook role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" +- set_fact: + matrix_mautrix_facebook_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mautrix_facebook_sqlite_database_path_local }}" + register: matrix_mautrix_facebook_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mautrix_facebook_sqlite_database_path_local }}" + dst: "{{ matrix_mautrix_facebook_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mautrix_facebook_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mautrix-facebook.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mautrix_facebook_requires_restart: true + when: "matrix_mautrix_facebook_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mautrix_facebook_database_engine == 'postgres'" + - name: Ensure Mautrix Facebook image is pulled docker_image: name: "{{ matrix_mautrix_facebook_docker_image }}" @@ -32,7 +58,7 @@ - name: Ensure Mautrix Facebook repository is present on self-build git: - repo: https://github.com/tulir/mautrix-facebook.git + repo: "{{ matrix_mautrix_facebook_container_image_self_build_repo }}" dest: "{{ matrix_mautrix_facebook_docker_src_files_path }}" # version: "{{ matrix_coturn_docker_image.split(':')[1] }}" force: "yes" @@ -43,12 +69,12 @@ docker_image: name: "{{ matrix_mautrix_facebook_docker_image }}" source: build - force_source: yes + force_source: "{{ matrix_mautrix_facebook_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mautrix_facebook_docker_src_files_path }}" pull: yes - when: "matrix_mautrix_facebook_enabled|bool and matrix_mautrix_facebook_container_image_self_build and matrix_mautrix_facebook_git_pull_results.changed" + when: "matrix_mautrix_facebook_enabled|bool and matrix_mautrix_facebook_container_image_self_build|bool" - name: Check if an old database file already exists stat: @@ -94,3 +120,9 @@ service: daemon_reload: yes when: "matrix_mautrix_facebook_systemd_service_result.changed" + +- name: Ensure matrix-mautrix-facebook.service restarted, if necessary + service: + name: "matrix-mautrix-facebook.service" + state: restarted + when: "matrix_mautrix_facebook_requires_restart|bool" diff --git a/roles/matrix-bridge-mautrix-facebook/templates/config.yaml.j2 b/roles/matrix-bridge-mautrix-facebook/templates/config.yaml.j2 index 7da7b588..09287362 100644 --- a/roles/matrix-bridge-mautrix-facebook/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mautrix-facebook/templates/config.yaml.j2 @@ -27,7 +27,7 @@ appservice: # Format examples: # SQLite: sqlite:///filename.db # Postgres: postgres://username:password@hostname/dbname - database: sqlite:////data/mautrix-facebook.db + database: {{ matrix_mautrix_facebook_appservice_database|to_json }} # Public part of web server for out-of-Matrix interaction with the bridge. public: @@ -81,23 +81,32 @@ bridge: command_prefix: "!fb" # Number of chats to sync (and create portals for) on startup/login. - # Maximum 20, set 0 to disable automatic syncing. + # Set 0 to disable automatic syncing. initial_chat_sync: 10 # Whether or not the Facebook users of logged in Matrix users should be # invited to private chats when the user sends a message from another client. invite_own_puppet_to_pm: false - # Whether or not to use /sync to get presence, read receipts and typing notifications when using - # your own Matrix account as the Matrix puppet for your Facebook account. + # Whether or not to use /sync to get presence, read receipts and typing notifications + # when double puppeting is enabled sync_with_custom_puppets: true - # Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth + # Whether or not to update the m.direct account data event when double puppeting is enabled. + # Note that updating the m.direct event is not atomic (except with mautrix-asmux) + # and is therefore prone to race conditions. + sync_direct_chat_list: false + # Servers to always allow double puppeting from + double_puppet_server_map: {} + # example.com: https://example.com + # Allow using double puppeting from any server with a valid client .well-known file. + double_puppet_allow_discovery: false + # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth # # If set, custom puppets will be enabled automatically for local users # instead of users having to find an access token and run `login-matrix` # manually. - login_shared_secret: {{ matrix_mautrix_facebook_login_shared_secret|to_json }} - # Whether or not to bridge presence in both directions. Facebook allows users not to broadcast - # presence, but then it won't send other users' presence to the client. - presence: true + # If using this for other servers than the bridge's server, + # you must also set the URL in the double_puppet_server_map. + login_shared_secret_map: {{ matrix_mautrix_facebook_bridge_login_shared_secret_map|to_json }} + presence: {{ matrix_mautrix_facebook_bridge_presence|to_json }} # Whether or not to update avatars when syncing all contacts at startup. update_avatar_initial_sync: true # End-to-bridge encryption support options. These require matrix-nio to be installed with pip diff --git a/roles/matrix-bridge-mautrix-facebook/templates/systemd/matrix-mautrix-facebook.service.j2 b/roles/matrix-bridge-mautrix-facebook/templates/systemd/matrix-mautrix-facebook.service.j2 index b593a2e3..caa52eb5 100644 --- a/roles/matrix-bridge-mautrix-facebook/templates/systemd/matrix-mautrix-facebook.service.j2 +++ b/roles/matrix-bridge-mautrix-facebook/templates/systemd/matrix-mautrix-facebook.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mautrix_facebook_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -17,6 +18,7 @@ ExecStartPre={{ matrix_host_command_docker }} run --rm --name matrix-mautrix-fac --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ + --network={{ matrix_docker_network }} \ -v {{ matrix_mautrix_facebook_config_path }}:/config:z \ -v {{ matrix_mautrix_facebook_data_path }}:/data:z \ {{ matrix_mautrix_facebook_docker_image }} \ diff --git a/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml b/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml index 8430527a..8dfee030 100644 --- a/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml @@ -4,9 +4,11 @@ matrix_mautrix_hangouts_enabled: true matrix_mautrix_hangouts_container_image_self_build: false +matrix_mautrix_hangouts_container_image_self_build_repo: "https://github.com/tulir/mautrix-hangouts.git" # See: https://mau.dev/tulir/mautrix-hangouts/container_registry -matrix_mautrix_hangouts_docker_image: "dock.mau.dev/tulir/mautrix-hangouts:latest" +matrix_mautrix_hangouts_docker_image: "{{ matrix_mautrix_hangouts_docker_image_name_prefix }}tulir/mautrix-hangouts:latest" +matrix_mautrix_hangouts_docker_image_name_prefix: "{{ 'localhost/' if matrix_mautrix_hangouts_container_image_self_build else 'dock.mau.dev/' }}" matrix_mautrix_hangouts_docker_image_force_pull: "{{ matrix_mautrix_hangouts_docker_image.endswith(':latest') }}" matrix_mautrix_hangouts_base_path: "{{ matrix_base_data_path }}/mautrix-hangouts" @@ -37,6 +39,35 @@ matrix_mautrix_hangouts_systemd_wanted_services_list: [] matrix_mautrix_hangouts_appservice_token: '' matrix_mautrix_hangouts_homeserver_token: '' + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_mautrix_hangouts_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_mautrix_hangouts_postgres_*` variables +matrix_mautrix_hangouts_database_engine: 'sqlite' + +matrix_mautrix_hangouts_sqlite_database_path_local: "{{ matrix_mautrix_hangouts_data_path }}/mautrix-hangouts.db" +matrix_mautrix_hangouts_sqlite_database_path_in_container: "/data/mautrix-hangouts.db" + +matrix_mautrix_hangouts_database_username: 'matrix_mautrix_hangouts' +matrix_mautrix_hangouts_database_password: 'some-password' +matrix_mautrix_hangouts_database_hostname: 'matrix-postgres' +matrix_mautrix_hangouts_database_port: 5432 +matrix_mautrix_hangouts_database_name: 'matrix_mautrix_hangouts' + +matrix_mautrix_hangouts_database_connection_string: 'postgres://{{ matrix_mautrix_hangouts_database_username }}:{{ matrix_mautrix_hangouts_database_password }}@{{ matrix_mautrix_hangouts_database_hostname }}:{{ matrix_mautrix_hangouts_database_port }}/{{ matrix_mautrix_hangouts_database_name }}' + +matrix_mautrix_hangouts_appservice_database: "{{ + { + 'sqlite': ('sqlite:///' + matrix_mautrix_hangouts_sqlite_database_path_in_container), + 'postgres': matrix_mautrix_hangouts_database_connection_string, + }[matrix_mautrix_hangouts_database_engine] +}}" + + # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mautrix_hangouts_login_shared_secret: '' diff --git a/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml index 97893be7..2ce8a441 100644 --- a/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml @@ -8,6 +8,32 @@ The matrix-bridge-mautrix-hangouts role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" +- set_fact: + matrix_mautrix_hangouts_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mautrix_hangouts_sqlite_database_path_local }}" + register: matrix_mautrix_hangouts_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mautrix_hangouts_sqlite_database_path_local }}" + dst: "{{ matrix_mautrix_hangouts_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mautrix_hangouts_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mautrix-hangouts.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mautrix_hangouts_requires_restart: true + when: "matrix_mautrix_hangouts_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mautrix_hangouts_database_engine == 'postgres'" + - name: Ensure Mautrix Hangouts image is pulled docker_image: name: "{{ matrix_mautrix_hangouts_docker_image }}" @@ -32,22 +58,22 @@ - name: Ensure Mautrix Hangots repository is present on self build git: - repo: https://github.com/tulir/mautrix-hangouts.git + repo: "{{ matrix_mautrix_hangouts_container_image_self_build_repo }}" dest: "{{ matrix_mautrix_hangouts_docker_src_files_path }}" force: "yes" register: matrix_mautrix_hangouts_git_pull_results - when: "matrix_mautrix_hangouts_enabled|bool and matrix_mautrix_hangouts_container_image_self_build" + when: "matrix_mautrix_hangouts_enabled|bool and matrix_mautrix_hangouts_container_image_self_build|bool" - name: Ensure Mautrix Hangouts Docker image is built docker_image: name: "{{ matrix_mautrix_hangouts_docker_image }}" source: build - force_source: yes + force_source: "{{ matrix_mautrix_hangouts_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mautrix_hangouts_docker_src_files_path }}" pull: yes - when: "matrix_mautrix_hangouts_enabled|bool and matrix_mautrix_hangouts_container_image_self_build and matrix_mautrix_hangouts_git_pull_results.changed" + when: "matrix_mautrix_hangouts_enabled|bool and matrix_mautrix_hangouts_container_image_self_build|bool" - name: Check if an old database file already exists stat: @@ -93,3 +119,9 @@ service: daemon_reload: yes when: "matrix_mautrix_hangouts_systemd_service_result.changed" + +- name: Ensure matrix-mautrix-hangouts.service restarted, if necessary + service: + name: "matrix-mautrix-hangouts.service" + state: restarted + when: "matrix_mautrix_hangouts_requires_restart|bool" diff --git a/roles/matrix-bridge-mautrix-hangouts/templates/config.yaml.j2 b/roles/matrix-bridge-mautrix-hangouts/templates/config.yaml.j2 index f274b203..cc2ca90b 100644 --- a/roles/matrix-bridge-mautrix-hangouts/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mautrix-hangouts/templates/config.yaml.j2 @@ -27,7 +27,7 @@ appservice: # Format examples: # SQLite: sqlite:///filename.db # Postgres: postgres://username:password@hostname/dbname - database: sqlite:////data/mautrix-hangouts.db + database: {{ matrix_mautrix_hangouts_appservice_database|to_json }} # The unique ID of this appservice. id: hangouts diff --git a/roles/matrix-bridge-mautrix-hangouts/templates/systemd/matrix-mautrix-hangouts.service.j2 b/roles/matrix-bridge-mautrix-hangouts/templates/systemd/matrix-mautrix-hangouts.service.j2 index 58433982..39559190 100644 --- a/roles/matrix-bridge-mautrix-hangouts/templates/systemd/matrix-mautrix-hangouts.service.j2 +++ b/roles/matrix-bridge-mautrix-hangouts/templates/systemd/matrix-mautrix-hangouts.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mautrix_hangouts_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -17,6 +18,7 @@ ExecStartPre={{ matrix_host_command_docker }} run --rm --name matrix-mautrix-han --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ + --network={{ matrix_docker_network }} \ -v {{ matrix_mautrix_hangouts_config_path }}:/config:z \ -v {{ matrix_mautrix_hangouts_data_path }}:/data:z \ {{ matrix_mautrix_hangouts_docker_image }} \ diff --git a/roles/matrix-bridge-mautrix-telegram/defaults/main.yml b/roles/matrix-bridge-mautrix-telegram/defaults/main.yml index d2ab9909..3f81617a 100644 --- a/roles/matrix-bridge-mautrix-telegram/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-telegram/defaults/main.yml @@ -4,7 +4,7 @@ matrix_mautrix_telegram_enabled: true # See: https://mau.dev/tulir/mautrix-telegram/container_registry -matrix_mautrix_telegram_docker_image: "dock.mau.dev/tulir/mautrix-telegram:v0.8.2" +matrix_mautrix_telegram_docker_image: "dock.mau.dev/tulir/mautrix-telegram:v0.9.0" matrix_mautrix_telegram_docker_image_force_pull: "{{ matrix_mautrix_telegram_docker_image.endswith(':latest') }}" matrix_mautrix_telegram_base_path: "{{ matrix_base_data_path }}/mautrix-telegram" @@ -43,6 +43,35 @@ matrix_mautrix_telegram_systemd_wanted_services_list: [] matrix_mautrix_telegram_appservice_token: '' matrix_mautrix_telegram_homeserver_token: '' + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_mautrix_telegram_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_mautrix_telegram_postgres_*` variables +matrix_mautrix_telegram_database_engine: 'sqlite' + +matrix_mautrix_telegram_sqlite_database_path_local: "{{ matrix_mautrix_telegram_data_path }}/mautrix-telegram.db" +matrix_mautrix_telegram_sqlite_database_path_in_container: "/data/mautrix-telegram.db" + +matrix_mautrix_telegram_database_username: 'matrix_mautrix_telegram' +matrix_mautrix_telegram_database_password: 'some-password' +matrix_mautrix_telegram_database_hostname: 'matrix-postgres' +matrix_mautrix_telegram_database_port: 5432 +matrix_mautrix_telegram_database_name: 'matrix_mautrix_telegram' + +matrix_mautrix_telegram_database_connection_string: 'postgres://{{ matrix_mautrix_telegram_database_username }}:{{ matrix_mautrix_telegram_database_password }}@{{ matrix_mautrix_telegram_database_hostname }}:{{ matrix_mautrix_telegram_database_port }}/{{ matrix_mautrix_telegram_database_name }}' + +matrix_mautrix_telegram_appservice_database: "{{ + { + 'sqlite': ('sqlite:///' + matrix_mautrix_telegram_sqlite_database_path_in_container), + 'postgres': matrix_mautrix_telegram_database_connection_string, + }[matrix_mautrix_telegram_database_engine] +}}" + + # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mautrix_telegram_login_shared_secret: '' diff --git a/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml index 9dc38ec2..e9a93c72 100644 --- a/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml @@ -8,6 +8,32 @@ The matrix-bridge-mautrix-telegram role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" +- set_fact: + matrix_mautrix_telegram_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mautrix_telegram_sqlite_database_path_local }}" + register: matrix_mautrix_telegram_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mautrix_telegram_sqlite_database_path_local }}" + dst: "{{ matrix_mautrix_telegram_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mautrix_telegram_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mautrix-telegram.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mautrix_telegram_requires_restart: true + when: "matrix_mautrix_telegram_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mautrix_telegram_database_engine == 'postgres'" + - name: Ensure Mautrix Telegram image is pulled docker_image: name: "{{ matrix_mautrix_telegram_docker_image }}" @@ -71,3 +97,9 @@ service: daemon_reload: yes when: "matrix_mautrix_telegram_systemd_service_result.changed" + +- name: Ensure matrix-mautrix-telegram.service restarted, if necessary + service: + name: "matrix-mautrix-telegram.service" + state: restarted + when: "matrix_mautrix_telegram_requires_restart|bool" diff --git a/roles/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 b/roles/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 index 1a4ac43e..52efba02 100644 --- a/roles/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 @@ -27,7 +27,7 @@ appservice: # Format examples: # SQLite: sqlite:///filename.db # Postgres: postgres://username:password@hostname/dbname - database: sqlite:////data/mautrix-telegram.db + database: {{ matrix_mautrix_telegram_appservice_database|to_json }} # Public part of web server for out-of-Matrix interaction with the bridge. # Used for things like login if the user wants to make sure the 2FA password isn't stored in diff --git a/roles/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 b/roles/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 index c0fb8938..d61cdaa4 100644 --- a/roles/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 +++ b/roles/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mautrix_telegram_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml b/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml index e9929f96..beda6d7d 100644 --- a/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml @@ -27,6 +27,42 @@ matrix_mautrix_whatsapp_systemd_wanted_services_list: [] matrix_mautrix_whatsapp_appservice_token: '' matrix_mautrix_whatsapp_homeserver_token: '' + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_mautrix_whatsapp_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_mautrix_whatsapp_postgres_*` variables +matrix_mautrix_whatsapp_database_engine: 'sqlite' + +matrix_mautrix_whatsapp_sqlite_database_path_local: "{{ matrix_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" +matrix_mautrix_whatsapp_sqlite_database_path_in_container: "/data/mautrix-whatsapp.db" + +matrix_mautrix_whatsapp_database_username: 'matrix_mautrix_whatsapp' +matrix_mautrix_whatsapp_database_password: 'some-password' +matrix_mautrix_whatsapp_database_hostname: 'matrix-postgres' +matrix_mautrix_whatsapp_database_port: 5432 +matrix_mautrix_whatsapp_database_name: 'matrix_mautrix_whatsapp' + +matrix_mautrix_whatsapp_database_connection_string: 'postgresql://{{ matrix_mautrix_whatsapp_database_username }}:{{ matrix_mautrix_whatsapp_database_password }}@{{ matrix_mautrix_whatsapp_database_hostname }}:{{ matrix_mautrix_whatsapp_database_port }}/{{ matrix_mautrix_whatsapp_database_name }}?sslmode=disable' + +matrix_mautrix_whatsapp_appservice_database_type: "{{ + { + 'sqlite': 'sqlite3', + 'postgres':'postgres', + }[matrix_mautrix_whatsapp_database_engine] +}}" + +matrix_mautrix_whatsapp_appservice_database_uri: "{{ + { + 'sqlite': matrix_mautrix_whatsapp_sqlite_database_path_in_container, + 'postgres': matrix_mautrix_whatsapp_database_connection_string, + }[matrix_mautrix_whatsapp_database_engine] +}}" + + # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mautrix_whatsapp_login_shared_secret: '' diff --git a/roles/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml index 6bd87bbe..1cfa60f8 100644 --- a/roles/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml @@ -8,6 +8,32 @@ The matrix-bridge-mautrix-whatsapp role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" +- set_fact: + matrix_mautrix_whatsapp_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mautrix_whatsapp_sqlite_database_path_local }}" + register: matrix_mautrix_whatsapp_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mautrix_whatsapp_sqlite_database_path_local }}" + dst: "{{ matrix_mautrix_whatsapp_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mautrix_whatsapp_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mautrix-whatsapp.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mautrix_whatsapp_requires_restart: true + when: "matrix_mautrix_whatsapp_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mautrix_whatsapp_database_engine == 'postgres'" + - name: Ensure Mautrix Whatsapp image is pulled docker_image: name: "{{ matrix_mautrix_whatsapp_docker_image }}" @@ -26,12 +52,12 @@ - "{{ matrix_mautrix_whatsapp_base_path }}" - "{{ matrix_mautrix_whatsapp_config_path }}" - "{{ matrix_mautrix_whatsapp_data_path }}" - + - name: Check if an old database file exists stat: path: "{{ matrix_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db" register: matrix_mautrix_whatsapp_stat_database - + - name: Check if an old matrix state file exists stat: path: "{{ matrix_mautrix_whatsapp_base_path }}/mx-state.json" @@ -48,7 +74,7 @@ - name: (Data relocation) Move mautrix-whatsapp database file to ./data directory command: "mv {{ matrix_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db {{ matrix_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" when: "matrix_mautrix_whatsapp_stat_database.stat.exists" - + - name: (Data relocation) Move mautrix-whatsapp mx-state file to ./data directory command: "mv {{ matrix_mautrix_whatsapp_base_path }}/mx-state.json {{ matrix_mautrix_whatsapp_data_path }}/mx-state.json" when: "matrix_mautrix_whatsapp_stat_mx_state.stat.exists" @@ -80,3 +106,9 @@ service: daemon_reload: yes when: "matrix_mautrix_whatsapp_systemd_service_result.changed" + +- name: Ensure matrix-mautrix-whatsapp.service restarted, if necessary + service: + name: "matrix-mautrix-whatsapp.service" + state: restarted + when: "matrix_mautrix_whatsapp_requires_restart|bool" diff --git a/roles/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 b/roles/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 index a527a188..89216695 100644 --- a/roles/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 @@ -19,11 +19,11 @@ appservice: # Database config. database: # The database type. "sqlite3" and "postgres" are supported. - type: sqlite3 + type: {{ matrix_mautrix_whatsapp_appservice_database_type|to_json }} # The database URI. # SQLite: File name is enough. https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database - uri: mautrix-whatsapp.db + uri: {{ matrix_mautrix_whatsapp_appservice_database_uri|to_json }} # Maximum number of connections. Mostly relevant for Postgres. max_open_conns: 20 max_idle_conns: 2 diff --git a/roles/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 b/roles/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 index ac2b961e..972d4e01 100644 --- a/roles/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 +++ b/roles/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mautrix_whatsapp_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml b/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml index 12c597d4..97b20313 100644 --- a/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml @@ -4,13 +4,15 @@ matrix_mx_puppet_discord_enabled: true matrix_mx_puppet_discord_container_image_self_build: false +matrix_mx_puppet_discord_container_image_self_build_repo: "https://github.com/matrix-discord/mx-puppet-discord.git" # Controls whether the mx-puppet-discord container exposes its HTTP port (tcp/8432 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8432"), or empty string to not expose. matrix_mx_puppet_discord_container_http_host_bind_port: '' -matrix_mx_puppet_discord_docker_image: "sorunome/mx-puppet-discord:latest" +matrix_mx_puppet_discord_docker_image: "{{ matrix_mx_puppet_discord_docker_image_name_prefix }}sorunome/mx-puppet-discord:latest" +matrix_mx_puppet_discord_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_discord_container_image_self_build else 'docker.io/' }}" matrix_mx_puppet_discord_docker_image_force_pull: "{{ matrix_mx_puppet_discord_docker_image.endswith(':latest') }}" matrix_mx_puppet_discord_base_path: "{{ matrix_base_data_path }}/mx-puppet-discord" @@ -53,6 +55,20 @@ matrix_mx_puppet_discord_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mx_puppet_discord_login_shared_secret: '' +# Database configuration +matrix_mx_puppet_discord_database_engine: 'sqlite' + +matrix_mx_puppet_discord_sqlite_database_path_local: "{{ matrix_mx_puppet_discord_data_path }}/database.db" +matrix_mx_puppet_discord_sqlite_database_path_in_container: "/data/database.db" + +matrix_mx_puppet_discord_database_username: matrix_mx_puppet_discord +matrix_mx_puppet_discord_database_password: ~ +matrix_mx_puppet_discord_database_hostname: 'matrix-postgres' +matrix_mx_puppet_discord_database_port: 5432 +matrix_mx_puppet_discord_database_name: matrix_mx_puppet_discord + +matrix_mx_puppet_discord_database_connection_string: 'postgresql://{{ matrix_mx_puppet_discord_database_username }}:{{ matrix_mx_puppet_discord_database_password }}@{{ matrix_mx_puppet_discord_database_hostname }}:{{ matrix_mx_puppet_discord_database_port }}/{{ matrix_mx_puppet_discord_database_name }}?sslmode=disable' + # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-bridge-mx-puppet-discord/tasks/setup_install.yml b/roles/matrix-bridge-mx-puppet-discord/tasks/setup_install.yml index e1aef147..c7865e98 100644 --- a/roles/matrix-bridge-mx-puppet-discord/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-discord/tasks/setup_install.yml @@ -8,14 +8,6 @@ The matrix-bridge-mx-puppet-discord role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" -- name: Ensure MX Puppet Discord image is pulled - docker_image: - name: "{{ matrix_mx_puppet_discord_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mx_puppet_discord_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_mx_puppet_discord_docker_image_force_pull }}" - when: matrix_mx_puppet_discord_enabled|bool and not matrix_mx_puppet_discord_container_image_self_build - - name: Ensure MX Puppet Discord paths exist file: path: "{{ item.path }}" @@ -30,39 +22,75 @@ - { path: "{{ matrix_mx_puppet_discord_docker_src_files_path }}", when: "{{ matrix_mx_puppet_discord_container_image_self_build }}" } when: matrix_mx_puppet_discord_enabled|bool and item.when|bool +- name: Check if an old database file already exists + stat: + path: "{{ matrix_mx_puppet_discord_base_path }}/database.db" + register: matrix_mx_puppet_discord_stat_database + +- block: + - name: (Data relocation) Ensure matrix-mx-puppet-discord.service is stopped + service: + name: matrix-mx-puppet-discord + state: stopped + daemon_reload: yes + failed_when: False + + - name: (Data relocation) Move mx-puppet-discord database file to ./data directory + command: "mv {{ matrix_mx_puppet_discord_base_path }}/database.db {{ matrix_mx_puppet_discord_data_path }}/database.db" + when: "matrix_mx_puppet_discord_stat_database.stat.exists" + +- set_fact: + matrix_mx_puppet_discord_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mx_puppet_discord_sqlite_database_path_local }}" + register: matrix_mx_puppet_discord_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mx_puppet_discord_sqlite_database_path_local }}" + dst: "{{ matrix_mx_puppet_discord_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mx_puppet_discord_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mx-puppet-discord.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mx_puppet_discord_requires_restart: true + when: "matrix_mx_puppet_discord_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mx_puppet_discord_database_engine == 'postgres'" + +- name: Ensure MX Puppet Discord image is pulled + docker_image: + name: "{{ matrix_mx_puppet_discord_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_mx_puppet_discord_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_mx_puppet_discord_docker_image_force_pull }}" + when: matrix_mx_puppet_discord_enabled|bool and not matrix_mx_puppet_discord_container_image_self_build + - name: Ensure MX Puppet Discord repository is present on self build git: - repo: https://github.com/matrix-discord/mx-puppet-discord.git + repo: "{{ matrix_mx_puppet_discord_container_image_self_build_repo }}" dest: "{{ matrix_mx_puppet_discord_docker_src_files_path }}" force: "yes" + register: matrix_mx_puppet_discord_git_pull_results when: "matrix_mx_puppet_discord_enabled|bool and matrix_mx_puppet_discord_container_image_self_build" - name: Ensure MX Puppet Discord Docker image is built docker_image: name: "{{ matrix_mx_puppet_discord_docker_image }}" source: build + force_source: "{{ matrix_mx_puppet_discord_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_discord_docker_src_files_path }}" pull: yes - when: "matrix_mx_puppet_discord_enabled|bool and matrix_mx_puppet_discord_container_image_self_build" - -- name: Check if an old database file already exists - stat: - path: "{{ matrix_mx_puppet_discord_base_path }}/database.db" - register: matrix_mx_puppet_discord_stat_database - -- name: (Data relocation) Ensure matrix-mx-puppet-discord.service is stopped - service: - name: matrix-mx-puppet-discord - state: stopped - daemon_reload: yes - failed_when: false - when: "matrix_mx_puppet_discord_stat_database.stat.exists" - -- name: (Data relocation) Move mx-puppet-discord database file to ./data directory - command: "mv {{ matrix_mx_puppet_discord_base_path }}/database.db {{ matrix_mx_puppet_discord_data_path }}/database.db" - when: "matrix_mx_puppet_discord_stat_database.stat.exists" + when: "matrix_mx_puppet_discord_enabled|bool and matrix_mx_puppet_discord_container_image_self_build|bool" - name: Ensure mx-puppet-discord config.yaml installed copy: @@ -91,3 +119,9 @@ service: daemon_reload: yes when: "matrix_mx_puppet_discord_systemd_service_result.changed" + +- name: Ensure matrix-mx-puppet-discord.service restarted, if necessary + service: + name: "matrix-mx-puppet-discord.service" + state: restarted + when: "matrix_mx_puppet_discord_requires_restart|bool" diff --git a/roles/matrix-bridge-mx-puppet-discord/templates/config.yaml.j2 b/roles/matrix-bridge-mx-puppet-discord/templates/config.yaml.j2 index 2c703796..1f4548d8 100644 --- a/roles/matrix-bridge-mx-puppet-discord/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mx-puppet-discord/templates/config.yaml.j2 @@ -100,15 +100,18 @@ namePatterns: group: :name database: +{% if matrix_mx_puppet_discord_database_engine == 'sqlite' %} + # Use SQLite3 as a database backend + # The name of the database file + filename: {{ matrix_mx_puppet_discord_sqlite_database_path_in_container|to_json }} +{% else %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - #connString: "postgres://user:pass@localhost/dbname?sslmode=disable" - # Use SQLite3 as a database backend - # The name of the database file - filename: /data/database.db + connString: {{ matrix_mx_puppet_discord_database_connection_string|to_json }} +{% endif %} logging: # Log level of console output diff --git a/roles/matrix-bridge-mx-puppet-discord/templates/systemd/matrix-mx-puppet-discord.service.j2 b/roles/matrix-bridge-mx-puppet-discord/templates/systemd/matrix-mx-puppet-discord.service.j2 index 78737a17..36a4da8b 100644 --- a/roles/matrix-bridge-mx-puppet-discord/templates/systemd/matrix-mx-puppet-discord.service.j2 +++ b/roles/matrix-bridge-mx-puppet-discord/templates/systemd/matrix-mx-puppet-discord.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mx_puppet_discord_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml b/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml index c7488cbb..cd08c010 100644 --- a/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml @@ -4,8 +4,10 @@ matrix_mx_puppet_instagram_enabled: true matrix_mx_puppet_instagram_container_image_self_build: false +matrix_mx_puppet_instagram_container_image_self_build_repo: "https://github.com/Sorunome/mx-puppet-instagram.git" -matrix_mx_puppet_instagram_docker_image: "docker.io/sorunome/mx-puppet-instagram:latest" +matrix_mx_puppet_instagram_docker_image: "{{ matrix_mx_puppet_instagram_docker_image_name_prefix }}sorunome/mx-puppet-instagram:latest" +matrix_mx_puppet_instagram_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_instagram_container_image_self_build else 'docker.io/' }}" matrix_mx_puppet_instagram_docker_image_force_pull: "{{ matrix_mx_puppet_instagram_docker_image.endswith(':latest') }}" matrix_mx_puppet_instagram_base_path: "{{ matrix_base_data_path }}/mx-puppet-instagram" @@ -44,6 +46,19 @@ matrix_mx_puppet_instagram_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mx_puppet_instagram_login_shared_secret: '' +matrix_mx_puppet_instagram_database_engine: sqlite + +matrix_mx_puppet_instagram_sqlite_database_path_local: "{{ matrix_mx_puppet_instagram_data_path }}/database.db" +matrix_mx_puppet_instagram_sqlite_database_path_in_container: "/data/database.db" + +matrix_mx_puppet_instagram_database_username: matrix_mx_puppet_instagram +matrix_mx_puppet_instagram_database_password: ~ +matrix_mx_puppet_instagram_database_hostname: 'matrix-postgres' +matrix_mx_puppet_instagram_database_port: 5432 +matrix_mx_puppet_instagram_database_name: matrix_mx_puppet_instagram + +matrix_mx_puppet_instagram_database_connection_string: 'postgresql://{{ matrix_mx_puppet_instagram_database_username }}:{{ matrix_mx_puppet_instagram_database_password }}@{{ matrix_mx_puppet_instagram_database_hostname }}:{{ matrix_mx_puppet_instagram_database_port }}/{{ matrix_mx_puppet_instagram_database_name }}?sslmode=disable' + # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-bridge-mx-puppet-instagram/tasks/setup_install.yml b/roles/matrix-bridge-mx-puppet-instagram/tasks/setup_install.yml index d60fbaf2..5701a916 100644 --- a/roles/matrix-bridge-mx-puppet-instagram/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-instagram/tasks/setup_install.yml @@ -8,6 +8,33 @@ The matrix-bridge-mx-puppet-instagram role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" + +- set_fact: + matrix_mx_puppet_instagram_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mx_puppet_instagram_sqlite_database_path_local }}" + register: matrix_mx_puppet_instagram_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mx_puppet_instagram_sqlite_database_path_local }}" + dst: "{{ matrix_mx_puppet_instagram_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mx_puppet_instagram_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mx-puppet-instagram.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mx_puppet_instagram_requires_restart: true + when: "matrix_mx_puppet_instagram_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mx_puppet_instagram_database_engine == 'postgres'" + - name: Ensure mx-puppet-instagram image is pulled docker_image: name: "{{ matrix_mx_puppet_instagram_docker_image }}" @@ -32,20 +59,22 @@ - name: Ensure mx-puppet-instagram repository is present on self build git: - repo: https://github.com/Sorunome/mx-puppet-instagram.git + repo: "{{ matrix_mx_puppet_instagram_container_image_self_build_repo }}" dest: "{{ matrix_mx_puppet_instagram_docker_src_files_path }}" force: "yes" - when: "matrix_mx_puppet_instagram_enabled|bool and matrix_mx_puppet_instagram_container_image_self_build" + register: matrix_mx_puppet_instagram_git_pull_results + when: "matrix_mx_puppet_instagram_enabled|bool and matrix_mx_puppet_instagram_container_image_self_build|bool" - name: Ensure mx-puppet-instagram Docker image is built docker_image: name: "{{ matrix_mx_puppet_instagram_docker_image }}" source: build + force_source: "{{ matrix_mx_puppet_instagram_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_instagram_docker_src_files_path }}" pull: yes - when: "matrix_mx_puppet_instagram_enabled|bool and matrix_mx_puppet_instagram_container_image_self_build" + when: "matrix_mx_puppet_instagram_enabled|bool and matrix_mx_puppet_instagram_container_image_self_build|bool" - name: Ensure mx-puppet-instagram config.yaml installed copy: @@ -75,4 +104,8 @@ daemon_reload: yes when: "matrix_mx_puppet_instagram_systemd_service_result.changed" - +- name: Ensure matrix-mx-puppet-instagram.service restarted, if necessary + service: + name: "matrix-mx-puppet-instagram.service" + state: restarted + when: "matrix_mx_puppet_instagram_requires_restart|bool" diff --git a/roles/matrix-bridge-mx-puppet-instagram/templates/config.yaml.j2 b/roles/matrix-bridge-mx-puppet-instagram/templates/config.yaml.j2 index 634fbaec..b830da2b 100644 --- a/roles/matrix-bridge-mx-puppet-instagram/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mx-puppet-instagram/templates/config.yaml.j2 @@ -44,15 +44,18 @@ provisioning: apiPrefix: /_matrix/provision database: +{% if matrix_mx_puppet_instagram_database_engine == 'postgres' %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - #connString: "postgres://user:pass@localhost/dbname?sslmode=disable" + connString: {{ matrix_mx_puppet_instagram_database_connection_string|to_json }} +{% else %} # Use SQLite3 as a database backend # The name of the database file - filename: /data/database.db + filename: {{ matrix_mx_puppet_instagram_sqlite_database_path_in_container|to_json }} +{% endif %} logging: # Log level of console output diff --git a/roles/matrix-bridge-mx-puppet-instagram/templates/systemd/matrix-mx-puppet-instagram.service.j2 b/roles/matrix-bridge-mx-puppet-instagram/templates/systemd/matrix-mx-puppet-instagram.service.j2 index 81e3e081..4c94c84a 100644 --- a/roles/matrix-bridge-mx-puppet-instagram/templates/systemd/matrix-mx-puppet-instagram.service.j2 +++ b/roles/matrix-bridge-mx-puppet-instagram/templates/systemd/matrix-mx-puppet-instagram.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mx_puppet_instagram_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml b/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml index 8b977acf..83cd3dc5 100644 --- a/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml @@ -4,8 +4,10 @@ matrix_mx_puppet_skype_enabled: true matrix_mx_puppet_skype_container_image_self_build: false +matrix_mx_puppet_skype_container_image_self_build_repo: "https://github.com/Sorunome/mx-puppet-skype.git" -matrix_mx_puppet_skype_docker_image: "sorunome/mx-puppet-skype:latest" +matrix_mx_puppet_skype_docker_image: "{{ matrix_mx_puppet_skype_docker_image_name_prefix }}sorunome/mx-puppet-skype:latest" +matrix_mx_puppet_skype_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_skype_container_image_self_build else 'docker.io/' }}" matrix_mx_puppet_skype_docker_image_force_pull: "{{ matrix_mx_puppet_skype_docker_image.endswith(':latest') }}" matrix_mx_puppet_skype_base_path: "{{ matrix_base_data_path }}/mx-puppet-skype" @@ -51,6 +53,20 @@ matrix_mx_puppet_skype_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mx_puppet_skype_login_shared_secret: '' +# Database configuration, role default is `sqlite` but playbook default is `postgres` +matrix_mx_puppet_skype_database_engine: sqlite + +matrix_mx_puppet_skype_sqlite_database_path_local: "{{ matrix_mx_puppet_skype_data_path }}/database.db" +matrix_mx_puppet_skype_sqlite_database_path_in_container: "/data/database.db" + +matrix_mx_puppet_skype_database_username: matrix_mx_puppet_skype +matrix_mx_puppet_skype_database_password: ~ +matrix_mx_puppet_skype_database_hostname: 'matrix-postgres' +matrix_mx_puppet_skype_database_port: 5432 +matrix_mx_puppet_skype_database_name: matrix_mx_puppet_skype + +matrix_mx_puppet_skype_database_connection_string: 'postgresql://{{ matrix_mx_puppet_skype_database_username }}:{{ matrix_mx_puppet_skype_database_password }}@{{ matrix_mx_puppet_skype_database_hostname }}:{{ matrix_mx_puppet_skype_database_port }}/{{ matrix_mx_puppet_skype_database_name }}?sslmode=disable' + # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-bridge-mx-puppet-skype/tasks/setup_install.yml b/roles/matrix-bridge-mx-puppet-skype/tasks/setup_install.yml index 1febca3e..68a1d7f4 100644 --- a/roles/matrix-bridge-mx-puppet-skype/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-skype/tasks/setup_install.yml @@ -8,14 +8,6 @@ The matrix-bridge-mx-puppet-skype role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" -- name: Ensure MX Puppet Skype image is pulled - docker_image: - name: "{{ matrix_mx_puppet_skype_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mx_puppet_skype_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_mx_puppet_skype_docker_image_force_pull }}" - when: matrix_mx_puppet_skype_enabled|bool and not matrix_mx_puppet_skype_container_image_self_build - - name: Ensure MX Puppet Skype paths exist file: path: "{{ item.path }}" @@ -30,25 +22,6 @@ - { path: "{{ matrix_mx_puppet_skype_docker_src_files_path }}", when: "{{ matrix_mx_puppet_skype_container_image_self_build }}" } when: matrix_mx_puppet_skype_enabled|bool and item.when|bool -- name: Ensure MX Puppet Skype repository is present on self build - git: - repo: https://github.com/Sorunome/mx-puppet-skype.git - dest: "{{ matrix_mx_puppet_skype_docker_src_files_path }}" - force: "yes" - register: matrix_mx_puppet_skype_git_pull_results - when: "matrix_mx_puppet_skype_enabled|bool and matrix_mx_puppet_skype_container_image_self_build" - -- name: Ensure MX Puppet Skype Docker image is built - docker_image: - name: "{{ matrix_mx_puppet_skype_docker_image }}" - source: build - force_source: yes - build: - dockerfile: Dockerfile - path: "{{ matrix_mx_puppet_skype_docker_src_files_path }}" - pull: yes - when: "matrix_mx_puppet_skype_enabled|bool and matrix_mx_puppet_skype_container_image_self_build and matrix_mx_puppet_skype_git_pull_results.changed" - - name: Check if an old database file already exists stat: path: "{{ matrix_mx_puppet_skype_base_path }}/database.db" @@ -66,6 +39,59 @@ command: "mv {{ matrix_mx_puppet_skype_base_path }}/database.db {{ matrix_mx_puppet_skype_data_path }}/database.db" when: "matrix_mx_puppet_skype_stat_database.stat.exists" +- set_fact: + matrix_mx_puppet_skype_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mx_puppet_skype_sqlite_database_path_local }}" + register: matrix_mx_puppet_skype_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mx_puppet_skype_sqlite_database_path_local }}" + dst: "{{ matrix_mx_puppet_skype_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mx_puppet_skype_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mx-puppet-skype.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mx_puppet_skype_requires_restart: true + when: "matrix_mx_puppet_skype_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mx_puppet_skype_database_engine == 'postgres'" + +- name: Ensure MX Puppet Skype image is pulled + docker_image: + name: "{{ matrix_mx_puppet_skype_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_mx_puppet_skype_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_mx_puppet_skype_docker_image_force_pull }}" + when: matrix_mx_puppet_skype_enabled|bool and not matrix_mx_puppet_skype_container_image_self_build + +- name: Ensure MX Puppet Skype repository is present on self build + git: + repo: "{{ matrix_mx_puppet_skype_container_image_self_build_repo }}" + dest: "{{ matrix_mx_puppet_skype_docker_src_files_path }}" + force: "yes" + register: matrix_mx_puppet_skype_git_pull_results + when: "matrix_mx_puppet_skype_enabled|bool and matrix_mx_puppet_skype_container_image_self_build|bool" + +- name: Ensure MX Puppet Skype Docker image is built + docker_image: + name: "{{ matrix_mx_puppet_skype_docker_image }}" + source: build + force_source: "{{ matrix_mx_puppet_skype_git_pull_results.changed }}" + build: + dockerfile: Dockerfile + path: "{{ matrix_mx_puppet_skype_docker_src_files_path }}" + pull: yes + when: "matrix_mx_puppet_skype_enabled|bool and matrix_mx_puppet_skype_container_image_self_build|bool" + - name: Ensure mx-puppet-skype config.yaml installed copy: content: "{{ matrix_mx_puppet_skype_configuration|to_nice_yaml }}" @@ -93,3 +119,9 @@ service: daemon_reload: yes when: "matrix_mx_puppet_skype_systemd_service_result.changed" + +- name: Ensure matrix-mx-puppet-skype.service restarted, if necessary + service: + name: "matrix-mx-puppet-skype.service" + state: restarted + when: "matrix_mx_puppet_skype_requires_restart|bool" diff --git a/roles/matrix-bridge-mx-puppet-skype/templates/config.yaml.j2 b/roles/matrix-bridge-mx-puppet-skype/templates/config.yaml.j2 index c7b5c870..d41d3a23 100644 --- a/roles/matrix-bridge-mx-puppet-skype/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mx-puppet-skype/templates/config.yaml.j2 @@ -68,15 +68,18 @@ logging: # - Store database: +{% if matrix_mx_puppet_skype_database_engine == 'postgres' %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - #connString: "postgres://user:pass@localhost/dbname?sslmode=disable" + connString: {{ matrix_mx_puppet_skype_database_connection_string|to_json }} +{% else %} # Use SQLite3 as a database backend # The name of the database file - filename: /data/database.db + filename: {{ matrix_mx_puppet_skype_sqlite_database_path_in_container|to_json }} +{% endif %} provisioning: # Regex of Matrix IDs allowed to use the puppet bridge diff --git a/roles/matrix-bridge-mx-puppet-skype/templates/systemd/matrix-mx-puppet-skype.service.j2 b/roles/matrix-bridge-mx-puppet-skype/templates/systemd/matrix-mx-puppet-skype.service.j2 index 8a46cb25..cd958662 100644 --- a/roles/matrix-bridge-mx-puppet-skype/templates/systemd/matrix-mx-puppet-skype.service.j2 +++ b/roles/matrix-bridge-mx-puppet-skype/templates/systemd/matrix-mx-puppet-skype.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mx_puppet_skype_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml b/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml index 6acfb714..70b98ece 100644 --- a/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml @@ -4,13 +4,15 @@ matrix_mx_puppet_slack_enabled: true matrix_mx_puppet_slack_container_image_self_build: false +matrix_mx_puppet_slack_container_image_self_build_repo: "https://github.com/Sorunome/mx-puppet-slack.git" # Controls whether the mx-puppet-slack container exposes its HTTP port (tcp/8432 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8432"), or empty string to not expose. matrix_mx_puppet_slack_container_http_host_bind_port: '' -matrix_mx_puppet_slack_docker_image: "sorunome/mx-puppet-slack:latest" +matrix_mx_puppet_slack_docker_image: "{{ matrix_mx_puppet_slack_docker_image_name_prefix }}sorunome/mx-puppet-slack:latest" +matrix_mx_puppet_slack_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_slack_container_image_self_build else 'docker.io/' }}" matrix_mx_puppet_slack_docker_image_force_pull: "{{ matrix_mx_puppet_slack_docker_image.endswith(':latest') }}" matrix_mx_puppet_slack_base_path: "{{ matrix_base_data_path }}/mx-puppet-slack" @@ -55,6 +57,20 @@ matrix_mx_puppet_slack_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mx_puppet_slack_login_shared_secret: '' +# Database configuration, role uses 'sqlite' per default but playbook sets up postgres by default +matrix_mx_puppet_slack_database_engine: sqlite + +matrix_mx_puppet_slack_sqlite_database_path_local: "{{ matrix_mx_puppet_slack_data_path }}/database.db" +matrix_mx_puppet_slack_sqlite_database_path_in_container: "/data/database.db" + +matrix_mx_puppet_slack_database_username: matrix_mx_puppet_slack +matrix_mx_puppet_slack_database_password: ~ +matrix_mx_puppet_slack_database_hostname: 'matrix-postgres' +matrix_mx_puppet_slack_database_port: 5432 +matrix_mx_puppet_slack_database_name: matrix_mx_puppet_slack + +matrix_mx_puppet_slack_database_connection_string: 'postgresql://{{ matrix_mx_puppet_slack_database_username }}:{{ matrix_mx_puppet_slack_database_password }}@{{ matrix_mx_puppet_slack_database_hostname }}:{{ matrix_mx_puppet_slack_database_port }}/{{ matrix_mx_puppet_slack_database_name }}?sslmode=disable' + # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-bridge-mx-puppet-slack/tasks/setup_install.yml b/roles/matrix-bridge-mx-puppet-slack/tasks/setup_install.yml index ddaede72..04eab20a 100644 --- a/roles/matrix-bridge-mx-puppet-slack/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-slack/tasks/setup_install.yml @@ -8,14 +8,6 @@ The matrix-bridge-mx-puppet-slack role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" -- name: Ensure MX Puppet Slack image is pulled - docker_image: - name: "{{ matrix_mx_puppet_slack_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mx_puppet_slack_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_mx_puppet_slack_docker_image_force_pull }}" - when: matrix_mx_puppet_slack_enabled|bool and not matrix_mx_puppet_slack_container_image_self_build - - name: Ensure MX Puppet Slack paths exist file: path: "{{ item.path }}" @@ -30,23 +22,6 @@ - { path: "{{ matrix_mx_puppet_slack_docker_src_files_path }}", when: "{{ matrix_mx_puppet_slack_container_image_self_build }}" } when: matrix_mx_puppet_slack_enabled|bool and item.when|bool -- name: Ensure MX Puppet Slack repository is present on self build - git: - repo: https://github.com/Sorunome/mx-puppet-slack.git - dest: "{{ matrix_mx_puppet_slack_docker_src_files_path }}" - force: "yes" - when: "matrix_mx_puppet_slack_enabled|bool and matrix_mx_puppet_slack_container_image_self_build" - -- name: Ensure MX Puppet Slack Docker image is built - docker_image: - name: "{{ matrix_mx_puppet_slack_docker_image }}" - source: build - build: - dockerfile: Dockerfile - path: "{{ matrix_mx_puppet_slack_docker_src_files_path }}" - pull: yes - when: "matrix_mx_puppet_slack_enabled|bool and matrix_mx_puppet_slack_container_image_self_build" - - name: Check if an old database file already exists stat: path: "{{ matrix_mx_puppet_slack_base_path }}/database.db" @@ -60,6 +35,59 @@ failed_when: false when: "matrix_mx_puppet_slack_stat_database.stat.exists" +- set_fact: + matrix_mx_puppet_slack_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mx_puppet_slack_sqlite_database_path_local }}" + register: matrix_mx_puppet_slack_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mx_puppet_slack_sqlite_database_path_local }}" + dst: "{{ matrix_mx_puppet_slack_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mx_puppet_slack_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mx-puppet-slack.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mx_puppet_slack_requires_restart: true + when: "matrix_mx_puppet_slack_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mx_puppet_slack_database_engine == 'postgres'" + +- name: Ensure MX Puppet Slack image is pulled + docker_image: + name: "{{ matrix_mx_puppet_slack_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_mx_puppet_slack_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_mx_puppet_slack_docker_image_force_pull }}" + when: matrix_mx_puppet_slack_enabled|bool and not matrix_mx_puppet_slack_container_image_self_build + +- name: Ensure MX Puppet Slack repository is present on self build + git: + repo: "{{ matrix_mx_puppet_slack_container_image_self_build_repo }}" + dest: "{{ matrix_mx_puppet_slack_docker_src_files_path }}" + force: "yes" + register: matrix_mx_puppet_slack_git_pull_results + when: "matrix_mx_puppet_slack_enabled|bool and matrix_mx_puppet_slack_container_image_self_build" + +- name: Ensure MX Puppet Slack Docker image is built + docker_image: + name: "{{ matrix_mx_puppet_slack_docker_image }}" + source: build + force_source: "{{ matrix_mx_puppet_slack_git_pull_results.changed }}" + build: + dockerfile: Dockerfile + path: "{{ matrix_mx_puppet_slack_docker_src_files_path }}" + pull: yes + when: "matrix_mx_puppet_slack_enabled|bool and matrix_mx_puppet_slack_container_image_self_build" + - name: (Data relocation) Move mx-puppet-slack database file to ./data directory command: "mv {{ matrix_mx_puppet_slack_base_path }}/database.db {{ matrix_mx_puppet_slack_data_path }}/database.db" when: "matrix_mx_puppet_slack_stat_database.stat.exists" @@ -91,3 +119,9 @@ service: daemon_reload: yes when: "matrix_mx_puppet_slack_systemd_service_result.changed" + +- name: Ensure matrix-mx-puppet-slack.service restarted, if necessary + service: + name: "matrix-mx-puppet-slack.service" + state: restarted + when: "matrix_mx_puppet_slack_requires_restart|bool" diff --git a/roles/matrix-bridge-mx-puppet-slack/templates/config.yaml.j2 b/roles/matrix-bridge-mx-puppet-slack/templates/config.yaml.j2 index b6e88784..af6b5cb8 100644 --- a/roles/matrix-bridge-mx-puppet-slack/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mx-puppet-slack/templates/config.yaml.j2 @@ -58,15 +58,18 @@ provisioning: apiPrefix: /_matrix/provision database: +{% if matrix_mx_puppet_slack_database_engine == 'postgres' %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - #connString: "postgres://user:pass@localhost/dbname?sslmode=disable" + connString: {{ matrix_mx_puppet_slack_database_connection_string|to_json }} +{% else %} # Use SQLite3 as a database backend # The name of the database file - filename: /data/database.db + filename: {{ matrix_mx_puppet_slack_sqlite_database_path_in_container|to_json }} +{% endif %} logging: # Log level of console output diff --git a/roles/matrix-bridge-mx-puppet-slack/templates/systemd/matrix-mx-puppet-slack.service.j2 b/roles/matrix-bridge-mx-puppet-slack/templates/systemd/matrix-mx-puppet-slack.service.j2 index 23c2504f..2b1456f5 100644 --- a/roles/matrix-bridge-mx-puppet-slack/templates/systemd/matrix-mx-puppet-slack.service.j2 +++ b/roles/matrix-bridge-mx-puppet-slack/templates/systemd/matrix-mx-puppet-slack.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mx_puppet_slack_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml b/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml index bea26d39..15fa889f 100644 --- a/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml @@ -4,13 +4,15 @@ matrix_mx_puppet_steam_enabled: true matrix_mx_puppet_steam_container_image_self_build: false +matrix_mx_puppet_steam_container_image_self_build_repo: "https://github.com/icewind1991/mx-puppet-steam.git" # Controls whether the mx-puppet-steam container exposes its HTTP port (tcp/8432 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8432"), or empty string to not expose. matrix_mx_puppet_steam_container_http_host_bind_port: '' -matrix_mx_puppet_steam_docker_image: "icewind1991/mx-puppet-steam:latest" +matrix_mx_puppet_steam_docker_image: "{{ matrix_mx_puppet_steam_docker_image_name_prefix }}icewind1991/mx-puppet-steam:latest" +matrix_mx_puppet_steam_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_steam_container_image_self_build else 'docker.io/' }}" matrix_mx_puppet_steam_docker_image_force_pull: "{{ matrix_mx_puppet_steam_docker_image.endswith(':latest') }}" matrix_mx_puppet_steam_base_path: "{{ matrix_base_data_path }}/mx-puppet-steam" @@ -53,6 +55,19 @@ matrix_mx_puppet_steam_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mx_puppet_steam_login_shared_secret: '' +matrix_mx_puppet_steam_database_engine: sqlite + +matrix_mx_puppet_steam_sqlite_database_path_local: "{{ matrix_mx_puppet_steam_data_path }}/database.db" +matrix_mx_puppet_steam_sqlite_database_path_in_container: "/data/database.db" + +matrix_mx_puppet_steam_database_username: matrix_mx_puppet_steam +matrix_mx_puppet_steam_database_password: ~ +matrix_mx_puppet_steam_database_hostname: 'matrix-postgres' +matrix_mx_puppet_steam_database_port: 5432 +matrix_mx_puppet_steam_database_name: matrix_mx_puppet_steam + +matrix_mx_puppet_steam_database_connection_string: 'postgresql://{{ matrix_mx_puppet_steam_database_username }}:{{ matrix_mx_puppet_steam_database_password }}@{{ matrix_mx_puppet_steam_database_hostname }}:{{ matrix_mx_puppet_steam_database_port }}/{{ matrix_mx_puppet_steam_database_name }}?sslmode=disable' + # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml b/roles/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml index be41c645..6b574656 100644 --- a/roles/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml @@ -8,14 +8,6 @@ The matrix-bridge-mx-puppet-steam role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" -- name: Ensure MX Puppet Steam image is pulled - docker_image: - name: "{{ matrix_mx_puppet_steam_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mx_puppet_steam_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_mx_puppet_steam_docker_image_force_pull }}" - when: matrix_mx_puppet_steam_enabled|bool and not matrix_mx_puppet_steam_container_image_self_build - - name: Ensure MX Puppet Steam paths exist file: path: "{{ item.path }}" @@ -30,23 +22,6 @@ - { path: "{{ matrix_mx_puppet_steam_docker_src_files_path }}", when: "{{ matrix_mx_puppet_steam_container_image_self_build }}" } when: matrix_mx_puppet_steam_enabled|bool and item.when|bool -- name: Ensure MX Puppet Steam repository is present on self build - git: - repo: https://github.com/icewind1991/mx-puppet-steam.git - dest: "{{ matrix_mx_puppet_steam_docker_src_files_path }}" - force: "yes" - when: "matrix_mx_puppet_steam_enabled|bool and matrix_mx_puppet_steam_container_image_self_build" - -- name: Ensure MX Puppet Steam Docker image is built - docker_image: - name: "{{ matrix_mx_puppet_steam_docker_image }}" - source: build - build: - dockerfile: Dockerfile - path: "{{ matrix_mx_puppet_steam_docker_src_files_path }}" - pull: yes - when: "matrix_mx_puppet_steam_enabled|bool and matrix_mx_puppet_steam_container_image_self_build" - - name: Check if an old database file already exists stat: path: "{{ matrix_mx_puppet_steam_base_path }}/database.db" @@ -64,6 +39,59 @@ command: "mv {{ matrix_mx_puppet_steam_base_path }}/database.db {{ matrix_mx_puppet_steam_data_path }}/database.db" when: "matrix_mx_puppet_steam_stat_database.stat.exists" +- set_fact: + matrix_mx_puppet_steam_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mx_puppet_steam_sqlite_database_path_local }}" + register: matrix_mx_puppet_steam_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mx_puppet_steam_sqlite_database_path_local }}" + dst: "{{ matrix_mx_puppet_steam_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mx_puppet_steam_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mx-puppet-steam.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mx_puppet_steam_requires_restart: true + when: "matrix_mx_puppet_steam_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mx_puppet_steam_database_engine == 'postgres'" + +- name: Ensure MX Puppet Steam image is pulled + docker_image: + name: "{{ matrix_mx_puppet_steam_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_mx_puppet_steam_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_mx_puppet_steam_docker_image_force_pull }}" + when: matrix_mx_puppet_steam_enabled|bool and not matrix_mx_puppet_steam_container_image_self_build + +- name: Ensure MX Puppet Steam repository is present on self build + git: + repo: "{{ matrix_mx_puppet_steam_container_image_self_build_repo }}" + dest: "{{ matrix_mx_puppet_steam_docker_src_files_path }}" + force: "yes" + register: matrix_mx_puppet_steam_git_pull_results + when: "matrix_mx_puppet_steam_enabled|bool and matrix_mx_puppet_steam_container_image_self_build" + +- name: Ensure MX Puppet Steam Docker image is built + docker_image: + name: "{{ matrix_mx_puppet_steam_docker_image }}" + source: build + force_source: "{{ matrix_mx_puppet_steam_git_pull_results.changed }}" + build: + dockerfile: Dockerfile + path: "{{ matrix_mx_puppet_steam_docker_src_files_path }}" + pull: yes + when: "matrix_mx_puppet_steam_enabled|bool and matrix_mx_puppet_steam_container_image_self_build" + - name: Ensure mx-puppet-steam config.yaml installed copy: content: "{{ matrix_mx_puppet_steam_configuration|to_nice_yaml }}" @@ -91,3 +119,9 @@ service: daemon_reload: yes when: "matrix_mx_puppet_steam_systemd_service_result.changed" + +- name: Ensure matrix-mx-puppet-steam.service restarted, if necessary + service: + name: "matrix-mx-puppet-steam.service" + state: restarted + when: "matrix_mx_puppet_steam_requires_restart|bool" diff --git a/roles/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 b/roles/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 index d08982ca..149e08b6 100644 --- a/roles/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 @@ -61,15 +61,18 @@ selfService: blacklist: {{ matrix_mx_puppet_steam_provisioning_blacklist|to_json }} database: +{% if matrix_mx_puppet_steam_database_engine == 'postgres' %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - #connString: "postgres://user:pass@localhost/dbname?sslmode=disable" + connString: {{ matrix_mx_puppet_steam_database_connection_string|to_json }} +{% else %} # Use SQLite3 as a database backend # The name of the database file - filename: /data/database.db + filename: {{ matrix_mx_puppet_steam_sqlite_database_path_in_container|to_json }} +{% endif %} logging: # Log level of console output diff --git a/roles/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 b/roles/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 index 986c5d2c..e263154b 100644 --- a/roles/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 +++ b/roles/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mx_puppet_steam_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml b/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml index 8299fd81..28639fda 100644 --- a/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml @@ -4,13 +4,15 @@ matrix_mx_puppet_twitter_enabled: true matrix_mx_puppet_twitter_container_image_self_build: false +matrix_mx_puppet_twitter_container_image_self_build_repo: "https://github.com/Sorunome/mx-puppet-twitter.git" # Controls whether the mx-puppet-twitter container exposes its HTTP port (tcp/8432 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8432"), or empty string to not expose. matrix_mx_puppet_twitter_container_http_host_bind_port: '' -matrix_mx_puppet_twitter_docker_image: "sorunome/mx-puppet-twitter:latest" +matrix_mx_puppet_twitter_docker_image: "{{ matrix_mx_puppet_twitter_docker_image_name_prefix }}sorunome/mx-puppet-twitter:latest" +matrix_mx_puppet_twitter_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_twitter_container_image_self_build else 'docker.io/' }}" matrix_mx_puppet_twitter_docker_image_force_pull: "{{ matrix_mx_puppet_twitter_docker_image.endswith(':latest') }}" matrix_mx_puppet_twitter_base_path: "{{ matrix_base_data_path }}/mx-puppet-twitter" @@ -58,6 +60,20 @@ matrix_mx_puppet_twitter_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). matrix_mx_puppet_twitter_login_shared_secret: '' +# Database configuration +matrix_mx_puppet_twitter_database_engine: sqlite + +matrix_mx_puppet_twitter_sqlite_database_path_local: "{{ matrix_mx_puppet_twitter_data_path }}/database.db" +matrix_mx_puppet_twitter_sqlite_database_path_in_container: "/data/database.db" + +matrix_mx_puppet_twitter_database_username: mx_puppet_twitter +matrix_mx_puppet_twitter_database_password: ~ +matrix_mx_puppet_twitter_database_hostname: 'matrix-postgres' +matrix_mx_puppet_twitter_database_port: 5432 +matrix_mx_puppet_twitter_database_name: matrix_mx_puppet_twitter + +matrix_mx_puppet_twitter_database_connection_string: 'postgresql://{{ matrix_mx_puppet_twitter_database_username }}:{{ matrix_mx_puppet_twitter_database_password }}@{{ matrix_mx_puppet_twitter_database_hostname }}:{{ matrix_mx_puppet_twitter_database_port }}/{{ matrix_mx_puppet_twitter_database_name }}?sslmode=disable' + # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-bridge-mx-puppet-twitter/tasks/setup_install.yml b/roles/matrix-bridge-mx-puppet-twitter/tasks/setup_install.yml index 4773055d..1c48c030 100644 --- a/roles/matrix-bridge-mx-puppet-twitter/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-twitter/tasks/setup_install.yml @@ -8,14 +8,6 @@ The matrix-bridge-mx-puppet-twitter role needs to execute before the matrix-synapse role. when: "matrix_synapse_role_executed|default(False)" -- name: Ensure MX Puppet Twitter image is pulled - docker_image: - name: "{{ matrix_mx_puppet_twitter_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mx_puppet_twitter_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_mx_puppet_twitter_docker_image_force_pull }}" - when: matrix_mx_puppet_twitter_enabled|bool and not matrix_mx_puppet_twitter_container_image_self_build - - name: Ensure MX Puppet Twitter paths exist file: path: "{{ item.path }}" @@ -30,23 +22,6 @@ - { path: "{{ matrix_mx_puppet_twitter_docker_src_files_path }}", when: "{{ matrix_mx_puppet_twitter_container_image_self_build }}" } when: matrix_mx_puppet_twitter_enabled|bool and item.when|bool -- name: Ensure MX Puppet Twitter repository is present on self build - git: - repo: https://github.com/Sorunome/mx-puppet-twitter.git - dest: "{{ matrix_mx_puppet_twitter_docker_src_files_path }}" - force: "yes" - when: "matrix_mx_puppet_twitter_enabled|bool and matrix_mx_puppet_twitter_container_image_self_build" - -- name: Ensure MX Puppet Twitter Docker image is built - docker_image: - name: "{{ matrix_mx_puppet_twitter_docker_image }}" - source: build - build: - dockerfile: Dockerfile - path: "{{ matrix_mx_puppet_twitter_docker_src_files_path }}" - pull: yes - when: "matrix_mx_puppet_twitter_enabled|bool and matrix_mx_puppet_twitter_container_image_self_build" - - name: Check if an old database file already exists stat: path: "{{ matrix_mx_puppet_twitter_base_path }}/database.db" @@ -64,6 +39,59 @@ command: "mv {{ matrix_mx_puppet_twitter_base_path }}/database.db {{ matrix_mx_puppet_twitter_data_path }}/database.db" when: "matrix_mx_puppet_twitter_stat_database.stat.exists" +- set_fact: + matrix_mx_puppet_twitter_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_mx_puppet_twitter_sqlite_database_path_local }}" + register: matrix_mx_puppet_twitter_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_mx_puppet_twitter_sqlite_database_path_local }}" + dst: "{{ matrix_mx_puppet_twitter_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_mx_puppet_twitter_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mx-puppet-twitter.service'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_mx_puppet_twitter_requires_restart: true + when: "matrix_mx_puppet_twitter_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_mx_puppet_twitter_database_engine == 'postgres'" + +- name: Ensure MX Puppet Twitter image is pulled + docker_image: + name: "{{ matrix_mx_puppet_twitter_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_mx_puppet_twitter_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_mx_puppet_twitter_docker_image_force_pull }}" + when: matrix_mx_puppet_twitter_enabled|bool and not matrix_mx_puppet_twitter_container_image_self_build + +- name: Ensure MX Puppet Twitter repository is present on self build + git: + repo: "{{ matrix_mx_puppet_twitter_container_image_self_build_repo }}" + dest: "{{ matrix_mx_puppet_twitter_docker_src_files_path }}" + force: "yes" + register: matrix_mx_puppet_twitter_git_pull_results + when: "matrix_mx_puppet_twitter_enabled|bool and matrix_mx_puppet_twitter_container_image_self_build" + +- name: Ensure MX Puppet Twitter Docker image is built + docker_image: + name: "{{ matrix_mx_puppet_twitter_docker_image }}" + source: build + force_source: "{{ matrix_mx_puppet_twitter_git_pull_results.changed }}" + build: + dockerfile: Dockerfile + path: "{{ matrix_mx_puppet_twitter_docker_src_files_path }}" + pull: yes + when: "matrix_mx_puppet_twitter_enabled|bool and matrix_mx_puppet_twitter_container_image_self_build" + - name: Ensure mx-puppet-twitter config.yaml installed copy: content: "{{ matrix_mx_puppet_twitter_configuration|to_nice_yaml }}" @@ -91,3 +119,9 @@ service: daemon_reload: yes when: "matrix_mx_puppet_twitter_systemd_service_result.changed" + +- name: Ensure matrix-mx-puppet-twitter.service restarted, if necessary + service: + name: "matrix-mx-puppet-twitter.service" + state: restarted + when: "matrix_mx_puppet_twitter_requires_restart|bool" diff --git a/roles/matrix-bridge-mx-puppet-twitter/templates/config.yaml.j2 b/roles/matrix-bridge-mx-puppet-twitter/templates/config.yaml.j2 index 7d3033b3..bdecf1dc 100644 --- a/roles/matrix-bridge-mx-puppet-twitter/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mx-puppet-twitter/templates/config.yaml.j2 @@ -54,15 +54,18 @@ provisioning: apiPrefix: /_matrix/provision database: +{% if matrix_mx_puppet_twitter_database_engine == 'postgres' %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - #connString: "postgres://user:pass@localhost/dbname?sslmode=disable" + connString: {{ matrix_mx_puppet_twitter_database_connection_string|to_json }} +{% else %} # Use SQLite3 as a database backend # The name of the database file - filename: /data/database.db + filename: {{ matrix_mx_puppet_twitter_sqlite_database_path_in_container|to_json }} +{% endif %} logging: # Log level of console output diff --git a/roles/matrix-bridge-mx-puppet-twitter/templates/systemd/matrix-mx-puppet-twitter.service.j2 b/roles/matrix-bridge-mx-puppet-twitter/templates/systemd/matrix-mx-puppet-twitter.service.j2 index 6afb6fb4..8d7898eb 100644 --- a/roles/matrix-bridge-mx-puppet-twitter/templates/systemd/matrix-mx-puppet-twitter.service.j2 +++ b/roles/matrix-bridge-mx-puppet-twitter/templates/systemd/matrix-mx-puppet-twitter.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_mx_puppet_twitter_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-bridge-sms/defaults/main.yml b/roles/matrix-bridge-sms/defaults/main.yml index 25d2208c..3c6b4c61 100644 --- a/roles/matrix-bridge-sms/defaults/main.yml +++ b/roles/matrix-bridge-sms/defaults/main.yml @@ -3,43 +3,27 @@ matrix_sms_bridge_enabled: true -matrix_sms_bridge_docker_image: "folivonet/matrix-sms-bridge:0.3.2.RELEASE" -matrix_sms_bridge_database_docker_image: "neo4j:latest" -matrix_sms_bridge_database_docker_image_force_pull: "{{ matrix_sms_bridge_docker_image.endswith(':latest') }}" +matrix_sms_bridge_docker_image: "docker.io/folivonet/matrix-sms-bridge:0.5.5" matrix_sms_bridge_base_path: "{{ matrix_base_data_path }}/matrix-sms-bridge" matrix_sms_bridge_config_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/config" matrix_sms_bridge_data_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data" -matrix_sms_bridge_data_log_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data/log" -matrix_sms_bridge_data_spool_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data/spool" -matrix_sms_bridge_data_spool_inbox_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data/spool/inbox" -matrix_sms_bridge_data_spool_inbox_processed_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data/spool/inbox_processed" -matrix_sms_bridge_data_spool_outbox_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data/spool/outbox" -matrix_sms_bridge_data_spool_sent_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data/spool/sent" -matrix_sms_bridge_data_spool_error_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data/spool/error" -matrix_sms_bridge_database_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/database" matrix_sms_bridge_appservice_token: '' matrix_sms_bridge_homeserver_token: '' -matrix_sms_bridge_database_username: 'neo4j' -matrix_sms_bridge_database_password: '' - matrix_sms_bridge_container_http_host_bind_port: '' # A list of extra arguments to pass to the container matrix_sms_bridge_container_extra_arguments: [] # List of systemd services that service depends on. -matrix_sms_bridge_systemd_required_services_list: ['docker.service','matrix-sms-bridge-database.service'] -matrix_sms_bridge_database_systemd_required_services_list: ['docker.service'] +matrix_sms_bridge_systemd_required_services_list: ['docker.service'] # List of systemd services that service wants matrix_sms_bridge_systemd_wanted_services_list: [] -matrix_sms_bridge_database_systemd_wanted_services_list: [] matrix_sms_bridge_appservice_url: 'http://matrix-sms-bridge:8080' -matrix_sms_bridge_database_url: 'bolt://matrix-sms-bridge-database:7687' matrix_sms_bridge_homeserver_hostname: 'matrix-synapse' matrix_sms_bridge_homeserver_port: '8008' @@ -47,25 +31,19 @@ matrix_sms_bridge_homserver_domain: "{{ matrix_domain }}" matrix_sms_bridge_default_room: '' matrix_sms_bridge_default_region: '' matrix_sms_bridge_default_timezone: '' +matrix_sms_bridge_single_mode_enabled: false -matrix_sms_bridge_gammu_modem: '' -matrix_sms_bridge_modem_group: 'dialout' -matrix_sms_bridge_gammu_reset_frequency: 0 -matrix_sms_bridge_gammu_hard_reset_frequency: 0 +matrix_sms_bridge_provider_android_baseurl: '' +matrix_sms_bridge_provider_android_username: '' +matrix_sms_bridge_provider_android_password: '' +matrix_sms_bridge_provider_android_truststore_local_path: '' +matrix_sms_bridge_provider_android_truststore_password: '' matrix_sms_bridge_configuration_yaml: | #jinja2: lstrip_blocks: "True" # Database connection - org: - neo4j: - driver: - uri: {{ matrix_sms_bridge_database_url }} - authentication: - username: {{ matrix_sms_bridge_database_username }} - password: {{ matrix_sms_bridge_database_password }} - matrix: bridge: sms: @@ -74,17 +52,33 @@ matrix_sms_bridge_configuration_yaml: | defaultRoomId: "{{ matrix_sms_bridge_default_room }}" defaultRegion: "{{ matrix_sms_bridge_default_region }}" defaultTimeZone: "{{ matrix_sms_bridge_default_timezone }}" + singleModeEnabled: "{{ matrix_sms_bridge_single_mode_enabled }}" provider: - gammu: + android: # (optional) default is disabled enabled: true - # (optional) Path to the Gammu-Inbox directory. - inboxPath: /data/spool/inbox - # (optional) Path to the directory, where to put processed messages. - inboxProcessedPath: /data/spool/inbox_processed + # The url to the android-sms-gateway-server + baseUrl: {{ matrix_sms_bridge_provider_android_baseurl }} + # The username of the gateway + username: {{ matrix_sms_bridge_provider_android_username }} + # The password of the gateway + password: {{ matrix_sms_bridge_provider_android_password }} + # (optional) if you use a self signed certificate, you can add the public key here + {% if matrix_sms_bridge_provider_android_truststore_local_path %} + trustStore: + path: /config/matrix-sms-gateway-server.p12 + password: {{ matrix_sms_bridge_provider_android_truststore_password }} + type: PKCS12 + {% endif %} bot: # The domain-part of matrix-ids. E. g. example.org when your userIds look like @unicorn:example.org serverName: {{ matrix_sms_bridge_homserver_domain }} + migration: + url: "jdbc:h2:file:/data/database/db" + username: sa + database: + url: "r2dbc:h2:file:////data/database/db" + username: sa client: homeServer: # The hostname of your Homeserver. @@ -112,31 +106,6 @@ matrix_sms_bridge_configuration_extension: "{{ matrix_sms_bridge_configuration_e matrix_sms_bridge_configuration: "{{ matrix_sms_bridge_configuration_yaml|from_yaml|combine(matrix_sms_bridge_configuration_extension, recursive=True) }}" -matrix_sms_bridge_gammu_configuration: | - [gammu] - Device = {{ matrix_sms_bridge_gammu_modem }} - LogFile = /data/log/gammu.log - debugLevel = 1 - - [smsd] - Service = files - LoopSleep = 2 - InboxPath = /data/spool/inbox/ - OutboxPath = /data/spool/outbox/ - SentSMSPath = /data/spool/sent/ - ErrorSMSPath = /data/spool/error/ - InboxFormat = detail - OutboxFormat = detail - TransmitFormat = auto - ResetFrequency = {{ matrix_sms_bridge_gammu_reset_frequency }} - HardResetFrequency = {{ matrix_sms_bridge_gammu_hard_reset_frequency }} - debugLevel = 1 - LogFile = /data/log/smsd.log - DeliveryReport = no - HangupCalls = 1 - CheckBattery = 0 - - matrix_sms_bridge_registration_yaml: | id: sms as_token: "{{ matrix_sms_bridge_appservice_token }}" @@ -145,6 +114,9 @@ matrix_sms_bridge_registration_yaml: | users: - exclusive: true regex: '^@sms_.+:{{ matrix_sms_bridge_homserver_domain|regex_escape }}$' + aliases: + - exclusive: true + regex: '^#sms_.+:{{ matrix_sms_bridge_homserver_domain|regex_escape }}$' url: {{ matrix_sms_bridge_appservice_url }} sender_localpart: smsbot rate_limited: false diff --git a/roles/matrix-bridge-sms/tasks/init.yml b/roles/matrix-bridge-sms/tasks/init.yml index 7a49e4b2..cca4d4c5 100644 --- a/roles/matrix-bridge-sms/tasks/init.yml +++ b/roles/matrix-bridge-sms/tasks/init.yml @@ -7,7 +7,7 @@ when: "matrix_sms_bridge_enabled and matrix_synapse_role_executed|default(False)" - set_fact: - matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-sms-bridge','matrix-sms-bridge-database'] }}" + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-sms-bridge'] }}" when: matrix_sms_bridge_enabled|bool # If the matrix-synapse role is not used, these variables may not exist. diff --git a/roles/matrix-bridge-sms/tasks/setup_install.yml b/roles/matrix-bridge-sms/tasks/setup_install.yml index 254510a3..61de923f 100644 --- a/roles/matrix-bridge-sms/tasks/setup_install.yml +++ b/roles/matrix-bridge-sms/tasks/setup_install.yml @@ -5,14 +5,6 @@ name: "{{ matrix_sms_bridge_docker_image }}" source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" -- name: Ensure matrix-sms-bridge databse image is pulled - docker_image: - name: "{{ matrix_sms_bridge_database_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_sms_bridge_database_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_sms_bridge_database_docker_image_force_pull }}" - - - name: Ensure matrix-sms-bridge paths exist file: path: "{{ item }}" @@ -24,14 +16,6 @@ - "{{ matrix_sms_bridge_base_path }}" - "{{ matrix_sms_bridge_config_path }}" - "{{ matrix_sms_bridge_data_path }}" - - "{{ matrix_sms_bridge_data_log_path }}" - - "{{ matrix_sms_bridge_data_spool_path }}" - - "{{ matrix_sms_bridge_data_spool_inbox_path }}" - - "{{ matrix_sms_bridge_data_spool_inbox_processed_path }}" - - "{{ matrix_sms_bridge_data_spool_outbox_path }}" - - "{{ matrix_sms_bridge_data_spool_sent_path }}" - - "{{ matrix_sms_bridge_data_spool_error_path }}" - - "{{ matrix_sms_bridge_database_path }}" - name: Ensure matrix-sms-bridge application.yml installed copy: @@ -49,13 +33,14 @@ owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" -- name: Ensure matrix-sms-bridge gammu-smsdrc installed +- name: Ensure android-sms-gateway-server cert installed copy: - content: "{{ matrix_sms_bridge_gammu_configuration }}" - dest: "{{ matrix_sms_bridge_config_path }}/gammu-smsdrc" + src: "{{ matrix_sms_bridge_provider_android_truststore_local_path }}" + dest: "{{ matrix_sms_bridge_config_path }}/matrix-sms-gateway-server.p12" mode: 0644 owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" + when: matrix_sms_bridge_provider_android_truststore_local_path != "" - name: Ensure matrix-sms-bridge.service installed template: @@ -64,14 +49,7 @@ mode: 0644 register: matrix_sms_bridge_systemd_service_result -- name: Ensure matrix-sms-bridge-database.service installed - template: - src: "{{ role_path }}/templates/systemd/matrix-sms-bridge-database.service.j2" - dest: "{{ matrix_systemd_path }}/matrix-sms-bridge-database.service" - mode: 0644 - register: matrix_sms_bridge_database_systemd_service_result - -- name: Ensure systemd reloaded after matrix-sms-bridge.service or matrix-sms-bridge-database.service installation +- name: Ensure systemd reloaded after matrix-sms-bridge.service installation service: daemon_reload: yes - when: matrix_sms_bridge_systemd_service_result.changed or matrix_sms_bridge_database_systemd_service_result.changed + when: matrix_sms_bridge_systemd_service_result.changed \ No newline at end of file diff --git a/roles/matrix-bridge-sms/tasks/setup_uninstall.yml b/roles/matrix-bridge-sms/tasks/setup_uninstall.yml index 87436687..03ddaad0 100644 --- a/roles/matrix-bridge-sms/tasks/setup_uninstall.yml +++ b/roles/matrix-bridge-sms/tasks/setup_uninstall.yml @@ -5,11 +5,6 @@ path: "{{ matrix_systemd_path }}/matrix-sms-bridge.service" register: matrix_sms_bridge_service_stat -- name: Check existence of matrix-sms-bridge-database service - stat: - path: "{{ matrix_systemd_path }}/matrix-sms-bridge-database.service" - register: matrix_sms_bridge_database_service_stat - - name: Ensure matrix-sms-bridge is stopped service: name: matrix-sms-bridge @@ -17,26 +12,8 @@ daemon_reload: yes when: "matrix_sms_bridge_service_stat.stat.exists" -- name: Ensure matrix-sms-bridge-database is stopped - service: - name: matrix-sms-bridge-database - state: stopped - daemon_reload: yes - when: "matrix_sms_bridge_database_service_stat.stat.exists" - - name: Ensure matrix-sms-bridge.service doesn't exist file: path: "{{ matrix_systemd_path }}/matrix-sms-bridge.service" state: absent - when: "matrix_sms_bridge_service_stat.stat.exists" - -- name: Ensure matrix-sms-bridge-database.service doesn't exist - file: - path: "{{ matrix_systemd_path }}/matrix-sms-bridge-database.service" - state: absent - when: "matrix_sms_bridge_database_service_stat.stat.exists" - -- name: Ensure systemd reloaded after matrix-sms-bridge.service or matrix-sms-bridge-database.service removal - service: - daemon_reload: yes - when: matrix_sms_bridge_service_stat.stat.exists or matrix_sms_bridge_database_service_stat.stat.exists + when: "matrix_sms_bridge_service_stat.stat.exists" \ No newline at end of file diff --git a/roles/matrix-bridge-sms/tasks/validate_config.yml b/roles/matrix-bridge-sms/tasks/validate_config.yml index 0e40aefa..6dc6ce9c 100644 --- a/roles/matrix-bridge-sms/tasks/validate_config.yml +++ b/roles/matrix-bridge-sms/tasks/validate_config.yml @@ -8,7 +8,8 @@ with_items: - "matrix_sms_bridge_appservice_token" - "matrix_sms_bridge_homeserver_token" - - "matrix_sms_bridge_database_password" - - "matrix_sms_bridge_gammu_modem" - "matrix_sms_bridge_default_region" - "matrix_sms_bridge_default_timezone" + - "matrix_sms_bridge_provider_android_baseurl" + - "matrix_sms_bridge_provider_android_username" + - "matrix_sms_bridge_provider_android_password" \ No newline at end of file diff --git a/roles/matrix-bridge-sms/templates/systemd/matrix-sms-bridge-database.service.j2 b/roles/matrix-bridge-sms/templates/systemd/matrix-sms-bridge-database.service.j2 deleted file mode 100644 index c9bb0343..00000000 --- a/roles/matrix-bridge-sms/templates/systemd/matrix-sms-bridge-database.service.j2 +++ /dev/null @@ -1,36 +0,0 @@ -#jinja2: lstrip_blocks: "True" -[Unit] -Description=Matrix sms bridge database -{% for service in matrix_sms_bridge_database_systemd_required_services_list %} -Requires={{ service }} -After={{ service }} -{% endfor %} -{% for service in matrix_sms_bridge_database_systemd_wanted_services_list %} -Wants={{ service }} -{% endfor %} - -[Service] -Type=simple -ExecStartPre=-/usr/bin/docker kill matrix-sms-bridge-database -ExecStartPre=-/usr/bin/docker rm matrix-sms-bridge-database - -# Intentional delay, so that the homeserver (we likely depend on) can manage to start. -ExecStartPre=/bin/sleep 5 - -ExecStart=/usr/bin/docker run --rm --name matrix-sms-bridge-database \ - --log-driver=none \ - --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ - --cap-drop=ALL \ - --network={{ matrix_docker_network }} \ - -v {{ matrix_sms_bridge_database_path }}:/data:z \ - -e NEO4J_AUTH={{ matrix_sms_bridge_database_username }}/{{ matrix_sms_bridge_database_password }} \ - {{ matrix_sms_bridge_database_docker_image }} - -ExecStop=-/usr/bin/docker kill matrix-sms-bridge-database -ExecStop=-/usr/bin/docker rm matrix-sms-bridge-database -Restart=always -RestartSec=30 -SyslogIdentifier=matrix-sms-bridge - - [Install] -WantedBy=multi-user.target diff --git a/roles/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 b/roles/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 index 7cab3742..0eb0eb58 100644 --- a/roles/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 +++ b/roles/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_sms_bridge_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -20,7 +21,6 @@ ExecStartPre=/bin/sleep 5 ExecStart=/usr/bin/docker run --rm --name matrix-sms-bridge \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ - --group-add {{ matrix_sms_bridge_modem_group }} \ --cap-drop=ALL \ --network={{ matrix_docker_network }} \ {% if matrix_sms_bridge_container_http_host_bind_port %} @@ -28,9 +28,7 @@ ExecStart=/usr/bin/docker run --rm --name matrix-sms-bridge \ {% endif %} -v {{ matrix_sms_bridge_config_path }}:/config:z \ -v {{ matrix_sms_bridge_data_path }}:/data:z \ - -v {{ matrix_sms_bridge_config_path }}/gammu-smsdrc:/etc/gammu-smsdrc:z \ - --privileged \ - -v /dev:/dev:slave \ + --env SPRING_CONFIG_ADDITIONAL_LOCATION=/config/application.yml \ {% for arg in matrix_sms_bridge_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-client-element/defaults/main.yml b/roles/matrix-client-element/defaults/main.yml index d2b9258f..d0297193 100644 --- a/roles/matrix-client-element/defaults/main.yml +++ b/roles/matrix-client-element/defaults/main.yml @@ -1,8 +1,10 @@ matrix_client_element_enabled: true matrix_client_element_container_image_self_build: false +matrix_client_element_container_image_self_build_repo: "https://github.com/vector-im/riot-web.git" -matrix_client_element_docker_image: "vectorim/riot-web:v1.7.10" +matrix_client_element_docker_image: "{{ matrix_client_element_docker_image_name_prefix }}vectorim/element-web:v1.7.16" +matrix_client_element_docker_image_name_prefix: "{{ 'localhost/' if matrix_client_element_container_image_self_build else 'docker.io/' }}" matrix_client_element_docker_image_force_pull: "{{ matrix_client_element_docker_image.endswith(':latest') }}" matrix_client_element_data_path: "{{ matrix_base_data_path }}/client-element" diff --git a/roles/matrix-client-element/tasks/setup.yml b/roles/matrix-client-element/tasks/setup.yml index 2e8071ca..3b542b14 100644 --- a/roles/matrix-client-element/tasks/setup.yml +++ b/roles/matrix-client-element/tasks/setup.yml @@ -26,21 +26,23 @@ - name: Ensure Element repository is present on self-build git: - repo: https://github.com/vector-im/riot-web.git + repo: "{{ matrix_client_element_container_image_self_build_repo }}" dest: "{{ matrix_client_element_docker_src_files_path }}" version: "{{ matrix_client_element_docker_image.split(':')[1] }}" force: "yes" - when: "matrix_client_element_enabled|bool and matrix_client_element_container_image_self_build" + register: matrix_client_element_git_pull_results + when: "matrix_client_element_enabled|bool and matrix_client_element_container_image_self_build|bool" - name: Ensure Element Docker image is built docker_image: name: "{{ matrix_client_element_docker_image }}" source: build + force_source: "{{ matrix_client_element_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_client_element_docker_src_files_path }}" pull: yes - when: "matrix_client_element_enabled|bool and matrix_client_element_container_image_self_build" + when: "matrix_client_element_enabled|bool and matrix_client_element_container_image_self_build|bool" - name: Ensure Element configuration installed copy: diff --git a/roles/matrix-client-element/templates/systemd/matrix-client-element.service.j2 b/roles/matrix-client-element/templates/systemd/matrix-client-element.service.j2 index 49b2f198..e0dd2e7e 100644 --- a/roles/matrix-client-element/templates/systemd/matrix-client-element.service.j2 +++ b/roles/matrix-client-element/templates/systemd/matrix-client-element.service.j2 @@ -5,6 +5,7 @@ Description=Matrix Element server Requires={{ service }} After={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -21,13 +22,13 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-client-element -p {{ matrix_client_element_container_http_host_bind_port }}:8080 \ {% endif %} --tmpfs=/tmp:rw,noexec,nosuid,size=10m \ - -v {{ matrix_client_element_data_path }}/nginx.conf:/etc/nginx/nginx.conf:ro \ - -v {{ matrix_client_element_data_path }}/config.json:/app/config.json:ro \ - -v {{ matrix_client_element_data_path }}/config.json:/app/config.{{ matrix_server_fqn_element }}.json:ro \ + --mount type=bind,src={{ matrix_client_element_data_path }}/nginx.conf,dst=/etc/nginx/nginx.conf,ro \ + --mount type=bind,src={{ matrix_client_element_data_path }}/config.json,dst=/app/config.json,ro \ + --mount type=bind,src={{ matrix_client_element_data_path }}/config.json,dst=/app/config.{{ matrix_server_fqn_element }}.json,ro \ {% if matrix_client_element_embedded_pages_home_path is not none %} - -v {{ matrix_client_element_data_path }}/home.html:/app/home.html:ro \ + --mount type=bind,src={{ matrix_client_element_data_path }}/home.html,dst=/app/home.html,ro \ {% endif %} - -v {{ matrix_client_element_data_path }}/welcome.html:/app/welcome.html:ro \ + --mount type=bind,src={{ matrix_client_element_data_path }}/welcome.html,dst=/app/welcome.html,ro \ {% for arg in matrix_client_element_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-common-after/tasks/start.yml b/roles/matrix-common-after/tasks/start.yml index 4bb59bfe..bad84d92 100644 --- a/roles/matrix-common-after/tasks/start.yml +++ b/roles/matrix-common-after/tasks/start.yml @@ -1,5 +1,9 @@ --- +- name: Deterimne whether we should make services autostart + set_fact: + matrix_services_autostart_enabled_bool: "{{ true if matrix_services_autostart_enabled|default('') == '' else matrix_services_autostart_enabled|bool }}" + - name: Ensure systemd is reloaded service: daemon_reload: yes @@ -14,7 +18,7 @@ - name: Ensure Matrix services are started service: name: "{{ item }}" - enabled: yes + enabled: "{{ matrix_services_autostart_enabled_bool }}" state: started with_items: "{{ matrix_systemd_services_list }}" when: not ansible_check_mode diff --git a/roles/matrix-corporal/defaults/main.yml b/roles/matrix-corporal/defaults/main.yml index 52681a30..cccaadd0 100644 --- a/roles/matrix-corporal/defaults/main.yml +++ b/roles/matrix-corporal/defaults/main.yml @@ -3,6 +3,9 @@ matrix_corporal_enabled: true +matrix_corporal_container_image_self_build: false +matrix_corporal_container_image_self_build_repo: "https://github.com/devture/matrix-corporal.git" + # Controls whether the matrix-corporal container exposes its gateway HTTP port (tcp/41080 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:41080"), or empty string to not expose. @@ -19,10 +22,13 @@ matrix_corporal_container_extra_arguments: [] # List of systemd services that matrix-corporal.service depends on matrix_corporal_systemd_required_services_list: ['docker.service'] -matrix_corporal_docker_image: "devture/matrix-corporal:1.11.0" +matrix_corporal_docker_image: "{{ matrix_corporal_docker_image_name_prefix }}devture/matrix-corporal:{{ matrix_corporal_docker_image_tag }}" +matrix_corporal_docker_image_name_prefix: "{{ 'localhost/' if matrix_corporal_container_image_self_build else 'docker.io/' }}" +matrix_corporal_docker_image_tag: "1.11.0" matrix_corporal_docker_image_force_pull: "{{ matrix_corporal_docker_image.endswith(':latest') }}" matrix_corporal_base_path: "{{ matrix_base_data_path }}/corporal" +matrix_corporal_container_src_files_path: "{{ matrix_corporal_base_path }}/container-src" matrix_corporal_config_dir_path: "{{ matrix_corporal_base_path }}/config" matrix_corporal_cache_dir_path: "{{ matrix_corporal_base_path }}/cache" matrix_corporal_var_dir_path: "{{ matrix_corporal_base_path }}/var" diff --git a/roles/matrix-corporal/tasks/setup_corporal.yml b/roles/matrix-corporal/tasks/setup_corporal.yml index 72b6a5b2..188f09bf 100644 --- a/roles/matrix-corporal/tasks/setup_corporal.yml +++ b/roles/matrix-corporal/tasks/setup_corporal.yml @@ -17,13 +17,33 @@ - "{{ matrix_corporal_var_dir_path }}" when: matrix_corporal_enabled|bool +- name: Ensure Matrix Corporal repository is present on self-build + git: + repo: "{{ matrix_corporal_container_image_self_build_repo }}" + dest: "{{ matrix_corporal_container_src_files_path }}" + version: "{{ matrix_corporal_docker_image.split(':')[1] }}" + force: "yes" + register: matrix_corporal_git_pull_results + when: "matrix_corporal_enabled|bool and matrix_corporal_container_image_self_build|bool" + +- name: Ensure Matrix Corporal Docker image is built + docker_image: + name: "{{ matrix_corporal_docker_image }}" + source: build + force_source: "{{ matrix_corporal_git_pull_results.changed }}" + build: + dockerfile: etc/docker/Dockerfile + path: "{{ matrix_corporal_container_src_files_path }}" + pull: yes + when: "matrix_corporal_enabled|bool and matrix_corporal_container_image_self_build|bool" + - name: Ensure Matrix Corporal Docker image is pulled docker_image: name: "{{ matrix_corporal_docker_image }}" source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" force_source: "{{ matrix_corporal_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_corporal_docker_image_force_pull }}" - when: matrix_corporal_enabled|bool + when: "matrix_corporal_enabled|bool and not matrix_corporal_container_image_self_build|bool" - name: Ensure Matrix Corporal config installed copy: diff --git a/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 b/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 index 533ece0a..e8ce8c0a 100644 --- a/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 +++ b/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 @@ -5,6 +5,7 @@ Description=Matrix Corporal Requires={{ service }} After={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -23,9 +24,9 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-corporal \ {% if matrix_corporal_container_http_api_host_bind_port %} -p {{ matrix_corporal_container_http_api_host_bind_port }}:41081 \ {% endif %} - -v {{ matrix_corporal_config_dir_path }}:/etc/matrix-corporal:ro \ - -v {{ matrix_corporal_cache_dir_path }}:/var/cache/matrix-corporal:rw \ - -v {{ matrix_corporal_var_dir_path }}:/var/matrix-corporal:rw \ + --mount type=bind,src={{ matrix_corporal_config_dir_path }},dst=/etc/matrix-corporal,ro \ + --mount type=bind,src={{ matrix_corporal_cache_dir_path }},dst=/var/cache/matrix-corporal \ + --mount type=bind,src={{ matrix_corporal_var_dir_path }},dst=/var/matrix-corporal \ {% for arg in matrix_corporal_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-coturn/defaults/main.yml b/roles/matrix-coturn/defaults/main.yml index 104019a4..8cbb3e3f 100644 --- a/roles/matrix-coturn/defaults/main.yml +++ b/roles/matrix-coturn/defaults/main.yml @@ -1,8 +1,10 @@ matrix_coturn_enabled: true matrix_coturn_container_image_self_build: false +matrix_coturn_container_image_self_build_repo: "https://github.com/instrumentisto/coturn-docker-image.git" -matrix_coturn_docker_image: "instrumentisto/coturn:4.5.1.3" +matrix_coturn_docker_image: "{{ matrix_coturn_docker_image_name_prefix }}instrumentisto/coturn:4.5.1.3" +matrix_coturn_docker_image_name_prefix: "{{ 'localhost/' if matrix_coturn_container_image_self_build else 'docker.io/' }}" matrix_coturn_docker_image_force_pull: "{{ matrix_coturn_docker_image.endswith(':latest') }}" # The Docker network that Coturn would be put into. diff --git a/roles/matrix-coturn/tasks/setup_coturn.yml b/roles/matrix-coturn/tasks/setup_coturn.yml index 17b6137d..1f13da03 100644 --- a/roles/matrix-coturn/tasks/setup_coturn.yml +++ b/roles/matrix-coturn/tasks/setup_coturn.yml @@ -25,21 +25,23 @@ - name: Ensure Coturn repository is present on self-build git: - repo: https://github.com/instrumentisto/coturn-docker-image.git + repo: "{{ matrix_coturn_container_image_self_build_repo }}" dest: "{{ matrix_coturn_docker_src_files_path }}" version: "{{ matrix_coturn_docker_image.split(':')[1] }}" force: "yes" + register: matrix_coturn_git_pull_results when: "matrix_coturn_enabled|bool and matrix_coturn_container_image_self_build" - name: Ensure Coturn Docker image is built docker_image: name: "{{ matrix_coturn_docker_image }}" source: build + force_source: "{{ matrix_coturn_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_coturn_docker_src_files_path }}" pull: yes - when: "matrix_coturn_enabled|bool and matrix_coturn_container_image_self_build" + when: "matrix_coturn_enabled|bool and matrix_coturn_container_image_self_build|bool" - name: Ensure Coturn configuration path exists file: diff --git a/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 b/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 index a6d19705..16ca5d2a 100644 --- a/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 +++ b/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 @@ -5,6 +5,7 @@ Description=Matrix Coturn server Requires={{ service }} After={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -30,7 +31,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-coturn \ {% if matrix_coturn_container_turn_range_listen_interface is not none %} -p {{ matrix_coturn_container_turn_range_listen_interface }}{{ ':' if matrix_coturn_container_turn_range_listen_interface else '' }}{{ matrix_coturn_turn_udp_min_port }}-{{ matrix_coturn_turn_udp_max_port }}:{{ matrix_coturn_turn_udp_min_port }}-{{ matrix_coturn_turn_udp_max_port }}/udp \ {% endif %} - -v {{ matrix_coturn_config_path }}:/turnserver.conf:ro \ + --mount type=bind,src={{ matrix_coturn_config_path }},dst=/turnserver.conf,ro \ {% for volume in matrix_coturn_container_additional_volumes %} -v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \ {% endfor %} diff --git a/roles/matrix-dimension/defaults/main.yml b/roles/matrix-dimension/defaults/main.yml index 33e7212c..8a691946 100644 --- a/roles/matrix-dimension/defaults/main.yml +++ b/roles/matrix-dimension/defaults/main.yml @@ -12,9 +12,15 @@ matrix_dimension_widgets_allow_self_signed_ssl_certificates: false matrix_dimension_base_path: "{{ matrix_base_data_path }}/dimension" -matrix_dimension_docker_image: "turt2live/matrix-dimension:latest" +matrix_dimension_docker_image: "docker.io/turt2live/matrix-dimension:latest" matrix_dimension_docker_image_force_pull: "{{ matrix_dimension_docker_image.endswith(':latest') }}" +# List of systemd services that matrix-dimension.service depends on. +matrix_dimension_systemd_required_services_list: ['docker.service'] + +# List of systemd services that matrix-dimension.service wants +matrix_dimension_systemd_wanted_services_list: [] + # The user and group id correspond to the node user in the `turt2live/matrix-dimension` image. matrix_dimension_user_uid: '1000' matrix_dimension_user_gid: '1000' @@ -34,6 +40,28 @@ matrix_dimension_integrations_jitsi_widget_url: "https://{{ matrix_server_fqn_di matrix_dimension_homeserver_federationUrl: "http://matrix-synapse:8048" + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_dimension_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_dimension_postgres_*` variables +matrix_dimension_database_engine: 'sqlite' + +matrix_dimension_sqlite_database_path_local: "{{ matrix_dimension_base_path }}/dimension.db" +matrix_dimension_sqlite_database_path_in_container: "dimension.db" + +matrix_dimension_database_username: 'matrix_dimension' +matrix_dimension_database_password: 'some-password' +matrix_dimension_database_hostname: 'matrix-postgres' +matrix_dimension_database_port: 5432 +matrix_dimension_database_name: 'matrix_dimension' + +matrix_dimension_database_connection_string: 'postgres://{{ matrix_dimension_database_username }}:{{ matrix_dimension_database_password }}@{{ matrix_dimension_database_hostname }}:{{ matrix_dimension_database_port }}/{{ matrix_dimension_database_name }}' + + # Default Dimension configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-dimension/tasks/main.yml b/roles/matrix-dimension/tasks/main.yml index 1888f945..aad55286 100644 --- a/roles/matrix-dimension/tasks/main.yml +++ b/roles/matrix-dimension/tasks/main.yml @@ -8,8 +8,14 @@ - setup-all - setup-dimension -- import_tasks: "{{ role_path }}/tasks/setup_dimension.yml" - when: run_setup|bool +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: run_setup|bool and matrix_dimension_enabled|bool + tags: + - setup-all + - setup-dimension + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: run_setup|bool and not matrix_dimension_enabled|bool tags: - setup-all - setup-dimension diff --git a/roles/matrix-dimension/tasks/setup_dimension.yml b/roles/matrix-dimension/tasks/setup_dimension.yml deleted file mode 100644 index 2437a547..00000000 --- a/roles/matrix-dimension/tasks/setup_dimension.yml +++ /dev/null @@ -1,85 +0,0 @@ ---- - -# -# Tasks related to setting up the dimension -# - -- name: Ensure Dimension base path exists - file: - path: "{{ matrix_dimension_base_path }}" - state: directory - mode: 0770 - owner: "{{ matrix_user_username }}" - group: "{{ matrix_dimension_user_gid }}" - when: matrix_dimension_enabled|bool - -- name: Ensure Dimension config installed - copy: - content: "{{ matrix_dimension_configuration|to_nice_yaml }}" - dest: "{{ matrix_dimension_base_path }}/config.yaml" - mode: 0640 - owner: "{{ matrix_user_username }}" - group: "{{ matrix_dimension_user_gid }}" - when: matrix_dimension_enabled|bool - -- name: Ensure Dimension image is pulled - docker_image: - name: "{{ matrix_dimension_docker_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_dimension_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_dimension_docker_image_force_pull }}" - when: matrix_dimension_enabled|bool - -- name: Ensure matrix-dimension.service installed - template: - src: "{{ role_path }}/templates/systemd/matrix-dimension.service.j2" - dest: "{{ matrix_systemd_path }}/matrix-dimension.service" - mode: 0644 - register: matrix_dimension_systemd_service_result - when: matrix_dimension_enabled|bool - -- name: Ensure systemd reloaded after matrix-dimension.service installation - service: - daemon_reload: yes - when: "matrix_dimension_enabled|bool and matrix_dimension_systemd_service_result.changed" - -# -# Tasks related to getting rid of the dimension (if it was previously enabled) -# - -- name: Check existence of matrix-dimension service - stat: - path: "{{ matrix_systemd_path }}/matrix-dimension.service" - register: matrix_dimension_service_stat - when: "not matrix_dimension_enabled|bool" - -- name: Ensure matrix-dimension is stopped - service: - name: matrix-dimension - state: stopped - daemon_reload: yes - register: stopping_result - when: "not matrix_dimension_enabled|bool and matrix_dimension_service_stat.stat.exists" - -- name: Ensure matrix-dimension.service doesn't exist - file: - path: "{{ matrix_systemd_path }}/matrix-dimension.service" - state: absent - when: "not matrix_dimension_enabled|bool and matrix_dimension_service_stat.stat.exists" - -- name: Ensure systemd reloaded after matrix-dimension.service removal - service: - daemon_reload: yes - when: "not matrix_dimension_enabled|bool and matrix_dimension_service_stat.stat.exists" - -- name: Ensure Dimension environment variables path doesn't exist - file: - path: "{{ matrix_dimension_base_path }}" - state: absent - when: "not matrix_dimension_enabled|bool" - -- name: Ensure Dimension Docker image doesn't exist - docker_image: - name: "{{ matrix_dimension_docker_image }}" - state: absent - when: "not matrix_dimension_enabled|bool" diff --git a/roles/matrix-dimension/tasks/setup_install.yml b/roles/matrix-dimension/tasks/setup_install.yml new file mode 100644 index 00000000..26a75bcb --- /dev/null +++ b/roles/matrix-dimension/tasks/setup_install.yml @@ -0,0 +1,109 @@ +--- + +- set_fact: + matrix_dimension_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_dimension_sqlite_database_path_local }}" + register: matrix_dimension_sqlite_database_path_local_stat_result + + - block: + # pgloader makes a few columns `smallint`, instead of `boolean`. + # We need to fix them up. + - set_fact: + matrix_dimension_pgloader_additional_psql_statements_list: [] + + - set_fact: + matrix_dimension_pgloader_additional_psql_statements_list: | + {{ + matrix_dimension_pgloader_additional_psql_statements_list + + + ([] if item.default == '' else ['ALTER TABLE ' + item.table + ' ALTER COLUMN "' + item.column + '" DROP default;']) + + + (['ALTER TABLE ' + item.table + ' ALTER COLUMN "' + item.column + '" TYPE BOOLEAN USING("' + item.column + '"::text::boolean);']) + + + ([] if item.default == '' else ['ALTER TABLE ' + item.table + ' ALTER COLUMN "' + item.column + '" SET default ' + item.default + ';']) + }} + with_items: + - {'table': 'dimension_widgets', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_widgets', 'column': 'isPublic', 'default': ''} + - {'table': 'dimension_webhook_bridges', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_user_sticker_packs', 'column': 'isSelected', 'default': ''} + - {'table': 'dimension_scalar_tokens', 'column': 'isDimensionToken', 'default': ''} + - {'table': 'dimension_users', 'column': 'isSelfBot', 'default': 'false'} + - {'table': 'dimension_telegram_bridges', 'column': 'allowTgPuppets', 'default': ''} + - {'table': 'dimension_telegram_bridges', 'column': 'allowMxPuppets', 'default': ''} + - {'table': 'dimension_telegram_bridges', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_sticker_packs', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_sticker_packs', 'column': 'isPublic', 'default': ''} + - {'table': 'dimension_slack_bridges', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_neb_integrations', 'column': 'isPublic', 'default': ''} + - {'table': 'dimension_irc_bridges', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_irc_bridge_networks', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_gitter_bridges', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_custom_simple_bots', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_custom_simple_bots', 'column': 'isPublic', 'default': ''} + - {'table': 'dimension_bridges', 'column': 'isEnabled', 'default': ''} + - {'table': 'dimension_bridges', 'column': 'isPublic', 'default': ''} + + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_dimension_sqlite_database_path_local }}" + dst: "{{ matrix_dimension_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_dimension_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-dimension.service'] + pgloader_options: ['--with "quote identifiers"'] + additional_psql_statements_list: "{{ matrix_dimension_pgloader_additional_psql_statements_list }}" + additional_psql_statements_db_name: "{{ matrix_dimension_database_name }}" + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_dimension_requires_restart: true + when: "matrix_dimension_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_dimension_database_engine == 'postgres'" + +- name: Ensure Dimension base path exists + file: + path: "{{ matrix_dimension_base_path }}" + state: directory + mode: 0770 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_dimension_user_gid }}" + +- name: Ensure Dimension config installed + copy: + content: "{{ matrix_dimension_configuration|to_nice_yaml }}" + dest: "{{ matrix_dimension_base_path }}/config.yaml" + mode: 0640 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_dimension_user_gid }}" + +- name: Ensure Dimension image is pulled + docker_image: + name: "{{ matrix_dimension_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_dimension_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_dimension_docker_image_force_pull }}" + +- name: Ensure matrix-dimension.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-dimension.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-dimension.service" + mode: 0644 + register: matrix_dimension_systemd_service_result + +- name: Ensure systemd reloaded after matrix-dimension.service installation + service: + daemon_reload: yes + when: "matrix_dimension_systemd_service_result.changed|bool" + +- name: Ensure matrix-dimension.service restarted, if necessary + service: + name: "matrix-dimension.service" + state: restarted + when: "matrix_dimension_requires_restart|bool" diff --git a/roles/matrix-dimension/tasks/setup_uninstall.yml b/roles/matrix-dimension/tasks/setup_uninstall.yml new file mode 100644 index 00000000..9bc4ac8b --- /dev/null +++ b/roles/matrix-dimension/tasks/setup_uninstall.yml @@ -0,0 +1,35 @@ +--- + +- name: Check existence of matrix-dimension service + stat: + path: "{{ matrix_systemd_path }}/matrix-dimension.service" + register: matrix_dimension_service_stat + +- name: Ensure matrix-dimension is stopped + service: + name: matrix-dimension + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_dimension_service_stat.stat.exists|bool" + +- name: Ensure matrix-dimension.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-dimension.service" + state: absent + when: "matrix_dimension_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-dimension.service removal + service: + daemon_reload: yes + when: "matrix_dimension_service_stat.stat.exists|bool" + +- name: Ensure Dimension base directory doesn't exist + file: + path: "{{ matrix_dimension_base_path }}" + state: absent + +- name: Ensure Dimension Docker image doesn't exist + docker_image: + name: "{{ matrix_dimension_docker_image }}" + state: absent diff --git a/roles/matrix-dimension/templates/config.yaml.j2 b/roles/matrix-dimension/templates/config.yaml.j2 index a05b6c35..200871e7 100644 --- a/roles/matrix-dimension/templates/config.yaml.j2 +++ b/roles/matrix-dimension/templates/config.yaml.j2 @@ -44,7 +44,11 @@ widgetBlacklist: # Where the database for Dimension is database: - file: "dimension.db" +{% if matrix_dimension_database_engine == 'sqlite' %} + file: {{ matrix_dimension_sqlite_database_path_in_container|to_json }} +{% elif matrix_dimension_database_engine == 'postgres' %} + uri: {{ matrix_dimension_database_connection_string|to_json }} +{% endif %} # Display settings that apply to self-hosted go-neb instances goneb: diff --git a/roles/matrix-dimension/templates/systemd/matrix-dimension.service.j2 b/roles/matrix-dimension/templates/systemd/matrix-dimension.service.j2 index db9d58a8..ff10224a 100644 --- a/roles/matrix-dimension/templates/systemd/matrix-dimension.service.j2 +++ b/roles/matrix-dimension/templates/systemd/matrix-dimension.service.j2 @@ -1,8 +1,14 @@ #jinja2: lstrip_blocks: "True" [Unit] Description=Matrix Dimension -After=docker.service -Requires=docker.service +{% for service in matrix_dimension_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_dimension_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -10,7 +16,9 @@ ExecStartPre=-{{ matrix_host_command_docker }} kill matrix-dimension ExecStartPre=-{{ matrix_host_command_docker }} rm matrix-dimension # Fixup database ownership if it got changed somehow (during a server migration, etc.) -ExecStartPre=-{{ matrix_host_command_chown }} {{ matrix_dimension_user_uid }}:{{ matrix_dimension_user_gid }} {{ matrix_dimension_base_path }}/dimension.db +{% if matrix_dimension_database_engine == 'sqlite' %} +ExecStartPre=-{{ matrix_host_command_chown }} {{ matrix_dimension_user_uid }}:{{ matrix_dimension_user_gid }} {{ matrix_dimension_sqlite_database_path_local }} +{% endif %} ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-dimension \ --log-driver=none \ @@ -23,7 +31,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-dimension \ {% if matrix_dimension_container_http_host_bind_port %} -p {{ matrix_dimension_container_http_host_bind_port }}:8184 \ {% endif %} - -v {{ matrix_dimension_base_path }}:/data:rw \ + --mount type=bind,src={{ matrix_dimension_base_path }},dst=/data \ {% for arg in matrix_dimension_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-dynamic-dns/defaults/main.yml b/roles/matrix-dynamic-dns/defaults/main.yml new file mode 100644 index 00000000..b33961c1 --- /dev/null +++ b/roles/matrix-dynamic-dns/defaults/main.yml @@ -0,0 +1,46 @@ +# Whether dynamic dns is enabled +matrix_dynamic_dns_enabled: true + +# The dynamic dns daemon interval +matrix_dynamic_dns_daemon_interval: '300' + +# The docker container to use when in mode +matrix_dynamic_dns_docker_image: '{{ matrix_dynamic_dns_docker_image_name_prefix }}linuxserver/ddclient:v3.9.1-ls45' + +matrix_dynamic_dns_docker_image_name_prefix: "{{ 'localhost/' if matrix_dynamic_dns_container_image_self_build else 'docker.io/' }}" + +# The image to force pull +matrix_dynamic_dns_docker_image_force_pull: "{{ matrix_dynamic_dns_docker_image.endswith(':latest') }}" + +# List of extra arguments to pass to the ontainer mode +matrix_dynamic_dns_container_extra_arguments: [] + +# List of wanted services when running in mode +matrix_dynamic_dns_systemd_wanted_services_list: [] + +# List of required services when running in mode +matrix_dynamic_dns_systemd_required_services_list: ['docker.service'] + +# Build the container from source when running in mode +matrix_dynamic_dns_container_image_self_build: false +matrix_dynamic_dns_container_image_self_build_repo: "https://github.com/linuxserver/docker-ddclient.git" + +# Config paths +matrix_dynamic_dns_base_path: "{{ matrix_base_data_path }}/dynamic-dns" +matrix_dynamic_dns_config_path: "{{ matrix_dynamic_dns_base_path }}/config" +matrix_dynamic_dns_docker_src_files_path: "{{ matrix_dynamic_dns_base_path }}/docker-src" + +# Holds the configurations (the domains to update DNS for, the providers they use, etc.) +# +# Example: +# matrix_dynamic_dns_domain_configurations: +# - provider: domains.google.com +# protocol: dyndn2 +# username: XXXXXXXXXXXXXXXX +# password: XXXXXXXXXXXXXXXX +# domain: "{{ matrix_domain }}" +matrix_dynamic_dns_domain_configurations: [] + +# Config options +matrix_dynamic_dns_additional_configuration_blocks: [] +matrix_dynamic_dns_use: "web" diff --git a/roles/matrix-dynamic-dns/tasks/init.yml b/roles/matrix-dynamic-dns/tasks/init.yml new file mode 100644 index 00000000..7b87fdb1 --- /dev/null +++ b/roles/matrix-dynamic-dns/tasks/init.yml @@ -0,0 +1,3 @@ +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-dynamic-dns'] }}" + when: "matrix_dynamic_dns_enabled|bool" diff --git a/roles/matrix-dynamic-dns/tasks/install.yml b/roles/matrix-dynamic-dns/tasks/install.yml new file mode 100644 index 00000000..e7b06d95 --- /dev/null +++ b/roles/matrix-dynamic-dns/tasks/install.yml @@ -0,0 +1,61 @@ +--- + +- name: Ensure Dynamic DNS image is pulled + docker_image: + name: "{{ matrix_dynamic_dns_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_dynamic_dns_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_dynamic_dns_docker_image_force_pull }}" + when: matrix_dynamic_dns_enabled|bool and not matrix_dynamic_dns_container_image_self_build + +- name: Ensure Dynamic DNS paths exist + file: + path: "{{ item.path }}" + state: directory + mode: 0751 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - { path: "{{ matrix_dynamic_dns_base_path }}", when: true } + - { path: "{{ matrix_dynamic_dns_config_path }}", when: true } + - { path: "{{ matrix_dynamic_dns_docker_src_files_path }}", when: "{{ matrix_dynamic_dns_container_image_self_build }}" } + when: matrix_dynamic_dns_enabled|bool and item.when|bool + +- name: Ensure Dynamic DNS repository is present on self build + git: + repo: "{{ matrix_dynamic_dns_container_image_self_build_repo }}" + dest: "{{ matrix_dynamic_dns_docker_src_files_path }}" + force: "yes" + register: matrix_dynamic_dns_git_pull_results + when: "matrix_dynamic_dns_enabled|bool and matrix_dynamic_dns_container_image_self_build|bool" + +- name: Ensure Dynamic DNS Docker image is built + docker_image: + name: "{{ matrix_dynamic_dns_docker_image }}" + source: build + force_source: "{{ matrix_dynamic_dns_git_pull_results.changed }}" + build: + dockerfile: Dockerfile + path: "{{ matrix_dynamic_dns_docker_src_files_path }}" + pull: yes + when: "matrix_dynamic_dns_enabled|bool and matrix_dynamic_dns_container_image_self_build|bool" + +- name: Ensure Dynamic DNS ddclient.conf installed + template: + src: "{{ role_path }}/templates/ddclient.conf.j2" + dest: "{{ matrix_dynamic_dns_config_path }}/ddclient.conf" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + +- name: Ensure matrix-dynamic-dns.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-dynamic-dns.service.j2" + dest: "/etc/systemd/system/matrix-dynamic-dns.service" + mode: 0644 + register: matrix_dynamic_dns_systemd_service_result + +- name: Ensure systemd reloaded after matrix-dynamic-dns.service installation + service: + daemon_reload: yes + when: "matrix_dynamic_dns_systemd_service_result.changed" diff --git a/roles/matrix-dynamic-dns/tasks/main.yml b/roles/matrix-dynamic-dns/tasks/main.yml new file mode 100644 index 00000000..f9aaab8f --- /dev/null +++ b/roles/matrix-dynamic-dns/tasks/main.yml @@ -0,0 +1,21 @@ +- import_tasks: "{{ role_path }}/tasks/init.yml" + tags: + - always + +- import_tasks: "{{ role_path }}/tasks/validate_config.yml" + when: "run_setup|bool and matrix_dynamic_dns_enabled|bool" + tags: + - setup-all + - setup-dynamic-dns + +- import_tasks: "{{ role_path }}/tasks/install.yml" + when: "run_setup|bool and matrix_dynamic_dns_enabled|bool" + tags: + - setup-all + - setup-dynamic-dns + +- import_tasks: "{{ role_path }}/tasks/uninstall.yml" + when: "run_setup|bool and not matrix_dynamic_dns_enabled|bool" + tags: + - setup-all + - setup-dynamic-dns diff --git a/roles/matrix-dynamic-dns/tasks/uninstall.yml b/roles/matrix-dynamic-dns/tasks/uninstall.yml new file mode 100644 index 00000000..98dca0e8 --- /dev/null +++ b/roles/matrix-dynamic-dns/tasks/uninstall.yml @@ -0,0 +1,24 @@ +--- + +- name: Check existence of matrix-dynamic-dns service + stat: + path: "{{ matrix_systemd_path }}/matrix-dynamic-dns.service" + register: matrix_dynamic_dns_service_stat + +- name: Ensure matrix-dynamic-dns is stopped + service: + name: matrix-dynamic-dns + state: stopped + daemon_reload: yes + when: "matrix_dynamic_dns_service_stat.stat.exists" + +- name: Ensure matrix-dynamic-dns.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-dynamic-dns.service" + state: absent + when: "matrix_dynamic_dns_service_stat.stat.exists" + +- name: Ensure systemd reloaded after matrix-dynamic-dns.service removal + service: + daemon_reload: yes + when: "matrix_dynamic_dns_service_stat.stat.exists" diff --git a/roles/matrix-dynamic-dns/tasks/validate_config.yml b/roles/matrix-dynamic-dns/tasks/validate_config.yml new file mode 100644 index 00000000..8f0001ea --- /dev/null +++ b/roles/matrix-dynamic-dns/tasks/validate_config.yml @@ -0,0 +1,16 @@ +--- + +- name: Fail if no configurations specified + fail: + msg: >- + You need to define at least one configuration in `matrix_dynamic_dns_domain_configurations` for using matrix-dynamic-dns. + when: "matrix_dynamic_dns_domain_configurations|length == 0" + +- name: Fail if required settings not defined in configuration blocks + fail: + msg: >- + One of the configurations in matrix_dynamic_dns_domain_configurations is missing a required key (domain, provider, protocol). + when: "'domain' not in configuration or 'provider' not in configuration or 'protocol' not in configuration" + with_items: "{{ matrix_dynamic_dns_domain_configurations }}" + loop_control: + loop_var: configuration diff --git a/roles/matrix-dynamic-dns/templates/ddclient.conf.j2 b/roles/matrix-dynamic-dns/templates/ddclient.conf.j2 new file mode 100644 index 00000000..1480d834 --- /dev/null +++ b/roles/matrix-dynamic-dns/templates/ddclient.conf.j2 @@ -0,0 +1,26 @@ +daemon={{ matrix_dynamic_dns_daemon_interval }} +syslog=no +pid=/var/run/ddclient/ddclient.pid +ssl=yes +use={{ matrix_dynamic_dns_use }} + +{% for dynamic_dns_domain_configuration in matrix_dynamic_dns_domain_configurations %} +protocol={{ dynamic_dns_domain_configuration.protocol }} +server={{ dynamic_dns_domain_configuration.provider }} {% if 'username' in dynamic_dns_domain_configuration %} +login='{{ dynamic_dns_domain_configuration.username }}' {% endif %} {% if 'password' in dynamic_dns_domain_configuration %} +password='{{ dynamic_dns_domain_configuration.password }}' {% endif %} {% if 'static' in dynamic_dns_domain_configuration %} +static=yes {% endif %} {% if 'custom' in dynamic_dns_domain_configuration %} +custom=yes {% endif %} {% if 'zone' in dynamic_dns_domain_configuration %} +zone={{ dynamic_dns_domain_configuration.zone }} {% endif %} {% if 'ttl' in dynamic_dns_domain_configuration %} +ttl={{ dynamic_dns_domain_configuration.ttl }} {% endif %} {% if 'mx' in dynamic_dns_domain_configuration %} +mx={{ dynamic_dns_domain_configuration.mx }} {% endif %} {% if 'wildcard' in dynamic_dns_domain_configuration %} +wildcard=yes {% endif %} +{{ dynamic_dns_domain_configuration.domain }} + +{% endfor %} + + +{% for matrix_dynamic_dns_additional_configuration in matrix_dynamic_dns_additional_configuration_blocks %} +{{ matrix_dynamic_dns_additional_configuration }} + +{% endfor %} diff --git a/roles/matrix-dynamic-dns/templates/systemd/matrix-dynamic-dns.service.j2 b/roles/matrix-dynamic-dns/templates/systemd/matrix-dynamic-dns.service.j2 new file mode 100644 index 00000000..df7d810a --- /dev/null +++ b/roles/matrix-dynamic-dns/templates/systemd/matrix-dynamic-dns.service.j2 @@ -0,0 +1,35 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix Dynamic DNS +{% for service in matrix_dynamic_dns_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_dynamic_dns_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +ExecStartPre=-{{ matrix_host_command_docker }} kill matrix-dynamic-dns +ExecStartPre=-{{ matrix_host_command_docker }} rm matrix-dynamic-dns +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-dynamic-dns \ + --log-driver=none \ + --network={{ matrix_docker_network }} \ + -e PUID={{ matrix_user_uid }} \ + -e PGID={{ matrix_user_gid }} \ + -v {{ matrix_dynamic_dns_config_path }}:/config:z \ + {% for arg in matrix_dynamic_dns_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_dynamic_dns_docker_image }} + +ExecStop=-{{ matrix_host_command_docker }} kill matrix-dynamic-dns +ExecStop=-{{ matrix_host_command_docker }} rm matrix-dynamic-dns +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-dynamic-dns + +[Install] +WantedBy=multi-user.target diff --git a/roles/matrix-email2matrix/defaults/main.yml b/roles/matrix-email2matrix/defaults/main.yml index 68ff1990..7917decf 100644 --- a/roles/matrix-email2matrix/defaults/main.yml +++ b/roles/matrix-email2matrix/defaults/main.yml @@ -3,7 +3,7 @@ matrix_email2matrix_enabled: true matrix_email2matrix_base_path: "{{ matrix_base_data_path }}/email2matrix" matrix_email2matrix_config_dir_path: "{{ matrix_email2matrix_base_path }}/config" -matrix_email2matrix_docker_image: "devture/email2matrix:1.0.1" +matrix_email2matrix_docker_image: "docker.io/devture/email2matrix:1.0.1" matrix_email2matrix_docker_image_force_pull: "{{ matrix_email2matrix_docker_image.endswith(':latest') }}" # A list of extra arguments to pass to the container diff --git a/roles/matrix-email2matrix/templates/systemd/matrix-email2matrix.service.j2 b/roles/matrix-email2matrix/templates/systemd/matrix-email2matrix.service.j2 index 52806f35..1577877b 100644 --- a/roles/matrix-email2matrix/templates/systemd/matrix-email2matrix.service.j2 +++ b/roles/matrix-email2matrix/templates/systemd/matrix-email2matrix.service.j2 @@ -3,6 +3,7 @@ Description=Email2Matrix After=docker.service Requires=docker.service +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-jitsi/defaults/main.yml b/roles/matrix-jitsi/defaults/main.yml index 7486821d..924198b4 100644 --- a/roles/matrix-jitsi/defaults/main.yml +++ b/roles/matrix-jitsi/defaults/main.yml @@ -4,8 +4,9 @@ matrix_jitsi_base_path: "{{ matrix_base_data_path }}/jitsi" matrix_jitsi_enable_auth: false matrix_jitsi_enable_guests: false -matrix_jitsi_enable_recording: true -matrix_jitsi_enable_transcriptions: true +matrix_jitsi_enable_recording: false +matrix_jitsi_enable_transcriptions: false +matrix_jitsi_enable_p2p: true # Authentication type, must be one of internal, jwt or ldap. Currently only # internal and ldap are supported by this playbook. @@ -51,9 +52,9 @@ matrix_jitsi_jibri_recorder_password: '' matrix_jitsi_enable_lobby: false -matrix_jitsi_container_image_tag: "stable-4857" +matrix_jitsi_container_image_tag: "stable-5142" -matrix_jitsi_web_docker_image: "jitsi/web:{{ matrix_jitsi_container_image_tag }}" +matrix_jitsi_web_docker_image: "docker.io/jitsi/web:{{ matrix_jitsi_container_image_tag }}" matrix_jitsi_web_docker_image_force_pull: "{{ matrix_jitsi_web_docker_image.endswith(':latest') }}" matrix_jitsi_web_base_path: "{{ matrix_base_data_path }}/jitsi/web" @@ -77,44 +78,88 @@ matrix_jitsi_web_container_extra_arguments: [] # List of systemd services that matrix-jitsi-web.service depends on matrix_jitsi_web_systemd_required_services_list: ['docker.service'] -matrix_jitsi_web_config_defaultLanguage: 'en' -matrix_jitsi_web_config_start_with_audio_muted: false -matrix_jitsi_web_config_start_with_video_muted: false -matrix_jitsi_web_config_testing_enableFirefoxSimulcast: false -matrix_jitsi_web_config_testing_p2pTestMode: false +# Some variables controlling the interface of Jitsi Web. +# These get applied to `templates/web/interface_config.js.j2`. +# +# Besides this, you can also use `matrix_jitsi_web_custom_interface_config_extension` +# to define any other configuration option. matrix_jitsi_web_interface_config_lang_detection: false matrix_jitsi_web_interface_config_show_jitsi_watermark: true matrix_jitsi_web_interface_config_jitsi_watermark_link: "https://jitsi.org" matrix_jitsi_web_interface_config_show_brand_watermark: false matrix_jitsi_web_interface_config_brand_watermark_link: "" -matrix_jitsi_web_interface_config_show_watermark_for_guests: true matrix_jitsi_web_interface_config_generate_room_names_on_welcome_page: true matrix_jitsi_web_interface_config_display_welcome_page_content: true matrix_jitsi_web_interface_config_app_name: "Jitsi Meet" matrix_jitsi_web_interface_config_native_app_name: "Jitsi Meet" matrix_jitsi_web_interface_config_provider_name: "Jitsi" -matrix_jitsi_web_interface_config_invitation_powered_by: true matrix_jitsi_web_interface_config_show_powered_by: false matrix_jitsi_web_interface_config_disable_transcription_subtitles: false matrix_jisti_web_interface_config_show_deep_linking_image: false -# Jitsi_web Fine Tune default values. -# Useful to manage bandwidth and CPU consumption in server and client side -matrix_jitsi_web_config_disableAudioLevels: false -matrix_jitsi_web_config_enableLayerSuspension: false -matrix_jitsi_web_config_channelLastN: -1 -# If 'matrix_jitsi_web_config_constraints_enabled: false' -# the video constraints will be disabled and will take the default values of jitsi -matrix_jitsi_web_config_constraints_enabled: false -# This settings work if matrix_jitsi_web_config_constraints_enabled: true -# See their definitions in config.js.j2 (templates / web) -matrix_jitsi_web_config_constraints_video_aspectRatio: 16 / 9 -matrix_jitsi_web_config_constraints_video_height_ideal: 720 -matrix_jitsi_web_config_constraints_video_height_max: 720 -matrix_jitsi_web_config_constraints_video_height_min: 240 +# Custom configuration to be injected into `interface_config.js`, passed to Jitsi Web. +# This configuration gets appended to the final interface configuration that Jitsi Web uses. +# +# Note: not to be confused with `matrix_jitsi_web_custom_config_extension`. +# +# For interface configuration, the flow is like this: +# - the contents of `templates/web/interface_config.js.j2` is generated (based on various `matrix_jitsi_web_interface_config_*` variables you see in this file) +# - the contents of `matrix_jitsi_web_custom_interface_config_extension` is appended and can define new settings or override defaults. +# +# Example: +# matrix_jitsi_web_custom_interface_config_extension: | +# interfaceConfig.CONNECTION_INDICATOR_AUTO_HIDE_ENABLED = false; +# interfaceConfig.DISABLE_VIDEO_BACKGROUND = true; +matrix_jitsi_web_custom_interface_config_extension: '' -matrix_jitsi_prosody_docker_image: "jitsi/prosody:{{ matrix_jitsi_container_image_tag }}" + +# Controls after which participant audio will be muted. If not specified, defaults to Jitsi's default value (likely 10) +matrix_jitsi_web_config_start_audio_muted_after_nth_participant: ~ +# Controls after which participant video will be muted. If not specified, defaults to Jitsi's default value (likely 10) +matrix_jitsi_web_config_start_video_muted_after_nth_participant: ~ + +matrix_jitsi_web_config_defaultLanguage: 'en' + +# Ideal and also maximum resolution width. If not specified, defaults to Jitsi's default value (likely 1280) +matrix_jitsi_web_config_resolution_width_ideal_and_max: ~ +# Minimum resolution width. If not specified, defaults to Jitsi's default value (likely 320) +matrix_jitsi_web_config_resolution_width_min: ~ +# Ideal and also maximum resolution height. If not specified, defaults to Jitsi's default value (likely 720) +matrix_jitsi_web_config_resolution_height_ideal_and_max: ~ +# Minimum resolution height. If not specified, defaults to Jitsi's default value (likely 180) +matrix_jitsi_web_config_resolution_height_min: ~ + +# Custom configuration to be injected into `custom-config.js`, passed to Jitsi Web. +# This configuration gets appended to the final configuration that Jitsi Web uses. +# +# Note: not to be confused with `matrix_jitsi_web_custom_interface_config_extension`. +# +# The flow is like this: +# - some default configuration is automatically generated based on the environment variables passed to the Jitsi Web container +# - the contents of `custom-config.js` is appended to it (see `templates/web/custom-config.js.j2`) +# - said `custom-config.js` contains your custom contents specified in `matrix_jitsi_web_custom_config_extension`. +# +# Example: +# matrix_jitsi_web_custom_config_extension: | +# if (!config.hasOwnProperty('testing')) config.testing = {}; +# config.testing.p2pTestMode = true +matrix_jitsi_web_custom_config_extension: '' + +# Additional environment variables to pass to the Jitsi Web container. +# You can use this to further influence the default configuration generated by the Jitsi Web container on every startup. +# Besides influencing the final configuration by passing environment variables, you can also inject custom configuration +# by using `matrix_jitsi_web_custom_config_extension`. +# +# Example: +# matrix_jitsi_web_environment_variables_extension: | +# ENABLE_FILE_RECORDING_SERVICE=1 +# DROPBOX_APPKEY=something +# DROPBOX_REDIRECT_URI=something +matrix_jitsi_web_environment_variables_extension: '' + + +matrix_jitsi_prosody_docker_image: "docker.io/jitsi/prosody:{{ matrix_jitsi_container_image_tag }}" matrix_jitsi_prosody_docker_image_force_pull: "{{ matrix_jitsi_prosody_docker_image.endswith(':latest') }}" matrix_jitsi_prosody_base_path: "{{ matrix_base_data_path }}/jitsi/prosody" @@ -128,7 +173,7 @@ matrix_jitsi_prosody_container_extra_arguments: [] matrix_jitsi_prosody_systemd_required_services_list: ['docker.service'] -matrix_jitsi_jicofo_docker_image: "jitsi/jicofo:{{ matrix_jitsi_container_image_tag }}" +matrix_jitsi_jicofo_docker_image: "docker.io/jitsi/jicofo:{{ matrix_jitsi_container_image_tag }}" matrix_jitsi_jicofo_docker_image_force_pull: "{{ matrix_jitsi_jicofo_docker_image.endswith(':latest') }}" matrix_jitsi_jicofo_base_path: "{{ matrix_base_data_path }}/jitsi/jicofo" @@ -145,7 +190,7 @@ matrix_jitsi_jicofo_auth_user: focus matrix_jitsi_jicofo_auth_password: '' -matrix_jitsi_jvb_docker_image: "jitsi/jvb:{{ matrix_jitsi_container_image_tag }}" +matrix_jitsi_jvb_docker_image: "docker.io/jitsi/jvb:{{ matrix_jitsi_container_image_tag }}" matrix_jitsi_jvb_docker_image_force_pull: "{{ matrix_jitsi_jvb_docker_image.endswith(':latest') }}" matrix_jitsi_jvb_base_path: "{{ matrix_base_data_path }}/jitsi/jvb" @@ -168,6 +213,31 @@ matrix_jitsi_jvb_brewery_muc: jvbbrewery matrix_jitsi_jvb_rtp_udp_port: 10000 matrix_jitsi_jvb_rtp_tcp_port: 4443 +# Custom configuration to be injected into `custom-sip-communicator.properties`, passed to Jitsi JVB. +# This configuration gets appended to the final configuration that Jitsi JVB uses. +# +# The flow is like this: +# - some default configuration is automatically generated based on the environment variables passed to the Jitsi JVB container +# - the contents of `custom-sip-communicator.properties` is appended to it (see `templates/jvb/custom-sip-communicator.properties.j2`) +# - said `custom-sip-communicator.properties` contains your custom contents specified in `matrix_jitsi_jvb_custom_config_extension`. +# +# Example: +# matrix_jitsi_jvb_custom_config_extension: | +# org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=false +# org.jitsi.videobridge.ENABLE_STATISTICS=false +matrix_jitsi_jvb_custom_config_extension: '' + +# Additional environment variables to pass to the Jitsi JVB container. +# You can use this to further influence the default configuration generated by the Jitsi JVB container on every startup. +# Besides influencing the final configuration by passing environment variables, you can also inject custom configuration +# by using `matrix_jitsi_jvb_custom_config_extension`. +# +# Example: +# matrix_jitsi_jvb_environment_variables_extension: | +# SOME_VARIABLE=1 +# ANOTHER_VARIABLE=something +matrix_jitsi_jvb_environment_variables_extension: '' + # Controls whether the matrix-jitsi-jvb container exposes its RTP UDP port (udp/10000 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:10000"), or empty string to not expose. @@ -177,3 +247,8 @@ matrix_jitsi_jvb_container_rtp_udp_host_bind_port: "{{ matrix_jitsi_jvb_rtp_udp_ # # Takes an ":" or "" value (e.g. "127.0.0.1:4443"), or empty string to not expose. matrix_jitsi_jvb_container_rtp_tcp_host_bind_port: "{{ matrix_jitsi_jvb_rtp_tcp_port }}" + +# Controls whether the matrix-jitsi-jvb container exposes its Colibri WebSocket port (tcp/9090 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:12090"), or empty string to not expose. +matrix_jitsi_jvb_container_colibri_ws_host_bind_port: '' diff --git a/roles/matrix-jitsi/tasks/setup_jitsi_jvb.yml b/roles/matrix-jitsi/tasks/setup_jitsi_jvb.yml index 09055b59..e4c7f277 100644 --- a/roles/matrix-jitsi/tasks/setup_jitsi_jvb.yml +++ b/roles/matrix-jitsi/tasks/setup_jitsi_jvb.yml @@ -30,7 +30,7 @@ dest: "{{ matrix_jitsi_jvb_config_path }}/{{ item }}" mode: 0644 with_items: - - sip-communicator.properties + - custom-sip-communicator.properties - logging.properties when: matrix_jitsi_enabled|bool diff --git a/roles/matrix-jitsi/tasks/setup_jitsi_web.yml b/roles/matrix-jitsi/tasks/setup_jitsi_web.yml index 6e5d20b0..3dd6f30c 100644 --- a/roles/matrix-jitsi/tasks/setup_jitsi_web.yml +++ b/roles/matrix-jitsi/tasks/setup_jitsi_web.yml @@ -38,7 +38,7 @@ dest: "{{ matrix_jitsi_web_config_path }}/{{ item }}" mode: 0644 with_items: - - config.js + - custom-config.js - interface_config.js when: matrix_jitsi_enabled|bool diff --git a/roles/matrix-jitsi/tasks/validate_config.yml b/roles/matrix-jitsi/tasks/validate_config.yml index ea92c914..bd939d3a 100644 --- a/roles/matrix-jitsi/tasks/validate_config.yml +++ b/roles/matrix-jitsi/tasks/validate_config.yml @@ -19,3 +19,24 @@ - "matrix_jitsi_jicofo_component_secret" - "matrix_jitsi_jicofo_auth_password" - "matrix_jitsi_jvb_auth_password" + +- name: (Deprecation) Catch and report renamed settings + fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please change your configuration to rename the variable (`{{ item.old }}` -> `{{ item.new }}`). + when: "item.old in vars" + with_items: + - {'old': 'matrix_jitsi_web_config_constraints_enabled', 'new': ''} + - {'old': 'matrix_jitsi_web_config_constraints_video_aspectRatio', 'new': ''} + - {'old': 'matrix_jitsi_web_config_constraints_video_height_ideal', 'new': 'matrix_jitsi_web_config_resolution_height_ideal_and_max'} + - {'old': 'matrix_jitsi_web_config_constraints_video_height_max', 'new': 'matrix_jitsi_web_config_resolution_height_ideal_and_max'} + - {'old': 'matrix_jitsi_web_config_constraints_video_height_min', 'new': 'matrix_jitsi_web_config_resolution_height_min'} + - {'old': 'matrix_jitsi_web_config_disableAudioLevels', 'new': ''} + - {'old': 'matrix_jitsi_web_config_enableLayerSuspension', 'new': ''} + - {'old': 'matrix_jitsi_web_config_channelLastN', 'new': ''} + - {'old': 'matrix_jitsi_web_config_testing_p2pTestMode', 'new': ''} + - {'old': 'matrix_jitsi_web_config_start_with_audio_muted', 'new': ''} + - {'old': 'matrix_jitsi_web_config_start_with_video_muted', 'new': ''} + - {'old': 'matrix_jitsi_web_interface_config_show_watermark_for_guests', 'new': ''} + - {'old': 'matrix_jitsi_web_interface_config_invitation_powered_by', 'new': ''} diff --git a/roles/matrix-jitsi/templates/jicofo/matrix-jitsi-jicofo.service.j2 b/roles/matrix-jitsi/templates/jicofo/matrix-jitsi-jicofo.service.j2 index 3512b3af..6b5cc941 100644 --- a/roles/matrix-jitsi/templates/jicofo/matrix-jitsi-jicofo.service.j2 +++ b/roles/matrix-jitsi/templates/jicofo/matrix-jitsi-jicofo.service.j2 @@ -5,6 +5,7 @@ Description=Matrix jitsi-jicofo server Requires={{ service }} After={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -15,7 +16,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-jitsi-jicofo \ --log-driver=none \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_jitsi_jicofo_base_path }}/env \ - -v {{ matrix_jitsi_jicofo_config_path }}:/config \ + --mount type=bind,src={{ matrix_jitsi_jicofo_config_path }},dst=/config \ {% for arg in matrix_jitsi_jicofo_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-jitsi/templates/jvb/custom-sip-communicator.properties.j2 b/roles/matrix-jitsi/templates/jvb/custom-sip-communicator.properties.j2 new file mode 100644 index 00000000..44b6b8c2 --- /dev/null +++ b/roles/matrix-jitsi/templates/jvb/custom-sip-communicator.properties.j2 @@ -0,0 +1,7 @@ +org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=true + +org.jitsi.videobridge.ENABLE_STATISTICS=true +org.jitsi.videobridge.STATISTICS_TRANSPORT=muc +org.jitsi.videobridge.STATISTICS_INTERVAL=5000 + +{{ matrix_jitsi_jvb_custom_config_extension }} diff --git a/roles/matrix-jitsi/templates/jvb/env.j2 b/roles/matrix-jitsi/templates/jvb/env.j2 index 423070db..f7dc9247 100644 --- a/roles/matrix-jitsi/templates/jvb/env.j2 +++ b/roles/matrix-jitsi/templates/jvb/env.j2 @@ -1 +1,20 @@ JVB_AUTH_PASSWORD={{ matrix_jitsi_jvb_auth_password }} +JVB_TCP_PORT={{ matrix_jitsi_jvb_rtp_tcp_port }} +JVB_PORT={{ matrix_jitsi_jvb_rtp_udp_port }} +JVB_AUTH_USER={{ matrix_jitsi_jvb_auth_user }} +JVB_AUTH_PASSWORD={{ matrix_jitsi_jvb_auth_password }} +JVB_BREWERY_MUC={{ matrix_jitsi_jvb_brewery_muc }} + +XMPP_SERVER={{ matrix_jitsi_xmpp_server }} +XMPP_AUTH_DOMAIN={{ matrix_jitsi_xmpp_auth_domain }} +XMPP_INTERNAL_MUC_DOMAIN={{ matrix_jitsi_xmpp_internal_muc_domain }} + +HOSTNAME=matrix-jitsi-jvb + +{% if matrix_jitsi_jvb_stun_servers|length > 0 %} +JVB_STUN_SERVERS={{ matrix_jitsi_jvb_stun_servers|join(',') }} +{% endif %} + +PUBLIC_URL={{ matrix_jitsi_web_public_url }} + +{{ matrix_jitsi_jvb_environment_variables_extension }} diff --git a/roles/matrix-jitsi/templates/jvb/matrix-jitsi-jvb.service.j2 b/roles/matrix-jitsi/templates/jvb/matrix-jitsi-jvb.service.j2 index a189df9c..2931133f 100644 --- a/roles/matrix-jitsi/templates/jvb/matrix-jitsi-jvb.service.j2 +++ b/roles/matrix-jitsi/templates/jvb/matrix-jitsi-jvb.service.j2 @@ -5,6 +5,7 @@ Description=Matrix jitsi-jvb server Requires={{ service }} After={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -21,7 +22,10 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-jitsi-jvb \ {% if matrix_jitsi_jvb_container_rtp_tcp_host_bind_port %} -p {{ matrix_jitsi_jvb_container_rtp_tcp_host_bind_port }}:{{ matrix_jitsi_jvb_rtp_tcp_port }} \ {% endif %} - -v {{ matrix_jitsi_jvb_config_path }}:/config \ + {% if matrix_jitsi_jvb_container_colibri_ws_host_bind_port %} + -p {{ matrix_jitsi_jvb_container_colibri_ws_host_bind_port }}:9090 \ + {% endif %} + --mount type=bind,src={{ matrix_jitsi_jvb_config_path }},dst=/config \ {% for arg in matrix_jitsi_jvb_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-jitsi/templates/jvb/sip-communicator.properties.j2 b/roles/matrix-jitsi/templates/jvb/sip-communicator.properties.j2 deleted file mode 100644 index 173af0b6..00000000 --- a/roles/matrix-jitsi/templates/jvb/sip-communicator.properties.j2 +++ /dev/null @@ -1,19 +0,0 @@ -org.jitsi.videobridge.SINGLE_PORT_HARVESTER_PORT={{ matrix_jitsi_jvb_rtp_udp_port }} -org.jitsi.videobridge.DISABLE_TCP_HARVESTER=false -org.jitsi.videobridge.TCP_HARVESTER_PORT={{ matrix_jitsi_jvb_rtp_tcp_port }} - -{% if matrix_jitsi_jvb_stun_servers|length > 0 %} -org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES={{ matrix_jitsi_jvb_stun_servers|join(',') }} -{% endif %} - -org.jitsi.videobridge.xmpp.user.shard.HOSTNAME={{ matrix_jitsi_xmpp_server }} -org.jitsi.videobridge.xmpp.user.shard.DOMAIN={{ matrix_jitsi_xmpp_auth_domain }} -org.jitsi.videobridge.xmpp.user.shard.USERNAME={{ matrix_jitsi_jvb_auth_user }} -org.jitsi.videobridge.xmpp.user.shard.PASSWORD={{ matrix_jitsi_jvb_auth_password }} -org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS={{ matrix_jitsi_jvb_brewery_muc }}@{{ matrix_jitsi_xmpp_internal_muc_domain }} -org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=matrix-jitsi-jvb -org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=true - -org.jitsi.videobridge.ENABLE_STATISTICS=true -org.jitsi.videobridge.STATISTICS_TRANSPORT=muc -org.jitsi.videobridge.STATISTICS_INTERVAL=5000 diff --git a/roles/matrix-jitsi/templates/prosody/matrix-jitsi-prosody.service.j2 b/roles/matrix-jitsi/templates/prosody/matrix-jitsi-prosody.service.j2 index 30801d77..4f532d89 100644 --- a/roles/matrix-jitsi/templates/prosody/matrix-jitsi-prosody.service.j2 +++ b/roles/matrix-jitsi/templates/prosody/matrix-jitsi-prosody.service.j2 @@ -5,6 +5,7 @@ Description=Matrix jitsi-prosody server Requires={{ service }} After={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -15,8 +16,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-jitsi-prosody --log-driver=none \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_jitsi_prosody_base_path }}/env \ - -v {{ matrix_jitsi_prosody_config_path }}:/config \ - -v {{ matrix_jitsi_prosody_plugins_path }}:/prosody-plugins-custom \ + --mount type=bind,src={{ matrix_jitsi_prosody_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_jitsi_prosody_plugins_path }},dst=/prosody-plugins-custom \ {% for arg in matrix_jitsi_prosody_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-jitsi/templates/web/config.js.j2 b/roles/matrix-jitsi/templates/web/config.js.j2 deleted file mode 100644 index ad0e5410..00000000 --- a/roles/matrix-jitsi/templates/web/config.js.j2 +++ /dev/null @@ -1,491 +0,0 @@ -/* eslint-disable no-unused-vars, no-var */ - -var config = { - // Configuration - // - - // Alternative location for the configuration. - // configLocation: './config.json', - - // Custom function which given the URL path should return a room name. - // getroomnode: function (path) { return 'someprefixpossiblybasedonpath'; }, - - - // Connection - // - - hosts: { - // XMPP domain. - domain: '{{ matrix_jitsi_xmpp_domain }}', - - {% if matrix_jitsi_enable_auth %} - {% if matrix_jitsi_enable_guests %} - // When using authentication, domain for guest users. - anonymousdomain: '{{ matrix_jitsi_xmpp_guest_domain }}', - {% endif %} - - // Domain for authenticated users. Defaults to . - authdomain: '{{ matrix_jitsi_xmpp_domain }}', - {% endif %} - - // Jirecon recording component domain. - // jirecon: 'jirecon.{{ matrix_jitsi_xmpp_domain }}', - - // Call control component (Jigasi). - // call_control: 'callcontrol.{{ matrix_jitsi_xmpp_domain }}', - - // Focus component domain. Defaults to focus.. - // focus: 'focus.{{ matrix_jitsi_xmpp_domain }}', - - // XMPP MUC domain. FIXME: use XEP-0030 to discover it. - muc: {{ matrix_jitsi_xmpp_muc_domain|to_json }}, - }, - - // BOSH URL. FIXME: use XEP-0156 to discover it. - bosh: '/http-bind', - - // The name of client node advertised in XEP-0115 'c' stanza - clientNode: 'http://jitsi.org/jitsimeet', - - // The real JID of focus participant - can be overridden here - focusUserJid: {{ matrix_jitsi_jicofo_auth_user|to_json }} + '@' + {{ matrix_jitsi_xmpp_auth_domain|to_json }}, - - - // Testing / experimental features. - // - - testing: { - // Enables experimental simulcast support on Firefox. - enableFirefoxSimulcast: {{ matrix_jitsi_web_config_testing_enableFirefoxSimulcast|to_json }}, - - // P2P test mode disables automatic switching to P2P when there are 2 - // participants in the conference. - p2pTestMode: {{ matrix_jitsi_web_config_testing_p2pTestMode|to_json }} - - // Enables the test specific features consumed by jitsi-meet-torture - // testMode: false - }, - - // Disables ICE/UDP by filtering out local and remote UDP candidates in - // signalling. - // webrtcIceUdpDisable: false, - - // Disables ICE/TCP by filtering out local and remote TCP candidates in - // signalling. - // webrtcIceTcpDisable: false, - - - // Media - // - - // Audio - - // Disable measuring of audio levels. - disableAudioLevels: {{ matrix_jitsi_web_config_disableAudioLevels|to_json }}, - - // Start the conference in audio only mode (no video is being received nor - // sent). - // startAudioOnly: false, - - // Every participant after the Nth will start audio muted. - // startAudioMuted: 10, - - // Start calls with audio muted. Unlike the option above, this one is only - // applied locally. FIXME: having these 2 options is confusing. - // startWithAudioMuted: false, - startWithAudioMuted: {{ matrix_jitsi_web_config_start_with_audio_muted|to_json }}, - - // Enabling it (with #params) will disable local audio output of remote - // participants and to enable it back a reload is needed. - // startSilent: false - - // Video - - // Sets the preferred resolution (height) for local video. Defaults to 720. - // resolution: 720, - - // w3c spec-compliant video constraints to use for video capture. Currently - // used by browsers that return true from lib-jitsi-meet's - // util#browser#usesNewGumFlow. The constraints are independency from - // this config's resolution value. Defaults to requesting an ideal aspect - // ratio of 16:9 with an ideal resolution of 720. - {% if matrix_jitsi_web_config_constraints_enabled %} - constraints: { - video: { - aspectRatio: {{ matrix_jitsi_web_config_constraints_video_aspectRatio }}, - height: { - ideal: {{ matrix_jitsi_web_config_constraints_video_height_ideal|to_json }}, - max: {{ matrix_jitsi_web_config_constraints_video_height_max|to_json }}, - min: {{ matrix_jitsi_web_config_constraints_video_height_min|to_json }} - } - } - }, - {% endif %} - // Enable / disable simulcast support. - // disableSimulcast: false, - - // Enable / disable layer suspension. If enabled, endpoints whose HD - // layers are not in use will be suspended (no longer sent) until they - // are requested again. - enableLayerSuspension: {{ matrix_jitsi_web_config_enableLayerSuspension|to_json }}, - - // Suspend sending video if bandwidth estimation is too low. This may cause - // problems with audio playback. Disabled until these are fixed. - disableSuspendVideo: true, - - // Every participant after the Nth will start video muted. - // startVideoMuted: 10, - - // Start calls with video muted. Unlike the option above, this one is only - // applied locally. FIXME: having these 2 options is confusing. - // startWithVideoMuted: false, - startWithVideoMuted: {{ matrix_jitsi_web_config_start_with_video_muted|to_json }}, - - // If set to true, prefer to use the H.264 video codec (if supported). - // Note that it's not recommended to do this because simulcast is not - // supported when using H.264. For 1-to-1 calls this setting is enabled by - // default and can be toggled in the p2p section. - // preferH264: true, - - // If set to true, disable H.264 video codec by stripping it out of the - // SDP. - // disableH264: false, - - // Desktop sharing - - // The ID of the jidesha extension for Chrome. - desktopSharingChromeExtId: null, - - // Whether desktop sharing should be disabled on Chrome. - // desktopSharingChromeDisabled: false, - - // The media sources to use when using screen sharing with the Chrome - // extension. - desktopSharingChromeSources: [ 'screen', 'window', 'tab' ], - - // Required version of Chrome extension - desktopSharingChromeMinExtVersion: '0.1', - - // Whether desktop sharing should be disabled on Firefox. - // desktopSharingFirefoxDisabled: false, - - // Optional desktop sharing frame rate options. Default value: min:5, max:5. - // desktopSharingFrameRate: { - // min: 5, - // max: 5 - // }, - - // Try to start calls with screen-sharing instead of camera video. - // startScreenSharing: false, - - // Recording -hiddenDomain: {{ matrix_jitsi_recorder_domain|to_json }}, - - // Whether to enable file recording or not. - fileRecordingsEnabled: {{ matrix_jitsi_enable_recording|to_json }}, - // Enable the dropbox integration. - // dropbox: { - // appKey: '' // Specify your app key here. - // // A URL to redirect the user to, after authenticating - // // by default uses: - // // 'https://{{ matrix_jitsi_xmpp_domain }}/static/oauth.html' - // redirectURI: - // 'https://{{ matrix_jitsi_xmpp_domain }}/subfolder/static/oauth.html' - // }, - // When integrations like dropbox are enabled only that will be shown, - // by enabling fileRecordingsServiceEnabled, we show both the integrations - // and the generic recording service (its configuration and storage type - // depends on jibri configuration) - // fileRecordingsServiceEnabled: false, - // Whether to show the possibility to share file recording with other people - // (e.g. meeting participants), based on the actual implementation - // on the backend. - // fileRecordingsServiceSharingEnabled: false, - - // Whether to enable live streaming or not. - liveStreamingEnabled: {{ matrix_jitsi_enable_recording|to_json }}, - - // Transcription (in interface_config, - // subtitles and buttons can be configured) - transcribingEnabled: {{ matrix_jitsi_enable_transcriptions|to_json }}, - - // Misc - - // Default value for the channel "last N" attribute. -1 for unlimited. - channelLastN: {{ matrix_jitsi_web_config_channelLastN|to_json }}, - - // Disables or enables RTX (RFC 4588) (defaults to false). - // disableRtx: false, - - // Disables or enables TCC (the default is in Jicofo and set to true) - // (draft-holmer-rmcat-transport-wide-cc-extensions-01). This setting - // affects congestion control, it practically enables send-side bandwidth - // estimations. - // enableTcc: true, - - // Disables or enables REMB (the default is in Jicofo and set to false) - // (draft-alvestrand-rmcat-remb-03). This setting affects congestion - // control, it practically enables recv-side bandwidth estimations. When - // both TCC and REMB are enabled, TCC takes precedence. When both are - // disabled, then bandwidth estimations are disabled. - // enableRemb: false, - - // Defines the minimum number of participants to start a call (the default - // is set in Jicofo and set to 2). - // minParticipants: 2, - - // Use XEP-0215 to fetch STUN and TURN servers. - // useStunTurn: true, - - // Enable IPv6 support. - // useIPv6: true, - - // Enables / disables a data communication channel with the Videobridge. - // Values can be 'datachannel', 'websocket', true (treat it as - // 'datachannel'), undefined (treat it as 'datachannel') and false (don't - // open any channel). - // openBridgeChannel: true, - - - // UI - // - - // Use display name as XMPP nickname. - // useNicks: false, - - // Require users to always specify a display name. - // requireDisplayName: true, - - // Whether to use a welcome page or not. In case it's false a random room - // will be joined when no room is specified. - enableWelcomePage: true, - - // Enabling the close page will ignore the welcome page redirection when - // a call is hangup. - // enableClosePage: false, - - // Disable hiding of remote thumbnails when in a 1-on-1 conference call. - // disable1On1Mode: false, - - // Default language for the user interface. - defaultLanguage: {{ matrix_jitsi_web_config_defaultLanguage|to_json }}, - - // If true all users without a token will be considered guests and all users - // with token will be considered non-guests. Only guests will be allowed to - // edit their profile. - enableUserRolesBasedOnToken: false, - - // Whether or not some features are checked based on token. - // enableFeaturesBasedOnToken: false, - - // Enable lock room for all moderators, even when userRolesBasedOnToken is enabled and participants are guests. - // lockRoomGuestEnabled: false, - - // When enabled the password used for locking a room is restricted to up to the number of digits specified - // roomPasswordNumberOfDigits: 10, - // default: roomPasswordNumberOfDigits: false, - - // Message to show the users. Example: 'The service will be down for - // maintenance at 01:00 AM GMT, - // noticeMessage: '', - - // Enables calendar integration, depends on googleApiApplicationClientID - // and microsoftApiApplicationClientID - // enableCalendarIntegration: false, - - // Stats - // - - // Whether to enable stats collection or not in the TraceablePeerConnection. - // This can be useful for debugging purposes (post-processing/analysis of - // the webrtc stats) as it is done in the jitsi-meet-torture bandwidth - // estimation tests. - // gatherStats: false, - - // To enable sending statistics to callstats.io you must provide the - // Application ID and Secret. - // callStatsID: '', - // callStatsSecret: '', - - // enables callstatsUsername to be reported as statsId and used - // by callstats as repoted remote id - // enableStatsID: false - - // enables sending participants display name to callstats - // enableDisplayNameInStats: false - - - // Privacy - // - - // If third party requests are disabled, no other server will be contacted. - // This means avatars will be locally generated and callstats integration - // will not function. - // disableThirdPartyRequests: false, - - - // Peer-To-Peer mode: used (if enabled) when there are just 2 participants. - // - - p2p: { - // Enables peer to peer mode. When enabled the system will try to - // establish a direct connection when there are exactly 2 participants - // in the room. If that succeeds the conference will stop sending data - // through the JVB and use the peer to peer connection instead. When a - // 3rd participant joins the conference will be moved back to the JVB - // connection. - enabled: true, - - // Use XEP-0215 to fetch STUN and TURN servers. - // useStunTurn: true, - - // The STUN servers that will be used in the peer to peer connections - {% if matrix_jitsi_web_stun_servers|length > 0 %} - stunServers: [ - {% for url in matrix_jitsi_web_stun_servers %} - { urls: {{ url|to_json }} }{% if not loop.last %},{% endif %} - {% endfor %} - ], - {% endif %} - - // Sets the ICE transport policy for the p2p connection. At the time - // of this writing the list of possible values are 'all' and 'relay', - // but that is subject to change in the future. The enum is defined in - // the WebRTC standard: - // https://www.w3.org/TR/webrtc/#rtcicetransportpolicy-enum. - // If not set, the effective value is 'all'. - // iceTransportPolicy: 'all', - - // If set to true, it will prefer to use H.264 for P2P calls (if H.264 - // is supported). - preferH264: true - - // If set to true, disable H.264 video codec by stripping it out of the - // SDP. - // disableH264: false, - - // How long we're going to wait, before going back to P2P after the 3rd - // participant has left the conference (to filter out page reload). - // backToP2PDelay: 5 - }, - - analytics: { - // The Google Analytics Tracking ID: - // googleAnalyticsTrackingId: 'your-tracking-id-UA-123456-1' - - // The Amplitude APP Key: - // amplitudeAPPKey: '' - - // Array of script URLs to load as lib-jitsi-meet "analytics handlers". - // scriptURLs: [ - // "libs/analytics-ga.min.js", // google-analytics - // "https://example.com/my-custom-analytics.js" - // ], - }, - - // Information about the jitsi-meet instance we are connecting to, including - // the user region as seen by the server. - deploymentInfo: { - // shard: "shard1", - // region: "europe", - // userRegion: "asia" - } - - // Local Recording - // - - // localRecording: { - // Enables local recording. - // Additionally, 'localrecording' (all lowercase) needs to be added to - // TOOLBAR_BUTTONS in interface_config.js for the Local Recording - // button to show up on the toolbar. - // - // enabled: true, - // - - // The recording format, can be one of 'ogg', 'flac' or 'wav'. - // format: 'flac' - // - - // } - - // Options related to end-to-end (participant to participant) ping. - // e2eping: { - // // The interval in milliseconds at which pings will be sent. - // // Defaults to 10000, set to <= 0 to disable. - // pingInterval: 10000, - // - // // The interval in milliseconds at which analytics events - // // with the measured RTT will be sent. Defaults to 60000, set - // // to <= 0 to disable. - // analyticsInterval: 60000, - // } - - // If set, will attempt to use the provided video input device label when - // triggering a screenshare, instead of proceeding through the normal flow - // for obtaining a desktop stream. - // NOTE: This option is experimental and is currently intended for internal - // use only. - // _desktopSharingSourceDevice: 'sample-id-or-label' - - // If true, any checks to handoff to another application will be prevented - // and instead the app will continue to display in the current browser. - // disableDeepLinking: false - - // A property to disable the right click context menu for localVideo - // the menu has option to flip the locally seen video for local presentations - // disableLocalVideoFlip: false - - // List of undocumented settings used in jitsi-meet - /** - _immediateReloadThreshold - autoRecord - autoRecordToken - debug - debugAudioLevels - deploymentInfo - dialInConfCodeUrl - dialInNumbersUrl - dialOutAuthUrl - dialOutCodesUrl - disableRemoteControl - displayJids - etherpad_base - externalConnectUrl - firefox_fake_device - googleApiApplicationClientID - iAmRecorder - iAmSipGateway - microsoftApiApplicationClientID - peopleSearchQueryTypes - peopleSearchUrl - requireDisplayName - tokenAuthUrl - */ - - // List of undocumented settings used in lib-jitsi-meet - /** - _peerConnStatusOutOfLastNTimeout - _peerConnStatusRtcMuteTimeout - abTesting - avgRtpStatsN - callStatsConfIDNamespace - callStatsCustomScriptUrl - desktopSharingSources - disableAEC - disableAGC - disableAP - disableHPF - disableNS - enableLipSync - enableTalkWhileMuted - forceJVB121Ratio - hiddenDomain - ignoreStartMuted - nick - startBitrate - */ - -}; - -/* eslint-enable no-unused-vars, no-var */ diff --git a/roles/matrix-jitsi/templates/web/custom-config.js.j2 b/roles/matrix-jitsi/templates/web/custom-config.js.j2 new file mode 100644 index 00000000..02316ca0 --- /dev/null +++ b/roles/matrix-jitsi/templates/web/custom-config.js.j2 @@ -0,0 +1,15 @@ +config.defaultLanguage = {{ matrix_jitsi_web_config_defaultLanguage|to_json }}; + + +if (!config.hasOwnProperty('p2p')) config.p2p = {% raw %}{}{% endraw %}; + +{% if matrix_jitsi_web_stun_servers|length > 0 %} +config.p2p.stunServers = [ + {% for url in matrix_jitsi_web_stun_servers %} + { urls: {{ url|to_json }} }{% if not loop.last %},{% endif %} + {% endfor %} +]; +{% 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 b85e9af5..353a3d14 100644 --- a/roles/matrix-jitsi/templates/web/env.j2 +++ b/roles/matrix-jitsi/templates/web/env.j2 @@ -3,6 +3,8 @@ ENABLE_GUESTS={{ 1 if matrix_jitsi_enable_guests else 0 }} ENABLE_TRANSCRIPTIONS={{ 1 if matrix_jitsi_enable_transcriptions else 0 }} +ENABLE_P2P={{ 1 if matrix_jitsi_enable_p2p else 0 }} + DISABLE_HTTPS=1 JICOFO_AUTH_USER={{ matrix_jitsi_jicofo_auth_user }} @@ -26,3 +28,13 @@ JIBRI_RECORDER_USER={{ matrix_jitsi_jibri_recorder_user }} JIBRI_RECORDER_PASSWORD={{ matrix_jitsi_jibri_recorder_password }} ENABLE_RECORDING={{ 1 if matrix_jitsi_enable_recording else 0 }} + +RESOLUTION={{ matrix_jitsi_web_config_resolution_height_ideal_and_max }} +RESOLUTION_MIN={{ matrix_jitsi_web_config_resolution_height_min }} +RESOLUTION_WIDTH={{ matrix_jitsi_web_config_resolution_width_ideal_and_max }} +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 }} + +{{ matrix_jitsi_web_environment_variables_extension }} diff --git a/roles/matrix-jitsi/templates/web/interface_config.js.j2 b/roles/matrix-jitsi/templates/web/interface_config.js.j2 index c56f8c8c..a12ca973 100644 --- a/roles/matrix-jitsi/templates/web/interface_config.js.j2 +++ b/roles/matrix-jitsi/templates/web/interface_config.js.j2 @@ -1,137 +1,23 @@ /* eslint-disable no-unused-vars, no-var, max-len */ +/* eslint sort-keys: ["error", "asc", {"caseSensitive": false}] */ var interfaceConfig = { - // TO FIX: this needs to be handled from SASS variables. There are some - // methods allowing to use variables both in css and js. - DEFAULT_BACKGROUND: '#474747', - - /** - * Whether or not the blurred video background for large video should be - * displayed on browsers that can support it. - */ - DISABLE_VIDEO_BACKGROUND: false, - - INITIAL_TOOLBAR_TIMEOUT: 20000, - TOOLBAR_TIMEOUT: 4000, - TOOLBAR_ALWAYS_VISIBLE: false, - DEFAULT_REMOTE_DISPLAY_NAME: 'Fellow Jitster', - DEFAULT_LOCAL_DISPLAY_NAME: 'me', - SHOW_JITSI_WATERMARK: {{ matrix_jitsi_web_interface_config_show_jitsi_watermark|to_json }}, - JITSI_WATERMARK_LINK: {{ matrix_jitsi_web_interface_config_jitsi_watermark_link|to_json }}, - - // if watermark is disabled by default, it can be shown only for guests - SHOW_WATERMARK_FOR_GUESTS: {{ matrix_jitsi_web_interface_config_show_watermark_for_guests|to_json }}, - SHOW_BRAND_WATERMARK: {{ matrix_jitsi_web_interface_config_show_brand_watermark|to_json }}, - BRAND_WATERMARK_LINK: {{ matrix_jitsi_web_interface_config_brand_watermark_link|to_json }}, - SHOW_POWERED_BY: {{ matrix_jitsi_web_interface_config_show_powered_by|to_json }}, - SHOW_DEEP_LINKING_IMAGE: {{ matrix_jisti_web_interface_config_show_deep_linking_image|to_json }}, - GENERATE_ROOMNAMES_ON_WELCOME_PAGE: {{ matrix_jitsi_web_interface_config_generate_room_names_on_welcome_page|to_json }}, - DISPLAY_WELCOME_PAGE_CONTENT: {{ matrix_jitsi_web_interface_config_display_welcome_page_content|to_json }}, APP_NAME: {{ matrix_jitsi_web_interface_config_app_name|to_json }}, - NATIVE_APP_NAME: {{ matrix_jitsi_web_interface_config_native_app_name|to_json }}, - PROVIDER_NAME: {{ matrix_jitsi_web_interface_config_provider_name|to_json }}, - LANG_DETECTION: {{ matrix_jitsi_web_interface_config_lang_detection|to_json }}, // Allow i18n to detect the system language - INVITATION_POWERED_BY: {{ matrix_jitsi_web_interface_config_invitation_powered_by|to_json }}, - - /** - * If we should show authentication block in profile - */ - AUTHENTICATION_ENABLE: true, - - /** - * The name of the toolbar buttons to display in the toolbar. If present, - * the button will display. Exceptions are "livestreaming" and "recording" - * which also require being a moderator and some values in config.js to be - * enabled. Also, the "profile" button will not display for user's with a - * jwt. - */ - TOOLBAR_BUTTONS: [ - {% if matrix_jitsi_enable_transcriptions %} - 'closedcaptions', - {% endif %} - - 'microphone', 'camera', 'desktop', 'fullscreen', - 'fodeviceselection', 'hangup', 'profile', 'info', 'chat', 'recording', - 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand', - 'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts', - 'tileview', 'videobackgroundblur' - ], - - SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar' ], - - // Determines how the video would fit the screen. 'both' would fit the whole - // screen, 'height' would fit the original video height to the height of the - // screen, 'width' would fit the original video width to the width of the - // screen respecting ratio. - VIDEO_LAYOUT_FIT: 'both', - - /** - * Whether to only show the filmstrip (and hide the toolbar). - */ - filmStripOnly: false, - - /** - * Whether to show thumbnails in filmstrip as a column instead of as a row. - */ - VERTICAL_FILMSTRIP: true, - - // A html text to be shown to guests on the close page, false disables it - CLOSE_PAGE_GUEST_HINT: false, - RANDOM_AVATAR_URL_PREFIX: false, - RANDOM_AVATAR_URL_SUFFIX: false, - FILM_STRIP_MAX_HEIGHT: 120, - - // Enables feedback star animation. - ENABLE_FEEDBACK_ANIMATION: false, - DISABLE_FOCUS_INDICATOR: false, - DISABLE_DOMINANT_SPEAKER_INDICATOR: false, - - /** - * Whether the speech to text transcription subtitles panel is disabled. - * If {@code undefined}, defaults to {@code false}. - * - * @type {boolean} - */ - DISABLE_TRANSCRIPTION_SUBTITLES: {{ matrix_jitsi_web_interface_config_disable_transcription_subtitles|to_json }}, - - /** - * Whether the ringing sound in the call/ring overlay is disabled. If - * {@code undefined}, defaults to {@code false}. - * - * @type {boolean} - */ - DISABLE_RINGING: false, AUDIO_LEVEL_PRIMARY_COLOR: 'rgba(255,255,255,0.4)', AUDIO_LEVEL_SECONDARY_COLOR: 'rgba(255,255,255,0.2)', - POLICY_LOGO: null, - LOCAL_THUMBNAIL_RATIO: 16 / 9, // 16:9 - REMOTE_THUMBNAIL_RATIO: 1, // 1:1 - // Documentation reference for the live streaming feature. - LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live', /** - * Whether the mobile app Jitsi Meet is to be promoted to participants - * attempting to join a conference in a mobile Web browser. If - * {@code undefined}, defaults to {@code true}. + * A UX mode where the last screen share participant is automatically + * pinned. Valid values are the string "remote-only" so remote participants + * get pinned but not local, otherwise any truthy value for all participants, + * and any falsy value to disable the feature. * - * @type {boolean} + * Note: this mode is experimental and subject to breakage. */ - MOBILE_APP_PROMO: true, - - /** - * Maximum coeficient of the ratio of the large video to the visible area - * after the large video is scaled to fit the window. - * - * @type {number} - */ - MAXIMUM_ZOOMING_COEFFICIENT: 1.3, - - /* - * If indicated some of the error dialogs may point to the support URL for - * help. - */ - SUPPORT_URL: 'https://github.com/jitsi/jitsi-meet/issues/new', + AUTO_PIN_LATEST_SCREEN_SHARE: 'remote-only', + BRAND_WATERMARK_LINK: {{ matrix_jitsi_web_interface_config_brand_watermark_link|to_json }}, + CLOSE_PAGE_GUEST_HINT: false, // A html text to be shown to guests on the close page, false disables it /** * Whether the connection indicator icon should hide itself based on * connection strength. If true, the connection indicator will remain @@ -158,6 +44,194 @@ var interfaceConfig = { */ CONNECTION_INDICATOR_DISABLED: false, + DEFAULT_BACKGROUND: '#474747', + DEFAULT_LOCAL_DISPLAY_NAME: 'me', + DEFAULT_LOGO_URL: 'images/watermark.svg', + DEFAULT_REMOTE_DISPLAY_NAME: 'Fellow Jitster', + DEFAULT_WELCOME_PAGE_LOGO_URL: 'images/watermark.svg', + + DISABLE_DOMINANT_SPEAKER_INDICATOR: false, + + DISABLE_FOCUS_INDICATOR: false, + + /** + * If true, notifications regarding joining/leaving are no longer displayed. + */ + DISABLE_JOIN_LEAVE_NOTIFICATIONS: false, + + /** + * If true, presence status: busy, calling, connected etc. is not displayed. + */ + DISABLE_PRESENCE_STATUS: false, + + /** + * Whether the ringing sound in the call/ring overlay is disabled. If + * {@code undefined}, defaults to {@code false}. + * + * @type {boolean} + */ + DISABLE_RINGING: false, + + /** + * Whether the speech to text transcription subtitles panel is disabled. + * If {@code undefined}, defaults to {@code false}. + * + * @type {boolean} + */ + DISABLE_TRANSCRIPTION_SUBTITLES: {{ matrix_jitsi_web_interface_config_disable_transcription_subtitles|to_json }}, + + /** + * Whether or not the blurred video background for large video should be + * displayed on browsers that can support it. + */ + DISABLE_VIDEO_BACKGROUND: false, + + DISPLAY_WELCOME_FOOTER: true, + DISPLAY_WELCOME_PAGE_ADDITIONAL_CARD: false, + DISPLAY_WELCOME_PAGE_CONTENT: {{ matrix_jitsi_web_interface_config_display_welcome_page_content|to_json }}, + DISPLAY_WELCOME_PAGE_TOOLBAR_ADDITIONAL_CONTENT: false, + + ENABLE_DIAL_OUT: true, + + ENABLE_FEEDBACK_ANIMATION: false, // Enables feedback star animation. + + FILM_STRIP_MAX_HEIGHT: 120, + + GENERATE_ROOMNAMES_ON_WELCOME_PAGE: {{ matrix_jitsi_web_interface_config_generate_room_names_on_welcome_page|to_json }}, + + /** + * Hide the logo on the deep linking pages. + */ + HIDE_DEEP_LINKING_LOGO: false, + + /** + * Hide the invite prompt in the header when alone in the meeting. + */ + HIDE_INVITE_MORE_HEADER: false, + + INITIAL_TOOLBAR_TIMEOUT: 20000, + JITSI_WATERMARK_LINK: {{ matrix_jitsi_web_interface_config_jitsi_watermark_link|to_json }}, + + LANG_DETECTION: {{ matrix_jitsi_web_interface_config_lang_detection|to_json }}, // Allow i18n to detect the system language + LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live', // Documentation reference for the live streaming feature. + LOCAL_THUMBNAIL_RATIO: 16 / 9, // 16:9 + + /** + * Maximum coefficient of the ratio of the large video to the visible area + * after the large video is scaled to fit the window. + * + * @type {number} + */ + MAXIMUM_ZOOMING_COEFFICIENT: 1.3, + + /** + * Whether the mobile app Jitsi Meet is to be promoted to participants + * attempting to join a conference in a mobile Web browser. If + * {@code undefined}, defaults to {@code true}. + * + * @type {boolean} + */ + MOBILE_APP_PROMO: true, + + /** + * Specify custom URL for downloading android mobile app. + */ + MOBILE_DOWNLOAD_LINK_ANDROID: 'https://play.google.com/store/apps/details?id=org.jitsi.meet', + + /** + * Specify custom URL for downloading f droid app. + */ + MOBILE_DOWNLOAD_LINK_F_DROID: 'https://f-droid.org/en/packages/org.jitsi.meet/', + + /** + * Specify URL for downloading ios mobile app. + */ + MOBILE_DOWNLOAD_LINK_IOS: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905', + + NATIVE_APP_NAME: {{ matrix_jitsi_web_interface_config_native_app_name|to_json }}, + + // Names of browsers which should show a warning stating the current browser + // has a suboptimal experience. Browsers which are not listed as optimal or + // unsupported are considered suboptimal. Valid values are: + // chrome, chromium, edge, electron, firefox, nwjs, opera, safari + OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'nwjs', 'electron', 'safari' ], + + POLICY_LOGO: null, + PROVIDER_NAME: {{ matrix_jitsi_web_interface_config_provider_name|to_json }}, + + /** + * If true, will display recent list + * + * @type {boolean} + */ + RECENT_LIST_ENABLED: true, + REMOTE_THUMBNAIL_RATIO: 1, // 1:1 + + SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar' ], + SHOW_BRAND_WATERMARK: {{ matrix_jitsi_web_interface_config_show_brand_watermark|to_json }}, + + /** + * Decides whether the chrome extension banner should be rendered on the landing page and during the meeting. + * If this is set to false, the banner will not be rendered at all. If set to true, the check for extension(s) + * being already installed is done before rendering. + */ + SHOW_CHROME_EXTENSION_BANNER: false, + + SHOW_DEEP_LINKING_IMAGE: {{ matrix_jisti_web_interface_config_show_deep_linking_image|to_json }}, + SHOW_JITSI_WATERMARK: {{ matrix_jitsi_web_interface_config_show_jitsi_watermark|to_json }}, + SHOW_POWERED_BY: {{ matrix_jitsi_web_interface_config_show_powered_by|to_json }}, + SHOW_PROMOTIONAL_CLOSE_PAGE: false, + + /* + * If indicated some of the error dialogs may point to the support URL for + * help. + */ + SUPPORT_URL: 'https://community.jitsi.org/', + + TOOLBAR_ALWAYS_VISIBLE: false, + + /** + * The name of the toolbar buttons to display in the toolbar, including the + * "More actions" menu. If present, the button will display. Exceptions are + * "livestreaming" and "recording" which also require being a moderator and + * some values in config.js to be enabled. Also, the "profile" button will + * not display for users with a JWT. + * Notes: + * - it's impossible to choose which buttons go in the "More actions" menu + * - it's impossible to control the placement of buttons + * - 'desktop' controls the "Share your screen" button + */ + TOOLBAR_BUTTONS: [ + {% if matrix_jitsi_enable_transcriptions %} + 'closedcaptions', + {% endif %} + {% if matrix_jitsi_enable_recording %} + 'recording', + {% endif %} + 'microphone', 'camera', 'desktop', 'embedmeeting', 'fullscreen', + 'fodeviceselection', 'hangup', 'profile', 'chat', + 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand', + 'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts', + 'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'security' + ], + + TOOLBAR_TIMEOUT: 4000, + + // Browsers, in addition to those which do not fully support WebRTC, that + // are not supported and should show the unsupported browser page. + UNSUPPORTED_BROWSERS: [], + + /** + * Whether to show thumbnails in filmstrip as a column instead of as a row. + */ + VERTICAL_FILMSTRIP: true, + + // Determines how the video would fit the screen. 'both' would fit the whole + // screen, 'height' would fit the original video height to the height of the + // screen, 'width' would fit the original video width to the width of the + // screen respecting ratio. + VIDEO_LAYOUT_FIT: 'both', + /** * If true, hides the video quality label indicating the resolution status * of the current large video. @@ -166,33 +240,6 @@ var interfaceConfig = { */ VIDEO_QUALITY_LABEL_DISABLED: false, - /** - * If true, will display recent list - * - * @type {boolean} - */ - RECENT_LIST_ENABLED: true, - - // Names of browsers which should show a warning stating the current browser - // has a suboptimal experience. Browsers which are not listed as optimal or - // unsupported are considered suboptimal. Valid values are: - // chrome, chromium, edge, electron, firefox, nwjs, opera, safari - OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'nwjs', 'electron' ], - - // Browsers, in addition to those which do not fully support WebRTC, that - // are not supported and should show the unsupported browser page. - UNSUPPORTED_BROWSERS: [], - - /** - * A UX mode where the last screen share participant is automatically - * pinned. Valid values are the string "remote-only" so remote participants - * get pinned but not local, otherwise any truthy value for all participants, - * and any falsy value to disable the feature. - * - * Note: this mode is experimental and subject to breakage. - */ - AUTO_PIN_LATEST_SCREEN_SHARE: 'remote-only' - /** * How many columns the tile view can expand to. The respected range is * between 1 and 5. @@ -200,14 +247,15 @@ var interfaceConfig = { // TILE_VIEW_MAX_COLUMNS: 5, /** - * Specify custom URL for downloading android mobile app. + * Specify Firebase dynamic link properties for the mobile apps. */ - // MOBILE_DOWNLOAD_LINK_ANDROID: 'https://play.google.com/store/apps/details?id=org.jitsi.meet', - - /** - * Specify URL for downloading ios mobile app. - */ - // MOBILE_DOWNLOAD_LINK_IOS: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905', + // MOBILE_DYNAMIC_LINK: { + // APN: 'org.jitsi.meet', + // APP_CODE: 'w2atb', + // CUSTOM_DOMAIN: undefined, + // IBI: 'com.atlassian.JitsiMeet.ios', + // ISI: '1165103905' + // }, /** * Specify mobile app scheme for opening the app from the mobile browser. @@ -225,6 +273,23 @@ var interfaceConfig = { * milliseconds, those notifications should remain displayed. */ // ENFORCE_NOTIFICATION_AUTO_DISMISS_TIMEOUT: 15000, + + // List of undocumented settings + /** + INDICATOR_FONT_SIZES + PHONE_NUMBER_REGEX + */ + + // Allow all above example options to include a trailing comma and + // prevent fear when commenting out the last value. + // eslint-disable-next-line sort-keys + makeJsonParserHappy: 'even if last key had a trailing comma' + + // No configuration value should follow this line. }; + +{{ matrix_jitsi_web_custom_interface_config_extension }} + + /* eslint-enable no-unused-vars, no-var, max-len */ diff --git a/roles/matrix-jitsi/templates/web/matrix-jitsi-web.service.j2 b/roles/matrix-jitsi/templates/web/matrix-jitsi-web.service.j2 index 1f8a890b..1978fb0e 100644 --- a/roles/matrix-jitsi/templates/web/matrix-jitsi-web.service.j2 +++ b/roles/matrix-jitsi/templates/web/matrix-jitsi-web.service.j2 @@ -5,6 +5,7 @@ Description=Matrix jitsi-web server Requires={{ service }} After={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -18,8 +19,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-jitsi-web \ {% if matrix_jitsi_web_container_http_host_bind_port %} -p {{ matrix_jitsi_web_container_http_host_bind_port }}:80 \ {% endif %} - -v {{ matrix_jitsi_web_config_path }}:/config \ - -v {{ matrix_jitsi_web_transcripts_path }}:/usr/share/jitsi-meet/transcripts \ + --mount type=bind,src={{ matrix_jitsi_web_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_jitsi_web_transcripts_path }},dst=/usr/share/jitsi-meet/transcripts \ {% for arg in matrix_jitsi_web_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-ma1sd/defaults/main.yml b/roles/matrix-ma1sd/defaults/main.yml index 63bc5a59..2932f3ed 100644 --- a/roles/matrix-ma1sd/defaults/main.yml +++ b/roles/matrix-ma1sd/defaults/main.yml @@ -4,10 +4,12 @@ matrix_ma1sd_enabled: true matrix_ma1sd_container_image_self_build: false +matrix_ma1sd_container_image_self_build_repo: "https://github.com/ma1uta/ma1sd.git" matrix_ma1sd_architecture: "amd64" -matrix_ma1sd_docker_image: "ma1uta/ma1sd:2.4.0-{{ matrix_ma1sd_architecture }}" +matrix_ma1sd_docker_image: "{{ matrix_ma1sd_docker_image_name_prefix }}ma1uta/ma1sd:2.4.0-{{ matrix_ma1sd_architecture }}" +matrix_ma1sd_docker_image_name_prefix: "{{ 'localhost/' if matrix_ma1sd_container_image_self_build else 'docker.io/' }}" matrix_ma1sd_docker_image_force_pull: "{{ matrix_ma1sd_docker_image.endswith(':latest') }}" matrix_ma1sd_base_path: "{{ matrix_base_data_path }}/ma1sd" @@ -37,6 +39,28 @@ matrix_ma1sd_systemd_wanted_services_list: [] # Enabling this is discouraged. Learn more here: https://github.com/ma1uta/ma1sd/blob/master/docs/features/identity.md#lookups matrix_ma1sd_matrixorg_forwarding_enabled: false + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_ma1sd_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_ma1sd_postgres_*` variables +matrix_ma1sd_database_engine: 'sqlite' + +matrix_ma1sd_sqlite_database_path_local: "{{ matrix_ma1sd_data_path }}/ma1sd.db" +matrix_ma1sd_sqlite_database_path_in_container: "/var/ma1sd/ma1sd.db" + +matrix_ma1sd_database_username: 'matrix_ma1sd' +matrix_ma1sd_database_password: 'some-password' +matrix_ma1sd_database_hostname: 'matrix-postgres' +matrix_ma1sd_database_port: 5432 +matrix_ma1sd_database_name: 'matrix_ma1sd' + +matrix_ma1sd_database_connection_string: 'postgresql://{{ matrix_ma1sd_database_username }}:{{ matrix_ma1sd_database_password }}@{{ matrix_ma1sd_database_hostname }}:{{ matrix_ma1sd_database_port }}/{{ matrix_ma1sd_database_name }}' + + # ma1sd has serveral supported identity stores. # One of them is storing identities directly in Synapse's database. # Learn more here: https://github.com/ma1uta/ma1sd/blob/master/docs/stores/synapse.md diff --git a/roles/matrix-ma1sd/tasks/main.yml b/roles/matrix-ma1sd/tasks/main.yml index f5ac34d6..0b8a114e 100644 --- a/roles/matrix-ma1sd/tasks/main.yml +++ b/roles/matrix-ma1sd/tasks/main.yml @@ -8,7 +8,14 @@ - setup-all - setup-ma1sd -- import_tasks: "{{ role_path }}/tasks/setup_ma1sd.yml" +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: "run_setup|bool and matrix_ma1sd_enabled|bool" + tags: + - setup-all + - setup-ma1sd + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: "run_setup|bool and not matrix_ma1sd_enabled|bool" tags: - setup-all - setup-ma1sd diff --git a/roles/matrix-ma1sd/tasks/setup_ma1sd.yml b/roles/matrix-ma1sd/tasks/setup_install.yml similarity index 61% rename from roles/matrix-ma1sd/tasks/setup_ma1sd.yml rename to roles/matrix-ma1sd/tasks/setup_install.yml index 44fe6b19..a0a32728 100644 --- a/roles/matrix-ma1sd/tasks/setup_ma1sd.yml +++ b/roles/matrix-ma1sd/tasks/setup_install.yml @@ -1,9 +1,5 @@ --- -# -# Tasks related to setting up ma1sd -# - - name: Ensure ma1sd paths exist file: path: "{{ item.path }}" @@ -15,10 +11,39 @@ - { path: "{{ matrix_ma1sd_config_path }}", when: true } - { path: "{{ matrix_ma1sd_data_path }}", when: true } - { path: "{{ matrix_ma1sd_docker_src_files_path }}", when: "{{ matrix_ma1sd_container_image_self_build }}"} - when: matrix_ma1sd_enabled|bool and item.when + when: "item.when|bool" - import_tasks: "{{ role_path }}/tasks/migrate_mxisd.yml" - when: matrix_ma1sd_enabled|bool + + +# These (SQLite -> Postgres) migration tasks are usually at the top, +# but we'd like to run them after `migrate_mxisd.yml`, which requires the ma1sd paths to exist. +- set_fact: + matrix_ma1sd_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_ma1sd_sqlite_database_path_local }}" + register: matrix_ma1sd_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_ma1sd_sqlite_database_path_local }}" + dst: "{{ matrix_ma1sd_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_ma1sd_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-ma1sd.service'] + pgloader_options: ['--with "quote identifiers"'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_ma1sd_requires_restart: true + when: "matrix_ma1sd_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_ma1sd_database_engine == 'postgres'" - name: Ensure ma1sd image is pulled docker_image: @@ -26,7 +51,7 @@ source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" force_source: "{{ matrix_ma1sd_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_ma1sd_docker_image_force_pull }}" - when: matrix_ma1sd_enabled|bool and not matrix_ma1sd_container_image_self_build + when: "not matrix_ma1sd_container_image_self_build|bool" - block: - name: Ensure gradle is installed for self-building (Debian) @@ -52,10 +77,11 @@ - name: Ensure ma1sd repository is present on self-build git: - repo: https://github.com/ma1uta/ma1sd.git + repo: "{{ matrix_ma1sd_container_image_self_build_repo }}" dest: "{{ matrix_ma1sd_docker_src_files_path }}" version: "{{ matrix_ma1sd_docker_image.split(':')[1].split('-')[0] }}" force: "yes" + register: matrix_ma1sd_git_pull_results - name: Ensure ma1sd Docker image is built shell: "./gradlew dockerBuild" @@ -64,11 +90,14 @@ - name: Ensure ma1sd Docker image is tagged correctly docker_image: - name: "{{ matrix_ma1sd_docker_image.split('-')[0] }}" + # The build script always tags the image with something like `ma1uta/ma1sd:2.4.0`. + # Remove the `-{{ matrix_ma1sd_architecture }}` suffix and our `localhost/` prefix (applied when self-building) + # to get to what has actually been built, so we can retag it as `{{ matrix_ma1sd_docker_image }}`. + name: "{{ matrix_ma1sd_docker_image.split('-')[0].replace('localhost/', '') }}" repository: "{{ matrix_ma1sd_docker_image }}" force_tag: yes source: local - when: "matrix_ma1sd_enabled|bool and matrix_ma1sd_container_image_self_build" + when: "matrix_ma1sd_container_image_self_build|bool" - name: Ensure ma1sd config installed copy: @@ -77,7 +106,6 @@ mode: 0644 owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" - when: matrix_ma1sd_enabled|bool - name: Ensure custom templates are installed if any copy: @@ -91,7 +119,7 @@ - {value: "{{ matrix_ma1sd_threepid_medium_email_custom_session_validation_template }}", location: 'validate-template.eml'} - {value: "{{ matrix_ma1sd_threepid_medium_email_custom_unbind_fraudulent_template }}", location: 'unbind-fraudulent.eml'} - {value: "{{ matrix_ma1sd_threepid_medium_email_custom_matrixid_template }}", location: 'mxid-template.eml'} - when: "matrix_ma1sd_enabled|bool and matrix_ma1sd_threepid_medium_email_custom_templates_enabled|bool and item.value" + when: "matrix_ma1sd_threepid_medium_email_custom_templates_enabled|bool and item.value" - name: Ensure matrix-ma1sd.service installed template: @@ -99,49 +127,14 @@ dest: "{{ matrix_systemd_path }}/matrix-ma1sd.service" mode: 0644 register: matrix_ma1sd_systemd_service_result - when: matrix_ma1sd_enabled|bool - name: Ensure systemd reloaded after matrix-ma1sd.service installation service: daemon_reload: yes - when: "matrix_ma1sd_enabled|bool and matrix_ma1sd_systemd_service_result.changed" + when: "matrix_ma1sd_systemd_service_result.changed|bool" -# -# Tasks related to getting rid of ma1sd (if it was previously enabled) -# - -- name: Check existence of matrix-ma1sd service - stat: - path: "{{ matrix_systemd_path }}/matrix-ma1sd.service" - register: matrix_ma1sd_service_stat - -- name: Ensure matrix-ma1sd is stopped +- name: Ensure matrix-ma1sd.service restarted, if necessary service: - name: matrix-ma1sd - state: stopped - daemon_reload: yes - register: stopping_result - when: "not matrix_ma1sd_enabled|bool and matrix_ma1sd_service_stat.stat.exists" - -- name: Ensure matrix-ma1sd.service doesn't exist - file: - path: "{{ matrix_systemd_path }}/matrix-ma1sd.service" - state: absent - when: "not matrix_ma1sd_enabled|bool and matrix_ma1sd_service_stat.stat.exists" - -- name: Ensure systemd reloaded after matrix-ma1sd.service removal - service: - daemon_reload: yes - when: "not matrix_ma1sd_enabled|bool and matrix_ma1sd_service_stat.stat.exists" - -- name: Ensure Matrix ma1sd paths don't exist - file: - path: "{{ matrix_ma1sd_base_path }}" - state: absent - when: "not matrix_ma1sd_enabled|bool" - -- name: Ensure ma1sd Docker image doesn't exist - docker_image: - name: "{{ matrix_ma1sd_docker_image }}" - state: absent - when: "not matrix_ma1sd_enabled|bool" + name: "matrix-ma1sd.service" + state: restarted + when: "matrix_ma1sd_requires_restart|bool" diff --git a/roles/matrix-ma1sd/tasks/setup_uninstall.yml b/roles/matrix-ma1sd/tasks/setup_uninstall.yml new file mode 100644 index 00000000..b36ab508 --- /dev/null +++ b/roles/matrix-ma1sd/tasks/setup_uninstall.yml @@ -0,0 +1,35 @@ +--- + +- name: Check existence of matrix-ma1sd service + stat: + path: "{{ matrix_systemd_path }}/matrix-ma1sd.service" + register: matrix_ma1sd_service_stat + +- name: Ensure matrix-ma1sd is stopped + service: + name: matrix-ma1sd + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_ma1sd_service_stat.stat.exists|bool" + +- name: Ensure matrix-ma1sd.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-ma1sd.service" + state: absent + when: "matrix_ma1sd_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-ma1sd.service removal + service: + daemon_reload: yes + when: "matrix_ma1sd_service_stat.stat.exists|bool" + +- name: Ensure Matrix ma1sd paths don't exist + file: + path: "{{ matrix_ma1sd_base_path }}" + state: absent + +- name: Ensure ma1sd Docker image doesn't exist + docker_image: + name: "{{ matrix_ma1sd_docker_image }}" + state: absent diff --git a/roles/matrix-ma1sd/templates/ma1sd.yaml.j2 b/roles/matrix-ma1sd/templates/ma1sd.yaml.j2 index 8f3569b1..9a426c47 100644 --- a/roles/matrix-ma1sd/templates/ma1sd.yaml.j2 +++ b/roles/matrix-ma1sd/templates/ma1sd.yaml.j2 @@ -11,9 +11,19 @@ key: path: /var/ma1sd/sign.key storage: - provider: - sqlite: - database: /var/ma1sd/ma1sd.db + {% if matrix_ma1sd_database_engine == 'sqlite' %} + backend: sqlite + provider: + sqlite: + database: {{ matrix_ma1sd_sqlite_database_path_in_container|to_json }} + {% elif matrix_ma1sd_database_engine == 'postgres' %} + backend: postgresql + provider: + postgresql: + database: //{{ matrix_ma1sd_database_hostname }}:{{ matrix_ma1sd_database_port }}/{{ matrix_ma1sd_database_name }} + username: {{ matrix_ma1sd_database_username|to_json }} + password: {{ matrix_ma1sd_database_password|to_json }} + {% endif %} {% if matrix_ma1sd_dns_overwrite_enabled %} dns: @@ -73,10 +83,10 @@ hashing: - none # the same as v1 bulk lookup - sha256 # hash the 3PID and pepper. delay: 2m # how often hashes will be updated if rotation policy = per_seconds (default is 10s) - requests: 10 + requests: 10 {% endif %} synapseSql: - enabled: {{ matrix_ma1sd_synapsesql_enabled }} - type: {{ matrix_ma1sd_synapsesql_type }} - connection: {{ matrix_ma1sd_synapsesql_connection }} + enabled: {{ matrix_ma1sd_synapsesql_enabled|to_json }} + type: {{ matrix_ma1sd_synapsesql_type|to_json }} + connection: {{ matrix_ma1sd_synapsesql_connection|to_json }} diff --git a/roles/matrix-ma1sd/templates/systemd/matrix-ma1sd.service.j2 b/roles/matrix-ma1sd/templates/systemd/matrix-ma1sd.service.j2 index 80370088..95f15254 100644 --- a/roles/matrix-ma1sd/templates/systemd/matrix-ma1sd.service.j2 +++ b/roles/matrix-ma1sd/templates/systemd/matrix-ma1sd.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_ma1sd_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -29,8 +30,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-ma1sd \ {% if matrix_ma1sd_verbose_logging %} -e MA1SD_LOG_LEVEL=debug \ {% endif %} - -v {{ matrix_ma1sd_config_path }}:/etc/ma1sd:ro \ - -v {{ matrix_ma1sd_data_path }}:/var/ma1sd:rw \ + --mount type=bind,src={{ matrix_ma1sd_config_path }},dst=/etc/ma1sd,ro \ + --mount type=bind,src={{ matrix_ma1sd_data_path }},dst=/var/ma1sd \ {% for arg in matrix_ma1sd_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-mailer/defaults/main.yml b/roles/matrix-mailer/defaults/main.yml index 0a8fd13c..f396d8ee 100644 --- a/roles/matrix-mailer/defaults/main.yml +++ b/roles/matrix-mailer/defaults/main.yml @@ -7,7 +7,8 @@ matrix_mailer_container_image_self_build_repository_url: "https://github.com/dev matrix_mailer_container_image_self_build_src_files_path: "{{ matrix_mailer_base_path }}/docker-src" matrix_mailer_container_image_self_build_version: "{{ matrix_mailer_docker_image.split(':')[1] }}" -matrix_mailer_docker_image: "devture/exim-relay:4.93.1-r0" +matrix_mailer_docker_image: "{{ matrix_mailer_docker_image_name_prefix }}devture/exim-relay:4.93.1-r0" +matrix_mailer_docker_image_name_prefix: "{{ 'localhost/' if matrix_mailer_container_image_self_build else 'docker.io/' }}" matrix_mailer_docker_image_force_pull: "{{ matrix_mailer_docker_image.endswith(':latest') }}" # The user/group that the container runs with. diff --git a/roles/matrix-mailer/tasks/setup_mailer.yml b/roles/matrix-mailer/tasks/setup_mailer.yml index 99370638..cb979080 100644 --- a/roles/matrix-mailer/tasks/setup_mailer.yml +++ b/roles/matrix-mailer/tasks/setup_mailer.yml @@ -29,12 +29,14 @@ dest: "{{ matrix_mailer_container_image_self_build_src_files_path }}" version: "{{ matrix_mailer_container_image_self_build_version }}" force: "yes" - when: "matrix_mailer_container_image_self_build|bool" + register: matrix_mailer_git_pull_results + when: "matrix_mailer_enabled|bool and matrix_mailer_container_image_self_build|bool" - name: Ensure exim-relay Docker image is built docker_image: name: "{{ matrix_mailer_docker_image }}" source: build + force_source: "{{ matrix_mailer_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mailer_container_image_self_build_src_files_path }}" diff --git a/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 b/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 index 1371a861..9345a1d6 100644 --- a/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 +++ b/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 @@ -3,6 +3,7 @@ Description=Matrix mailer After=docker.service Requires=docker.service +DefaultDependencies=no [Service] Type=simple @@ -18,7 +19,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-mailer \ --tmpfs=/var/spool/exim:rw,noexec,nosuid,size=100m \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_mailer_base_path }}/env-mailer \ - --hostname={{ matrix_server_fqn_matrix }} \ + --hostname=matrix-mailer \ {% for arg in matrix_mailer_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-nginx-proxy/defaults/main.yml b/roles/matrix-nginx-proxy/defaults/main.yml index 643d723e..61653db4 100644 --- a/roles/matrix-nginx-proxy/defaults/main.yml +++ b/roles/matrix-nginx-proxy/defaults/main.yml @@ -3,7 +3,7 @@ matrix_nginx_proxy_enabled: true # We use an official nginx image, which we fix-up to run unprivileged. # An alternative would be an `nginxinc/nginx-unprivileged` image, but # that is frequently out of date. -matrix_nginx_proxy_docker_image: "nginx:1.19.3-alpine" +matrix_nginx_proxy_docker_image: "docker.io/nginx:1.19.6-alpine" matrix_nginx_proxy_docker_image_force_pull: "{{ matrix_nginx_proxy_docker_image.endswith(':latest') }}" matrix_nginx_proxy_base_path: "{{ matrix_base_data_path }}/nginx-proxy" @@ -92,6 +92,8 @@ matrix_nginx_proxy_base_domain_homepage_template: |- +# Option to disable the access log +matrix_nginx_proxy_access_log_enabled: true # Controls whether proxying the riot domain should be done. matrix_nginx_proxy_proxy_riot_compat_redirect_enabled: false @@ -147,7 +149,39 @@ matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_key: "" matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "matrix-synapse:8008" matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "127.0.0.1:8008" # This needs to be equal or higher than the maximum upload size accepted by Synapse. -matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: 25 +matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: 50 + + +# Tells whether `/_synapse/client` is forwarded to the Matrix Client API server. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_client_api_enabled: true + +# Tells whether `/_synapse/oidc` is forwarded to the Matrix Client API server. +# Enable this if you need OpenID Connect authentication support. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_oidc_api_enabled: false + +# Tells whether `/_synapse/admin` is forwarded to the Matrix Client API server. +# Following these recommendations (https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md), by default, we don't. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: false + +# `matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefixes` holds +# the location prefixes that get forwarded to the Matrix Client API server. +# These locations get combined into a regex like this `^(/_matrix|/_synapse/client)`. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefix_regexes: | + {{ + (['/_matrix']) + + + (['/_synapse/client'] if matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_client_api_enabled else []) + + + (['/_synapse/oidc'] if matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_oidc_api_enabled else []) + + + (['/_synapse/admin'] if matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled else []) + }} + +# Specifies where requests for the root URI (`/`) on the `matrix.` domain should be redirected. +# If this has an empty value, they're just passed to the homeserver, which serves a static page. +# If you'd like to make `https://matrix.DOMAIN` redirect to `https://element.DOMAIN` (or something of that sort), specify the domain name here. +# Example value: `element.DOMAIN` (or `{{ matrix_server_fqn_element }}`). +matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: "" # Controls whether proxying for the Matrix Federation API should be done. matrix_nginx_proxy_proxy_matrix_federation_api_enabled: false @@ -227,7 +261,7 @@ matrix_ssl_domains_to_obtain_certificates_for: [] # Controls whether to obtain production or staging certificates from Let's Encrypt. matrix_ssl_lets_encrypt_staging: false -matrix_ssl_lets_encrypt_certbot_docker_image: "certbot/certbot:{{ matrix_ssl_architecture }}-v1.9.0" +matrix_ssl_lets_encrypt_certbot_docker_image: "docker.io/certbot/certbot:{{ matrix_ssl_architecture }}-v1.10.1" matrix_ssl_lets_encrypt_certbot_docker_image_force_pull: "{{ matrix_ssl_lets_encrypt_certbot_docker_image.endswith(':latest') }}" matrix_ssl_lets_encrypt_certbot_standalone_http_port: 2402 matrix_ssl_lets_encrypt_support_email: ~ @@ -243,6 +277,10 @@ matrix_ssl_base_path: "{{ matrix_base_data_path }}/ssl" matrix_ssl_config_dir_path: "{{ matrix_ssl_base_path }}/config" matrix_ssl_log_dir_path: "{{ matrix_ssl_base_path }}/log" +# If you'd like to start some service before a certificate is obtained, specify it here. +# This could be something like `matrix-dynamic-dns`, etc. +matrix_ssl_pre_obtaining_required_service_name: ~ +matrix_ssl_pre_obtaining_required_service_start_wait_time_seconds: 60 # nginx status page configurations. matrix_nginx_proxy_proxy_matrix_nginx_status_enabled: false diff --git a/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml b/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml index e80b655d..4639f122 100644 --- a/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml +++ b/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml @@ -12,6 +12,19 @@ - set_fact: domain_name_needs_cert: "{{ not domain_name_certificate_path_stat.stat.exists }}" +- block: + - name: Ensure required service for obtaining is started + service: + name: "{{ matrix_ssl_pre_obtaining_required_service_name }}" + state: started + register: matrix_ssl_pre_obtaining_required_service_start_result + + - name: Wait some time, so that the required service for obtaining can start + wait_for: + timeout: "{{ matrix_ssl_service_to_start_before_obtaining_start_wait_time_seconds }}" + when: "matrix_ssl_pre_obtaining_required_service_start_result.changed|bool" + when: "domain_name_needs_cert|bool and matrix_ssl_pre_obtaining_required_service_name != ''" + # This will fail if there is something running on port 80 (like matrix-nginx-proxy). # We suppress the error, as we'll try another method below. - name: Attempt initial SSL certificate retrieval with standalone authenticator (directly) @@ -22,8 +35,8 @@ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL -p {{ matrix_ssl_lets_encrypt_container_standalone_http_host_bind_port }}:8080 - -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt - -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst=/etc/letsencrypt + --mount type=bind,src={{ matrix_ssl_log_dir_path }},dst=/var/log/letsencrypt {{ matrix_ssl_lets_encrypt_certbot_docker_image }} certonly --non-interactive @@ -50,8 +63,8 @@ --cap-drop=ALL -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:8080 --network={{ matrix_docker_network }} - -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt - -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst=/etc/letsencrypt + --mount type=bind,src={{ matrix_ssl_log_dir_path }},dst=/var/log/letsencrypt {{ matrix_ssl_lets_encrypt_certbot_docker_image }} certonly --non-interactive diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 index 4cacf1f1..500f1943 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 @@ -23,6 +23,27 @@ proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } + + # colibri (JVB) websockets + location ~ ^/colibri-ws/([a-zA-Z0-9-\.]+)/(.*) { + {% if matrix_nginx_proxy_enabled %} + resolver 127.0.0.11 valid=5s; + set $backend "matrix-jitsi-jvb:9090"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:12090; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_http_version 1.1; + + tcp_nodelay on; + } {% endmacro %} server { diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 index 8fd87958..adbee18e 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 @@ -34,7 +34,7 @@ {% endif %} {% if matrix_nginx_proxy_proxy_matrix_corporal_api_enabled %} - location /_matrix/corporal { + location ^~ /_matrix/corporal { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} resolver 127.0.0.11 valid=5s; @@ -51,7 +51,7 @@ {% endif %} {% if matrix_nginx_proxy_proxy_matrix_identity_api_enabled %} - location /_matrix/identity { + location ^~ /_matrix/identity { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} resolver 127.0.0.11 valid=5s; @@ -68,7 +68,7 @@ {% endif %} {% if matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled %} - location /_matrix/client/r0/user_directory/search { + location ^~ /_matrix/client/r0/user_directory/search { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} resolver 127.0.0.11 valid=5s; @@ -105,29 +105,6 @@ {{- configuration_block }} {% endfor %} - {# - This handles the Matrix Client API only. - The Matrix Federation API is handled by a separate vhost. - #} - location /_matrix { - {% if matrix_nginx_proxy_enabled %} - {# Use the embedded DNS resolver in Docker containers to discover the service #} - resolver 127.0.0.11 valid=5s; - set $backend "{{ matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container }}"; - proxy_pass http://$backend; - {% else %} - {# Generic configuration for use outside of our container setup #} - proxy_pass http://{{ matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container }}; - {% endif %} - - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; - - client_body_buffer_size 25M; - client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb }}M; - proxy_max_temp_file_size 0; - } - {% if matrix_nginx_proxy_proxy_synapse_metrics %} location /_synapse/metrics { {% if matrix_nginx_proxy_enabled %} @@ -150,7 +127,11 @@ } {% endif %} - location /_synapse { + {# + This handles the Matrix Client API only. + The Matrix Federation API is handled by a separate vhost. + #} + location ~* ^({{ matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefix_regexes|join('|') }}) { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} resolver 127.0.0.11 valid=5s; @@ -170,7 +151,11 @@ } location / { - rewrite ^/$ /_matrix/static/ last; + {% if matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain %} + return 302 $scheme://{{ matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain }}$request_uri; + {% else %} + rewrite ^/$ /_matrix/static/ last; + {% endif %} } {% endmacro %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 index 51aa8a00..975c8b4f 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 @@ -33,7 +33,11 @@ http { '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; + {% if matrix_nginx_proxy_access_log_enabled %} access_log /var/log/nginx/access.log main; + {% else %} + access_log off; + {% endif %} sendfile on; #tcp_nopush on; diff --git a/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 b/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 index 7a385a64..58f5c953 100644 --- a/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 +++ b/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_nginx_proxy_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -30,11 +31,13 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-nginx-proxy \ {% if matrix_nginx_proxy_proxy_matrix_federation_api_enabled and matrix_nginx_proxy_container_federation_host_bind_port %} -p {{ matrix_nginx_proxy_container_federation_host_bind_port }}:8448 \ {% endif %} - -v {{ matrix_nginx_proxy_base_path }}/nginx.conf:/etc/nginx/nginx.conf:ro \ - -v {{ matrix_nginx_proxy_data_path }}:/nginx-data:ro \ - -v {{ matrix_nginx_proxy_confd_path }}:/etc/nginx/conf.d:ro \ - -v {{ matrix_ssl_config_dir_path }}:{{ matrix_ssl_config_dir_path }}:ro \ - -v {{ matrix_static_files_base_path }}:{{ matrix_static_files_base_path }}:ro \ + --mount type=bind,src={{ matrix_nginx_proxy_base_path }}/nginx.conf,dst=/etc/nginx/nginx.conf,ro \ + --mount type=bind,src={{ matrix_nginx_proxy_data_path }},dst=/nginx-data,ro \ + --mount type=bind,src={{ matrix_nginx_proxy_confd_path }},dst=/etc/nginx/conf.d,ro \ + {% if matrix_ssl_retrieval_method != 'none' %} + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst={{ matrix_ssl_config_dir_path }},ro \ + {% endif %} + --mount type=bind,src={{ matrix_static_files_base_path }},dst={{ matrix_static_files_base_path }},ro \ {% for volume in matrix_nginx_proxy_container_additional_volumes %} -v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \ {% endfor %} diff --git a/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 b/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 index f7c930c0..39366abf 100644 --- a/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 +++ b/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 @@ -14,8 +14,8 @@ docker run \ --cap-drop=ALL \ --network="{{ matrix_docker_network }}" \ -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:8080 \ - -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt \ - -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \ + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst=/etc/letsencrypt \ + --mount type=bind,src={{ matrix_ssl_log_dir_path }},dst=/var/log/letsencrypt \ {{ matrix_ssl_lets_encrypt_certbot_docker_image }} \ renew \ --non-interactive \ diff --git a/roles/matrix-postgres/defaults/main.yml b/roles/matrix-postgres/defaults/main.yml index f4fc180e..8f1d0d78 100644 --- a/roles/matrix-postgres/defaults/main.yml +++ b/roles/matrix-postgres/defaults/main.yml @@ -8,11 +8,11 @@ matrix_postgres_db_name: "" matrix_postgres_base_path: "{{ matrix_base_data_path }}/postgres" matrix_postgres_data_path: "{{ matrix_postgres_base_path }}/data" -matrix_postgres_docker_image_v9: "postgres:9.6.19-alpine" -matrix_postgres_docker_image_v10: "postgres:10.14-alpine" -matrix_postgres_docker_image_v11: "postgres:11.9-alpine" -matrix_postgres_docker_image_v12: "postgres:12.4-alpine" -matrix_postgres_docker_image_v13: "postgres:13.0-alpine" +matrix_postgres_docker_image_v9: "docker.io/postgres:9.6.20-alpine" +matrix_postgres_docker_image_v10: "docker.io/postgres:10.15-alpine" +matrix_postgres_docker_image_v11: "docker.io/postgres:11.10-alpine" +matrix_postgres_docker_image_v12: "docker.io/postgres:12.5-alpine" +matrix_postgres_docker_image_v13: "docker.io/postgres:13.1-alpine" matrix_postgres_docker_image_latest: "{{ matrix_postgres_docker_image_v13 }}" # This variable is assigned at runtime. Overriding its value has no effect. @@ -31,4 +31,49 @@ matrix_postgres_container_extra_arguments: [] # Takes an ":" or "" value (e.g. "127.0.0.1:5432"), or empty string to not expose. matrix_postgres_container_postgres_bind_port: "" -matrix_postgres_tool_synapse_janitor: "https://raw.githubusercontent.com/xwiki-labs/synapse_scripts/a9188ff175ae581610f92d58ea6eac9a114d854b/synapse_janitor.sql" +# A list of additional (databases and their credentials) to create. +# +# Example: +# matrix_postgres_additional_databases: +# - name: matrix_appservice_discord +# username: matrix_appservice_discord +# password: some_password +# - name: matrix_appservice_slack +# username: matrix_appservice_slack +# password: some_password +matrix_postgres_additional_databases: [] + +# A list of roles/users to avoid creating when importing (or upgrading) the database. +# If a dump file contains the roles and they've also been created beforehand (see `matrix_postgres_additional_databases`), +# importing would fail. +# We either need to not create them or to ignore the `CREATE ROLE` statements in the dump. +matrix_postgres_import_roles_to_ignore: [matrix_postgres_connection_username] + +matrix_postgres_import_roles_ignore_regex: "^CREATE ROLE ({{ matrix_postgres_import_roles_to_ignore|join('|') }});" + +# A list of databases to avoid creating when importing (or upgrading) the database. +# If a dump file contains the databases and they've also been created beforehand (see `matrix_postgres_additional_databases`), +# importing would fail. +# We either need to not create them or to ignore the `CREATE DATABASE` statements in the dump. +matrix_postgres_import_databases_to_ignore: [matrix_postgres_db_name] + +matrix_postgres_import_databases_ignore_regex: "^CREATE DATABASE ({{ matrix_postgres_import_databases_to_ignore|join('|') }})\\s" + +# The number of seconds to wait after starting `matrix-postgres.service` +# and before trying to run queries for creating additional databases/users against it. +# +# For most (subsequent) runs, Postgres would already be running, so no waiting will be happening at all. +matrix_postgres_additional_databases_postgres_start_wait_timeout_seconds: 15 + + +matrix_postgres_pgloader_container_image_self_build: false +matrix_postgres_pgloader_container_image_self_build_repo: "https://github.com/illagrenan/pgloader-docker.git" +matrix_postgres_pgloader_container_image_self_build_repo_branch: "v{{ matrix_postgres_pgloader_docker_image_tag }}" +matrix_postgres_pgloader_container_image_self_build_src_path: "{{ matrix_postgres_base_path }}/pgloader-container-src" + +# We use illagrenan/pgloader, instead of the more official dimitri/pgloader image, +# because the official one only provides a `latest` tag. +matrix_postgres_pgloader_docker_image: "{{ matrix_postgres_pgloader_docker_image_name_prefix }}illagrenan/pgloader:{{ matrix_postgres_pgloader_docker_image_tag }}" +matrix_postgres_pgloader_docker_image_name_prefix: "{{ 'localhost/' if matrix_postgres_pgloader_container_image_self_build else 'docker.io/' }}" +matrix_postgres_pgloader_docker_image_tag: "3.6.2" +matrix_postgres_pgloader_docker_image_force_pull: "{{ matrix_postgres_pgloader_docker_image.endswith(':latest') }}" diff --git a/roles/matrix-postgres/tasks/import_generic_sqlite_db.yml b/roles/matrix-postgres/tasks/import_generic_sqlite_db.yml new file mode 100644 index 00000000..a42c6f55 --- /dev/null +++ b/roles/matrix-postgres/tasks/import_generic_sqlite_db.yml @@ -0,0 +1,97 @@ +--- + +# Pre-checks + +- name: Fail if Postgres not enabled + fail: + msg: "Postgres via the matrix-postgres role is not enabled (`matrix_postgres_enabled`). Cannot import." + when: "not matrix_postgres_enabled|bool" + +- name: Fail if playbook called incorrectly + fail: + msg: "The `sqlite_database_path` variable needs to be provided to this playbook, via --extra-vars" + when: "sqlite_database_path is not defined or sqlite_database_path.startswith('<')" + +- name: Check if the provided SQLite database file exists + stat: + path: "{{ sqlite_database_path }}" + register: sqlite_database_path_stat_result + +- name: Fail if provided SQLite database file doesn't exist + fail: + msg: "File cannot be found on the server at {{ sqlite_database_path }}" + when: "not sqlite_database_path_stat_result.stat.exists" + +# We either expect `postgres_db_connection_string` specifying a full Postgres database connection string, +# or `postgres_connection_string_variable_name`, specifying a name of a variable, which contains a valid connection string. + +- block: + - name: Fail if postgres_connection_string_variable_name points to an undefined variable + fail: msg="postgres_connection_string_variable_name is defined, but there is no variable with the name `{{ postgres_connection_string_variable_name }}`" + when: "postgres_connection_string_variable_name not in vars" + + - name: Get Postgres connection string from variable + set_fact: + postgres_db_connection_string: "{{ lookup('vars', postgres_connection_string_variable_name) }}" + when: 'postgres_connection_string_variable_name is defined' + +- name: Fail if playbook called incorrectly + fail: + msg: >- + Either a `postgres_db_connection_string` variable or a `postgres_connection_string_variable_name` needs to be provided to this playbook, via `--extra-vars`. + Example: `--extra-vars="postgres_db_connection_string=postgresql://username:password@localhost:/database_name"` or `--extra-vars="postgres_connection_string_variable_name=matrix_appservice_discord_database_connString"` + when: "postgres_db_connection_string is not defined or not postgres_db_connection_string.startswith('postgresql://')" + + +# Defaults + +- name: Set postgres_start_wait_time, if not provided + set_fact: + postgres_start_wait_time: 15 + when: "postgres_start_wait_time|default('') == ''" + + +# Actual import work + +- name: Ensure matrix-postgres is started + service: + name: matrix-postgres + state: started + daemon_reload: yes + register: matrix_postgres_service_start_result + +- name: Wait a bit, so that Postgres can start + wait_for: + timeout: "{{ postgres_start_wait_time }}" + delegate_to: 127.0.0.1 + become: false + when: "matrix_postgres_service_start_result.changed|bool" + +- name: Import SQLite database from {{ sqlite_database_path }} into Postgres + command: + cmd: >- + {{ matrix_host_command_docker }} run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --network={{ matrix_docker_network }} + --mount type=bind,src={{ sqlite_database_path }},dst=/in.db,ro + --entrypoint=/bin/sh + {{ matrix_postgres_pgloader_docker_image }} + -c + 'pgloader /in.db {{ postgres_db_connection_string }}' + +- name: Archive SQLite database ({{ sqlite_database_path }} -> {{ sqlite_database_path }}.backup) + command: + cmd: "mv {{ sqlite_database_path }} {{ sqlite_database_path }}.backup" + +- name: Inject result + set_fact: + matrix_playbook_runtime_results: | + {{ + matrix_playbook_runtime_results|default([]) + + + [ + "NOTE: Your SQLite database file has been imported into Postgres. The original file has been moved from `{{ sqlite_database_path }}` to `{{ sqlite_database_path }}.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete this file." + ] + }} diff --git a/roles/matrix-postgres/tasks/import_postgres.yml b/roles/matrix-postgres/tasks/import_postgres.yml index 0753c292..c26affbb 100644 --- a/roles/matrix-postgres/tasks/import_postgres.yml +++ b/roles/matrix-postgres/tasks/import_postgres.yml @@ -69,13 +69,13 @@ --cap-drop=ALL --network={{ matrix_docker_network }} --env-file={{ matrix_postgres_base_path }}/env-postgres-psql - -v {{ server_path_postgres_dump }}:/{{ server_path_postgres_dump|basename }}:ro + --mount type=bind,src={{ server_path_postgres_dump }},dst=/{{ server_path_postgres_dump|basename }},ro --entrypoint=/bin/sh {{ matrix_postgres_docker_image_latest }} -c "cat /{{ server_path_postgres_dump|basename }} | {{ 'gunzip |' if server_path_postgres_dump.endswith('.gz') else '' }} - grep -vE '^CREATE ROLE {{ matrix_postgres_connection_username }}' | - grep -vE '^CREATE DATABASE {{ matrix_postgres_db_name }}' | + grep -vE '{{ matrix_postgres_import_roles_ignore_regex }}' | + grep -vE '{{ matrix_postgres_import_databases_ignore_regex }}' | psql -v ON_ERROR_STOP=1 -h matrix-postgres" # This is a hack. diff --git a/roles/matrix-postgres/tasks/import_sqlite_db.yml b/roles/matrix-postgres/tasks/import_synapse_sqlite_db.yml similarity index 90% rename from roles/matrix-postgres/tasks/import_sqlite_db.yml rename to roles/matrix-postgres/tasks/import_synapse_sqlite_db.yml index c877ead4..ea15c5a8 100644 --- a/roles/matrix-postgres/tasks/import_sqlite_db.yml +++ b/roles/matrix-postgres/tasks/import_synapse_sqlite_db.yml @@ -79,8 +79,8 @@ --cap-drop=ALL --network={{ matrix_docker_network }} --entrypoint=python - -v {{ matrix_synapse_config_dir_path }}:/data - -v {{ matrix_synapse_config_dir_path }}:/matrix-media-store-parent/media-store - -v {{ server_path_homeserver_db }}:/{{ server_path_homeserver_db|basename }} + --mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/data + --mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/matrix-media-store-parent/media-store + --mount type=bind,src={{ server_path_homeserver_db }},dst=/{{ server_path_homeserver_db|basename }} {{ matrix_synapse_docker_image }} /usr/local/bin/synapse_port_db --sqlite-database /{{ server_path_homeserver_db|basename }} --postgres-config /data/homeserver.yaml diff --git a/roles/matrix-postgres/tasks/main.yml b/roles/matrix-postgres/tasks/main.yml index 41b9c861..b9c2ae7c 100644 --- a/roles/matrix-postgres/tasks/main.yml +++ b/roles/matrix-postgres/tasks/main.yml @@ -19,21 +19,24 @@ tags: - import-postgres -- import_tasks: "{{ role_path }}/tasks/import_sqlite_db.yml" +# The `run_postgres_import_sqlite_db` variable had better be renamed to be consistent, +# but that's a breaking change which may cause trouble for people. +- import_tasks: "{{ role_path }}/tasks/import_synapse_sqlite_db.yml" when: run_postgres_import_sqlite_db|bool tags: - - import-sqlite-db + - import-synapse-sqlite-db + +# Perhaps we need a new variable here, instead of `run_postgres_import_sqlite_db`. +- import_tasks: "{{ role_path }}/tasks/import_generic_sqlite_db.yml" + when: run_postgres_import_sqlite_db|bool + tags: + - import-generic-sqlite-db - import_tasks: "{{ role_path }}/tasks/upgrade_postgres.yml" when: run_postgres_upgrade|bool tags: - upgrade-postgres -- import_tasks: "{{ role_path }}/tasks/run_synapse_janitor.yml" - when: run_postgres_synapse_janitor|bool - tags: - - run-postgres-synapse-janitor - - import_tasks: "{{ role_path }}/tasks/run_vacuum.yml" when: run_postgres_vacuum|bool tags: diff --git a/roles/matrix-postgres/tasks/run_synapse_janitor.yml b/roles/matrix-postgres/tasks/run_synapse_janitor.yml deleted file mode 100644 index d7f283be..00000000 --- a/roles/matrix-postgres/tasks/run_synapse_janitor.yml +++ /dev/null @@ -1,117 +0,0 @@ ---- - -# Pre-checks - -- name: Fail if Postgres not enabled - fail: - msg: "Postgres via the matrix-postgres role is not enabled (`matrix_postgres_enabled`). Cannot run synapse-janitor." - when: "not matrix_postgres_enabled|bool" - -- name: Fail if not aware of the risks - fail: - msg: >- - Using Synapse Janitor is considered dangerous and may break your database. - See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/465. - If you'd like to run it anyway, add `--extra-vars='i_know_synapse_janitor_is_dangerous=1'` to your command. - when: "i_know_synapse_janitor_is_dangerous|default('') == ''" - -# Defaults - -- name: Set postgres_start_wait_time, if not provided - set_fact: - postgres_start_wait_time: 15 - when: "postgres_start_wait_time|default('') == ''" - -- name: Set postgres_synapse_janitor_wait_time, if not provided - set_fact: - postgres_synapse_janitor_wait_time: "{{ 7 * 86400 }}" - when: "postgres_synapse_janitor_wait_time|default('') == ''" - -- name: Set postgres_synapse_janitor_tool_path, if not provided - set_fact: - postgres_synapse_janitor_tool_path: "{{ matrix_postgres_base_path }}/synapse_janitor.sql" - when: "postgres_synapse_janitor_tool_path|default('') == ''" - - -# Actual janitor work - -- name: Download synapse-janitor tool - get_url: - url: "{{ matrix_postgres_tool_synapse_janitor }}" - dest: "{{ postgres_synapse_janitor_tool_path }}" - force: true - mode: 0550 - owner: "{{ matrix_user_username }}" - group: "{{ matrix_user_groupname }}" - -- name: Ensure matrix-postgres is started - service: - name: matrix-postgres - state: started - daemon_reload: yes - -- name: Wait a bit, so that Postgres can start - wait_for: - timeout: "{{ postgres_start_wait_time }}" - delegate_to: 127.0.0.1 - become: false - -- import_tasks: tasks/util/detect_existing_postgres_version.yml - -- name: Abort, if no existing Postgres version detected - fail: - msg: "Could not find existing Postgres installation" - when: "not matrix_postgres_detected_existing|bool" - -- name: Generate Postgres database synapse-janitor command - set_fact: - matrix_postgres_synapse_janitor_command: >- - {{ matrix_host_command_docker }} run --rm --name matrix-postgres-synapse-janitor - --user={{ matrix_user_uid }}:{{ matrix_user_gid }} - --cap-drop=ALL - --network={{ matrix_docker_network }} - --env-file={{ matrix_postgres_base_path }}/env-postgres-psql - --mount type=bind,src={{ postgres_synapse_janitor_tool_path }},dst=/synapse_janitor.sql,ro=true - {{ matrix_postgres_docker_image_latest }} - psql -v ON_ERROR_STOP=1 -h matrix-postgres {{ matrix_synapse_database_database }} -f /synapse_janitor.sql - -- name: Note about Postgres purging alternative - debug: - msg: >- - Running synapse-janitor with the following Postgres command: `{{ matrix_postgres_synapse_janitor_command }}`. - If this crashes, you can stop all processes (`systemctl stop matrix-*`), - start Postgres only (`systemctl start matrix-postgres`) - and manually run the above command directly on the server. - -- name: Populate service facts - service_facts: - -- set_fact: - matrix_postgres_synapse_was_running: "{{ ansible_facts.services['matrix-synapse.service']|default(none) is not none and ansible_facts.services['matrix-synapse.service'].state == 'running' }}" - -- name: Ensure matrix-synapse is stopped - service: - name: matrix-synapse - state: stopped - daemon_reload: yes - -- name: Run synapse-janitor - command: "{{ matrix_postgres_synapse_janitor_command }}" - async: "{{ postgres_synapse_janitor_wait_time }}" - poll: 10 - register: matrix_postgres_synapse_janitor_result - -# Intentionally show the results -- debug: var="matrix_postgres_synapse_janitor_result" - -- name: Ensure matrix-synapse is started, if it previously was - service: - name: matrix-synapse - state: started - daemon_reload: yes - when: "matrix_postgres_synapse_was_running|bool" - -- name: Delete synapse-janitor tool - file: - path: "{{ postgres_synapse_janitor_tool_path }}" - state: absent diff --git a/roles/matrix-postgres/tasks/setup_postgres.yml b/roles/matrix-postgres/tasks/setup_postgres.yml index f186bdca..518d1a5f 100644 --- a/roles/matrix-postgres/tasks/setup_postgres.yml +++ b/roles/matrix-postgres/tasks/setup_postgres.yml @@ -113,6 +113,13 @@ daemon_reload: yes when: "matrix_postgres_enabled|bool and matrix_postgres_systemd_service_result.changed" +- include_tasks: + file: "{{ role_path }}/tasks/util/create_additional_databases.yml" + apply: + tags: + - always + when: "matrix_postgres_enabled|bool and matrix_postgres_additional_databases|length > 0" + # # Tasks related to getting rid of the internal postgres server (if it was previously enabled) # diff --git a/roles/matrix-postgres/tasks/upgrade_postgres.yml b/roles/matrix-postgres/tasks/upgrade_postgres.yml index c1a01d3f..564265d8 100644 --- a/roles/matrix-postgres/tasks/upgrade_postgres.yml +++ b/roles/matrix-postgres/tasks/upgrade_postgres.yml @@ -85,7 +85,7 @@ --network={{ matrix_docker_network }} --env-file={{ matrix_postgres_base_path }}/env-postgres-psql --entrypoint=/bin/sh - -v {{ postgres_dump_dir }}:/out + --mount type=bind,src={{ postgres_dump_dir }},dst=/out {{ matrix_postgres_detected_version_corresponding_docker_image }} -c "pg_dumpall -h matrix-postgres {{ '| gzip -c ' if postgres_dump_name.endswith('.gz') else '' }} @@ -131,12 +131,12 @@ --network={{ matrix_docker_network }} --env-file={{ matrix_postgres_base_path }}/env-postgres-psql --entrypoint=/bin/sh - -v {{ postgres_dump_dir }}:/in:ro + --mount type=bind,src={{ postgres_dump_dir }},dst=/in,ro {{ matrix_postgres_docker_image_latest }} -c "cat /in/{{ postgres_dump_name }} | {{ 'gunzip |' if postgres_dump_name.endswith('.gz') else '' }} - grep -vE '^CREATE ROLE {{ matrix_postgres_connection_username }}' | - grep -vE '^CREATE DATABASE {{ matrix_postgres_db_name }}' | + grep -vE '{{ matrix_postgres_import_roles_ignore_regex }}' | + grep -vE '{{ matrix_postgres_import_databases_ignore_regex }}' | psql -v ON_ERROR_STOP=1 -h matrix-postgres" # This is a hack. diff --git a/roles/matrix-postgres/tasks/util/create_additional_database.yml b/roles/matrix-postgres/tasks/util/create_additional_database.yml new file mode 100644 index 00000000..ce064d59 --- /dev/null +++ b/roles/matrix-postgres/tasks/util/create_additional_database.yml @@ -0,0 +1,40 @@ +--- + +# It'd be better if this is belonged to `validate_config.yml`, but it would have to be some loop-within-a-loop there, +# and that's ugly. We also don't expect this to catch errors often. It's more of a defensive last-minute check. +- name: Fail if additional database data appears invalid + fail: + msg: "Additional database definition ({{ additional_db }} lacks a required key: {{ item }}" + when: "item not in additional_db" + with_items: "{{ ['name', 'username', 'password'] }}" + +# The SQL statements that we'll run against Postgres are stored in a file that others can't read. +# This file will be mounted into the container and fed to Postgres. +# This way, we avoid passing sensitive data around in CLI commands that other users on the system can see. +- name: Create additional database initialization SQL file for {{ additional_db.name }} + template: + src: "{{ role_path }}/templates/init-additional-db-user-and-role.sql.j2" + dest: "/tmp/matrix-postgres-init-additional-db-user-and-role.sql" + mode: 0600 + owner: "{{ matrix_user_uid }}" + group: "{{ matrix_user_gid }}" + +- name: Execute Postgres additional database initialization SQL file for {{ additional_db.name }} + command: + cmd: >- + {{ matrix_host_command_docker }} run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --env-file={{ matrix_postgres_base_path }}/env-postgres-psql + --network {{ matrix_docker_network }} + --mount type=bind,src=/tmp/matrix-postgres-init-additional-db-user-and-role.sql,dst=/matrix-postgres-init-additional-db-user-and-role.sql,ro + --entrypoint=/bin/sh + {{ matrix_postgres_docker_image_to_use }} + -c + 'psql -h {{ matrix_postgres_connection_hostname }} --file=/matrix-postgres-init-additional-db-user-and-role.sql' + +- name: Delete additional database initialization SQL file for {{ additional_db.name }} + file: + path: /tmp/matrix-postgres-init-additional-db-user-and-role.sql + state: absent diff --git a/roles/matrix-postgres/tasks/util/create_additional_databases.yml b/roles/matrix-postgres/tasks/util/create_additional_databases.yml new file mode 100644 index 00000000..0ad460dd --- /dev/null +++ b/roles/matrix-postgres/tasks/util/create_additional_databases.yml @@ -0,0 +1,23 @@ +--- + +- name: Ensure matrix-postgres is started + service: + name: matrix-postgres + state: started + daemon_reload: yes + register: matrix_postgres_service_start_result + +- name: Wait a bit, so that Postgres can start + wait_for: + timeout: "{{ matrix_postgres_additional_databases_postgres_start_wait_timeout_seconds }}" + delegate_to: 127.0.0.1 + become: false + when: "matrix_postgres_service_start_result.changed|bool" + +- name: Create additional Postgres user and database + include_tasks: "{{ role_path }}/tasks/util/create_additional_database.yml" + with_items: "{{ matrix_postgres_additional_databases }}" + loop_control: + loop_var: additional_db + # Suppress logging to avoid dumping the credentials to the shell + no_log: true diff --git a/roles/matrix-postgres/tasks/util/migrate_db_to_postgres.yml b/roles/matrix-postgres/tasks/util/migrate_db_to_postgres.yml new file mode 100644 index 00000000..af95815f --- /dev/null +++ b/roles/matrix-postgres/tasks/util/migrate_db_to_postgres.yml @@ -0,0 +1,167 @@ +--- + +- name: Fail if Postgres not enabled + fail: + msg: "Postgres via the matrix-postgres role is not enabled (`matrix_postgres_enabled`). Cannot migrate." + when: "not matrix_postgres_enabled|bool" + +- name: Fail if util called incorrectly (missing matrix_postgres_db_migration_request) + fail: + msg: "The `matrix_postgres_db_migration_request` variable needs to be provided to this util." + when: "matrix_postgres_db_migration_request is not defined" + +- name: Fail if util called incorrectly (invalid matrix_postgres_db_migration_request) + fail: + msg: "The `matrix_postgres_db_migration_request` variable needs to contain `{{ item }}`." + with_items: + - src + - dst + - caller + - engine_variable_name + - systemd_services_to_stop + when: "item not in matrix_postgres_db_migration_request" + +- name: Check if the provided source database file exists + stat: + path: "{{ matrix_postgres_db_migration_request.src }}" + register: matrix_postgres_db_migration_request_src_stat_result + +- name: Fail if provided source database file doesn't exist + fail: + msg: "File cannot be found on the server at {{ matrix_postgres_db_migration_request.src }}" + when: "not matrix_postgres_db_migration_request_src_stat_result.stat.exists" + +- block: + - name: Ensure pgloader repository is present on self-build + git: + repo: "{{ matrix_postgres_pgloader_container_image_self_build_repo }}" + dest: "{{ matrix_postgres_pgloader_container_image_self_build_src_path }}" + version: "{{ matrix_postgres_pgloader_container_image_self_build_repo_branch }}" + force: "yes" + register: matrix_postgres_pgloader_git_pull_results + + # If `stable` is used, we hit an error when processing /opt/src/pgloader/build/quicklisp/dists/quicklisp/software/uax-15-20201220-git/data/CompositionExclusions.txt: + # > the octet sequence #(194) cannot be decoded + # + # The issue is described here and is not getting fixed for months: https://github.com/dimitri/pgloader/pull/1179 + # + # Although we're not using the dimitri/pgloader image, the one we're using suffers from the same problem. + - name: Switch pgloader base image from Debian stable (likely 10.x/Buster) to Bullseye + lineinfile: + path: "{{ matrix_postgres_pgloader_container_image_self_build_src_path }}/Dockerfile" + regexp: "{{ item.match }}" + line: "{{ item.replace }}" + with_items: + - match: '^FROM debian:stable-slim as builder$' + replace: 'FROM debian:bullseye-slim as builder' + - match: '^FROM debian:stable-slim$' + replace: 'FROM debian:bullseye-slim' + + - name: Ensure pgloader Docker image is built + docker_image: + name: "{{ matrix_postgres_pgloader_docker_image }}" + source: build + force_source: "{{ matrix_postgres_pgloader_git_pull_results.changed }}" + build: + dockerfile: Dockerfile + path: "{{ matrix_postgres_pgloader_container_image_self_build_src_path }}" + pull: yes + when: "matrix_postgres_pgloader_container_image_self_build|bool" + +- name: Ensure pgloader Docker image is pulled + docker_image: + name: "{{ matrix_postgres_pgloader_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_postgres_pgloader_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_postgres_pgloader_docker_image_force_pull }}" + when: "not matrix_postgres_pgloader_container_image_self_build" + +# Defaults + +- name: Set postgres_start_wait_time, if not provided + set_fact: + postgres_start_wait_time: 15 + when: "postgres_start_wait_time|default('') == ''" + +# Actual import work + +# matrix-postgres is most likely started already +- name: Ensure matrix-postgres is started + service: + name: matrix-postgres + state: started + daemon_reload: yes + register: matrix_postgres_service_start_result + +- name: Wait a bit, so that Postgres can start + wait_for: + timeout: "{{ postgres_start_wait_time }}" + delegate_to: 127.0.0.1 + become: false + when: "matrix_postgres_service_start_result.changed|bool" + +# We only stop services here, leaving it to the caller to start them later. +# +# We can't start them, because they probably need to be reconfigured too (changing the configuration from using SQLite to Postgres, etc.), +# before starting. +# +# Since the caller will be starting them, it might make sense to leave stopping to it as well. +# However, we don't do it, because it's simpler having it here, and it also gets to happen only if we'll be doing an import. +# If we bailed out (somewhere above), nothing would have gotten stopped. It's nice to leave this running in such cases. +- name: Ensure systemd services blocking the database import are stopped + service: + name: "{{ item }}" + state: stopped + with_items: "{{ matrix_postgres_db_migration_request.systemd_services_to_stop }}" + +- name: Import {{ matrix_postgres_db_migration_request.engine_old }} database from {{ matrix_postgres_db_migration_request.src }} into Postgres + command: + cmd: >- + {{ matrix_host_command_docker }} run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --network={{ matrix_docker_network }} + --mount type=bind,src={{ matrix_postgres_db_migration_request.src }},dst=/in.db,ro + --entrypoint=/bin/sh + {{ matrix_postgres_pgloader_docker_image }} + -c + 'pgloader {{ matrix_postgres_db_migration_request.pgloader_options|default([])|join(' ') }} /in.db {{ matrix_postgres_db_migration_request.dst }}' + +- block: + # We can't use `{{ role_path }}` here, neither with `import_tasks`, nor with `include_tasks`, + # because it refers to the role that included this util, and not to the role this file belongs to. + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/detect_existing_postgres_version.yml" + + - set_fact: + matrix_postgres_docker_image_to_use: "{{ matrix_postgres_docker_image_latest if matrix_postgres_detected_version_corresponding_docker_image == '' else matrix_postgres_detected_version_corresponding_docker_image }}" + + - name: Execute additional Postgres SQL migration statements + command: + cmd: >- + {{ matrix_host_command_docker }} run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --env-file={{ matrix_postgres_base_path }}/env-postgres-psql + --network={{ matrix_docker_network }} + {{ matrix_postgres_docker_image_to_use }} + psql --host=matrix-postgres --dbname={{ matrix_postgres_db_migration_request.additional_psql_statements_db_name }} --command='{{ item }}' + with_items: "{{ matrix_postgres_db_migration_request.additional_psql_statements_list }}" + + when: "matrix_postgres_db_migration_request.additional_psql_statements_list|default([])|length > 0" + +- name: Archive {{ matrix_postgres_db_migration_request.engine_old }} database ({{ matrix_postgres_db_migration_request.src }} -> {{ matrix_postgres_db_migration_request.src }}.backup) + command: + cmd: "mv {{ matrix_postgres_db_migration_request.src }} {{ matrix_postgres_db_migration_request.src }}.backup" + +- name: Inject result + set_fact: + matrix_playbook_runtime_results: | + {{ + matrix_playbook_runtime_results|default([]) + + + [ + "NOTE: Your {{ matrix_postgres_db_migration_request.engine_old }} database file has been imported into Postgres. The original database file has been moved from `{{ matrix_postgres_db_migration_request.src }}` to `{{ matrix_postgres_db_migration_request.src }}.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete this file." + ] + }} diff --git a/roles/matrix-postgres/tasks/validate_config.yml b/roles/matrix-postgres/tasks/validate_config.yml index 4985a4c7..6ff5adb0 100644 --- a/roles/matrix-postgres/tasks/validate_config.yml +++ b/roles/matrix-postgres/tasks/validate_config.yml @@ -20,3 +20,8 @@ - "matrix_postgres_connection_username" - "matrix_postgres_connection_password" - "matrix_postgres_db_name" + +- name: Fail if Postgres password length exceeded + fail: + msg: "The maximum `matrix_postgres_connection_password` length is 99 characters" + when: "matrix_postgres_connection_hostname|length > 99" diff --git a/roles/matrix-postgres/templates/init-additional-db-user-and-role.sql.j2 b/roles/matrix-postgres/templates/init-additional-db-user-and-role.sql.j2 new file mode 100644 index 00000000..609a1344 --- /dev/null +++ b/roles/matrix-postgres/templates/init-additional-db-user-and-role.sql.j2 @@ -0,0 +1,19 @@ +-- `CREATE USER` does not support `IF NOT EXISTS`, so we use this workaround to prevent an error and raise a notice instead. +-- Seen here: https://stackoverflow.com/a/49858797 +DO $$ +BEGIN + CREATE USER {{ additional_db.username }}; + EXCEPTION WHEN DUPLICATE_OBJECT THEN + RAISE NOTICE 'not creating user {{ additional_db.username }}, since it already exists'; +END +$$; + +-- This is useful for initial user creation (since we don't assign a password above) and for handling subsequent password changes +-- TODO - we should escape quotes in the password. +ALTER ROLE {{ additional_db.username }} PASSWORD '{{ additional_db.password }}'; + +-- This will generate an error on subsequent execution +CREATE DATABASE {{ additional_db.name }} WITH LC_CTYPE 'C' LC_COLLATE 'C' OWNER {{ additional_db.username }}; + +-- This is useful for changing the database owner subsequently +ALTER DATABASE {{ additional_db.name }} OWNER TO {{ additional_db.username }}; diff --git a/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 b/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 index 8e6392c1..0a935fb0 100644 --- a/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 +++ b/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 @@ -3,6 +3,7 @@ Description=Matrix Postgres server After=docker.service Requires=docker.service +DefaultDependencies=no [Service] Type=simple @@ -21,8 +22,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-postgres \ -p {{ matrix_postgres_container_postgres_bind_port }}:5432 \ {% endif %} --env-file={{ matrix_postgres_base_path }}/env-postgres-server \ - -v {{ matrix_postgres_data_path }}:/var/lib/postgresql/data:rw \ - -v /etc/passwd:/etc/passwd:ro \ + --mount type=bind,src={{ matrix_postgres_data_path }},dst=/var/lib/postgresql/data \ + --mount type=bind,src=/etc/passwd,dst=/etc/passwd,ro \ {% for arg in matrix_postgres_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-registration/defaults/main.yml b/roles/matrix-registration/defaults/main.yml index 7eb9340e..065e0c48 100644 --- a/roles/matrix-registration/defaults/main.yml +++ b/roles/matrix-registration/defaults/main.yml @@ -4,17 +4,19 @@ matrix_registration_enabled: true matrix_registration_container_image_self_build: false +matrix_registration_container_image_self_build_repo: "https://github.com/ZerataX/matrix-registration" +matrix_registration_container_image_self_build_branch: "{{ 'master' if matrix_registration_version == 'latest' else matrix_registration_version }}" matrix_registration_base_path: "{{ matrix_base_data_path }}/matrix-registration" matrix_registration_config_path: "{{ matrix_registration_base_path }}/config" matrix_registration_data_path: "{{ matrix_registration_base_path }}/data" matrix_registration_docker_src_files_path: "{{ matrix_registration_base_path }}/docker-src" -matrix_registration_version: "v0.7.0" +matrix_registration_version: "v0.7.2" -matrix_registration_docker_image: "devture/zeratax-matrix-registration:{{ matrix_registration_version }}" +matrix_registration_docker_image: "{{ matrix_registration_docker_image_name_prefix }}zeratax/matrix-registration:{{ matrix_registration_version }}" +matrix_registration_docker_image_name_prefix: "{{ 'localhost/' if matrix_registration_container_image_self_build else 'docker.io/' }}" matrix_registration_docker_image_force_pull: "{{ matrix_registration_docker_image.endswith(':latest') }}" -matrix_registration_docker_repo: "https://github.com/ZerataX/matrix-registration" # A list of extra arguments to pass to the container matrix_registration_container_extra_arguments: [] @@ -30,10 +32,42 @@ matrix_registration_systemd_wanted_services_list: [] # Takes an ":" or "" value (e.g. "127.0.0.1:8767"), or empty string to not expose. matrix_registration_container_http_host_bind_port: '' +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_registration_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_registration_postgres_*` variables +matrix_registration_database_engine: 'sqlite' + +matrix_registration_sqlite_database_path_local: "{{ matrix_registration_data_path }}/db.sqlite3" +matrix_registration_sqlite_database_path_in_container: "/data/db.sqlite3" + +matrix_registration_database_username: 'matrix_registration' +matrix_registration_database_password: 'some-password' +matrix_registration_database_hostname: 'matrix-postgres' +matrix_registration_database_port: 5432 +matrix_registration_database_name: 'matrix_registration' + +matrix_registration_database_connection_string: 'postgresql://{{ matrix_registration_database_username }}:{{ matrix_registration_database_password }}@{{ matrix_registration_database_hostname }}:{{ matrix_registration_database_port }}/{{ matrix_registration_database_name }}' + +# For some reason, matrix-registraiton expects the `db` field to be like this: `sqlite:////data/db.sqlite3`. +# (seems like one too many slashes, but..) +matrix_registration_db: "{{ + { + 'sqlite': ('sqlite:///' + matrix_registration_sqlite_database_path_in_container), + 'postgres': matrix_registration_database_connection_string, + }[matrix_registration_database_engine] +}}" + + # The path at which Matrix Registration will be exposed on `matrix.DOMAIN` # (only applies when matrix-nginx-proxy is used). matrix_registration_public_endpoint: /matrix-registration +matrix_registration_base_url: "{{ matrix_registration_public_endpoint }}" + matrix_registration_api_register_endpoint: "{{ matrix_homeserver_url }}{{ matrix_registration_public_endpoint }}/register" matrix_registration_api_token_endpoint: "{{ matrix_homeserver_url }}{{ matrix_registration_public_endpoint }}/token" @@ -54,7 +88,6 @@ matrix_registration_admin_secret: "" matrix_registration_riot_instance: "https://riot.im/app/" - # Default matrix-registration configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/matrix-registration/tasks/init.yml b/roles/matrix-registration/tasks/init.yml index 8a7cdc75..bdb3928e 100644 --- a/roles/matrix-registration/tasks/init.yml +++ b/roles/matrix-registration/tasks/init.yml @@ -30,15 +30,12 @@ {% endif %} {# - Workaround matrix-registration serving static files at /static - (see https://github.com/ZerataX/matrix-registration/issues/29) - - Also fixing the form, which goes to /register. + Workaround matrix-registration serving the background image at /static + (see https://github.com/ZerataX/matrix-registration/issues/47) #} sub_filter_once off; - sub_filter_types text/html text/css; + sub_filter_types text/css; sub_filter "/static/" "{{ matrix_registration_public_endpoint }}/static/"; - sub_filter "/register" "{{ matrix_registration_public_endpoint }}/register"; } - name: Register matrix-registration proxying configuration with matrix-nginx-proxy diff --git a/roles/matrix-registration/tasks/main.yml b/roles/matrix-registration/tasks/main.yml index 4a884ccd..4fef6abe 100644 --- a/roles/matrix-registration/tasks/main.yml +++ b/roles/matrix-registration/tasks/main.yml @@ -8,7 +8,14 @@ - setup-all - setup-matrix-registration -- import_tasks: "{{ role_path }}/tasks/setup.yml" +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: "run_setup|bool and matrix_registration_enabled|bool" + tags: + - setup-all + - setup-matrix-registration + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: "run_setup|bool and not matrix_registration_enabled|bool" tags: - setup-all - setup-matrix-registration diff --git a/roles/matrix-registration/tasks/setup.yml b/roles/matrix-registration/tasks/setup_install.yml similarity index 50% rename from roles/matrix-registration/tasks/setup.yml rename to roles/matrix-registration/tasks/setup_install.yml index 29b2347b..2b806fe0 100644 --- a/roles/matrix-registration/tasks/setup.yml +++ b/roles/matrix-registration/tasks/setup_install.yml @@ -1,8 +1,35 @@ --- -# -# Tasks related to setting up matrix-registration -# +- set_fact: + matrix_registration_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_registration_sqlite_database_path_local }}" + register: matrix_registration_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_registration_sqlite_database_path_local }}" + dst: "{{ matrix_registration_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_registration_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-registration.service'] + # pgloader makes `ex_date` of type `TIMESTAMP WITH TIMEZONE`, + # which makes matrix-registration choke on it later on when comparing dates. + additional_psql_statements_list: + - ALTER TABLE tokens ALTER COLUMN ex_date TYPE TIMESTAMP WITHOUT TIME ZONE; + additional_psql_statements_db_name: "{{ matrix_registration_database_name }}" + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_registration_requires_restart: true + when: "matrix_registration_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_registration_database_engine == 'postgres'" - name: Ensure matrix-registration paths exist file: @@ -16,7 +43,7 @@ - { path: "{{ matrix_registration_config_path }}", when: true } - { path: "{{ matrix_registration_data_path }}", when: true } - { path: "{{ matrix_registration_docker_src_files_path }}", when: "{{ matrix_registration_container_image_self_build }}"} - when: matrix_registration_enabled|bool and item.when + when: "item.when|bool" - name: Ensure matrix-registration image is pulled docker_image: @@ -24,27 +51,27 @@ source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" force_source: "{{ matrix_registration_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_registration_docker_image_force_pull }}" - when: "matrix_registration_enabled|bool and not matrix_registration_container_image_self_build|bool" + when: "not matrix_registration_container_image_self_build|bool" - name: Ensure matrix-registration repository is present when self-building git: - repo: "{{ matrix_registration_docker_repo }}" + repo: "{{ matrix_registration_container_image_self_build_repo }}" dest: "{{ matrix_registration_docker_src_files_path }}" - version: "{{ matrix_registration_version }}" + version: "{{ matrix_registration_container_image_self_build_branch }}" force: "yes" register: matrix_registration_git_pull_results - when: "matrix_registration_enabled|bool and matrix_registration_container_image_self_build|bool" + when: "matrix_registration_container_image_self_build|bool" - name: Ensure matrix-registration Docker image is built docker_image: name: "{{ matrix_registration_docker_image }}" source: build - force_source: yes + force_source: "{{ matrix_registration_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_registration_docker_src_files_path }}" pull: yes - when: "matrix_registration_enabled|bool and matrix_registration_container_image_self_build|bool and matrix_registration_git_pull_results.changed" + when: "matrix_registration_container_image_self_build|bool" - name: Ensure matrix-registration config installed copy: @@ -53,7 +80,6 @@ mode: 0644 owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" - when: matrix_registration_enabled|bool - name: Ensure matrix-registration.service installed template: @@ -61,43 +87,14 @@ dest: "{{ matrix_systemd_path }}/matrix-registration.service" mode: 0644 register: matrix_registration_systemd_service_result - when: matrix_registration_enabled|bool - name: Ensure systemd reloaded after matrix-registration.service installation service: daemon_reload: yes - when: "matrix_registration_enabled|bool and matrix_registration_systemd_service_result.changed" + when: "matrix_registration_systemd_service_result.changed|bool" -# -# Tasks related to getting rid of matrix-registration (if it was previously enabled) -# - -- name: Check existence of matrix-registration service - stat: - path: "{{ matrix_systemd_path }}/matrix-registration.service" - register: matrix_registration_service_stat - -- name: Ensure matrix-registration is stopped +- name: Ensure matrix-registration.service restarted, if necessary service: - name: matrix-registration - state: stopped - daemon_reload: yes - register: stopping_result - when: "not matrix_registration_enabled|bool and matrix_registration_service_stat.stat.exists" - -- name: Ensure matrix-registration.service doesn't exist - file: - path: "{{ matrix_systemd_path }}/matrix-registration.service" - state: absent - when: "not matrix_registration_enabled|bool and matrix_registration_service_stat.stat.exists" - -- name: Ensure systemd reloaded after matrix-registration.service removal - service: - daemon_reload: yes - when: "not matrix_registration_enabled|bool and matrix_registration_service_stat.stat.exists" - -- name: Ensure matrix-registration Docker image doesn't exist - docker_image: - name: "{{ matrix_registration_docker_image }}" - state: absent - when: "not matrix_registration_enabled|bool" + name: "matrix-registration.service" + state: restarted + when: "matrix_registration_requires_restart|bool" diff --git a/roles/matrix-registration/tasks/setup_uninstall.yml b/roles/matrix-registration/tasks/setup_uninstall.yml new file mode 100644 index 00000000..573f8170 --- /dev/null +++ b/roles/matrix-registration/tasks/setup_uninstall.yml @@ -0,0 +1,30 @@ +--- + +- name: Check existence of matrix-registration service + stat: + path: "{{ matrix_systemd_path }}/matrix-registration.service" + register: matrix_registration_service_stat + +- name: Ensure matrix-registration is stopped + service: + name: matrix-registration + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_registration_service_stat.stat.exists|bool" + +- name: Ensure matrix-registration.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-registration.service" + state: absent + when: "matrix_registration_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-registration.service removal + service: + daemon_reload: yes + when: "matrix_registration_service_stat.stat.exists|bool" + +- name: Ensure matrix-registration Docker image doesn't exist + docker_image: + name: "{{ matrix_registration_docker_image }}" + state: absent diff --git a/roles/matrix-registration/tasks/validate_config.yml b/roles/matrix-registration/tasks/validate_config.yml index 6b2f0277..90466b46 100644 --- a/roles/matrix-registration/tasks/validate_config.yml +++ b/roles/matrix-registration/tasks/validate_config.yml @@ -9,3 +9,12 @@ - "matrix_registration_shared_secret" - "matrix_registration_admin_secret" - "matrix_registration_server_location" + +- name: (Deprecation) Catch and report renamed settings + fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please change your configuration to rename the variable (`{{ item.old }}` -> `{{ item.new }}`). + when: "item.old in vars" + with_items: + - {'old': 'matrix_registration_docker_repo', 'new': 'matrix_registration_container_image_self_build_repo'} diff --git a/roles/matrix-registration/templates/config.yaml.j2 b/roles/matrix-registration/templates/config.yaml.j2 index f3b1c57b..39211b24 100644 --- a/roles/matrix-registration/templates/config.yaml.j2 +++ b/roles/matrix-registration/templates/config.yaml.j2 @@ -3,7 +3,7 @@ server_name: {{ matrix_registration_server_name|to_json }} shared_secret: {{ matrix_registration_shared_secret|to_json }} admin_secret: {{ matrix_registration_admin_secret|to_json }} riot_instance: {{ matrix_registration_riot_instance|to_json }} -db: 'sqlite:////data/db.sqlite3' +db: {{ matrix_registration_db|to_json }} host: '0.0.0.0' port: 5000 rate_limit: ["100 per day", "10 per minute"] @@ -28,3 +28,4 @@ logging: # password requirements password: min_length: 8 +base_url: {{ matrix_registration_base_url|to_json }} diff --git a/roles/matrix-registration/templates/systemd/matrix-registration.service.j2 b/roles/matrix-registration/templates/systemd/matrix-registration.service.j2 index 38860729..3744c2de 100644 --- a/roles/matrix-registration/templates/systemd/matrix-registration.service.j2 +++ b/roles/matrix-registration/templates/systemd/matrix-registration.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_registration_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -22,8 +23,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-registration \ {% if matrix_registration_container_http_host_bind_port %} -p {{ matrix_registration_container_http_host_bind_port }}:5000 \ {% endif %} - -v {{ matrix_registration_config_path }}:/config:ro \ - -v {{ matrix_registration_data_path }}:/data \ + --mount type=bind,src={{ matrix_registration_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_registration_data_path }},dst=/data \ {% for arg in matrix_registration_container_extra_arguments %} {{ arg }} \ {% endfor %} diff --git a/roles/matrix-synapse-admin/defaults/main.yml b/roles/matrix-synapse-admin/defaults/main.yml index 17de0636..1dbf0ad2 100644 --- a/roles/matrix-synapse-admin/defaults/main.yml +++ b/roles/matrix-synapse-admin/defaults/main.yml @@ -4,10 +4,12 @@ matrix_synapse_admin_enabled: true matrix_synapse_admin_container_self_build: false -matrix_synapse_admin_docker_repo: "https://github.com/Awesome-Technologies/synapse-admin.git" +matrix_synapse_admin_container_self_build_repo: "https://github.com/Awesome-Technologies/synapse-admin.git" + matrix_synapse_admin_docker_src_files_path: "{{ matrix_base_data_path }}/synapse-admin/docker-src" -matrix_synapse_admin_docker_image: "awesometechnologies/synapse-admin:0.5.0" +matrix_synapse_admin_docker_image: "{{ matrix_synapse_admin_docker_image_name_prefix }}awesometechnologies/synapse-admin:0.6.1" +matrix_synapse_admin_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_admin_container_self_build else 'docker.io/' }}" matrix_synapse_admin_docker_image_force_pull: "{{ matrix_synapse_admin_docker_image.endswith(':latest') }}" # A list of extra arguments to pass to the container diff --git a/roles/matrix-synapse-admin/tasks/main.yml b/roles/matrix-synapse-admin/tasks/main.yml index 3763ba28..b5cb1689 100644 --- a/roles/matrix-synapse-admin/tasks/main.yml +++ b/roles/matrix-synapse-admin/tasks/main.yml @@ -2,6 +2,12 @@ tags: - always +- import_tasks: "{{ role_path }}/tasks/validate_config.yml" + when: run_setup|bool + tags: + - setup-all + - setup-synapse-admin + - import_tasks: "{{ role_path }}/tasks/setup.yml" tags: - setup-all diff --git a/roles/matrix-synapse-admin/tasks/setup.yml b/roles/matrix-synapse-admin/tasks/setup.yml index 0ee5e8d2..a96ec10f 100644 --- a/roles/matrix-synapse-admin/tasks/setup.yml +++ b/roles/matrix-synapse-admin/tasks/setup.yml @@ -14,7 +14,7 @@ - name: Ensure matrix-synapse-admin repository is present when self-building git: - repo: "{{ matrix_synapse_admin_docker_repo }}" + repo: "{{ matrix_synapse_admin_container_self_build_repo }}" dest: "{{ matrix_synapse_admin_docker_src_files_path }}" force: "yes" register: matrix_synapse_admin_git_pull_results @@ -24,12 +24,12 @@ docker_image: name: "{{ matrix_synapse_admin_docker_image }}" source: build - force_source: yes + force_source: "{{ matrix_synapse_admin_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_synapse_admin_docker_src_files_path }}" pull: yes - when: "matrix_synapse_admin_enabled|bool and matrix_synapse_admin_container_self_build|bool and matrix_synapse_admin_git_pull_results.changed" + when: "matrix_synapse_admin_enabled|bool and matrix_synapse_admin_container_self_build|bool" - name: Ensure matrix-synapse-admin.service installed template: diff --git a/roles/matrix-synapse-admin/tasks/validate_config.yml b/roles/matrix-synapse-admin/tasks/validate_config.yml new file mode 100644 index 00000000..e08680e0 --- /dev/null +++ b/roles/matrix-synapse-admin/tasks/validate_config.yml @@ -0,0 +1,10 @@ +--- + +- name: (Deprecation) Catch and report renamed settings + fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please change your configuration to rename the variable (`{{ item.old }}` -> `{{ item.new }}`). + when: "item.old in vars" + with_items: + - {'old': 'matrix_synapse_admin_docker_repo', 'new': 'matrix_synapse_admin_container_self_build_repo'} diff --git a/roles/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2 b/roles/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2 index c03c627b..7b1e40de 100644 --- a/roles/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2 +++ b/roles/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_synapse_admin_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple diff --git a/roles/matrix-synapse/defaults/main.yml b/roles/matrix-synapse/defaults/main.yml index fd8eaa52..0dc71646 100644 --- a/roles/matrix-synapse/defaults/main.yml +++ b/roles/matrix-synapse/defaults/main.yml @@ -4,8 +4,14 @@ matrix_synapse_enabled: true matrix_synapse_container_image_self_build: false +matrix_synapse_container_image_self_build_repo: "https://github.com/matrix-org/synapse.git" -matrix_synapse_docker_image: "matrixdotorg/synapse:v1.21.2" +matrix_synapse_docker_image: "{{ matrix_synapse_docker_image_name_prefix }}matrixdotorg/synapse:{{ matrix_synapse_docker_image_tag }}" +matrix_synapse_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_container_image_self_build else 'docker.io/' }}" +# The if statement below may look silly at times (leading to the same version being returned), +# but ARM-compatible container images are only released 1-7 hours after a release, +# so we may often be on different versions for different architectures when new Synapse releases come out. +matrix_synapse_docker_image_tag: "{{ 'v1.24.0' if matrix_architecture == 'amd64' else 'v1.24.0' }}" matrix_synapse_docker_image_force_pull: "{{ matrix_synapse_docker_image.endswith(':latest') }}" matrix_synapse_base_path: "{{ matrix_base_data_path }}/synapse" @@ -58,7 +64,7 @@ matrix_synapse_systemd_required_services_list: ['docker.service'] # List of systemd services that matrix-synapse.service wants matrix_synapse_systemd_wanted_services_list: [] -matrix_synapse_in_container_python_packages_path: "/usr/local/lib/python3.7/site-packages" +matrix_synapse_in_container_python_packages_path: "/usr/local/lib/python3.8/site-packages" # Specifies which template files to use when configuring Synapse. # If you'd like to have your own different configuration, feel free to copy and paste @@ -73,7 +79,7 @@ matrix_synapse_registration_shared_secret: "{{ matrix_synapse_macaroon_secret_ke matrix_synapse_allow_guest_access: false matrix_synapse_form_secret: "{{ matrix_synapse_macaroon_secret_key }}" -matrix_synapse_max_upload_size_mb: 10 +matrix_synapse_max_upload_size_mb: 50 # The tmpfs at /tmp needs to be large enough to handle multiple concurrent file uploads. matrix_synapse_tmp_directory_size_mb: "{{ matrix_synapse_max_upload_size_mb * 50 }}" @@ -134,6 +140,11 @@ matrix_synapse_tls_private_key_path: "/data/{{ matrix_server_fqn_matrix }}.tls.k # names. matrix_synapse_http_listener_resource_names: ["client"] +# Resources served on Synapse's federation port. +# When disabling federation, we may wish to serve the `openid` resource here, +# so that services like Dimension and ma1sd can work. +matrix_synapse_federation_listener_resource_names: "{{ ['federation'] if matrix_synapse_federation_enabled else (['openid'] if matrix_synapse_federation_port_openid_resource_required else []) }}" + # Enable this to allow Synapse to report utilization statistics about your server to matrix.org # (things like number of users, number of messages sent, uptime, load, etc.) matrix_synapse_report_stats: false @@ -209,10 +220,25 @@ matrix_synapse_caches_global_factor: 0.5 # Controls whether Synapse will federate at all. # Disable this to completely isolate your server from the rest of the Matrix network. -# Also see: `matrix_synapse_tls_federation_listener_enabled` if you wish to keep federation enabled, +# +# Disabling this still keeps the federation port exposed, because it may be used for other services (`openid`). +# +# Also see: +# - `matrix_synapse_tls_federation_listener_enabled` if you wish to keep federation enabled, # but want to stop the TLS listener (port 8448). +# - `matrix_synapse_federation_port_enabled` to avoid exposing the federation ports matrix_synapse_federation_enabled: true +# Controls whether the federation ports are used at all. +# One may wish to disable federation (`matrix_synapse_federation_enabled: true`), +# but still run other resources (like `openid`) on the federation port +# by enabling them in `matrix_synapse_federation_listener_resource_names`. +matrix_synapse_federation_port_enabled: "{{ matrix_synapse_federation_enabled or matrix_synapse_federation_port_openid_resource_required }}" + +# Controls whether an `openid` listener is to be enabled. Useful when disabling federation, +# but needing the `openid` APIs for Dimension or an identity server like ma1sd. +matrix_synapse_federation_port_openid_resource_required: false + # A list of domain names that are allowed to federate with the given Synapse server. # An empty list value (`[]`) will also effectively stop federation, but if that's the desired # result, it's better to accomplish it by changing `matrix_synapse_federation_enabled`. @@ -349,7 +375,7 @@ matrix_synapse_room_list_publication_rules: room_id: "*" action: allow -matrix_synapse_default_room_version: "5" +matrix_synapse_default_room_version: "6" # Controls the Synapse `spam_checker` setting. # diff --git a/roles/matrix-synapse/tasks/main.yml b/roles/matrix-synapse/tasks/main.yml index 48e72ace..e366a13f 100644 --- a/roles/matrix-synapse/tasks/main.yml +++ b/roles/matrix-synapse/tasks/main.yml @@ -17,7 +17,7 @@ - import_tasks: "{{ role_path }}/tasks/import_media_store.yml" when: run_synapse_import_media_store|bool tags: - - import-media-store + - import-synapse-media-store - import_tasks: "{{ role_path }}/tasks/register_user.yml" when: run_synapse_register_user|bool diff --git a/roles/matrix-synapse/tasks/rust-synapse-compress-state/compress_room.yml b/roles/matrix-synapse/tasks/rust-synapse-compress-state/compress_room.yml index ad7b91b4..8570411f 100644 --- a/roles/matrix-synapse/tasks/rust-synapse-compress-state/compress_room.yml +++ b/roles/matrix-synapse/tasks/rust-synapse-compress-state/compress_room.yml @@ -8,7 +8,7 @@ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL --network={{ matrix_docker_network }} - -v {{ matrix_synapse_rust_synapse_compress_state_base_path }}:/work + --mount type=bind,src={{ matrix_synapse_rust_synapse_compress_state_base_path }},dst=/work {{ matrix_synapse_rust_synapse_compress_state_docker_image }} /synapse-compress-state -t -o /work/state-compressor.sql -p "host={{ matrix_synapse_database_host }} user={{ matrix_synapse_database_user }} password={{ matrix_synapse_database_password }} dbname={{ matrix_synapse_database_database }}" @@ -30,7 +30,7 @@ --cap-drop=ALL --network={{ matrix_docker_network }} --env-file={{ matrix_postgres_base_path }}/env-postgres-psql - -v {{ matrix_synapse_rust_synapse_compress_state_base_path }}:/work:ro + --mount type=bind,src={{ matrix_synapse_rust_synapse_compress_state_base_path }},dst=/work,ro --entrypoint=/bin/sh {{ matrix_postgres_docker_image_latest }} -c "cat /work/state-compressor.sql | diff --git a/roles/matrix-synapse/tasks/synapse/setup_install.yml b/roles/matrix-synapse/tasks/synapse/setup_install.yml index 58f4d31d..f1abcbcc 100644 --- a/roles/matrix-synapse/tasks/synapse/setup_install.yml +++ b/roles/matrix-synapse/tasks/synapse/setup_install.yml @@ -20,21 +20,23 @@ - name: Ensure Synapse repository is present on self-build git: - repo: https://github.com/matrix-org/synapse.git + repo: "{{ matrix_synapse_container_image_self_build_repo }}" dest: "{{ matrix_synapse_docker_src_files_path }}" version: "{{ matrix_synapse_docker_image.split(':')[1] }}" force: "yes" - when: "matrix_synapse_container_image_self_build" + register: matrix_synapse_git_pull_results + when: "matrix_synapse_container_image_self_build|bool" - name: Ensure Synapse Docker image is built docker_image: name: "{{ matrix_synapse_docker_image }}" source: build + force_source: "{{ matrix_synapse_git_pull_results.changed }}" build: dockerfile: docker/Dockerfile path: "{{ matrix_synapse_docker_src_files_path }}" pull: yes - when: "matrix_synapse_container_image_self_build" + when: "matrix_synapse_container_image_self_build|bool" - name: Ensure Synapse Docker image is pulled docker_image: @@ -63,7 +65,7 @@ --name=matrix-config --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL - -v {{ matrix_synapse_config_dir_path }}:/data + --mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/data -e UID={{ matrix_user_uid }} -e GID={{ matrix_user_gid }} -e SYNAPSE_CONFIG_PATH=/data/homeserver.yaml diff --git a/roles/matrix-synapse/templates/goofys/systemd/matrix-goofys.service.j2 b/roles/matrix-synapse/templates/goofys/systemd/matrix-goofys.service.j2 index d9d752c2..0bbfde99 100644 --- a/roles/matrix-synapse/templates/goofys/systemd/matrix-goofys.service.j2 +++ b/roles/matrix-synapse/templates/goofys/systemd/matrix-goofys.service.j2 @@ -3,6 +3,7 @@ Description=Matrix Goofys media store After=docker.service Requires=docker.service +DefaultDependencies=no [Service] Type=simple @@ -12,13 +13,13 @@ ExecStartPre=-{{ matrix_host_command_docker }} rm %n ExecStart={{ matrix_host_command_docker }} run --rm --name %n \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ - -v /etc/passwd:/etc/passwd:ro \ - -v /etc/group:/etc/group:ro \ + --mount type=bind,src=/etc/passwd,dst=/etc/passwd,ro \ + --mount type=bind,src=/etc/group,dst=/etc/group,ro \ + --mount type=bind,src={{ matrix_synapse_media_store_path }},dst=/s3,bind-propagation=shared \ --security-opt apparmor:unconfined \ --cap-add mknod \ --cap-add sys_admin \ --device=/dev/fuse \ - -v {{ matrix_synapse_media_store_path }}:/s3:shared \ --env-file={{ matrix_synapse_config_dir_path }}/env-goofys \ --entrypoint /bin/sh \ {{ matrix_s3_goofys_docker_image }} \ diff --git a/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 b/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 index f58f34f8..41b28c88 100644 --- a/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 +++ b/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 @@ -188,7 +188,7 @@ listeners: - '0.0.0.0' {% endif %} -{% if matrix_synapse_federation_enabled and matrix_synapse_tls_federation_listener_enabled %} +{% if matrix_synapse_federation_port_enabled and matrix_synapse_tls_federation_listener_enabled %} # TLS-enabled listener: for when matrix traffic is sent directly to synapse. - port: 8448 tls: true @@ -197,7 +197,7 @@ listeners: x_forwarded: false resources: - - names: [federation] + - names: {{ matrix_synapse_federation_listener_resource_names|to_json }} compress: false {% endif %} @@ -213,7 +213,7 @@ listeners: - names: {{ matrix_synapse_http_listener_resource_names|to_json }} compress: false -{% if matrix_synapse_federation_enabled %} +{% if matrix_synapse_federation_port_enabled %} # Unsecure HTTP listener (Federation API): for when matrix traffic passes through a reverse proxy # that unwraps TLS. - port: 8048 @@ -223,7 +223,7 @@ listeners: x_forwarded: true resources: - - names: [federation] + - names: {{ matrix_synapse_federation_listener_resource_names|to_json }} compress: false {% endif %} @@ -1202,8 +1202,9 @@ allow_guest_access: {{ matrix_synapse_allow_guest_access|to_json }} # email will be globally disabled. # # Additionally, if `msisdn` is not set, registration and password resets via msisdn -# will be disabled regardless. This is due to Synapse currently not supporting any -# method of sending SMS messages on its own. +# will be disabled regardless, and users will not be able to associate an msisdn +# identifier to their account. This is due to Synapse currently not supporting +# any method of sending SMS messages on its own. # # To enable using an identity server for operations regarding a particular third-party # identifier type, set the value to the URL of that identity server as shown in the @@ -1482,10 +1483,8 @@ trusted_key_servers: {{ matrix_synapse_trusted_key_servers|to_json }} ## Single sign-on integration ## -# Enable SAML2 for registration and login. Uses pysaml2. -# -# At least one of `sp_config` or `config_path` must be set in this section to -# enable SAML login. +# The following settings can be used to make Synapse use a single sign-on +# provider for authentication, instead of its internal password database. # # You will probably also want to set the following options to `false` to # disable the regular login/registration flows: @@ -1494,6 +1493,11 @@ trusted_key_servers: {{ matrix_synapse_trusted_key_servers|to_json }} # # You will also want to investigate the settings under the "sso" configuration # section below. + +# Enable SAML2 for registration and login. Uses pysaml2. +# +# At least one of `sp_config` or `config_path` must be set in this section to +# enable SAML login. # # Once SAML support is enabled, a metadata file will be exposed at # https://:/_matrix/saml2/metadata.xml, which you may be able to @@ -1509,40 +1513,70 @@ saml2_config: # so it is not normally necessary to specify them unless you need to # override them. # - #sp_config: - # # point this to the IdP's metadata. You can use either a local file or - # # (preferably) a URL. - # metadata: - # #local: ["saml2/idp.xml"] - # remote: - # - url: https://our_idp/metadata.xml - # - # # By default, the user has to go to our login page first. If you'd like - # # to allow IdP-initiated login, set 'allow_unsolicited: true' in a - # # 'service.sp' section: - # # - # #service: - # # sp: - # # allow_unsolicited: true - # - # # The examples below are just used to generate our metadata xml, and you - # # may well not need them, depending on your setup. Alternatively you - # # may need a whole lot more detail - see the pysaml2 docs! - # - # description: ["My awesome SP", "en"] - # name: ["Test SP", "en"] - # - # organization: - # name: Example com - # display_name: - # - ["Example co", "en"] - # url: "http://example.com" - # - # contact_person: - # - given_name: Bob - # sur_name: "the Sysadmin" - # email_address": ["admin@example.com"] - # contact_type": technical + sp_config: + # Point this to the IdP's metadata. You must provide either a local + # file via the `local` attribute or (preferably) a URL via the + # `remote` attribute. + # + #metadata: + # local: ["saml2/idp.xml"] + # remote: + # - url: https://our_idp/metadata.xml + + # Allowed clock difference in seconds between the homeserver and IdP. + # + # Uncomment the below to increase the accepted time difference from 0 to 3 seconds. + # + #accepted_time_diff: 3 + + # By default, the user has to go to our login page first. If you'd like + # to allow IdP-initiated login, set 'allow_unsolicited: true' in a + # 'service.sp' section: + # + #service: + # sp: + # allow_unsolicited: true + + # The examples below are just used to generate our metadata xml, and you + # may well not need them, depending on your setup. Alternatively you + # may need a whole lot more detail - see the pysaml2 docs! + + #description: ["My awesome SP", "en"] + #name: ["Test SP", "en"] + + #ui_info: + # display_name: + # - lang: en + # text: "Display Name is the descriptive name of your service." + # description: + # - lang: en + # text: "Description should be a short paragraph explaining the purpose of the service." + # information_url: + # - lang: en + # text: "https://example.com/terms-of-service" + # privacy_statement_url: + # - lang: en + # text: "https://example.com/privacy-policy" + # keywords: + # - lang: en + # text: ["Matrix", "Element"] + # logo: + # - lang: en + # text: "https://example.com/logo.svg" + # width: "200" + # height: "80" + + #organization: + # name: Example com + # display_name: + # - ["Example co", "en"] + # url: "http://example.com" + + #contact_person: + # - given_name: Bob + # sur_name: "the Sysadmin" + # email_address": ["admin@example.com"] + # contact_type": technical # Instead of putting the config inline as above, you can specify a # separate pysaml2 configuration file: @@ -1617,37 +1651,19 @@ saml2_config: # - attribute: department # value: "sales" - # Directory in which Synapse will try to find the template files below. - # If not set, default templates from within the Synapse package will be used. + # If the metadata XML contains multiple IdP entities then the `idp_entityid` + # option must be set to the entity to redirect users to. # - # DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates. - # If you *do* uncomment it, you will need to make sure that all the templates - # below are in the directory. + # Most deployments only have a single IdP entity and so should omit this + # option. # - # Synapse will look for the following templates in this directory: - # - # * HTML page to display to users if something goes wrong during the - # authentication process: 'saml_error.html'. - # - # When rendering, this template is given the following variables: - # * code: an HTML error code corresponding to the error that is being - # returned (typically 400 or 500) - # - # * msg: a textual message describing the error. - # - # The variables will automatically be HTML-escaped. - # - # You can see the default templates at: - # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates - # - #template_dir: "res/templates" + #idp_entityid: 'https://our_idp/entityid' -# OpenID Connect integration. The following settings can be used to make Synapse -# use an OpenID Connect Provider for authentication, instead of its internal -# password database. +# Enable OpenID Connect (OIDC) / OAuth 2.0 for registration and login. # -# See https://github.com/matrix-org/synapse/blob/master/docs/openid.md. +# See https://github.com/matrix-org/synapse/blob/master/docs/openid.md +# for some example configurations. # oidc_config: # Uncomment the following to enable authorization against an OpenID Connect @@ -1770,17 +1786,47 @@ oidc_config: # #display_name_template: "{% raw %}{{ user.given_name }} {{ user.last_name }}{% endraw %}" + # Jinja2 templates for extra attributes to send back to the client during + # login. + # + # Note that these are non-standard and clients will ignore them without modifications. + # + #extra_attributes: + #birthdate: "{% raw %}{{ user.birthdate }}{% endraw %}" -# Enable CAS for registration and login. + +# Enable Central Authentication Service (CAS) for registration and login. # -#cas_config: -# enabled: true -# server_url: "https://cas-server.com" -# service_url: "https://homeserver.domain.com:8448" -# #displayname_attribute: name -# #required_attributes: -# # name: value +cas_config: + # Uncomment the following to enable authorization against a CAS server. + # Defaults to false. + # + #enabled: true + + # The URL of the CAS authorization endpoint. + # + #server_url: "https://cas-server.com" + + # The public URL of the homeserver. + # + #service_url: "https://homeserver.domain.com:8448" + + # The attribute of the CAS response to use as the display name. + # + # If unset, no displayname will be set. + # + #displayname_attribute: name + + # It is possible to configure Synapse to only allow logins if CAS attributes + # match particular values. All of the keys in the mapping below must exist + # and the values must match the given value. Alternately if the given value + # is None then any value is allowed (the attribute just must exist). + # All of the listed attributes must match for the login to be permitted. + # + #required_attributes: + # userGroup: "staff" + # department: None # Additional settings to use with single-sign on systems such as OpenID Connect, @@ -1880,7 +1926,7 @@ sso: # and issued at ("iat") claims are validated if present. # # Note that this is a non-standard login type and client support is -# expected to be non-existant. +# expected to be non-existent. # # See https://github.com/matrix-org/synapse/blob/master/docs/jwt.md. # @@ -2191,21 +2237,35 @@ password_providers: {% endif %} +## Push ## -# Clients requesting push notifications can either have the body of -# the message sent in the notification poke along with other details -# like the sender, or just the event ID and room ID (`event_id_only`). -# If clients choose the former, this option controls whether the -# notification request includes the content of the event (other details -# like the sender are still included). For `event_id_only` push, it -# has no effect. -# -# For modern android devices the notification content will still appear -# because it is loaded by the app. iPhone, however will send a -# notification saying only that a message arrived and who it came from. -# push: - include_content: {{ matrix_synapse_push_include_content|to_json }} + # Clients requesting push notifications can either have the body of + # the message sent in the notification poke along with other details + # like the sender, or just the event ID and room ID (`event_id_only`). + # If clients choose the former, this option controls whether the + # notification request includes the content of the event (other details + # like the sender are still included). For `event_id_only` push, it + # has no effect. + # + # For modern android devices the notification content will still appear + # because it is loaded by the app. iPhone, however will send a + # notification saying only that a message arrived and who it came from. + # + # The default value is "true" to include message details. Uncomment to only + # include the event ID and room ID in push notification payloads. + # + include_content: {{ matrix_synapse_push_include_content|to_json }} + + # When a push notification is received, an unread count is also sent. + # This number can either be calculated as the number of unread messages + # for the user, or the number of *rooms* the user has unread messages in. + # + # The default value is "true", meaning push clients will see the number of + # rooms with unread messages in them. Uncomment to instead send the number + # of unread messages. + # + #group_unread_count_by_room: false # Spam checkers are third-party modules that can block specific actions @@ -2411,7 +2471,7 @@ alias_creation_rules: {{ matrix_synapse_alias_creation_rules|to_json }} # # Options for the rules include: # -# user_id: Matches agaisnt the creator of the alias +# user_id: Matches against the creator of the alias # room_id: Matches against the room ID being published # alias: Matches against any current local or canonical aliases # associated with the room @@ -2459,7 +2519,7 @@ opentracing: # This is a list of regexes which are matched against the server_name of the # homeserver. # - # By defult, it is empty, so no servers are matched. + # By default, it is empty, so no servers are matched. # #homeserver_whitelist: # - ".*" diff --git a/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 b/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 index 47786eee..30c85b99 100644 --- a/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 +++ b/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 @@ -8,6 +8,7 @@ After={{ service }} {% for service in matrix_synapse_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} +DefaultDependencies=no [Service] Type=simple @@ -43,8 +44,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-synapse \ {% if matrix_synapse_manhole_enabled and matrix_synapse_container_manhole_api_host_bind_port %} -p {{ matrix_synapse_container_manhole_api_host_bind_port }}:9000 \ {% endif %} - -v {{ matrix_synapse_config_dir_path }}:/data:ro \ - -v {{ matrix_synapse_storage_path }}:/matrix-media-store-parent:slave \ + --mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/data,ro \ + --mount type=bind,src={{ matrix_synapse_storage_path }},dst=/matrix-media-store-parent,bind-propagation=slave \ {% for volume in matrix_synapse_container_additional_volumes %} -v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \ {% endfor %} diff --git a/setup.yml b/setup.yml index 67639f3e..cc913b65 100755 --- a/setup.yml +++ b/setup.yml @@ -5,6 +5,7 @@ roles: - matrix-base + - matrix-dynamic-dns - matrix-mailer - matrix-postgres - matrix-corporal