diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index bc3c8e75..6e7102bf 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -2,3 +2,5 @@ # https://liberapay.com/s.pantaleev/ liberapay: s.pantaleev +# https://ko-fi.com/spantaleev +ko_fi: spantaleev diff --git a/CHANGELOG.md b/CHANGELOG.md index 329b2ea8..8fd1c8d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,76 @@ +# 2021-05-21 + +## Hydrogen support + +Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook now supports [Hydrogen](https://github.com/vector-im/hydrogen-web) - a new lightweight matrix client with legacy and mobile browser support. + +By default, we still install Element, as Hydrogen is still not fully-featured. Still, people who'd like to try Hydrogen out can now install it via the playbook. + +Additional details are available in [Setting up Hydrogen](docs/configuring-playbook-client-hydrogen.md). + + +# 2021-05-19 + +## Heisenbridge support + +Thanks to [Toni Spets (hifi)](https://github.com/hifi), the playbook now supports bridging to [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) using yet another bridge (besides matrix-appservice-irc), called [Heisenbridge](https://github.com/hifi/heisenbridge). + +Additional details are available in [Setting up Heisenbridge bouncer-style IRC bridging](docs/configuring-playbook-bridge-heisenbridge.md). + + +# 2021-04-16 + +## Disabling TLSv1 and TLSv1.1 for Coturn + +To improve security, we've [removed TLSv1 and TLSv1.1 support](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/999) from our default [Coturn](https://github.com/coturn/coturn) configuration. + +If you need to support old clients, you can re-enable both (or whichever one you need) with the following configuration: + +```yaml +matrix_coturn_tls_v1_enabled: true +matrix_coturn_tls_v1_1_enabled: true +``` + + +# 2021-04-05 + +## Automated local Postgres backup support + +Thanks to [foxcris](https://github.com/foxcris), the playbook can now make automated local Postgres backups on a fixed schedule using [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local). + +Additional details are available in [Setting up postgres backup](docs/configuring-playbook-postgres-backup.md). + + + +# 2021-04-03 + +## Mjolnir moderation tool (bot) support + +Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook can now install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation tool (bot). + +Additional details are available in [Setting up Mjolnir](docs/configuring-playbook-bot-mjolnir.md). + + +# 2021-03-20 + +## Sygnal push gateway support + +The playbook can now install the [Sygnal](https://github.com/matrix-org/sygnal) push gateway for you. + +This is only useful to people who develop/build their own Matrix client applications. + +Additional details are available in our [Setting up Sygnal](docs/configuring-playbook-sygnal.md) docs. + + +# 2021-03-16 + +## Go-NEB support + +Thanks to [Zir0h](https://github.com/Zir0h), the playbook can now install and configure the [Go-NEB](https://github.com/matrix-org/go-neb) bot. + +Additional details are available in [Setting up Go-NEB](docs/configuring-playbook-bot-go-neb.md). + + # 2021-02-19 ## GroupMe bridging support via mx-puppet-groupme diff --git a/README.md b/README.md index 463a1504..8448680c 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Using this playbook, you can get the following services configured on your serve - (optional, default) an [Element](https://app.element.io/) ([formerly Riot](https://element.io/previously-riot)) web UI, which is configured to connect to your own Synapse server by default -- (optional, default) an [ma1sd](https://github.com/ma1uta/ma1sd) Matrix Identity server +- (optional, default) a [ma1sd](https://github.com/ma1uta/ma1sd) Matrix Identity server - (optional, default) an [Exim](https://www.exim.org/) mail server, through which all Matrix services send outgoing email (can be configured to relay through another SMTP server) @@ -47,7 +47,7 @@ Using this playbook, you can get the following services configured on your serve - (optional) the [mautrix-telegram](https://github.com/tulir/mautrix-telegram) bridge for bridging your Matrix server to [Telegram](https://telegram.org/) -- (optional) the [mautrix-whatsapp](https://github.com/tulir/mautrix-whatsapp) bridge for bridging your Matrix server to [Whatsapp](https://www.whatsapp.com/) +- (optional) the [mautrix-whatsapp](https://github.com/tulir/mautrix-whatsapp) bridge for bridging your Matrix server to [WhatsApp](https://www.whatsapp.com/) - (optional) the [mautrix-facebook](https://github.com/tulir/mautrix-facebook) bridge for bridging your Matrix server to [Facebook](https://facebook.com/) @@ -67,6 +67,8 @@ Using this playbook, you can get the following services configured on your serve - (optional) the [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) for bridging your Matrix server to SMS - see [docs/configuring-playbook-bridge-matrix-bridge-sms.md](docs/configuring-playbook-bridge-matrix-bridge-sms.md) for setup documentation +- (optional) the [Heisenbridge](https://github.com/hifi/heisenbridge) for bridging your Matrix server to IRC bouncer-style - see [docs/configuring-playbook-bridge-heisenbridge.md](docs/configuring-playbook-bridge-heisenbridge.md) for setup documentation + - (optional) the [mx-puppet-skype](https://hub.docker.com/r/sorunome/mx-puppet-skype) for bridging your Matrix server to [Skype](https://www.skype.com) - see [docs/configuring-playbook-bridge-mx-puppet-skype.md](docs/configuring-playbook-bridge-mx-puppet-skype.md) for setup documentation - (optional) the [mx-puppet-slack](https://hub.docker.com/r/sorunome/mx-puppet-slack) for bridging your Matrix server to [Slack](https://slack.com) - see [docs/configuring-playbook-bridge-mx-puppet-slack.md](docs/configuring-playbook-bridge-mx-puppet-slack.md) for setup documentation @@ -91,13 +93,21 @@ Using this playbook, you can get the following services configured on your serve - (optional) [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) for scheduling one-off & recurring reminders and alarms - see [docs/configuring-playbook-bot-matrix-reminder-bot.md](docs/configuring-playbook-bot-matrix-reminder-bot.md) for setup documentation +- (optional) [Go-NEB](https://github.com/matrix-org/go-neb) multi functional bot written in Go - see [docs/configuring-playbook-bot-go-neb.md](docs/configuring-playbook-bot-go-neb.md) for setup documentation + +- (optional) [Mjolnir](https://github.com/matrix-org/mjolnir), a moderation tool for Matrix - see [docs/configuring-playbook-bot-mjolnir.md](docs/configuring-playbook-bot-mjolnir.md) for setup documentation + - (optional) [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin), a web UI tool for administrating users and rooms on your Matrix server - see [docs/configuring-playbook-synapse-admin.md](docs/configuring-playbook-synapse-admin.md) for setup documentation - (optional) [matrix-registration](https://github.com/ZerataX/matrix-registration), a simple python application to have a token based matrix registration - see [docs/configuring-playbook-matrix-registration.md](docs/configuring-playbook-matrix-registration.md) for setup documentation - (optional) the [Prometheus](https://prometheus.io) time-series database server, the Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter, and the [Grafana](https://grafana.com/) web UI - see [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](docs/configuring-playbook-prometheus-grafana.md) for setup documentation -Basically, this playbook aims to get you up-and-running with all the basic necessities around Matrix, without you having to do anything else. +- (optional) the [Sygnal](https://github.com/matrix-org/sygnal) push gateway - see [Setting up the Sygnal push gateway](docs/configuring-playbook-sygnal.md) for setup documentation + +- (optional) the [Hydrogen](https://github.com/vector-im/hydrogen-web) web client - see [docs/configuring-playbook-client-hydrogen.md](docs/configuring-playbook-client-hydrogen.md) for setup documentation + +Basically, this playbook aims to get you up-and-running with all the necessities around Matrix, without you having to do anything else. **Note**: the list above is exhaustive. It includes optional or even some advanced components that you will most likely not need. Sticking with the defaults (which install a subset of the above components) is the best choice, especially for a new installation. @@ -122,4 +132,11 @@ When updating the playbook, refer to [the changelog](CHANGELOG.md) to catch up w - IRC channel: `#matrix-docker-ansible-deploy` on the [Freenode](https://freenode.net/) IRC network (irc.freenode.net) -- Github issues: [spantaleev/matrix-docker-ansible-deploy/issues](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues) +- GitHub issues: [spantaleev/matrix-docker-ansible-deploy/issues](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues) + + +## Services by the community + +- [etke.cc](https://etke.cc) - matrix-docker-ansible-deploy and system stuff "as a service". That service will create your matrix homeserver on your domain and server (doesn't matter if it's cloud provider or on an old laptop in the corner of your room), (optional) maintains it (server's system updates, cleanup, security adjustments, tuning, etc.; matrix homeserver updates & maintenance) and (optional) provide full-featured email service for your domain + +- [GoMatrixHosting](https://gomatrixhosting.com) - matrix-docker-ansible-deploy "as a service" with [Ansible AWX](https://github.com/ansible/awx). Members can be assigned a server from DigitalOcean, or they can connect their on-premises server. This AWX system can manage the updates, configuration, import and export, backups, and monitoring on its own. For more information [see our GitLab group](https://gitlab.com/GoMatrixHosting) or come [visit us on Matrix](https://matrix.to/#/#general:gomatrixhosting.com). diff --git a/docs/configuring-awx-system.md b/docs/configuring-awx-system.md new file mode 100644 index 00000000..cc90fb98 --- /dev/null +++ b/docs/configuring-awx-system.md @@ -0,0 +1,45 @@ +# Configuring AWX System (optional) + +An AWX setup for managing multiple Matrix servers. + +This section is used in an AWX system that can create and manage multiple [Matrix](http://matrix.org/) servers. You can issue members an AWX login to their own 'organisation', which they can use to manage/configure 1 to N servers. + +Members can be assigned a server from Digitalocean, or they can connect their own on-premises server. This script is free to use in a commercial context with the 'MemberPress Plus' and 'WP Oauth Sever' addons. It can also be run in a non-commercial context. + +The AWX system is arranged into 'members' each with their own 'subscriptions'. After creating a subscription the user enters the 'provision stage' where they defined the URLs they will use, the servers location and whether or not there's already a website at the base domain. They then proceed onto the 'deploy stage' where they can configure their Matrix server. + +Ideally this system can manage the updates, configuration, backups and monitoring on it's own. It is an extension of the popular deploy script [spantaleev/matrix-docker-ansible-deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy). + +Warning: This project is currently alpha quality and should only be run by the brave. + + +## Other Required Playbooks + +The following repositories allow you to copy and use this setup: + +[Create AWX System](https://gitlab.com/GoMatrixHosting/create-awx-system) - Creates and configures the AWX system for you. + +[Ansible Create Delete Subscription Membership](https://gitlab.com/GoMatrixHosting/ansible-create-delete-subscription-membership) - Used by the AWX system to create memberships and subscriptions. Also includes other administrative playbooks for updates, backups and restoring servers. + +[Ansible Provision Server](https://gitlab.com/GoMatrixHosting/ansible-provision-server) - Used by AWX members to perform initial configuration of their DigitalOcean or On-Premises server. + +## Testing Fork For This Playbook + +Updates to this section are trailed here: + +[GoMatrixHosting Matrix Docker Ansible Deploy](https://gitlab.com/GoMatrixHosting/gomatrixhosting-matrix-docker-ansible-deploy) + + +## Does I need an AWX setup to use this? How do I configure it? + +Yes, you'll need to configure an AWX instance, the [Create AWX System](https://gitlab.com/GoMatrixHosting/create-awx-system) repository makes it easy to do. Just follow the steps listed in ['/docs/Installation.md' of that repository](https://gitlab.com/GoMatrixHosting/create-awx-system/-/blob/master/docs/Installation.md). + +For simpler installation steps you can use to get started with this system, check out our minimal installation guide at ['/doc/Installation_Minimal.md of that repository'](https://gitlab.com/GoMatrixHosting/create-awx-system/-/blob/master/docs/Installation_Minimal.md). + + +## Does I need a front-end WordPress site? And a DigitalOcean account? + +You do not need a front-end WordPress site or any of the mentioned WordPress plugins to use this setup. It can be run on it's own in a non-commercial context. + +You also don't need a DigitalOcean account, but this will limit you to only being able to connect 'On-Premises' servers. + diff --git a/docs/configuring-dns.md b/docs/configuring-dns.md index c25b079e..0016464f 100644 --- a/docs/configuring-dns.md +++ b/docs/configuring-dns.md @@ -15,31 +15,34 @@ As we discuss in [Server Delegation](howto-server-delegation.md), there are 2 di This playbook mostly discusses the well-known file method, because it's easier to manage with regard to certificates. If you decide to go with the alternative method ([Server Delegation via a DNS SRV record (advanced)](howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced)), please be aware that the general flow that this playbook guides you through may not match what you need to do. -## Required DNS settings for services enabled by default +## DNS settings for services enabled by default | Type | Host | Priority | Weight | Port | Target | | ----- | ---------------------------- | -------- | ------ | ---- | ---------------------- | | A | `matrix` | - | - | - | `matrix-server-IP` | | CNAME | `element` | - | - | - | `matrix.` | -| SRV | `_matrix-identity._tcp` | 10 | 0 | 443 | `matrix.` | Be mindful as to how long it will take for the DNS records to propagate. If you are using Cloudflare DNS, make sure to disable the proxy and set all records to `DNS only`. Otherwise, fetching certificates will fail. -## Required DNS settings for optional services +## DNS settings for optional services/features | Type | Host | Priority | Weight | Port | Target | | ----- | ---------------------------- | -------- | ------ | ---- | ---------------------- | +| SRV | `_matrix-identity._tcp` | 10 | 0 | 443 | `matrix.` | | CNAME | `dimension` (*) | - | - | - | `matrix.` | | CNAME | `jitsi` (*) | - | - | - | `matrix.` | | CNAME | `stats` (*) | - | - | - | `matrix.` | +| CNAME | `goneb` (*) | - | - | - | `matrix.` | +| CNAME | `sygnal` (*) | - | - | - | `matrix.` | +| CNAME | `hydrogen` (*) | - | - | - | `matrix.` | ## Subdomains setup 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/element-web) web client for you. +The `element.` subdomain may be 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. @@ -48,12 +51,21 @@ The `jitsi.` subdomain may be necessary, because this playbook coul The `stats.` subdomain may be necessary, because this playbook could install [Grafana](https://grafana.com/) and setup performance metrics for you. Grafana installation is disabled by default, it is not a core required component. To learn how to install it, see our [metrics and graphs guide](configuring-playbook-prometheus-grafana.md). If you do not wish to set up Grafana, feel free to skip the `stats.` DNS record. It is possible to install Prometheus without installing Grafana, this would also not require the `stats.` subdomain. +The `goneb.` subdomain may be necessary, because this playbook could install the [Go-NEB](https://github.com/matrix-org/go-neb) bot. The installation of Go-NEB is disabled by default, it is not a core required component. To learn how to install it, see our [configuring Go-NEB guide](configuring-playbook-bot-go-neb.md). If you do not wish to set up Go-NEB, feel free to skip the `goneb.` DNS record. + +The `sygnal.` subdomain may be necessary, because this playbook could install the [Sygnal](https://github.com/matrix-org/sygnal) push gateway. The installation of Sygnal is disabled by default, it is not a core required component. To learn how to install it, see our [configuring Sygnal guide](configuring-playbook-sygnal.md). If you do not wish to set up Sygnal (you probably don't, unless you're also developing/building your own Matrix apps), feel free to skip the `sygnal.` DNS record. + +The `hydrogen.` subdomain may be necessary, because this playbook could install the [Hydrogen](https://github.com/vector-im/hydrogen-web) web client. The installation of Hydrogen is disabled by default, it is not a core required component. To learn how to install it, see our [configuring Hydrogen guide](configuring-playbook-client-hydrogen.md). If you do not wish to set up Hydrogen, feel free to skip the `hydrogen.` DNS record. + ## `_matrix-identity._tcp` SRV record setup -To make the [ma1sd](https://github.com/ma1uta/ma1sd) Identity Server (which this playbook installs for you) be authoritative for your domain name, set up one more SRV record that looks like this: +To make the [ma1sd](https://github.com/ma1uta/ma1sd) Identity Server (which this playbook installs for you) enable its federation features, set up an SRV record that looks like this: - Name: `_matrix-identity._tcp` (use this text as-is) - Content: `10 0 443 matrix.` (replace `` with your own) +This is an optional feature. See [ma1sd's documentation](https://github.com/ma1uta/ma1sd/wiki/mxisd-and-your-privacy#choices-are-never-easy) for information on the privacy implications of setting up this SRV record. + +Note: This `_matrix-identity._tcp` SRV record for the identity server is different from the `_matrix._tcp` that can be used for Synapse delegation. See [howto-server-delegation.md](howto-server-delegation.md) for more information about delegation. When you're done with the DNS configuration and ready to proceed, continue with [Configuring this Ansible playbook](configuring-playbook.md). diff --git a/docs/configuring-playbook-bot-go-neb.md b/docs/configuring-playbook-bot-go-neb.md new file mode 100644 index 00000000..ab84e017 --- /dev/null +++ b/docs/configuring-playbook-bot-go-neb.md @@ -0,0 +1,226 @@ +# Setting up Go-NEB (optional) + +The playbook can install and configure [Go-NEB](https://github.com/matrix-org/go-neb) for you. + +Go-NEB is a Matrix bot written in Go. It is the successor to Matrix-NEB, the original Matrix bot written in Python. + +See the project's [documentation](https://github.com/matrix-org/go-neb) to learn what it does and why it might be useful to you. + + +## Registering the bot user + +The playbook does not automatically create users for you. The bot requires at least 1 access token to be able to connect to your homeserver. + +You **need to register the bot user manually** before setting up the bot. + +Choose a strong password for the bot. You can generate a good password with a command like this: `pwgen -s 64 1`. + +You can use the playbook to [register a new user](registering-users.md): + +``` +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.go-neb password=PASSWORD_FOR_THE_BOT admin=no' --tags=register-user +``` + + +## Getting an access token + +If you use curl, you can get an access token like this: + +``` +curl -X POST --header 'Content-Type: application/json' -d '{ + "identifier": { "type": "m.id.user", "user": "bot.go-neb" }, + "password": "a strong password", + "type": "m.login.password" +}' 'https://matrix.YOURDOMAIN/_matrix/client/r0/login' +``` + +Alternatively, you can use a full-featured client (such as Element) to log in and get the access token from there (note: don't log out from the client as that will invalidate the token), but doing so might lead to decryption problems. That warning comes from [here](https://github.com/matrix-org/go-neb#quick-start). + + +## Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs): + +```yaml +matrix_bot_go_neb_enabled: true + +# You need at least 1 client. +# Use the access token you obtained in the step above. +matrix_bot_go_neb_clients: + - UserID: "@goneb:{{ matrix_domain }}" + AccessToken: "MDASDASJDIASDJASDAFGFRGER" + DeviceID: "DEVICE1" + HomeserverURL: "{{ matrix_homeserver_container_url }}" + Sync: true + AutoJoinRooms: true + DisplayName: "Go-NEB!" + AcceptVerificationFromUsers: [":{{ matrix_domain }}"] + + - UserID: "@another_goneb:{{ matrix_domain }}" + AccessToken: "MDASDASJDIASDJASDAFGFRGER" + DeviceID: "DEVICE2" + HomeserverURL: "{{ matrix_homeserver_container_url }}" + Sync: false + AutoJoinRooms: false + DisplayName: "Go-NEB!" + AcceptVerificationFromUsers: ["^@admin:{{ matrix_domain }}"] + +# Optional, for use with the github_cmd, github_webhooks or jira services +matrix_bot_go_neb_realms: + - ID: "github_realm" + Type: "github" + Config: {} # No need for client ID or Secret as Go-NEB isn't generating OAuth URLs + +# Optional. The list of *authenticated* sessions which Go-NEB is aware of. +matrix_bot_go_neb_sessions: + - SessionID: "your_github_session" + RealmID: "github_realm" + UserID: "@YOUR_USER_ID:{{ matrix_domain }}" # This needs to be the username of the person that's allowed to use the !github commands + Config: + # Populate these fields by generating a "Personal Access Token" on github.com + AccessToken: "YOUR_GITHUB_ACCESS_TOKEN" + Scopes: "admin:org_hook,admin:repo_hook,repo,user" + +# The list of services which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# See the docs for /configureService for the full list of options: +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureServiceRequest +# You need at least 1 service. +matrix_bot_go_neb_services: + - ID: "echo_service" + Type: "echo" + UserID: "@goneb:{{ matrix_domain }}" + Config: {} + +# Can be obtained from https://developers.giphy.com/dashboard/ + - ID: "giphy_service" + Type: "giphy" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + api_key: "qwg4672vsuyfsfe" + use_downsized: false + +# This service has been dead for over a year :/ + - ID: "guggy_service" + Type: "guggy" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + api_key: "2356saaqfhgfe" + +# API Key via https://developers.google.com/custom-search/v1/introduction +# CX via http://www.google.com/cse/manage/all +# https://stackoverflow.com/questions/6562125/getting-a-cx-id-for-custom-search-google-api-python +# 'Search the entire web' and 'Image search' enabled for best results + - ID: "google_service" + Type: "google" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + api_key: "AIzaSyA4FD39m9" + cx: "AIASDFWSRRtrtr" + +# Get a key via https://api.imgur.com/oauth2/addclient +# Select "oauth2 without callback url" + - ID: "imgur_service" + Type: "imgur" + UserID: "@imgur:{{ matrix_domain }}" # requires a Syncing client + Config: + client_id: "AIzaSyA4FD39m9" + client_secret: "somesecret" + + - ID: "wikipedia_service" + Type: "wikipedia" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + + - ID: "rss_service" + Type: "rssbot" + UserID: "@another_goneb:{{ matrix_domain }}" + Config: + feeds: + "http://lorem-rss.herokuapp.com/feed?unit=second&interval=60": + rooms: ["!qmElAGdFYCHoCJuaNt:{{ matrix_domain }}"] + must_include: + author: + - author1 + description: + - lorem + - ipsum + must_not_include: + title: + - Lorem + - Ipsum + + - ID: "github_cmd_service" + Type: "github" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + RealmID: "github_realm" + + # Make sure your BASE_URL can be accessed by Github! + - ID: "github_webhook_service" + Type: "github-webhook" + UserID: "@another_goneb:{{ matrix_domain }}" + Config: + RealmID: "github_realm" + ClientUserID: "@YOUR_USER_ID:{{ matrix_domain }}" # needs to be an authenticated user so Go-NEB can create webhooks. Check the UserID field in the github_realm in matrix_bot_go_neb_sessions. + Rooms: + "!someroom:id": + Repos: + "matrix-org/synapse": + Events: ["push", "issues"] + "matrix-org/dendron": + Events: ["pull_request"] + "!anotherroom:id": + Repos: + "matrix-org/synapse": + Events: ["push", "issues"] + "matrix-org/dendron": + Events: ["pull_request"] + + - ID: "slackapi_service" + Type: "slackapi" + UserID: "@slackapi:{{ matrix_domain }}" + Config: + Hooks: + "hook1": + RoomID: "!someroom:id" + MessageType: "m.text" # default is m.text + + - ID: "alertmanager_service" + Type: "alertmanager" + UserID: "@alertmanager:{{ matrix_domain }}" + Config: + # This is for information purposes only. It should point to Go-NEB path as follows: + # `/services/hooks/` + # Where in this case "service ID" is "alertmanager_service" + # Make sure your BASE_URL can be accessed by the Alertmanager instance! + webhook_url: "http://localhost/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U" + # Each room will get the notification with the alert rendered with the given template + rooms: + "!someroomid:domain.tld": + text_template: "{{range .Alerts -}} [{{ .Status }}] {{index .Labels \"alertname\" }}: {{index .Annotations \"description\"}} {{ end -}}" + html_template: "{{range .Alerts -}} {{ $severity := index .Labels \"severity\" }} {{ if eq .Status \"firing\" }} {{ if eq $severity \"critical\"}} [FIRING - CRITICAL] {{ else if eq $severity \"warning\"}} [FIRING - WARNING] {{ else }} [FIRING - {{ $severity }}] {{ end }} {{ else }} [RESOLVED] {{ end }} {{ index .Labels \"alertname\"}} : {{ index .Annotations \"description\"}} source
{{end -}}" + msg_type: "m.text" # Must be either `m.text` or `m.notice` +``` + + +## Installing + +Don't forget to add `goneb.` to DNS as described in [Configuring DNS](configuring-dns.md) before running the playbook. + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + + +## Usage + +To use the bot, invite it to any existing Matrix room (`/invite @whatever_you_chose:DOMAIN` where `YOUR_DOMAIN` is your base domain, not the `matrix.` domain, make sure you have permission from the room owner if that's not you). + +Basic usage is like this: `!echo hi` or `!imgur puppies` or `!giphy matrix` + +If you enabled the github_cmd service you can get the supported commands via `!github help` + +You can also refer to the upstream [Documentation](https://github.com/matrix-org/go-neb). diff --git a/docs/configuring-playbook-bot-mjolnir.md b/docs/configuring-playbook-bot-mjolnir.md new file mode 100644 index 00000000..1b0241e1 --- /dev/null +++ b/docs/configuring-playbook-bot-mjolnir.md @@ -0,0 +1,121 @@ +# Setting up Mjolnir (optional) + +The playbook can install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation bot for you. + +See the project's [documentation](https://github.com/matrix-org/mjolnir) to learn what it does and why it might be useful to you. + +Note: the playbook does not currently support the Mjolnir Synapse module. The playbook does support another antispam module, see [Setting up Synapse Simple Antispam](configuring-playbook-synapse-simple-antispam.md). + + +## 1. Register the bot account + +The playbook does not automatically create users for you. The bot requires an access token to be able to connect to your homeserver. + +You **need to register the bot user manually** before setting up the bot. + +Choose a strong password for the bot. You can generate a good password with a command like this: `pwgen -s 64 1`. + +You can use the playbook to [register a new user](registering-users.md): + +``` +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.mjolnir password=PASSWORD_FOR_THE_BOT admin=no' --tags=register-user +``` + +If you would like Mjolnir to be able to deactivate users, move aliases, shutdown rooms, etc then it must be a server admin so you need to change `admin=no` to `admin=yes` in the command above. + + +## 2. Get an access token + +If you use curl, you can get an access token like this: + +``` +curl -X POST --header 'Content-Type: application/json' -d '{ + "identifier": { "type": "m.id.user", "user": "bot.mjolnir" }, + "password": "PASSWORD_FOR_THE_BOT", + "type": "m.login.password" +}' 'https://matrix.DOMAIN/_matrix/client/r0/login' +``` + +Alternatively, you can use a full-featured client (such as Element) to log in and get the access token from there (note: don't log out from the client as that will invalidate the token). + + +## 3. Make sure the account is free from rate limiting + +You will need to prevent Synapse from rate limiting the bot's account. This is not an optional step. If you do not do this step Mjolnir will crash. [Currently there is no Synapse config option for this](https://github.com/matrix-org/synapse/issues/6286) so you have to manually edit the Synapse database. Manually editing the Synapse database is rarely a good idea but in this case it is required. Please ask for help if you are uncomfortable with these steps. + +1. Copy the statement below into a text editor. + + ``` + INSERT INTO ratelimit_override VALUES ('@bot.mjolnir:DOMAIN', 0, 0); + ``` + +1. Change the username (`@bot.mjolnir:DOMAIN`) to the username you used when you registered the bot's account. You must change `DOMAIN` to your server's domain. + +1. Get a database terminal by following these steps: [maintenance-postgres.md#getting-a-database-terminal](maintenance-postgres.md#getting-a-database-terminal) + +1. Connect to Synapse's database by typing `\connect synapse` into the database terminal + +1. Paste in the `INSERT INTO` command that you edited and press enter. + +You can run `SELECT * FROM ratelimit_override;` to see if it worked. If the output looks like this: + +``` + user_id | messages_per_second | burst_count +-----------------------+---------------------+------------- + @bot.mjolnir:raim.ist | 0 | 0` +``` +then you did it correctly. + + +## 4. Create a management room + +Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room. Anyone in this room can control the bot so it is important that you only invite trusted users to this room. The room must be unencrypted since the playbook does not support installing Pantalaimon yet. + +Once you have created the room you need to copy the room ID so you can tell the bot to use that room. In Element you can do this by going to the room's settings, clicking Advanced, and then coping the internal room ID. The room ID will look something like `!QvgVuKq0ha8glOLGMG:DOMAIN`. + +Finally invite the `@bot.mjolnir:DOMAIN` account you created earlier into the room. + + +## 5. Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs): + +You must replace `ACCESS_TOKEN_FROM_STEP_2_GOES_HERE` and `ROOM_ID_FROM_STEP_4_GOES_HERE` with the your own values. + +```yaml +matrix_bot_mjolnir_enabled: true + +matrix_bot_mjolnir_access_token: "ACCESS_TOKEN_FROM_STEP_2_GOES_HERE" + +matrix_bot_mjolnir_management_room: "ROOM_ID_FROM_STEP_4_GOES_HERE" +``` + + +## 6. Installing + +After configuring the playbook, run the [installation](installing.md) command: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + + +## Usage + +You can refer to the upstream [documentation](https://github.com/matrix-org/mjolnir) for additional ways to use and configure mjolnir. Check out their [quickstart guide](https://github.com/matrix-org/mjolnir#quickstart-guide) for some basic commands you can give to the bot. + +You can configure additional options by adding the `matrix_bot_mjolnir_configuration_extension_yaml` variable to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file. + +For example to change mjolnir's `recordIgnoredInvites` option to `true` you would add the following to your `vars.yml` file. + +```yaml +matrix_bot_mjolnir_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bot_mjolnir_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bot_mjolnir_configuration_yaml`. + recordIgnoredInvites: true +``` diff --git a/docs/configuring-playbook-bridge-appservice-irc.md b/docs/configuring-playbook-bridge-appservice-irc.md index a9403cb5..93e0fb36 100644 --- a/docs/configuring-playbook-bridge-appservice-irc.md +++ b/docs/configuring-playbook-bridge-appservice-irc.md @@ -1,6 +1,8 @@ # Setting up Appservice IRC (optional) -The playbook can install and configure [matrix-appservice-irc](https://github.com/matrix-org/matrix-appservice-irc) for you. +**Note**: bridging to [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) can also happen via the [Heisenbridge](configuring-playbook-bridge-heisenbridge.md) bridge supported by the playbook. + +The playbook can install and configure the [matrix-appservice-irc](https://github.com/matrix-org/matrix-appservice-irc) bridge for you. See the project's [documentation](https://github.com/matrix-org/matrix-appservice-irc/blob/master/HOWTO.md) to learn what it does and why it might be useful to you. diff --git a/docs/configuring-playbook-bridge-appservice-slack.md b/docs/configuring-playbook-bridge-appservice-slack.md index a409a050..7d45d34d 100644 --- a/docs/configuring-playbook-bridge-appservice-slack.md +++ b/docs/configuring-playbook-bridge-appservice-slack.md @@ -1,5 +1,7 @@ # Setting up Appservice Slack (optional) +**Note**: bridging to [Slack](https://slack.com) can also happen via the [mx-puppet-slack](configuring-playbook-bridge-mx-puppet-slack.md) bridge supported by the playbook. + The playbook can install and configure [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) for you. See the project's [documentation](https://github.com/matrix-org/matrix-appservice-slack/blob/master/README.md) to learn what it does and why it might be useful to you. @@ -106,5 +108,5 @@ Check you logs, if they say something like `WARN SlackEventHandler Ignoring message from unrecognised slack channel id : %s (%s) ` -then unlink your room, reinvite the bot and re-link it again. This may particularly hit you, if you tried to unsuccessfully link +then unlink your room, reinvite the bot and re-link it again. This may particularly hit you, if you tried to unsuccessfully link your room multiple times without unlinking it after each failed attempt. diff --git a/docs/configuring-playbook-bridge-heisenbridge.md b/docs/configuring-playbook-bridge-heisenbridge.md new file mode 100644 index 00000000..9cf016f2 --- /dev/null +++ b/docs/configuring-playbook-bridge-heisenbridge.md @@ -0,0 +1,36 @@ +# Setting up Heisenbridge (optional) + +**Note**: bridging to [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) can also happen via the [matrix-appservice-irc](configuring-playbook-bridge-appservice-irc.md) bridge supported by the playbook. + +The playbook can install and configure [Heisenbridge](https://github.com/hifi/heisenbridge) - the bouncer-style [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) bridge for you. + +See the project's [README](https://github.com/hifi/heisenbridge/blob/master/README.md) to learn what it does and why it might be useful to you. + +## Configuration + +Below are the common configuration options that you may want to set, exhaustive list is in [the bridge's defaults var file](../roles/matrix-bridge-heisenbridge/defaults/main.yml). + +At a minimum, you only need to enable the bridge to get it up and running (`inventory/host_vars/matrix.DOMAIN/vars.yml`): + +```yaml +matrix_heisenbridge_enabled: true + +# set owner (optional) +matrix_heisenbridge_owner: "@you:your-homeserver" + +# to enable identd on host port 113/TCP (optional) +matrix_heisenbridge_identd_enabled: true +``` + +That's it! A registration file is automatically generated during the setup phase. + +Setting the owner is optional as the first local user to DM `@heisenbridge:your-homeserver` will be made the owner. +If you are not using a local user you must set it as otherwise you can't DM it at all. + +## Usage + +After the bridge is successfully running just DM `@heisenbridge:your-homeserver` to start setting it up. +Help is available for all commands with the `-h` switch. +If the bridge ignores you and a DM is not accepted then the owner setting may be wrong. + +If you encounter issues or feel lost you can join the project room at [#heisenbridge:vi.fi](https://matrix.to/#/#heisenbridge:vi.fi) for help. diff --git a/docs/configuring-playbook-bridge-mautrix-facebook.md b/docs/configuring-playbook-bridge-mautrix-facebook.md index a228f7cb..d07873ae 100644 --- a/docs/configuring-playbook-bridge-mautrix-facebook.md +++ b/docs/configuring-playbook-bridge-mautrix-facebook.md @@ -2,16 +2,37 @@ The playbook can install and configure [mautrix-facebook](https://github.com/tulir/mautrix-facebook) for you. -See the project's [documentation](https://github.com/tulir/mautrix-facebook/wiki#usage) to learn what it does and why it might be useful to you. +See the project's [documentation](https://github.com/tulir/mautrix-facebook/blob/master/ROADMAP.md) to learn what it does and why it might be useful to you. ```yaml matrix_mautrix_facebook_enabled: true ``` +There are some additional things you may wish to configure about the bridge before you continue. + +Encryption support is off by default. If you would like to enable encryption, add the following to your `vars.yml` file: +```yaml +matrix_mautrix_facebook_configuration_extension_yaml: | + bridge: + encryption: + allow: true + default: true +``` + +If you would like to be able to administrate the bridge from your account it can be configured like this: +```yaml +matrix_mautrix_facebook_configuration_extension_yaml: | + bridge: + permissions: + '@YOUR_USERNAME:YOUR_DOMAIN': admin +``` + +You may wish to look at `roles/matrix-bridge-mautrix-facebook/templates/config.yaml.j2` to find other things you would like to configure. + ## Set up Double Puppeting -If you'd like to use [Double Puppeting](https://github.com/tulir/mautrix-facebook/wiki/Authentication#double-puppeting) (hint: you most likely do), you have 2 ways of going about it. +If you'd like to use [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do), you have 2 ways of going about it. ### Method 1: automatically, by enabling Shared Secret Auth @@ -42,9 +63,7 @@ https://matrix.DOMAIN/_matrix/client/r0/login You then need to start a chat with `@facebookbot:YOUR_DOMAIN` (where `YOUR_DOMAIN` is your base domain, not the `matrix.` domain). -Send `login YOUR_FACEBOOK_EMAIL_ADDRESS YOUR_FACEBOOK_PASSWORD` to the bridge bot to enable bridging for your Facebook/Messenger account. - -You can learn more here about authentication from the bridge's [official documentation on Authentication](https://github.com/tulir/mautrix-facebook/wiki/Authentication). +Send `login YOUR_FACEBOOK_EMAIL_ADDRESS` to the bridge bot to enable bridging for your Facebook Messenger account. You can learn more here about authentication from the bridge's [official documentation on Authentication](https://docs.mau.fi/bridges/python/facebook/authentication.html). If you run into trouble, check the [Troubleshooting](#troubleshooting) section below. diff --git a/docs/configuring-playbook-bridge-mautrix-telegram.md b/docs/configuring-playbook-bridge-mautrix-telegram.md index 693c8168..bfdc6fc5 100644 --- a/docs/configuring-playbook-bridge-mautrix-telegram.md +++ b/docs/configuring-playbook-bridge-mautrix-telegram.md @@ -4,7 +4,7 @@ The playbook can install and configure [mautrix-telegram](https://github.com/tul See the project's [documentation](https://github.com/tulir/mautrix-telegram/wiki#usage) to learn what it does and why it might be useful to you. -You'll need to obtain API keys from `https://my.telegram.org/apps` and then use the following playbook configuration: +You'll need to obtain API keys from [https://my.telegram.org/apps](https://my.telegram.org/apps) and then use the following playbook configuration: ```yaml matrix_mautrix_telegram_enabled: true diff --git a/docs/configuring-playbook-bridge-mx-puppet-slack.md b/docs/configuring-playbook-bridge-mx-puppet-slack.md index 1f20219f..61600c7a 100644 --- a/docs/configuring-playbook-bridge-mx-puppet-slack.md +++ b/docs/configuring-playbook-bridge-mx-puppet-slack.md @@ -1,5 +1,7 @@ # Setting up MX Puppet Slack (optional) +**Note**: bridging to [Slack](https://slack.com) can also happen via the [matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md) bridge supported by the playbook. + The playbook can install and configure [mx-puppet-slack](https://github.com/Sorunome/mx-puppet-slack) for you. diff --git a/docs/configuring-playbook-client-hydrogen.md b/docs/configuring-playbook-client-hydrogen.md new file mode 100644 index 00000000..4b05240b --- /dev/null +++ b/docs/configuring-playbook-client-hydrogen.md @@ -0,0 +1,21 @@ +# Configuring Hydrogen (optional) + +This playbook can install the [Hydrogen](https://github.com/vector-im/hydrogen-web) Matrix web client for you. +Hydrogen is a lightweight web client that supports mobile and legacy web browsers. +Hydrogen can be installed alongside or instead of Element. + +If you'd like Hydrogen to be installed, add the following to your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_client_hydrogen_enabled: true +``` + +You will also need to add a DNS record so that Hydrogen can be accessed. +By default Hydrogen will use https://hydrogen.DOMAIN so you will need to create an CNAME record +for `hydrogen`. See [Configuring DNS](configuring-dns.md). + +If you would like to use a different domain, add the following to your configuration file (changing it to use your preferred domain): + +```yaml + matrix_server_fqn_hydrogen: "helium.{{ matrix_domain }}" +``` diff --git a/docs/configuring-playbook-jitsi.md b/docs/configuring-playbook-jitsi.md index f72241e1..81ceb9fb 100644 --- a/docs/configuring-playbook-jitsi.md +++ b/docs/configuring-playbook-jitsi.md @@ -13,8 +13,8 @@ Before installing Jitsi, make sure you've created the `jitsi.DOMAIN` DNS record. You may also need to open the following ports to your server: -- `10000/udp` - RTP media over UDP - `4443/tcp` - RTP media fallback over TCP +- `10000/udp` - RTP media over UDP. 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)). ## Installation diff --git a/docs/configuring-playbook-own-webserver.md b/docs/configuring-playbook-own-webserver.md index 915c2c37..8a827d0d 100644 --- a/docs/configuring-playbook-own-webserver.md +++ b/docs/configuring-playbook-own-webserver.md @@ -55,6 +55,8 @@ Note that if your nginx version is old, it might not like our default choice of matrix_nginx_proxy_ssl_protocols: "TLSv1.2" ``` +If you are experiencing issues, try updating to a newer version of Nginx. As a data point in May 2021 a user reported that Nginx 1.14.2 was not working for them. They were getting errors about socket leaks. Updating to Nginx 1.19 fixed their issue. + ### Using your own external Apache webserver diff --git a/docs/configuring-playbook-postgres-backup.md b/docs/configuring-playbook-postgres-backup.md new file mode 100644 index 00000000..2d878c11 --- /dev/null +++ b/docs/configuring-playbook-postgres-backup.md @@ -0,0 +1,32 @@ +# Setting up postgres backup (optional) + +The playbook can install and configure [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local) for you. + +## Adjusting the playbook configuration + +Minimal working configuration (`inventory/host_vars/matrix.DOMAIN/vars.yml`) to enable Postgres backup: + +```yaml +matrix_postgres_backup_enabled: true +``` + +Refer to the table below for additional configuration variables and their default values. + + +| Name | Default value | Description | +| :-------------------------------- | :--------------------------- | :--------------------------------------------------------------- | +|`matrix_postgres_backup_enabled`|`false`|Set to true to use [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local) to create automatic database backups| +|`matrix_postgres_backup_schedule`| `'@daily'` |Cron-schedule specifying the interval between postgres backups.| +|`matrix_postgres_backup_keep_days`|`7`|Number of daily backups to keep| +|`matrix_postgres_backup_keep_weeks`|`4`|Number of weekly backups to keep| +|`matrix_postgres_backup_keep_months`|`12`|Number of monthly backups to keep| +|`matrix_postgres_backup_path` | `"{{ matrix_base_data_path }}/postgres-backup"` | Storagepath for the database backups| + + +## Installing + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` diff --git a/docs/configuring-playbook-prometheus-grafana.md b/docs/configuring-playbook-prometheus-grafana.md index a10497cc..dc1b7b4c 100644 --- a/docs/configuring-playbook-prometheus-grafana.md +++ b/docs/configuring-playbook-prometheus-grafana.md @@ -4,6 +4,8 @@ It can be useful to have some (visual) insight into the performance of your home You can enable this with the following settings in your configuration file (`inventory/host_vars/matrix./vars.yml`): +Remember to add `stats.` to DNS as described in [Configuring DNS](configuring-dns.md) before running the playbook. + ```yaml matrix_prometheus_enabled: true @@ -15,11 +17,10 @@ matrix_grafana_anonymous_access: false # This has no relation to your Matrix user id. It can be any username you'd like. # Changing the username subsequently won't work. -matrix_grafana_default_admin_user: some_username_chosen_by_you +matrix_grafana_default_admin_user: "some_username_chosen_by_you" -# Passwords containing special characters may be troublesome. # Changing the password subsequently won't work. -matrix_grafana_default_admin_password: some_strong_password_chosen_by_you +matrix_grafana_default_admin_password: "some_strong_password_chosen_by_you" ``` By default, a [Grafana](https://grafana.com/) web user-interface will be available at `https://stats.`. @@ -55,9 +56,10 @@ Name | Description `matrix_nginx_proxy_proxy_synapse_metrics`|Set this to `true` to make matrix-nginx-proxy expose the Synapse metrics at `https://matrix.DOMAIN/_synapse/metrics` `matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_enabled`|Set this to `true` to password-protect (using HTTP Basic Auth) `https://matrix.DOMAIN/_synapse/metrics` (the username is always `prometheus`, the password is defined in `matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_key`) `matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_key`|Set this to a password to use for HTTP Basic Auth for protecting `https://matrix.DOMAIN/_synapse/metrics` (the username is always `prometheus` - it's not configurable) +`matrix_server_fqn_grafana`|Use this variable to override the domain at which the Grafana web user-interface is at (defaults to `stats.DOMAIN`). -## More inforation +## More information - [Understanding Synapse Performance Issues Through Grafana Graphs](https://github.com/matrix-org/synapse/wiki/Understanding-Synapse-Performance-Issues-Through-Grafana-Graphs) at the Synapse Github Wiki - [The Prometheus scraping rules](https://github.com/matrix-org/synapse/tree/master/contrib/prometheus) (we use v2) diff --git a/docs/configuring-playbook-sygnal.md b/docs/configuring-playbook-sygnal.md new file mode 100644 index 00000000..3eb626eb --- /dev/null +++ b/docs/configuring-playbook-sygnal.md @@ -0,0 +1,71 @@ +# Setting up Sygnal (optional) + +The playbook can install and configure the [Sygnal](https://github.com/matrix-org/sygnal) push gateway for you. + +See the project's [documentation](https://github.com/matrix-org/sygnal) to learn what it does and why it might be useful to you. + +**Note**: most people don't need to install their own gateway. As Sygnal's [Notes for application developers](https://github.com/matrix-org/sygnal/blob/master/docs/applications.md) documentation says: + +> It is not feasible to allow end-users to configure their own Sygnal instance, because the Sygnal instance needs the appropriate FCM or APNs secrets that belong to the application. + +This optional playbook component is only useful to people who develop/build their own Matrix client applications themselves. + + +## Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs): + +```yaml +matrix_sygnal_enabled: true + +# You need at least 1 app defined. +# The configuration below is incomplete. Read more below. +matrix_sygnal_apps: + com.example.myapp.ios: + type: apns + keyfile: /data/my_key.p8 + # .. more configuration .. + com.example.myapp.android: + type: gcm + api_key: your_api_key_for_gcm + # .. more configuration .. + +matrix_aux_file_definitions: + - dest: "{{ matrix_sygnal_data_path }}/my_key.p8" + content: | + some + content + here + mode: '0600' + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" +``` + +For a more complete example of available fields and values they can take, see `roles/matrix-sygnal/templates/sygnal.yaml.j2` (or the [upstream `sygnal.yaml.sample` configuration file](https://github.com/matrix-org/sygnal/blob/master/sygnal.yaml.sample)). + +Configuring [GCM/FCM](https://firebase.google.com/docs/cloud-messaging/) is easier, as it only requires that you provide some config values. + +To configure [APNS](https://developer.apple.com/notifications/) (Apple Push Notification Service), you'd need to provide one or more certificate files. +To do that, the above example configuration: + +- makes use of the `matrix-aux` role (and its `matrix_aux_file_definitions` variable) to make the playbook install files into `/matrix/sygnal/data` (the `matrix_sygnal_data_path` variable). See `roles/matrix-aux/defaults/main.yml` for usage examples. It also makes sure the files are owned by `matrix:matrix`, so that Sygnal can read them. Of course, you can also install these files manually yourself, if you'd rather not use `matrix-aux`. + +- references these files in the Sygnal configuration (`matrix_sygnal_apps`) using a path like `/data/..` (the `/matrix/sygnal/data` directory on the host system is mounted into the `/data` directory inside the container) + + +## Installing + +Don't forget to add `sygnal.` to DNS as described in [Configuring DNS](configuring-dns.md) before running the playbook. + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + + +## Usage + +To make use of your Sygnal installation, you'd need to build your own Matrix client application, which uses the same API keys (for [GCM/FCM](https://firebase.google.com/docs/cloud-messaging/)) and certificates (for [APNS](https://developer.apple.com/notifications/)) and is also pointed to `https://sygnal.DOMAIN` as the configured push server. + +Refer to Sygnal's [Notes for application developers](https://github.com/matrix-org/sygnal/blob/master/docs/applications.md) document. diff --git a/docs/configuring-playbook-synapse-admin.md b/docs/configuring-playbook-synapse-admin.md index 68d70305..5b9519e2 100644 --- a/docs/configuring-playbook-synapse-admin.md +++ b/docs/configuring-playbook-synapse-admin.md @@ -6,6 +6,8 @@ It's a web UI tool you can use to **administrate users and rooms on your Matrix See the project's [documentation](https://github.com/Awesome-Technologies/synapse-admin) to learn what it does and why it might be useful to you. +**Warning**: Synapse Admin will likely not work with Synapse v1.32 for now. See [this issue](https://github.com/Awesome-Technologies/synapse-admin/issues/132). If you insist on using Synapse Admin before there's a solution to this issue, you may wish to downgrade Synapse (adding `matrix_synapse_version: v1.31.0` or `matrix_synapse_version_arm64: v1.31.0` to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file). + ## Adjusting the playbook configuration diff --git a/docs/configuring-playbook.md b/docs/configuring-playbook.md index 34c52efc..fae66dca 100644 --- a/docs/configuring-playbook.md +++ b/docs/configuring-playbook.md @@ -8,15 +8,15 @@ To configure the playbook, you need to have done the following things: You can then follow these steps inside the playbook directory: -- create a directory to hold your configuration (`mkdir inventory/host_vars/matrix.`) +1. create a directory to hold your configuration (`mkdir inventory/host_vars/matrix.`) -- copy the sample configuration file (`cp examples/vars.yml inventory/host_vars/matrix./vars.yml`) +1. copy the sample configuration file (`cp examples/vars.yml inventory/host_vars/matrix./vars.yml`) -- edit the configuration file (`inventory/host_vars/matrix./vars.yml`) to your liking. You may also take a look at the various `roles/ROLE_NAME_HERE/defaults/main.yml` files and see if there's something you'd like to copy over and override in your `vars.yml` configuration file. +1. edit the configuration file (`inventory/host_vars/matrix./vars.yml`) to your liking. You may also take a look at the various `roles/ROLE_NAME_HERE/defaults/main.yml` files and see if there's something you'd like to copy over and override in your `vars.yml` configuration file. -- copy the sample inventory hosts file (`cp examples/hosts inventory/hosts`) +1. copy the sample inventory hosts file (`cp examples/hosts inventory/hosts`) -- edit the inventory hosts file (`inventory/hosts`) to your liking +1. edit the inventory hosts file (`inventory/hosts`) to your liking For a basic Matrix installation, that's all you need. @@ -68,6 +68,8 @@ When you're done with all the configuration you'd like to do, continue with [Ins - [Adjusting email-sending settings](configuring-playbook-email.md) (optional) +- [Setting up Hydrogen](configuring-playbook-client-hydrogen.md) - a new lightweight matrix client with legacy and mobile browser support (optional) + ### Authentication and user-related @@ -126,7 +128,18 @@ When you're done with all the configuration you'd like to do, continue with [Ins - [Setting up Matrix SMS bridging](configuring-playbook-bridge-matrix-bridge-sms.md) (optional) +- [Setting up Heisenbridge bouncer-style IRC bridging](configuring-playbook-bridge-heisenbridge.md) (optional) + ### Bots -- [Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) (optional) +- [Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) - a bot to remind you about stuff (optional) + +- [Setting up Go-NEB](configuring-playbook-bot-go-neb.md) - an extensible multifunctional bot (optional) + +- [Setting up Mjolnir](configuring-playbook-bot-mjolnir.md) - a moderation tool/bot (optional) + + +### Other specialized services + +- [Setting up the Sygnal push gateway](configuring-playbook-sygnal.md) (optional) diff --git a/docs/container-images.md b/docs/container-images.md index a5e304f4..f2914488 100644 --- a/docs/container-images.md +++ b/docs/container-images.md @@ -11,7 +11,7 @@ These services are enabled and used by default, but you can turn them off, if yo - [matrixdotorg/synapse](https://hub.docker.com/r/matrixdotorg/synapse/) - the official [Synapse](https://github.com/matrix-org/synapse) Matrix homeserver (optional) -- [instrumentisto/coturn](https://hub.docker.com/r/instrumentisto/coturn/) - the [Coturn](https://github.com/coturn/coturn) STUN/TURN server (optional) +- [coturn/coturn](https://hub.docker.com/r/coturn/coturn/) - the [Coturn](https://github.com/coturn/coturn) STUN/TURN server (optional) - [vectorim/element-web](https://hub.docker.com/r/vectorim/element-web/) - the [Element](https://element.io/) web client (optional) @@ -88,6 +88,10 @@ These services are not part of our default installation, but can be enabled by [ - [anoa/matrix-reminder-bot](https://hub.docker.com/r/anoa/matrix-reminder-bot) - the [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) bot for one-off & recurring reminders and alarms (optional) +- [matrixdotorg/go-neb](https://hub.docker.com/r/matrixdotorg/go-neb) - the [Go-NEB](https://github.com/matrix-org/go-neb) bot (optional) + +- [matrixdotorg/mjolnir](https://hub.docker.com/r/matrixdotorg/mjolnir) - the [mjolnir](https://github.com/matrix-org/mjolnir) moderation bot (optional) + - [awesometechnologies/synapse-admin](https://hub.docker.com/r/awesometechnologies/synapse-admin) - the [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin) web UI tool for administrating users and rooms on your Matrix server (optional) - [prom/prometheus](https://hub.docker.com/r/prom/prometheus/) - [Prometheus](https://github.com/prometheus/prometheus/) is a systems and service monitoring system @@ -95,3 +99,5 @@ These services are not part of our default installation, but can be enabled by [ - [prom/node-exporter](https://hub.docker.com/r/prom/node-exporter/) - [Prometheus Node Exporter](https://github.com/prometheus/node_exporter/) is an addon for Prometheus that gathers standard system metrics - [grafana/grafana](https://hub.docker.com/r/grafana/grafana/) - [Grafana](https://github.com/grafana/grafana/) is a graphing tool that works well with the above two images. Our playbook also adds two dashboards for [Synapse](https://github.com/matrix-org/synapse/tree/master/contrib/grafana) and [Node Exporter](https://github.com/rfrail3/grafana-dashboards) + +- [matrixdotorg/sygnal](https://hub.docker.com/r/matrixdotorg/sygnal/) - [Sygnal](https://github.com/matrix-org/sygnal) is a reference Push Gateway for Matrix diff --git a/docs/faq.md b/docs/faq.md index a6782231..6c9eedc2 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -289,7 +289,7 @@ matrix_mailer_enabled: false # You can also disable this to save more RAM, # at the expense of audio/video calls being unreliable. -matrix_coturn_enabled: true +matrix_coturn_enabled: false # This makes Synapse not keep track of who is online/offline. # @@ -297,7 +297,7 @@ matrix_coturn_enabled: true # hundreds of servers inside is insanely heavy (https://github.com/matrix-org/synapse/issues/3971). # # If your server does not federate with hundreds of others, enabling this doesn't hurt much. -matrix_synapse_use_presence: false +matrix_synapse_presence_enabled: false ``` You can also consider implementing a restriction on room complexity, in order to prevent users from joining very heavy rooms: @@ -458,3 +458,18 @@ If your server's IP address has changed, you may need to [set up DNS](configurin When you [perform a major Postgres upgrade](maintenance-postgres.md#upgrading-postgresql), we save the the old data files in `/matrix/postgres/data-auto-upgrade-backup`, just so you could easily restore them should something have gone wrong. After verifying that everything still works after the Postgres upgrade, you can safely delete `/matrix/postgres/data-auto-upgrade-backup` + +### How do I debug or force SSL certificate renewal? + +SSL certificate renewal normally happens automatically via [systemd timers](https://wiki.archlinux.org/index.php/Systemd/Timers). + +If you're having trouble with SSL certificate renewal, you can inspect the renewal logs using: + +- `journalctl -fu matrix-ssl-lets-encrypt-certificates-renew.service` +- *or* by looking at the log files in `/matrix/ssl/log/` + +To trigger renewal, run: `systemctl start matrix-ssl-lets-encrypt-certificates-renew.service`. You can then take a look at the logs again. + +If you're using the integrated webserver (`matrix-nginx-proxy`), you can reload it manually like this: `systemctl reload matrix-nginx-proxy`. Reloading also happens periodically via a systemd timer. + +If you're [using your own webserver](configuring-playbook-own-webserver.md) instead of the integrated one (`matrix-nginx-proxy`) you may also need to reload/restart it, to make it pick up the renewed SSL certificate files. diff --git a/docs/maintenance-migrating.md b/docs/maintenance-migrating.md index 71a38e58..d6380b99 100644 --- a/docs/maintenance-migrating.md +++ b/docs/maintenance-migrating.md @@ -1,6 +1,6 @@ # Migrating to new server -1. Prepare by lowering DNS TTL for your domains (`matrix.DOMAIN`, etc.), so that DNS record changes (step 4 below) would happen faster, leading ot less downtime +1. Prepare by lowering DNS TTL for your domains (`matrix.DOMAIN`, etc.), so that DNS record changes (step 4 below) would happen faster, leading to less downtime 2. Stop all services on the old server and make sure they won't be starting again. Execute this on the old server: `systemctl disable --now matrix*` 3. Copy directory `/matrix` from the old server to the new server. Make sure to preserve ownership and permissions (use `cp -p` or `rsync -ar`)! 4. Make sure your DNS records are adjusted to point to the new server's IP address diff --git a/docs/maintenance-postgres.md b/docs/maintenance-postgres.md index 50f5a55d..9b748d28 100644 --- a/docs/maintenance-postgres.md +++ b/docs/maintenance-postgres.md @@ -12,6 +12,7 @@ Table of contents: - [Upgrading PostgreSQL](#upgrading-postgresql), for upgrading to new major versions of PostgreSQL. Such **manual upgrades are sometimes required**. +- [Tuning PostgreSQL](#tuning-postgresql) to make it run faster ## Getting a database terminal @@ -48,23 +49,20 @@ ansible-playbook -i inventory/hosts setup.yml --tags=run-postgres-vacuum,start ## Backing up PostgreSQL -To make a back up of the current PostgreSQL database, make sure it's running and then execute a command like this on the server: +To automatically make Postgres database backups on a fixed schedule, see [Setting up postgres backup](configuring-playbook-postgres-backup.md). + +To make a one off back up of the current PostgreSQL database, make sure it's running and then execute a command like this on the server: ```bash -docker run \ ---rm \ ---log-driver=none \ ---network=matrix \ +/usr/bin/docker exec \ --env-file=/matrix/postgres/env-postgres-psql \ -docker.io/postgres:13.1-alpine \ -pg_dumpall -h matrix-postgres \ +matrix-postgres \ +/usr/local/bin/pg_dumpall -h matrix-postgres \ | gzip -c \ -> /postgres.sql.gz +> /matrix/postgres.sql.gz ``` -If you are using an [external Postgres server](configuring-playbook-external-postgres.md), the above command will not work, because the credentials file (`/matrix/postgres/env-postgres-psql`) is not available. - -If your server is on the ARM32 [architecture](alternative-architectures.md), you may need to remove the `-alpine` suffix from the image name in the command above. +If you are using an [external Postgres server](configuring-playbook-external-postgres.md), the above command will not work, because neither the credentials file (`/matrix/postgres/env-postgres-psql`), nor the `matrix-postgres` container is available. Restoring a backup made this way can be done by [importing it](importing-postgres.md). @@ -95,3 +93,43 @@ If you have plenty of space in `/tmp` and would rather avoid gzipping, you can e Example: `--extra-vars="postgres_dump_name=matrix-postgres-dump.sql"` **All databases, roles, etc. on the Postgres server are migrated**. + + +## Tuning PostgreSQL + +PostgreSQL can be tuned to make it run faster. This is done by passing extra arguments to Postgres with the `matrix_postgres_process_extra_arguments` variable. You should use a website like https://pgtune.leopard.in.ua/ or information from https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server to determine what Postgres settings you should change. + +### Here are some examples: + +These are not recommended values and they may not work well for you. This is just to give you an idea of some of the options that can be set. If you are an experienced PostgreSQL admin feel free to update this documentation with better examples. + +Here is an example config for a small 2 core server with 4GB of RAM and SSD storage: +``` +matrix_postgres_process_extra_arguments: [ + "-c 'shared_buffers=128MB'", + "-c 'effective_cache_size=2304MB'", + "-c 'effective_io_concurrency=100'", + "-c 'random_page_cost=2.0'", + "-c 'min_wal_size=500MB'", +] +``` + +Here is an example config for a large 6 core server with 24GB of RAM: +``` +matrix_postgres_process_extra_arguments: [ + "-c max_connections=40", + "-c shared_buffers=1536MB", + "-c checkpoint_completion_target=0.7", + "-c wal_buffers=16MB", + "-c default_statistics_target=100", + "-c random_page_cost=1.1", + "-c effective_io_concurrency=100", + "-c work_mem=2621kB", + "-c min_wal_size=1GB", + "-c max_wal_size=4GB", + "-c max_worker_processes=6", + "-c max_parallel_workers_per_gather=3", + "-c max_parallel_workers=6", + "-c max_parallel_maintenance_workers=3", +] +``` diff --git a/docs/maintenance-synapse.md b/docs/maintenance-synapse.md index 143238c1..62bb8b16 100644 --- a/docs/maintenance-synapse.md +++ b/docs/maintenance-synapse.md @@ -6,21 +6,15 @@ Table of contents: - [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) - - [Browse and manipulate the database](#browse-and-manipulate-the-database) +- [Compressing state with rust-synapse-compress-state](#compressing-state-with-rust-synapse-compress-state) - [Browse and manipulate the database](#browse-and-manipulate-the-database), for when you really need to take matters into your own hands +- [Make Synapse faster](#make-synapse-faster) ## Purging old data with the Purge History API -You can use the **Purge History API** to delete in-use (but old) data. - -**This is destructive** (especially for non-federated rooms), because it means **people will no longer have access to history past a certain point**. - -Synapse's [Purge History API](https://github.com/matrix-org/synapse/blob/master/docs/admin_api/purge_history_api.rst) can be used to purge on a per-room basis. +You can use the **[Purge History API](https://github.com/matrix-org/synapse/blob/master/docs/admin_api/purge_history_api.rst)** to delete old messages on a per-room basis. **This is destructive** (especially for non-federated rooms), because it means **people will no longer have access to history past a certain point**. To make use of this API, **you'll need an admin access token** first. You can find your access token in the setting of some clients (like Element). Alternatively, you can log in and obtain a new access token like this: @@ -31,6 +25,8 @@ curl \ https://matrix.DOMAIN/_matrix/client/r0/login ``` +Synapse's Admin API is not exposed to the internet by default. To expose it you will need to add `matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: true` to your `vars.yml` file. + Follow the [Purge History API](https://github.com/matrix-org/synapse/blob/master/docs/admin_api/purge_history_api.rst) documentation page for the actual purging instructions. After deleting data, you may wish to run a [`FULL` Postgres `VACUUM`](./maintenance-postgres.md#vacuuming-postgresql). @@ -38,7 +34,7 @@ After deleting data, you may wish to run a [`FULL` Postgres `VACUUM`](./maintena ## Compressing state with rust-synapse-compress-state -[rust-synapse-compress-state](https://github.com/matrix-org/rust-synapse-compress-state) can be used to optimize some `_state` tables used by Synapse. +[rust-synapse-compress-state](https://github.com/matrix-org/rust-synapse-compress-state) can be used to optimize some `_state` tables used by Synapse. If your server participates in large rooms this is the most effective way to reduce the size of your database. This tool should be safe to use (even when Synapse is running), but it's always a good idea to [make Postgres backups](./maintenance-postgres.md#backing-up-postgresql) first. @@ -56,7 +52,10 @@ After state compression, you may wish to run a [`FULL` Postgres `VACUUM`](./main ## 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. +When the [Synapse 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. + +Editing the database manually is not recommended or supported by the Synapse developers. If you are going to do so you should [make a database backup](./maintenance-postgres.md#backing-up-postgresql). + First, set up an SSH tunnel to your matrix server (skip if it is your local machine): ``` @@ -73,3 +72,13 @@ docker run --rm --publish 1799:8080 --link matrix-postgres --net matrix adminer You should then be able to browse the adminer database administration GUI at http://localhost:1799/ after entering your DB credentials (found in the `host_vars` or on the server in `{{matrix_synapse_config_dir_path}}/homeserver.yaml` under `database.args`) ⚠️ Be **very careful** with this, there is **no undo** for impromptu DB operations. + +## Make Synapse faster + +Synapse's presence feature which tracks which users are online and which are offline can use a lot of processing power. You can disable presence by adding `matrix_synapse_presence_enabled: false` to your `vars.yml` file. + +Tuning Synapse's cache factor can help reduce RAM usage. [See the upstream documentation](https://github.com/matrix-org/synapse#help-synapse-is-slow-and-eats-all-my-ram-cpu) for more information on what value to set the cache factor to. Use the variable `matrix_synapse_caches_global_factor` to set the cache factor. + +Tuning your PostgreSQL database will also make Synapse run significantly faster. See [maintenance-postgres.md##tuning-postgresql](maintenance-postgres.md##tuning-postgresql). + +See also [How do I optimize this setup for a low-power server?](faq.md#how-do-i-optimize-this-setup-for-a-low-power-server). diff --git a/docs/prerequisites.md b/docs/prerequisites.md index e678a0bd..39b42ef1 100644 --- a/docs/prerequisites.md +++ b/docs/prerequisites.md @@ -20,8 +20,6 @@ If your distro runs within an [LXC container](https://linuxcontainers.org/), you - The [Ansible](http://ansible.com/) program being installed on your own computer. It's used to run this playbook and configures your server for you. Take a look at [our guide about Ansible](ansible.md) for more information, as well as [version requirements](ansible.md#supported-ansible-versions) and alternative ways to run Ansible. -- Either the `dig` tool or `python-dns` installed on your own computer. Used later on, by the playbook's [services check](maintenance-checking-services.md) feature. - - An HTTPS-capable web server at the base domain name (``) which is capable of serving static files. Unless you decide to [Serve the base domain from the Matrix server](configuring-playbook-base-domain-serving.md) or alternatively, to use DNS SRV records for [Server Delegation](howto-server-delegation.md). - Properly configured DNS records for `` (details in [Configuring DNS](configuring-dns.md)). @@ -36,7 +34,6 @@ If your distro runs within an [LXC container](https://linuxcontainers.org/), you - `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)). + - potentially some other ports, depending on the additional (non-default) services that you enable in the **configuring the playbook** step (later on). Consult each service's documentation page in `docs/` for that. When ready to proceed, continue with [Configuring DNS](configuring-dns.md). diff --git a/docs/self-building.md b/docs/self-building.md index 0d41e419..303344ac 100644 --- a/docs/self-building.md +++ b/docs/self-building.md @@ -14,6 +14,7 @@ List of roles where self-building the Docker image is currently possible: - `matrix-synapse` - `matrix-synapse-admin` - `matrix-client-element` +- `matrix-client-hydrogen` - `matrix-registration` - `matrix-coturn` - `matrix-corporal` diff --git a/examples/caddy2/Caddyfile b/examples/caddy2/Caddyfile index d13b9788..c6d2841b 100644 --- a/examples/caddy2/Caddyfile +++ b/examples/caddy2/Caddyfile @@ -38,7 +38,6 @@ matrix.DOMAIN.tld { X-Frame-Options "DENY" # X-Robots-Tag X-Robots-Tag "noindex, noarchive, nofollow" - 167,9 79% } # Cache @@ -101,7 +100,7 @@ element.DOMAIN.tld { # creates letsencrypt certificate # tls your@email.com - + header { # Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" @@ -128,10 +127,10 @@ element.DOMAIN.tld { } #dimension.DOMAIN.tld { -# +# # # creates letsencrypt certificate # # tls your@email.com -# +# # header { # # Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS # Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" @@ -160,7 +159,7 @@ element.DOMAIN.tld { #jitsi.DOMAIN.tld { -# +# # creates letsencrypt certificate # tls your@email.com # @@ -193,7 +192,7 @@ element.DOMAIN.tld { # handle { # encode zstd gzip # -# reverse_proxy 127.0.0.1:12080 { +# reverse_proxy 127.0.0.1:13080 { # header_up X-Forwarded-Port {http.request.port} # header_up X-Forwarded-Proto {http.request.scheme} # header_up X-Forwarded-TlsProto {tls_protocol} @@ -201,4 +200,4 @@ element.DOMAIN.tld { # header_up X-Forwarded-HttpsProto {proto} # } # } -#} \ No newline at end of file +#} diff --git a/examples/caddy2/README.md b/examples/caddy2/README.md index 022a4fec..fe8d5763 100644 --- a/examples/caddy2/README.md +++ b/examples/caddy2/README.md @@ -8,5 +8,5 @@ This directory contains sample files that show you how to do reverse-proxying us | ------------------ | -------- | | tls your@email.com | Specify an email address for your [ACME account](https://caddyserver.com/docs/caddyfile/directives/tls) (but if only one email is used for all sites, we recommend the email [global option](https://caddyserver.com/docs/caddyfile/options) instead) | | tls | To enable [tls](https://caddyserver.com/docs/caddyfile/directives/tls) support uncomment the lines for tls | -| Dimnension | To enable Dimension support uncomment the lines for Dimension and set your data | -| Jitsi | To enable Jitsi support uncomment the lines for Jitsi and set your data | \ No newline at end of file +| Dimension | To enable Dimension support uncomment the lines for Dimension and set your data | +| Jitsi | To enable Jitsi support uncomment the lines for Jitsi and set your data | diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 07900778..e9be72ca 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -9,6 +9,7 @@ # You can also override ANY variable (seen here or in any given role), # by re-defining it in your own configuration file (`inventory/host_vars/matrix.`). +matrix_container_global_registry_prefix: "docker.io/" ###################################################################### # @@ -29,6 +30,25 @@ matrix_homeserver_container_url: "{{ 'http://matrix-nginx-proxy:12080' if matrix ###################################################################### +###################################################################### +# +# matrix-awx +# +###################################################################### + +# We don't enable AWX support by default. +matrix_awx_enabled: false + +matrix_nginx_proxy_data_path: "{{ '/chroot/website' if (matrix_awx_enabled and not matrix_nginx_proxy_base_domain_homepage_enabled) else (matrix_nginx_proxy_base_path + '/data') }}" +matrix_nginx_proxy_data_path_in_container: "{{ '/nginx-data/matrix-domain' if (matrix_awx_enabled and not matrix_nginx_proxy_base_domain_homepage_enabled) else '/nginx-data' }}" + +###################################################################### +# +# /matrix-awx +# +###################################################################### + + ###################################################################### # # matrix-bridge-appservice-discord @@ -44,7 +64,7 @@ matrix_appservice_discord_enabled: false matrix_appservice_discord_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9005' }}" # If the homeserver disables presence, it's likely better (less wasteful) to also disable presence on the bridge side. -matrix_appservice_discord_bridge_disablePresence: "{{ matrix_synapse_use_presence }}" +matrix_appservice_discord_bridge_disablePresence: "{{ not matrix_synapse_presence_enabled }}" matrix_appservice_discord_systemd_required_services_list: | {{ @@ -53,6 +73,8 @@ matrix_appservice_discord_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_appservice_discord_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'discord.as.token') | to_uuid }}" @@ -96,6 +118,8 @@ matrix_appservice_webhooks_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} ###################################################################### @@ -132,6 +156,8 @@ matrix_appservice_slack_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} # Postgres is the default, except if not using `matrix_postgres` (internal postgres) @@ -162,13 +188,15 @@ matrix_appservice_irc_container_http_host_bind_port: "{{ '' if matrix_nginx_prox # The IRC bridge docs say that if homeserver presence is disabled, it's better to also disable # IRC bridge presence, for performance reasons. -matrix_appservice_irc_homeserver_enablePresence: "{{ matrix_synapse_use_presence }}" +matrix_appservice_irc_homeserver_enablePresence: "{{ matrix_synapse_presence_enabled }}" matrix_appservice_irc_systemd_required_services_list: | {{ ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_appservice_irc_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'irc.as.token') | to_uuid }}" @@ -204,6 +232,8 @@ matrix_mautrix_facebook_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mautrix_facebook_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'fb.as.token') | to_uuid }}" @@ -212,7 +242,7 @@ 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 }}" +matrix_mautrix_facebook_bridge_presence: "{{ matrix_synapse_presence_enabled if matrix_synapse_enabled else true }}" # We'd like to force-set people with external Postgres to SQLite, so the bridge role can complain # and point them to a migration path. @@ -244,6 +274,8 @@ matrix_mautrix_hangouts_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mautrix_hangouts_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'ho.as.token') | to_uuid }}" @@ -283,6 +315,8 @@ matrix_mautrix_instagram_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mautrix_instagram_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'ig.as.token') | to_uuid }}" @@ -291,7 +325,7 @@ matrix_mautrix_instagram_homeserver_token: "{{ matrix_synapse_macaroon_secret_ke matrix_mautrix_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 '' }}" -matrix_mautrix_instagram_bridge_presence: "{{ matrix_synapse_use_presence if matrix_synapse_enabled else true }}" +matrix_mautrix_instagram_bridge_presence: "{{ matrix_synapse_presence_enabled if matrix_synapse_enabled else true }}" # We'd like to force-set people with external Postgres to SQLite, so the bridge role can complain # and point them to a migration path. @@ -322,6 +356,8 @@ matrix_mautrix_signal_systemd_required_services_list: | + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + + ['matrix-mautrix-signal-daemon.service'] }} @@ -364,6 +400,8 @@ matrix_mautrix_telegram_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mautrix_telegram_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'telegr.as.token') | to_uuid }}" @@ -402,6 +440,8 @@ matrix_mautrix_whatsapp_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mautrix_whatsapp_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'whats.as.token') | to_uuid }}" @@ -434,6 +474,8 @@ matrix_sms_bridge_systemd_required_services_list: | ['docker.service'] + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_sms_bridge_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'sms.as.token') | to_uuid }}" @@ -446,6 +488,32 @@ matrix_sms_bridge_homeserver_token: "{{ matrix_synapse_macaroon_secret_key | pas # ###################################################################### +###################################################################### +# +# matrix-bridge-heisenbridge +# +###################################################################### + +# We don't enable bridges by default. +matrix_heisenbridge_enabled: false + +matrix_heisenbridge_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'heisen.as.tok') | to_uuid }}" + +matrix_heisenbridge_homeserver_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'heisen.hs.tok') | to_uuid }}" + +matrix_heisenbridge_systemd_wanted_services_list: | + {{ + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +###################################################################### +# +# /matrix-bridge-heisenbridge +# +###################################################################### + ###################################################################### # # matrix-bridge-mx-puppet-skype @@ -464,6 +532,8 @@ matrix_mx_puppet_skype_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mx_puppet_skype_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'skype.as.tok') | to_uuid }}" @@ -501,6 +571,8 @@ matrix_mx_puppet_slack_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mx_puppet_slack_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxslk.as.tok') | to_uuid }}" @@ -537,6 +609,8 @@ matrix_mx_puppet_twitter_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mx_puppet_twitter_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxtwt.as.tok') | to_uuid }}" @@ -576,6 +650,8 @@ matrix_mx_puppet_instagram_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mx_puppet_instagram_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxig.as.tok') | to_uuid }}" @@ -612,6 +688,8 @@ matrix_mx_puppet_discord_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mx_puppet_discord_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxdsc.as.tok') | to_uuid }}" @@ -648,6 +726,8 @@ matrix_mx_puppet_steam_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mx_puppet_steam_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxste.as.tok') | to_uuid }}" @@ -684,6 +764,8 @@ matrix_mx_puppet_groupme_systemd_required_services_list: | (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} matrix_mx_puppet_groupme_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'mxgro.as.tok') | to_uuid }}" @@ -716,6 +798,10 @@ matrix_bot_matrix_reminder_bot_systemd_required_services_list: | ['docker.service'] + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} # Postgres is the default, except if not using `matrix_postgres` (internal postgres) @@ -729,6 +815,60 @@ matrix_bot_matrix_reminder_bot_database_password: "{{ matrix_synapse_macaroon_se ###################################################################### +###################################################################### +# +# matrix-bot-go-neb +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_go_neb_enabled: false + +matrix_bot_go_neb_systemd_required_services_list: | + {{ + ['docker.service'] + + + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_bot_go_neb_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:4050' }}" + +###################################################################### +# +# /matrix-bot-go-neb +# +###################################################################### + + +###################################################################### +# +# matrix-bot-mjolnir +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_mjolnir_enabled: false + +matrix_bot_mjolnir_systemd_required_services_list: | + {{ + ['docker.service'] + + + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +###################################################################### +# +# /matrix-bot-mjolnir +# +###################################################################### + + ###################################################################### # # matrix-corporal @@ -825,6 +965,10 @@ matrix_dimension_systemd_required_services_list: | ['docker.service'] + (['matrix-postgres.service'] if matrix_postgres_enabled else []) + + + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) }} # Postgres is the default, except if not using `matrix_postgres` (internal postgres) @@ -905,9 +1049,9 @@ matrix_jitsi_enabled: false # Normally, matrix-nginx-proxy is enabled and nginx can reach jitsi/web over the container network. # If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose # 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_web_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:13080' }}" -matrix_jitsi_jvb_container_colibri_ws_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:12090' }}" +matrix_jitsi_jvb_container_colibri_ws_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:13090' }}" 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 }}" @@ -995,7 +1139,9 @@ matrix_ma1sd_synapsesql_connection: //{{ matrix_synapse_database_host }}/{{ matr matrix_ma1sd_dns_overwrite_enabled: true matrix_ma1sd_dns_overwrite_homeserver_client_name: "{{ matrix_server_fqn_matrix }}" -matrix_ma1sd_dns_overwrite_homeserver_client_value: "http://{{ matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container }}" +# The `matrix_ma1sd_dns_overwrite_homeserver_client_value` value when matrix_nginx_proxy_enabled is false covers the general case, +# but may be inaccurate if matrix-corporal is enabled. +matrix_ma1sd_dns_overwrite_homeserver_client_value: "{{ ('http://' + matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container) if matrix_nginx_proxy_enabled else matrix_homeserver_container_url }}" # By default, we send mail through the `matrix-mailer` service. matrix_ma1sd_threepid_medium_email_identity_from: "{{ matrix_mailer_sender_address }}" @@ -1052,9 +1198,12 @@ matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: "{{ matrix_s matrix_nginx_proxy_proxy_matrix_enabled: true matrix_nginx_proxy_proxy_element_enabled: "{{ matrix_client_element_enabled }}" +matrix_nginx_proxy_proxy_hydrogen_enabled: "{{ matrix_client_hydrogen_enabled }}" matrix_nginx_proxy_proxy_dimension_enabled: "{{ matrix_dimension_enabled }}" +matrix_nginx_proxy_proxy_bot_go_neb_enabled: "{{ matrix_bot_go_neb_enabled }}" matrix_nginx_proxy_proxy_jitsi_enabled: "{{ matrix_jitsi_enabled }}" matrix_nginx_proxy_proxy_grafana_enabled: "{{ matrix_grafana_enabled }}" +matrix_nginx_proxy_proxy_sygnal_enabled: "{{ matrix_sygnal_enabled }}" matrix_nginx_proxy_proxy_matrix_corporal_api_enabled: "{{ matrix_corporal_enabled and matrix_corporal_http_api_enabled }}" matrix_nginx_proxy_proxy_matrix_corporal_api_addr_with_container: "matrix-corporal:41081" @@ -1072,7 +1221,9 @@ matrix_nginx_proxy_proxy_matrix_federation_api_addr_sans_container: "127.0.0.1:1 # Settings controlling matrix-synapse-proxy.conf matrix_nginx_proxy_proxy_synapse_enabled: "{{ matrix_synapse_enabled }}" -matrix_nginx_proxy_proxy_synapse_federation_api_enabled: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_enabled }}" + +# When matrix-nginx-proxy is disabled, the actual port number that the vhost uses may begin to matter. +matrix_nginx_proxy_proxy_matrix_federation_port: "{{ matrix_federation_public_port }}" matrix_nginx_proxy_container_federation_host_bind_port: "{{ matrix_federation_public_port }}" @@ -1089,7 +1240,12 @@ matrix_nginx_proxy_proxy_matrix_user_directory_search_addr_sans_container: "{{ m matrix_nginx_proxy_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" -matrix_nginx_proxy_synapse_presence_disabled: "{{ not matrix_synapse_use_presence }}" +# OCSP stapling does not make sense when self-signed certificates are used. +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1073 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1074 +matrix_nginx_proxy_ocsp_stapling_enabled: "{{ matrix_ssl_retrieval_method != 'self-signed' }}" + +matrix_nginx_proxy_synapse_presence_disabled: "{{ not matrix_synapse_presence_enabled }}" matrix_nginx_proxy_synapse_workers_enabled: "{{ matrix_synapse_workers_enabled }}" matrix_nginx_proxy_synapse_workers_list: "{{ matrix_synapse_workers_enabled_list }}" @@ -1101,7 +1257,7 @@ matrix_nginx_proxy_synapse_frontend_proxy_locations: "{{ matrix_synapse_workers matrix_nginx_proxy_systemd_wanted_services_list: | {{ - (['matrix-synapse.service']) + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + (['matrix-corporal.service'] if matrix_corporal_enabled else []) + @@ -1118,12 +1274,18 @@ matrix_ssl_domains_to_obtain_certificates_for: | + ([matrix_nginx_proxy_proxy_riot_compat_redirect_hostname] if matrix_nginx_proxy_proxy_riot_compat_redirect_enabled else []) + + ([matrix_server_fqn_hydrogen] if matrix_client_hydrogen_enabled else []) + + ([matrix_server_fqn_dimension] if matrix_dimension_enabled else []) + + ([matrix_server_fqn_bot_go_neb] if matrix_bot_go_neb_enabled else []) + + ([matrix_server_fqn_jitsi] if matrix_jitsi_enabled else []) + ([matrix_server_fqn_grafana] if matrix_grafana_enabled else []) + + ([matrix_server_fqn_sygnal] if matrix_sygnal_enabled else []) + + ([matrix_domain] if matrix_nginx_proxy_base_domain_serving_enabled else []) + matrix_ssl_additional_domains_to_obtain_certificates_for @@ -1224,7 +1386,7 @@ matrix_postgres_additional_databases: | 'username': matrix_mautrix_instagram_database_username, 'password': matrix_mautrix_instagram_database_password, }] if (matrix_mautrix_instagram_enabled and matrix_mautrix_instagram_database_engine == 'postgres' and matrix_mautrix_instagram_database_hostname == 'matrix-postgres') else []) - + + + ([{ 'name': matrix_mautrix_signal_database_name, 'username': matrix_mautrix_signal_database_username, @@ -1296,6 +1458,12 @@ matrix_postgres_additional_databases: | 'username': matrix_etherpad_database_username, 'password': matrix_etherpad_database_password, }] if (matrix_etherpad_enabled and matrix_etherpad_database_engine == 'postgres' and matrix_etherpad_database_hostname == 'matrix-postgres') else []) + + + ([{ + 'name': matrix_sygnal_database_name, + 'username': matrix_sygnal_database_username, + 'password': matrix_sygnal_database_password, + }] if (matrix_sygnal_enabled and matrix_sygnal_database_engine == 'postgres' and matrix_sygnal_database_hostname == 'matrix-postgres') else []) }} matrix_postgres_import_roles_to_ignore: | @@ -1320,6 +1488,32 @@ matrix_postgres_import_databases_to_ignore: | +###################################################################### +# +# matrix-sygnal +# +###################################################################### + +# Most people don't need their own push-server, because they also need their own app to utilize it from. +matrix_sygnal_enabled: false + +# If someone instals Prometheus via the playbook, they most likely wish to monitor Sygnal. +matrix_sygnal_metrics_prometheus_enabled: "{{ matrix_prometheus_enabled }}" + +matrix_sygnal_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:6000' }}" + +# Postgres is the default, except if not using `matrix_postgres` (internal postgres) +matrix_sygnal_database_engine: "{{ 'postgres' if matrix_postgres_enabled else 'sqlite' }}" +matrix_sygnal_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'sygnal') | to_uuid }}" + +###################################################################### +# +# /matrix-sygnal +# +###################################################################### + + + ###################################################################### # # matrix-redis @@ -1369,7 +1563,7 @@ matrix_client_element_registration_enabled: "{{ matrix_synapse_enable_registrati matrix_client_element_enable_presence_by_hs_url: | {{ none - if matrix_synapse_use_presence + if matrix_synapse_presence_enabled else {matrix_client_element_default_hs_url: false} }} @@ -1385,6 +1579,31 @@ matrix_client_element_jitsi_preferredDomain: "{{ matrix_server_fqn_jitsi if matr +###################################################################### +# +# matrix-client-hydrogen +# +###################################################################### + +matrix_client_hydrogen_enabled: false + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Hydrogen over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# the HTTP port to the local host. +matrix_client_hydrogen_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8768' }}" + +matrix_client_hydrogen_default_hs_url: "{{ matrix_homeserver_url }}" + +matrix_client_hydrogen_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +###################################################################### +# +# /matrix-client-hydrogen +# +###################################################################### + + + ###################################################################### # # matrix-synapse @@ -1517,11 +1736,6 @@ matrix_synapse_admin_container_self_build: "{{ matrix_architecture != 'amd64' }} matrix_prometheus_node_exporter_enabled: false -# Normally, matrix-nginx-proxy is enabled and nginx can reach Prometheus Node Exporter over the container network. -# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose -# Prometheus' HTTP port to the local host. -matrix_prometheus_node_exporter_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9100' }}" - ###################################################################### # # /matrix-prometheus-node-exporter @@ -1548,6 +1762,7 @@ matrix_prometheus_scraper_synapse_targets: ['matrix-synapse:{{ matrix_synapse_me matrix_prometheus_scraper_synapse_rules_synapse_tag: "{{ matrix_synapse_docker_image_tag }}" matrix_prometheus_scraper_node_enabled: "{{ matrix_prometheus_node_exporter_enabled }}" +matrix_prometheus_scraper_node_targets: "{{ ['matrix-prometheus-node-exporter:9100'] if matrix_prometheus_node_exporter_enabled else [] }}" ###################################################################### # @@ -1617,3 +1832,32 @@ matrix_registration_database_password: "{{ matrix_synapse_macaroon_secret_key | # /matrix-registration # ###################################################################### + +###################################################################### +# +# matrix-postgres-backup +# +###################################################################### + +matrix_postgres_backup_connection_hostname: "{{ matrix_postgres_connection_hostname }}" +matrix_postgres_backup_connection_port: "{{ matrix_postgres_connection_port }}" +matrix_postgres_backup_connection_username: "{{ matrix_postgres_connection_username }}" +matrix_postgres_backup_connection_password: "{{ matrix_postgres_connection_password }}" + +matrix_postgres_backup_postgres_data_path: "{{ matrix_postgres_data_path if matrix_postgres_enabled else '' }}" + +# the default matrix synapse databse is not always part of the matrix_postgres_additional_databases variable thus we have to add it if the default database is used +matrix_postgres_backup_databases: | + {{ + (([{ + 'name': matrix_synapse_database_database + }] if (matrix_synapse_enabled and matrix_synapse_database_database == matrix_postgres_db_name and matrix_synapse_database_host == 'matrix-postgres') else []) + + + matrix_postgres_additional_databases)|map(attribute='name')|list + }} + +###################################################################### +# +# /matrix-postgres-backup +# +###################################################################### diff --git a/roles/matrix-awx/defaults/main.yml b/roles/matrix-awx/defaults/main.yml new file mode 100755 index 00000000..fb9f56ae --- /dev/null +++ b/roles/matrix-awx/defaults/main.yml @@ -0,0 +1 @@ +matrix_awx_enabled: true diff --git a/roles/matrix-awx/surveys/access_export.json.j2 b/roles/matrix-awx/surveys/access_export.json.j2 new file mode 100644 index 00000000..c20a9749 --- /dev/null +++ b/roles/matrix-awx/surveys/access_export.json.j2 @@ -0,0 +1,42 @@ +{ + "name": "Access Export", + "description": "Access the services export.", + "spec": [ + { + "question_name": "SFTP Authorisation Method", + "question_description": "Set whether you want to disable SFTP, use a password to connect to SFTP or connect with a more secure SSH key.", + "required": true, + "min": null, + "max": null, + "default": "{{ sftp_auth_method | string }}", + "choices": "Disabled\nPassword\nSSH Key", + "new_question": true, + "variable": "sftp_auth_method", + "type": "multiplechoice" + }, + { + "question_name": "SFTP Password", + "question_description": "Sets the password of the 'sftp' account, which allows you to upload a multi-file static website by SFTP, as well as export the latest copy of your Matrix service. Must be defined if 'Password' method is selected. WARNING: You must set a strong and unique password here.", + "required": false, + "min": 0, + "max": 64, + "default": "{{ sftp_password }}", + "choices": "", + "new_question": true, + "variable": "sftp_password", + "type": "password" + }, + { + "question_name": "SFTP Public SSH Key (More Secure)", + "question_description": "Sets the public SSH key used to access the 'sftp' account, which allows you to upload a multi-file static website by SFTP, as well as export the latest copy of your Matrix service. Must be defined if 'SSH Key' method is selected.", + "required": false, + "min": 0, + "max": 16384, + "default": "{{ sftp_public_key }}", + "choices": "", + "new_question": true, + "variable": "sftp_public_key", + "type": "text" + } + ] +} diff --git a/roles/matrix-awx/surveys/backup_server.json.j2 b/roles/matrix-awx/surveys/backup_server.json.j2 new file mode 100644 index 00000000..80782b74 --- /dev/null +++ b/roles/matrix-awx/surveys/backup_server.json.j2 @@ -0,0 +1,19 @@ +{ + "name": "Backup Server", + "description": "Performs a backup of the entire service to a remote location.", + "spec": [ + { + "question_name": "Enable Backup", + "question_description": "Set if remote backup is enabled or not. If enabled a daily backup of your server will be sent to the backup server located in {{ backup_server_location }}.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_awx_backup_enabled | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_awx_backup_enabled", + "type": "multiplechoice" + } + ] +} + diff --git a/roles/matrix-awx/surveys/configure_corporal.json.j2 b/roles/matrix-awx/surveys/configure_corporal.json.j2 new file mode 100755 index 00000000..14e417ce --- /dev/null +++ b/roles/matrix-awx/surveys/configure_corporal.json.j2 @@ -0,0 +1,88 @@ +{ + "name": "Configure Matrix Corporal", + "description": "Configure Matrix Corporal, a tool that manages your Matrix server according to a configuration policy.", + "spec": [ + { + "question_name": "Enable Corporal", + "question_description": "Controls if Matrix Corporal is enabled at all. If you're unsure if you need Matrix Corporal or not, you most likely don't.", + "required": true, + "min": null, + "max": null, + "default": "{{ matrix_corporal_enabled|string|lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_corporal_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Corporal Policy Provider", + "question_description": "Controls what provider policy is used with Matrix Corporal.", + "required": true, + "min": null, + "max": null, + "default": "{{ matrix_corporal_policy_provider_mode }}", + "choices": "Simple Static File\nHTTP Pull Mode (API Enabled)\nHTTP Push Mode (API Enabled)", + "new_question": true, + "variable": "matrix_corporal_policy_provider_mode", + "type": "multiplechoice" + }, + { + "question_name": "Simple Static File Configuration", + "question_description": "The configuration file for Matrix Corporal, only needed if 'Simple Static File' provider is selected, any configuration entered here will be saved and applied.", + "required": false, + "min": 0, + "max": 65536, + "default": "", + "new_question": true, + "variable": "matrix_corporal_simple_static_config", + "type": "textarea" + }, + { + "question_name": "HTTP Pull Mode URI", + "question_description": "The network address to remotely fetch the configuration from. Only needed if 'HTTP Pull Mode (API Enabled)' provider is selected.", + "required": false, + "min": 0, + "max": 4096, + "default": "{{ matrix_corporal_pull_mode_uri }}", + "new_question": true, + "variable": "matrix_corporal_pull_mode_uri", + "type": "text" + }, + { + "question_name": "HTTP Pull Mode Authentication Token", + "question_description": "An authentication token for pulling the Corporal configuration from a network location. Only needed if 'HTTP Pull Mode (API Enabled)' provider is selected. WARNING: You must set a strong and unique password here.", + "required": false, + "min": 0, + "max": 256, + "default": "{{ matrix_corporal_pull_mode_token }}", + "choices": "", + "new_question": true, + "variable": "matrix_corporal_pull_mode_token", + "type": "password" + }, + { + "question_name": "Corporal API Authentication Token", + "question_description": "An authentication token for interfacing with Corporals API. Only needed to be set if 'HTTP Pull Mode (API Enabled)' or 'HTTP Push Mode (API Enabled)' provider is selected. WARNING: You must set a strong and unique password here.", + "required": false, + "min": 0, + "max": 256, + "default": "{{ matrix_corporal_http_api_auth_token }}", + "choices": "", + "new_question": true, + "variable": "matrix_corporal_http_api_auth_token", + "type": "password" + }, + { + "question_name": "Raise Synapse Ratelimits", + "question_description": "For Matrix Corporal to work you will need to temporarily raise the rate limits for logins, please return this value to 'Normal' after you're done using Corporal.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_corporal_raise_ratelimits }}", + "choices": "Normal\nRaised", + "new_question": true, + "variable": "matrix_corporal_raise_ratelimits", + "type": "multiplechoice" + } + ] +} diff --git a/roles/matrix-awx/surveys/configure_dimension.json.j2 b/roles/matrix-awx/surveys/configure_dimension.json.j2 new file mode 100644 index 00000000..2f39e80e --- /dev/null +++ b/roles/matrix-awx/surveys/configure_dimension.json.j2 @@ -0,0 +1,30 @@ +{ + "name": "Configure Dimension", + "description": "Configure Dimension, the self-hosted integrations server.", + "spec": [ + { + "question_name": "Enable Dimension", + "question_description": "Enables the Dimension integration server, before doing this you need to create a CNAME record for 'dimension.{{ matrix_domain }}' that points to 'matrix.{{ matrix_domain }}'.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_dimension_enabled | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_dimension_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Dimension Users", + "question_description": "Here you can list the user accounts that will be able to configure Dimension. Entries must be seperated with newlines and must be a complete Matrix ID. For example: '@dimension:{{ matrix_domain }}'", + "required": false, + "min": 0, + "max": 65536, + "default": {{ ext_dimension_users_raw_final | to_json }}, + "choices": "", + "new_question": true, + "variable": "ext_dimension_users_raw", + "type": "textarea" + } + ] +} diff --git a/roles/matrix-awx/surveys/configure_element.json.j2 b/roles/matrix-awx/surveys/configure_element.json.j2 new file mode 100755 index 00000000..02812fbc --- /dev/null +++ b/roles/matrix-awx/surveys/configure_element.json.j2 @@ -0,0 +1,78 @@ +{ + "name": "Configure Element", + "description": "Configure Element web client, Element is the most developed Matrix client software.", + "spec": [ + { + "question_name": "Enable Element-Web", + "question_description": "Set if Element web client is enabled or not.", + "required": true, + "min": null, + "max": null, + "default": "{{ matrix_client_element_enabled }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_client_element_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Set Branding for Web Client", + "question_description": "Sets the 'branding' seen in the tab and on the welcome page to a custom value.", + "required": false, + "min": 0, + "max": 256, + "default": "{{ matrix_client_element_brand }}", + "choices": "", + "new_question": true, + "variable": "matrix_client_element_brand", + "type": "text" + }, + { + "question_name": "Set Theme for Web Client", + "question_description": "Sets the default theme for the web client, can be changed later by individual users.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_client_element_default_theme }}", + "choices": "light\ndark", + "new_question": true, + "variable": "matrix_client_element_default_theme", + "type": "multiplechoice" + }, + { + "question_name": "Set Welcome Page Background", + "question_description": "URL to Wallpaper, shown in background of the welcome page. Must be a 'https' link, otherwise it won't be set.", + "required": false, + "min": 0, + "max": 1024, + "default": "{{ matrix_client_element_branding_welcomeBackgroundUrl }}", + "choices": "", + "new_question": true, + "variable": "matrix_client_element_branding_welcomeBackgroundUrl", + "type": "text" + }, + { + "question_name": "Show Registration Button", + "question_description": "If you show the registration button on the welcome page.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_client_element_registration_enabled }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_client_element_registration_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Set Element Subdomain", + "question_description": "Sets the subdomain of the Element web-client, you should only specify the subdomain, not the base domain you've already set. (Eg: 'element' for element.example.org) Note that if you change this value you'll need to reconfigure your DNS.", + "required": false, + "min": 0, + "max": 2048, + "default": "{{ element_subdomain }}", + "choices": "", + "new_question": true, + "variable": "element_subdomain", + "type": "text" + } + ] +} diff --git a/roles/matrix-awx/surveys/configure_jitsi.json.j2 b/roles/matrix-awx/surveys/configure_jitsi.json.j2 new file mode 100755 index 00000000..9cb3044d --- /dev/null +++ b/roles/matrix-awx/surveys/configure_jitsi.json.j2 @@ -0,0 +1,31 @@ +{ + "name": "Configure Jitsi", + "description": "Configure Jitsi conferencing settings.", + "spec": [ + { + "question_name": "Enable Jitsi", + "question_description": "Set if Jitsi is enabled or not. If disabled your server will use the https://jitsi.riot.im server. If you're on a smaller server disabling this might increase the performance of your Matrix service.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_jitsi_enabled }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_jitsi_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Set Default Language", + "question_description": "2 digit 639-1 language code to adjust the language of the web client. For a list of possible codes see: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes", + "required": false, + "min": 0, + "max": 2, + "default": "{{ matrix_jitsi_web_config_defaultLanguage }}", + "choices": "", + "new_question": true, + "variable": "matrix_jitsi_web_config_defaultLanguage", + "type": "text" + } + ] +} + diff --git a/roles/matrix-awx/surveys/configure_ma1sd.json.j2 b/roles/matrix-awx/surveys/configure_ma1sd.json.j2 new file mode 100644 index 00000000..67c2c88d --- /dev/null +++ b/roles/matrix-awx/surveys/configure_ma1sd.json.j2 @@ -0,0 +1,41 @@ +{ + "name": "Configure ma1sd", + "description": "Configure ma1sd settings, ma1sd is a self-hosted identity server for Matrix.", + "spec": [ + { + "question_name": "Enable ma1sd", + "question_description": "Set if ma1sd is enabled or not. If disabled your server will loose identity functionality (not recommended).", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_ma1sd_enabled | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_ma1sd_enabled", + "type": "multiplechoice" + }, + { + "question_name": "ma1sd Authentication Mode", + "question_description": "Set the source of user account authentication credentials with the ma1sd.", + "required": false, + "min": null, + "max": null, + "default": "{{ ext_matrix_ma1sd_auth_store }}", + "choices": "Synapse Internal\nLDAP/AD", + "new_question": true, + "variable": "ext_matrix_ma1sd_auth_store", + "type": "multiplechoice" + }, + { + "question_name": "LDAP/AD Configuration", + "question_description": "Settings for connecting LDAP/AD to the ma1sd service. (ignored if using Synapse Internal, see https://github.com/ma1uta/ma1sd/blob/master/docs/stores/README.md )", + "required": false, + "min": 0, + "max": 65536, + "default": {{ ext_matrix_ma1sd_configuration_extension_yaml | to_json }}, + "new_question": true, + "variable": "ext_matrix_ma1sd_configuration_extension_yaml", + "type": "textarea" + } + ] +} diff --git a/roles/matrix-awx/surveys/configure_synapse.json.j2 b/roles/matrix-awx/surveys/configure_synapse.json.j2 new file mode 100755 index 00000000..22b80303 --- /dev/null +++ b/roles/matrix-awx/surveys/configure_synapse.json.j2 @@ -0,0 +1,198 @@ +{ + "name": "Configure Synapse", + "description": "Configure Synapse settings. Synapse is the homeserver software that powers your Matrix instance.", + "spec": [ + { + "question_name": "Enable Public Registration", + "question_description": "Controls whether people with access to the homeserver can register by themselves.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_enable_registration | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_enable_registration", + "type": "multiplechoice" + }, + { + "question_name": "Enable Federation", + "question_description": "Controls whether Synapse will federate at all. Disable this to completely isolate your server from the rest of the Matrix network.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_federation_enabled | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_federation_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Allow Public Rooms Over Federation", + "question_description": "Controls whether remote servers can fetch this server's public rooms directory via federation. For private servers, you'll most likely want to forbid this.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_allow_public_rooms_over_federation | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_allow_public_rooms_over_federation", + "type": "multiplechoice" + }, + { + "question_name": "Enable Community Creation", + "question_description": "Allows regular users (who aren't server admins) to create 'communities', which are basically groups of rooms.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_enable_group_creation | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_enable_group_creation", + "type": "multiplechoice" + }, + { + "question_name": "Enable Synapse Presence", + "question_description": "Controls whether presence is enabled. This shows who's online and reading your posts. Disabling it will increase both performance and user privacy.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_presence_enabled | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_presence_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Enable URL Previews", + "question_description": "Controls whether URL previews should be generated. This will cause a request from Synapse to URLs shared by users.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_url_preview_enabled | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_url_preview_enabled", + "type": "multiplechoice" + }, + { + "question_name": "Enable Guest Access", + "question_description": "Controls whether 'guest accounts' can access rooms without registering. Guest users do not count towards your servers user limit.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_allow_guest_access | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_allow_guest_access", + "type": "multiplechoice" + }, + { + "question_name": "Registration Requires Email", + "question_description": "Controls whether an email address is required to register on the server.", + "required": false, + "min": null, + "max": null, + "default": "{{ ext_registrations_require_3pid | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "ext_registrations_require_3pid", + "type": "multiplechoice" + }, + { + "question_name": "Registration Shared Secret", + "question_description": "A secret that allows registration of standard or admin accounts by anyone who has the shared secret, even if registration is otherwise disabled. WARNING: You must set a strong and unique password here.", + "required": false, + "min": 0, + "max": 256, + "default": "", + "choices": "", + "new_question": true, + "variable": "matrix_synapse_registration_shared_secret", + "type": "password" + }, + { + "question_name": "Synapse Max Upload Size", + "question_description": "Sets the maximum size for uploaded files in MB.", + "required": false, + "min": 0, + "max": 3, + "default": "{{ matrix_synapse_max_upload_size_mb }}", + "choices": "", + "new_question": true, + "variable": "matrix_synapse_max_upload_size_mb_raw", + "type": "text" + }, + { + "question_name": "URL Preview Languages", + "question_description": "Sets the languages that URL previews will be generated in. Entries are a 2-3 letter IETF language tag, they must be seperated with newlines. For example: 'fr' https://en.wikipedia.org/wiki/IETF_language_tag", + "required": false, + "min": 0, + "max": 65536, + "default": {{ ext_url_preview_accept_language_default | to_json }}, + "choices": "", + "new_question": true, + "variable": "ext_url_preview_accept_language_raw", + "type": "textarea" + }, + { + "question_name": "Federation Whitelist", + "question_description": "Here you can list the URLs of other Matrix homeservers and Synapse will only federate with those homeservers. Entries must be seperated with newlines and must not have a 'https://' prefix. For example: 'matrix.example.org'", + "required": false, + "min": 0, + "max": 65536, + "default": {{ ext_federation_whitelist_raw | to_json }}, + "choices": "", + "new_question": true, + "variable": "ext_federation_whitelist_raw", + "type": "textarea" + }, + { + "question_name": "Synapse Auto-Join Rooms", + "question_description": "Sets the 'auto-join' rooms, where new users will be automatically invited to, these rooms must already exist. Entries must be room addresses that are separated with newlines. For example: '#announcements:example.org'", + "required": false, + "min": 0, + "max": 65536, + "default": {{ matrix_synapse_auto_join_rooms_raw | to_json }}, + "choices": "", + "new_question": true, + "variable": "matrix_synapse_auto_join_rooms_raw", + "type": "textarea" + }, + { + "question_name": "Enable ReCaptcha on Registration", + "question_description": "Enables Googles ReCaptcha verification for registering an account, recommended for public servers.", + "required": false, + "min": null, + "max": null, + "default": "{{ ext_enable_registration_captcha | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "ext_enable_registration_captcha", + "type": "multiplechoice" + }, + { + "question_name": "Recaptcha Public Key", + "question_description": "Sets the Google ReCaptcha public key for this website.", + "required": false, + "min": 0, + "max": 40, + "default": "{{ ext_recaptcha_public_key }}", + "choices": "", + "new_question": true, + "variable": "ext_recaptcha_public_key", + "type": "text" + }, + { + "question_name": "Recaptcha Private Key", + "question_description": "Sets the Google ReCaptcha private key for this website.", + "required": false, + "min": 0, + "max": 40, + "default": "{{ ext_recaptcha_private_key }}", + "choices": "", + "new_question": true, + "variable": "ext_recaptcha_private_key", + "type": "text" + } + ] +} diff --git a/roles/matrix-awx/surveys/configure_synapse_admin.json.j2 b/roles/matrix-awx/surveys/configure_synapse_admin.json.j2 new file mode 100644 index 00000000..8845b83a --- /dev/null +++ b/roles/matrix-awx/surveys/configure_synapse_admin.json.j2 @@ -0,0 +1,18 @@ +{ + "name": "Configure Synapse Admin", + "description": "Configure 'Synapse Admin', a moderation tool to help you manage your server.", + "spec": [ + { + "question_name": "Enable Synapse Admin", + "question_description": "Set if Synapse Admin is enabled or not. If enabled you can access it at https://{{ matrix_server_fqn_matrix }}/synapse-admin.", + "required": false, + "min": null, + "max": null, + "default": "{{ matrix_synapse_admin_enabled | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "matrix_synapse_admin_enabled", + "type": "multiplechoice" + } + ] +} diff --git a/roles/matrix-awx/surveys/configure_website_access_export.json.j2 b/roles/matrix-awx/surveys/configure_website_access_export.json.j2 new file mode 100755 index 00000000..2b3e1637 --- /dev/null +++ b/roles/matrix-awx/surveys/configure_website_access_export.json.j2 @@ -0,0 +1,54 @@ +{ + "name": "Configure Website Access Backup", + "description": "Configure base domain website settings and access the services backup.", + "spec": [ + { + "question_name": "Customise Base Domain Website", + "question_description": "Set if you want to adjust the base domain website using SFTP.", + "required": true, + "min": null, + "max": null, + "default": "{{ customise_base_domain_website | string | lower }}", + "choices": "true\nfalse", + "new_question": true, + "variable": "customise_base_domain_website", + "type": "multiplechoice" + }, + { + "question_name": "SFTP Authorisation Method", + "question_description": "Set whether you want to disable SFTP, use a password to connect to SFTP or connect with a more secure SSH key.", + "required": true, + "min": null, + "max": null, + "default": "{{ sftp_auth_method | string }}", + "choices": "Disabled\nPassword\nSSH Key", + "new_question": true, + "variable": "sftp_auth_method", + "type": "multiplechoice" + }, + { + "question_name": "SFTP Password", + "question_description": "Sets the password of the 'sftp' account, which allows you to upload a multi-file static website by SFTP, as well as export the latest copy of your Matrix service. Must be defined if 'Password' method is selected. WARNING: You must set a strong and unique password here.", + "required": false, + "min": 0, + "max": 64, + "default": "{{ sftp_password }}", + "choices": "", + "new_question": true, + "variable": "sftp_password", + "type": "password" + }, + { + "question_name": "SFTP Public SSH Key (More Secure)", + "question_description": "Sets the public SSH key used to access the 'sftp' account, which allows you to upload a multi-file static website by SFTP, as well as export the latest copy of your Matrix service. Must be defined if 'SSH Key' method is selected.", + "required": false, + "min": 0, + "max": 16384, + "default": "{{ sftp_public_key }}", + "choices": "", + "new_question": true, + "variable": "sftp_public_key", + "type": "text" + } + ] +} diff --git a/roles/matrix-awx/tasks/backup_server.yml b/roles/matrix-awx/tasks/backup_server.yml new file mode 100644 index 00000000..a82f46b0 --- /dev/null +++ b/roles/matrix-awx/tasks/backup_server.yml @@ -0,0 +1,83 @@ + +- name: Record Backup Server variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# AWX Settings Start' + with_dict: + 'matrix_awx_backup_enabled': '{{ matrix_awx_backup_enabled }}' + tags: use-survey + +- name: Save new 'Backup Server' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/backup_server.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/backup_server.json' + tags: use-survey + +- name: Copy new 'Backup Server' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/backup_server.json' + dest: '/matrix/awx/backup_server.json' + mode: '0660' + tags: use-survey + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + tags: use-survey + +- name: Recreate 'Backup Server' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 0 - Backup Server" + description: "Performs a backup of the entire service to a remote location." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "backup-server,use-survey" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/backup_server.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes + tags: use-survey + +- name: Run export.sh if this job template is run by the client + command: /bin/sh /root/export.sh + tags: use-survey + +- name: Include vars in matrix_vars.yml + include_vars: + file: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + no_log: True + +- name: Copy new 'matrix_vars.yml' to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + dest: '/matrix/awx/matrix_vars.yml' + mode: '0660' + tags: use-survey + +- name: Perform the borg backup + command: borgmatic + when: matrix_awx_backup_enabled|bool + +- name: Set boolean value to exit playbook + set_fact: + end_playbook: true + +- name: End playbook if this task list is called. + meta: end_play + when: end_playbook is defined and end_playbook|bool diff --git a/roles/matrix-awx/tasks/cache_matrix_variables.yml b/roles/matrix-awx/tasks/cache_matrix_variables.yml new file mode 100644 index 00000000..a34b3792 --- /dev/null +++ b/roles/matrix-awx/tasks/cache_matrix_variables.yml @@ -0,0 +1,12 @@ + +- name: Collect current datetime + set_fact: + awx_datetime: "{{ lookup('pipe', 'date +%Y-%m-%d_%H:%M') }}" + +- name: Create cached matrix_vars.yml file location + set_fact: + awx_cached_matrix_vars: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars_{{ awx_datetime }}.yml' + +- name: Create cached matrix_vars.yml + delegate_to: 127.0.0.1 + shell: "cp /var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml {{ awx_cached_matrix_vars }}" diff --git a/roles/matrix-awx/tasks/create_user.yml b/roles/matrix-awx/tasks/create_user.yml new file mode 100755 index 00000000..13a30596 --- /dev/null +++ b/roles/matrix-awx/tasks/create_user.yml @@ -0,0 +1,31 @@ +# +# Create user and define if they are admin +# +# /usr/local/bin/matrix-synapse-register-user +# + +- name: Set admin bool to zero + set_fact: + admin_bool: 0 + when: admin_access == 'false' + +- name: Examine if server admin set + set_fact: + admin_bool: 1 + when: admin_access == 'true' + +- name: Set boolean value to exit playbook + set_fact: + end_playbook: true + +- name: Create user account + command: | + /usr/local/bin/matrix-synapse-register-user {{ new_username | quote }} {{ new_password | quote }} {{ admin_bool }} + register: cmd + +- name: Result + debug: msg="{{ cmd.stdout }}" + +- name: End playbook if this task list is called. + meta: end_play + when: end_playbook is defined and end_playbook|bool diff --git a/roles/matrix-awx/tasks/customise_website_access_export.yml b/roles/matrix-awx/tasks/customise_website_access_export.yml new file mode 100755 index 00000000..b7e27e9d --- /dev/null +++ b/roles/matrix-awx/tasks/customise_website_access_export.yml @@ -0,0 +1,273 @@ + +- name: Enable index.html creation if user doesn't wish to customise base domain + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Base Domain Settings Start' + with_dict: + 'matrix_nginx_proxy_base_domain_homepage_enabled': 'true' + when: (customise_base_domain_website is defined) and not customise_base_domain_website|bool + +- name: Disable index.html creation to allow multi-file site if user does wish to customise base domain + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Base Domain Settings Start' + with_dict: + 'matrix_nginx_proxy_base_domain_homepage_enabled': 'false' + when: (customise_base_domain_website is defined) and customise_base_domain_website|bool + +- name: Record custom 'Customise Website + Access Export' variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Custom Settings Start' + with_dict: + 'sftp_auth_method': '"{{ sftp_auth_method }}"' + 'sftp_password': '"{{ sftp_password }}"' + 'sftp_public_key': '"{{ sftp_public_key }}"' + +- name: Record custom 'Customise Website + Access Export' variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Custom Settings Start' + with_dict: + 'customise_base_domain_website': '{{ customise_base_domain_website }}' + when: customise_base_domain_website is defined + +- name: Reload vars in matrix_vars.yml + include_vars: + file: '{{ awx_cached_matrix_vars }}' + no_log: True + +- name: Save new 'Customise Website + Access Export' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: './roles/matrix-awx/surveys/configure_website_access_export.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_website_access_export.json' + when: customise_base_domain_website is defined + +- name: Copy new 'Customise Website + Access Export' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_website_access_export.json' + dest: '/matrix/awx/configure_website_access_export.json' + mode: '0660' + when: customise_base_domain_website is defined + +- name: Save new 'Customise Website + Access Export' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: './roles/matrix-awx/surveys/access_export.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/access_export.json' + when: customise_base_domain_website is undefined + +- name: Copy new 'Customise Website + Access Export' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/access_export.json' + dest: '/matrix/awx/access_export.json' + mode: '0660' + when: customise_base_domain_website is undefined + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure Website + Access Export' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure Website + Access Export" + description: "Configure base domain website settings and access the servers export." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-nginx-proxy" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_website_access_export.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes + when: customise_base_domain_website is defined + +- name: Recreate 'Access Export' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Access Export" + description: "Access the services export." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-nginx-proxy" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/access_export.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes + when: customise_base_domain_website is undefined + +- name: Ensure group "sftp" exists + group: + name: sftp + state: present + +- name: If user doesn't define a sftp_password, create a disabled 'sftp' account + user: + name: sftp + comment: SFTP user to set custom web files and access servers export + shell: /bin/false + home: /home/sftp + group: sftp + password: '*' + update_password: always + when: sftp_password|length == 0 + +- name: If user defines sftp_password, enable account and set password on 'stfp' account + user: + name: sftp + comment: SFTP user to set custom web files and access servers export + shell: /bin/false + home: /home/sftp + group: sftp + password: "{{ sftp_password | password_hash('sha512') }}" + update_password: always + when: sftp_password|length > 0 + +- name: adding existing user 'sftp' to group matrix + user: + name: sftp + groups: matrix + append: yes + when: customise_base_domain_website is defined + +- name: Create the ro /chroot directory with sticky bit if it doesn't exist. (/chroot/website has matrix:matrix permissions and is mounted to nginx container) + file: + path: /chroot + state: directory + owner: root + group: root + mode: '1755' + +- name: Ensure /chroot/website location exists. + file: + path: /chroot/website + state: directory + owner: matrix + group: matrix + mode: '0574' + when: customise_base_domain_website is defined + +- name: Ensure /chroot/export location exists + file: + path: /chroot/export + state: directory + owner: sftp + group: sftp + mode: '0700' + +- name: Ensure /home/sftp/.ssh location exists + file: + path: /home/sftp/.ssh + state: directory + owner: sftp + group: sftp + mode: '0700' + +- name: Ensure /home/sftp/authorized_keys exists + file: + path: /home/sftp/.ssh/authorized_keys + state: touch + owner: sftp + group: sftp + mode: '0644' + +- name: Clear authorized_keys file + shell: echo "" > /home/sftp/.ssh/authorized_keys + +- name: Insert public SSH key into authorized_keys file + lineinfile: + path: /home/sftp/.ssh/authorized_keys + line: "{{ sftp_public_key }}" + owner: sftp + group: sftp + mode: '0644' + when: (sftp_public_key | length > 0) and (sftp_auth_method == "SSH Key") + +- name: Alter SSH Subsystem State 1 + lineinfile: + path: /etc/ssh/sshd_config + line: "Subsystem sftp /usr/lib/openssh/sftp-server" + state: absent + +- name: Alter SSH Subsystem State 2 + lineinfile: + path: /etc/ssh/sshd_config + insertafter: "^# override default of no subsystems" + line: "Subsystem sftp internal-sftp" + +- name: Add SSH Match User section for disabled auth + blockinfile: + path: /etc/ssh/sshd_config + state: absent + block: | + Match User sftp + ChrootDirectory /chroot + PermitTunnel no + X11Forwarding no + AllowTcpForwarding no + PasswordAuthentication yes + AuthorizedKeysFile /home/sftp/.ssh/authorized_keys + when: sftp_auth_method == "Disabled" + +- name: Add SSH Match User section for password auth + blockinfile: + path: /etc/ssh/sshd_config + state: present + block: | + Match User sftp + ChrootDirectory /chroot + PermitTunnel no + X11Forwarding no + AllowTcpForwarding no + PasswordAuthentication yes + when: sftp_auth_method == "Password" + +- name: Add SSH Match User section for publickey auth + blockinfile: + path: /etc/ssh/sshd_config + state: present + block: | + Match User sftp + ChrootDirectory /chroot + PermitTunnel no + X11Forwarding no + AllowTcpForwarding no + AuthorizedKeysFile /home/sftp/.ssh/authorized_keys + when: sftp_auth_method == "SSH Key" + +- name: Restart service ssh.service + service: + name: ssh.service + state: restarted diff --git a/roles/matrix-awx/tasks/import_awx.yml b/roles/matrix-awx/tasks/import_awx.yml new file mode 100644 index 00000000..6017152f --- /dev/null +++ b/roles/matrix-awx/tasks/import_awx.yml @@ -0,0 +1,18 @@ + +- name: Ensure /matrix/awx is empty + shell: rm -r /matrix/awx/* + ignore_errors: yes + +- name: Ensure /matrix/synapse is empty + shell: rm -r /matrix/synapse/* + ignore_errors: yes + +- name: Extract from /chroot/export + shell: tar -xvzf /chroot/export/matrix.tar.gz -C /matrix/ + +- name: Ensure correct ownership of /matrix/awx + shell: chown -R matrix:matrix /matrix/awx + +- name: Ensure correct ownership of /matrix/synapse + shell: chown -R matrix:matrix /matrix/synapse + diff --git a/roles/matrix-awx/tasks/load_hosting_and_org_variables.yml b/roles/matrix-awx/tasks/load_hosting_and_org_variables.yml new file mode 100644 index 00000000..ea866254 --- /dev/null +++ b/roles/matrix-awx/tasks/load_hosting_and_org_variables.yml @@ -0,0 +1,11 @@ + +- name: Include vars in organisation.yml + include_vars: + file: '/var/lib/awx/projects/clients/{{ member_id }}/organisation.yml' + no_log: True + +- name: Include vars in hosting_vars.yml + include_vars: + file: '/var/lib/awx/projects/hosting/hosting_vars.yml' + no_log: True + diff --git a/roles/matrix-awx/tasks/load_matrix_variables.yml b/roles/matrix-awx/tasks/load_matrix_variables.yml new file mode 100755 index 00000000..2a9f9a0d --- /dev/null +++ b/roles/matrix-awx/tasks/load_matrix_variables.yml @@ -0,0 +1,15 @@ + +- name: Include new vars in matrix_vars.yml + include_vars: + file: '{{ awx_cached_matrix_vars }}' + no_log: True + +- name: If include_vars succeeds overwrite the old matrix_vars.yml + delegate_to: 127.0.0.1 + shell: "cp {{ awx_cached_matrix_vars }} /var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml && rm {{ awx_cached_matrix_vars }}" + +- name: Copy new 'matrix_vars.yml' to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + dest: '/matrix/awx/matrix_vars.yml' + mode: '0660' diff --git a/roles/matrix-awx/tasks/main.yml b/roles/matrix-awx/tasks/main.yml new file mode 100755 index 00000000..abfef97c --- /dev/null +++ b/roles/matrix-awx/tasks/main.yml @@ -0,0 +1,162 @@ + +# Load initial hosting and organisation variables from AWX volume +- include_tasks: + file: "load_hosting_and_org_variables.yml" + apply: + tags: always + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - always + +# Renames the variables if needed +- include_tasks: + file: "rename_variables.yml" + apply: + tags: always + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - always + +# Perform a backup of the server +- include_tasks: + file: "backup_server.yml" + apply: + tags: backup-server + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - backup-server + +# Create a user account if called +- include_tasks: + file: "create_user.yml" + apply: + tags: create-user + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - create-user + +# Purge local/remote media if called +- include_tasks: + file: "purge_media_main.yml" + apply: + tags: purge-media + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - purge-media + +# Purge Synapse database if called +- include_tasks: + file: "purge_database_main.yml" + apply: + tags: purge-database + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - purge-database + +# Import configs, media repo from /chroot/backup import +- include_tasks: + file: "import_awx.yml" + apply: + tags: import-awx + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - import-awx + +# Perform extra self-check functions +- include_tasks: + file: "self_check.yml" + apply: + tags: self-check + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - self-check + +# Create cached matrix_vars.yml file +- include_tasks: + file: "cache_matrix_variables.yml" + apply: + tags: always + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - always + +# Configure SFTP so user can upload a static website or access the servers export +- include_tasks: + file: "customise_website_access_export.yml" + apply: + tags: setup-nginx-proxy + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-nginx-proxy + +# Additional playbook to set the variable file during Element configuration +- include_tasks: + file: "set_variables_element.yml" + apply: + tags: setup-client-element + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-client-element + +# Additional playbook to set the variable file during Synapse configuration +- include_tasks: + file: "set_variables_synapse.yml" + apply: + tags: setup-synapse + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-synapse + +# Additional playbook to set the variable file during Jitsi configuration +- include_tasks: + file: "set_variables_jitsi.yml" + apply: + tags: setup-jitsi + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-jitsi + +# Additional playbook to set the variable file during Ma1sd configuration +- include_tasks: + file: "set_variables_ma1sd.yml" + apply: + tags: setup-ma1sd + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-ma1sd + +# Additional playbook to set the variable file during Corporal configuration +- include_tasks: + file: "set_variables_corporal.yml" + apply: + tags: setup-corporal + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-corporal + +# Additional playbook to set the variable file during Dimension configuration +- include_tasks: + file: "set_variables_dimension.yml" + apply: + tags: setup-dimension + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-dimension + +# Additional playbook to set the variable file during Synapse Admin configuration +- include_tasks: + file: "set_variables_synapse_admin.yml" + apply: + tags: setup-synapse-admin + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - setup-synapse-admin + +# Load newly formed matrix variables from AWX volume +- include_tasks: + file: "load_matrix_variables.yml" + apply: + tags: always + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - always diff --git a/roles/matrix-awx/tasks/purge_database_build_list.yml b/roles/matrix-awx/tasks/purge_database_build_list.yml new file mode 100644 index 00000000..1ea05b7f --- /dev/null +++ b/roles/matrix-awx/tasks/purge_database_build_list.yml @@ -0,0 +1,10 @@ + +- name: Collect entire room list into stdout + shell: | + curl -X GET --header "Authorization: Bearer {{ janitors_token.stdout[1:-1] }}" '{{ synapse_container_ip.stdout }}:8008/_synapse/admin/v1/rooms?from={{ item }}' + register: rooms_output + +- name: Print stdout to file + delegate_to: 127.0.0.1 + shell: | + echo '{{ rooms_output.stdout }}' >> /tmp/{{ subscription_id }}_room_list_complete.json diff --git a/roles/matrix-awx/tasks/purge_database_events.yml b/roles/matrix-awx/tasks/purge_database_events.yml new file mode 100644 index 00000000..9e2ef9c2 --- /dev/null +++ b/roles/matrix-awx/tasks/purge_database_events.yml @@ -0,0 +1,13 @@ + +- name: Purge all rooms with more then N events + shell: | + curl --header "Authorization: Bearer {{ janitors_token.stdout[1:-1] }}" -X POST -H "Content-Type: application/json" -d '{ "delete_local_events": false, "purge_up_to_ts": {{ purge_epoche_time.stdout }}000 }' "{{ synapse_container_ip.stdout }}:8008/_synapse/admin/v1/purge_history/{{ item[1:-1] }}" + register: purge_command + +- name: Print output of purge command + debug: + msg: "{{ purge_command.stdout }}" + +- name: Pause for 5 seconds to let Synapse breathe + pause: + seconds: 5 diff --git a/roles/matrix-awx/tasks/purge_database_main.yml b/roles/matrix-awx/tasks/purge_database_main.yml new file mode 100644 index 00000000..ccd46c81 --- /dev/null +++ b/roles/matrix-awx/tasks/purge_database_main.yml @@ -0,0 +1,234 @@ + +- name: Ensure dateutils and curl is installed in AWX + delegate_to: 127.0.0.1 + yum: + name: dateutils + state: latest + +- name: Ensure dateutils, curl and jq intalled on target machine + apt: + pkg: + - curl + - jq + state: present + +- name: Include vars in matrix_vars.yml + include_vars: + file: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + no_log: True + +- name: Collect size of Synapse database + shell: du -sh /matrix/postgres/data + register: db_size_before_stat + no_log: True + +- name: Print before size of Synapse database + debug: + msg: "{{ db_size_before_stat.stdout.split('\n') }}" + when: db_size_before_stat is defined + +- name: Collect the internal IP of the matrix-synapse container + shell: "/usr/bin/docker inspect --format '{''{range.NetworkSettings.Networks}''}{''{.IPAddress}''}{''{end}''}' matrix-synapse" + register: synapse_container_ip + +- name: Collect access token for janitor user + shell: | + curl -X POST -d '{"type":"m.login.password", "user":"janitor", "password":"{{ matrix_awx_janitor_user_password }}"}' "{{ synapse_container_ip.stdout }}:8008/_matrix/client/r0/login" | jq '.access_token' + register: janitors_token + no_log: True + +- name: Collect total number of rooms + shell: | + curl -X GET --header "Authorization: Bearer {{ janitors_token.stdout[1:-1] }}" '{{ synapse_container_ip.stdout }}:8008/_synapse/admin/v1/rooms' | jq '.total_rooms' + when: purge_rooms|bool + register: rooms_total + +- name: Print total number of rooms + debug: + msg: '{{ rooms_total.stdout }}' + when: purge_rooms|bool + +- name: Calculate every 100 values for total number of rooms + delegate_to: 127.0.0.1 + shell: | + seq 0 100 {{ rooms_total.stdout }} + when: purge_rooms|bool + register: every_100_rooms + +- name: Ensure room_list_complete.json file exists + delegate_to: 127.0.0.1 + file: + path: /tmp/{{ subscription_id }}_room_list_complete.json + state: touch + when: purge_rooms|bool + +- name: Build file with total room list + include_tasks: purge_database_build_list.yml + loop: "{{ every_100_rooms.stdout_lines | flatten(levels=1) }}" + when: purge_rooms|bool + +- name: Generate list of rooms with no local users + delegate_to: 127.0.0.1 + shell: | + jq 'try .rooms[] | select(.joined_local_members == 0) | .room_id' < /tmp/{{ subscription_id }}_room_list_complete.json > /tmp/{{ subscription_id }}_room_list_no_local_users.txt + when: purge_rooms|bool + +- name: Count number of rooms with no local users + delegate_to: 127.0.0.1 + shell: | + wc -l /tmp/{{ subscription_id }}_room_list_no_local_users.txt | awk '{ print $1 }' + register: rooms_no_local_total + when: purge_rooms|bool + +- name: Setting host fact room_list_no_local_users + set_fact: + room_list_no_local_users: "{{ lookup('file', '/tmp/{{ subscription_id }}_room_list_no_local_users.txt') }}" + no_log: True + when: purge_rooms|bool + +- name: Purge all rooms with no local users + include_tasks: purge_database_no_local.yml + loop: "{{ room_list_no_local_users.splitlines() | flatten(levels=1) }}" + when: purge_rooms|bool + +- name: Collect epoche time from date + delegate_to: 127.0.0.1 + shell: | + date -d '{{ purge_date }}' +"%s" + when: purge_rooms|bool + register: purge_epoche_time + +- name: Generate list of rooms with more then N users + delegate_to: 127.0.0.1 + shell: | + jq 'try .rooms[] | select(.joined_members > {{ purge_metric_value }}) | .room_id' < /tmp/{{ subscription_id }}_room_list_complete.json > /tmp/{{ subscription_id }}_room_list_joined_members.txt + when: (purge_metric.find("Number of users") != -1) and (purge_rooms|bool) + +- name: Count number of rooms with more then N users + delegate_to: 127.0.0.1 + shell: | + wc -l /tmp/{{ subscription_id }}_room_list_joined_members.txt | awk '{ print $1 }' + register: rooms_join_members_total + when: (purge_metric.find("Number of users") != -1) and (purge_rooms|bool) + +- name: Setting host fact room_list_joined_members + delegate_to: 127.0.0.1 + set_fact: + room_list_joined_members: "{{ lookup('file', '/tmp/{{ subscription_id }}_room_list_joined_members.txt') }}" + when: (purge_metric.find("Number of users") != -1) and (purge_rooms|bool) + no_log: True + +- name: Purge all rooms with more then N users + include_tasks: purge_database_users.yml + loop: "{{ room_list_joined_members.splitlines() | flatten(levels=1) }}" + when: (purge_metric.find("Number of users") != -1) and (purge_rooms|bool) + +- name: Generate list of rooms with more then N events + delegate_to: 127.0.0.1 + shell: | + jq 'try .rooms[] | select(.state_events > {{ purge_metric_value }}) | .room_id' < /tmp/{{ subscription_id }}_room_list_complete.json > /tmp/{{ subscription_id }}_room_list_state_events.txt + when: (purge_metric.find("Number of events") != -1) and (purge_rooms|bool) + +- name: Count number of rooms with more then N users + delegate_to: 127.0.0.1 + shell: | + wc -l /tmp/{{ subscription_id }}_room_list_state_events.txt | awk '{ print $1 }' + register: rooms_state_events_total + when: (purge_metric.find("Number of events") != -1) and (purge_rooms|bool) + +- name: Setting host fact room_list_state_events + delegate_to: 127.0.0.1 + set_fact: + room_list_state_events: "{{ lookup('file', '/tmp/{{ subscription_id }}_room_list_state_events.txt') }}" + when: (purge_metric.find("Number of events") != -1) and (purge_rooms|bool) + no_log: True + +- name: Purge all rooms with more then N events + include_tasks: purge_database_events.yml + loop: "{{ room_list_state_events.splitlines() | flatten(levels=1) }}" + when: (purge_metric.find("Number of events") != -1) and (purge_rooms|bool) + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Execute rust-synapse-compress-state job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_launch: + job_template: "{{ matrix_domain }} - 0 - Deploy/Update a Server" + tags: "rust-synapse-compress-state" + wait: yes + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes + register: job + +- name: Stop Synapse service + shell: systemctl stop matrix-synapse.service + +- name: Re-index Synapse database + shell: docker exec -i matrix-postgres psql "host=127.0.0.1 port=5432 dbname=synapse user=synapse password={{ matrix_synapse_connection_password }}" -c 'REINDEX (VERBOSE) DATABASE synapse' + +- name: Execute run-postgres-vacuum job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_launch: + job_template: "{{ matrix_domain }} - 0 - Deploy/Update a Server" + tags: "run-postgres-vacuum,start" + wait: yes + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes + register: job + +- name: Cleanup room_list files + delegate_to: 127.0.0.1 + shell: | + rm /tmp/{{ subscription_id }}_room_list* + when: purge_rooms|bool + ignore_errors: yes + +- name: Collect size of Synapse database + shell: du -sh /matrix/postgres/data + register: db_size_after_stat + no_log: True + +- name: Print total number of rooms processed + debug: + msg: '{{ rooms_total.stdout }}' + when: purge_rooms|bool + +- name: Print the number of rooms purged with no local users + debug: + msg: '{{ rooms_no_local_total.stdout }}' + when: purge_rooms|bool + +- name: Print the number of rooms purged with more then N users + debug: + msg: '{{ rooms_join_members_total.stdout }}' + when: (purge_metric.find("Number of users") != -1) and (purge_rooms|bool) + +- name: Print the number of rooms purged with more then N events + debug: + msg: '{{ rooms_state_events_total.stdout }}' + when: (purge_metric.find("Number of events") != -1) and (purge_rooms|bool) + +- name: Print before purge size of Synapse database + debug: + msg: "{{ db_size_before_stat.stdout.split('\n') }}" + when: db_size_before_stat is defined + +- name: Print after purge size of Synapse database + debug: + msg: "{{ db_size_after_stat.stdout.split('\n') }}" + when: db_size_after_stat is defined + +- name: Set boolean value to exit playbook + set_fact: + end_playbook: true + +- name: End playbook early if this task is called. + meta: end_play + when: end_playbook is defined and end_playbook|bool diff --git a/roles/matrix-awx/tasks/purge_database_no_local.yml b/roles/matrix-awx/tasks/purge_database_no_local.yml new file mode 100644 index 00000000..d94fd007 --- /dev/null +++ b/roles/matrix-awx/tasks/purge_database_no_local.yml @@ -0,0 +1,13 @@ + +- name: Purge all rooms with no local users + shell: | + curl --header "Authorization: Bearer {{ janitors_token.stdout[1:-1] }}" -X POST -H "Content-Type: application/json" -d '{ "room_id": {{ item }} }' '{{ synapse_container_ip.stdout }}:8008/_synapse/admin/v1/purge_room' + register: purge_command + +- name: Print output of purge command + debug: + msg: "{{ purge_command.stdout }}" + +- name: Pause for 5 seconds to let Synapse breathe + pause: + seconds: 5 diff --git a/roles/matrix-awx/tasks/purge_database_users.yml b/roles/matrix-awx/tasks/purge_database_users.yml new file mode 100644 index 00000000..302dffd8 --- /dev/null +++ b/roles/matrix-awx/tasks/purge_database_users.yml @@ -0,0 +1,13 @@ + +- name: Purge all rooms with more then N users + shell: | + curl --header "Authorization: Bearer {{ janitors_token.stdout[1:-1] }}" -X POST -H "Content-Type: application/json" -d '{ "delete_local_events": false, "purge_up_to_ts": {{ purge_epoche_time.stdout }}000 }' "{{ synapse_container_ip.stdout }}:8008/_synapse/admin/v1/purge_history/{{ item[1:-1] }}" + register: purge_command + +- name: Print output of purge command + debug: + msg: "{{ purge_command.stdout }}" + +- name: Pause for 5 seconds to let Synapse breathe + pause: + seconds: 5 diff --git a/roles/matrix-awx/tasks/purge_media_local.yml b/roles/matrix-awx/tasks/purge_media_local.yml new file mode 100644 index 00000000..fcb4770f --- /dev/null +++ b/roles/matrix-awx/tasks/purge_media_local.yml @@ -0,0 +1,18 @@ + +- name: Collect epoche time from date + shell: | + date -d '{{ item }}' +"%s" + register: epoche_time + +- name: Purge local media to specific date + shell: | + curl -X POST --header "Authorization: Bearer {{ janitors_token.stdout[1:-1] }}" '{{ synapse_container_ip.stdout }}:8008/_synapse/admin/v1/media/matrix.{{ matrix_domain }}/delete?before_ts={{ epoche_time.stdout }}' + register: purge_command + +- name: Print output of purge command + debug: + msg: "{{ purge_command.stdout }}" + +- name: Pause for 5 seconds to let Synapse breathe + pause: + seconds: 5 diff --git a/roles/matrix-awx/tasks/purge_media_main.yml b/roles/matrix-awx/tasks/purge_media_main.yml new file mode 100644 index 00000000..77a8fecc --- /dev/null +++ b/roles/matrix-awx/tasks/purge_media_main.yml @@ -0,0 +1,98 @@ + +- name: Ensure dateutils and curl is installed in AWX + delegate_to: 127.0.0.1 + yum: + name: dateutils + state: latest + +- name: Include vars in matrix_vars.yml + include_vars: + file: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + no_log: True + +- name: Ensure curl and jq intalled on target machine + apt: + pkg: + - curl + - jq + state: present + +- name: Collect access token for janitor user + shell: | + curl -XPOST -d '{"type":"m.login.password", "user":"janitor", "password":"{{ matrix_awx_janitor_user_password }}"}' "https://matrix.{{ matrix_domain }}/_matrix/client/r0/login" | jq '.access_token' + register: janitors_token + +- name: Collect the internal IP of the matrix-synapse container + shell: "/usr/bin/docker inspect --format '{''{range.NetworkSettings.Networks}''}{''{.IPAddress}''}{''{end}''}' matrix-synapse" + register: synapse_container_ip + +- name: Generate list of dates to purge to + delegate_to: 127.0.0.1 + shell: "dateseq {{ matrix_purge_from_date }} {{ matrix_purge_to_date }}" + register: purge_dates + +- name: Calculate initial size of local media repository + shell: du -sh /matrix/synapse/storage/media-store/local* + register: local_media_size_before + when: matrix_purge_media_type == "Local Media" + ignore_errors: yes + no_log: True + +- name: Calculate initial size of remote media repository + shell: du -sh /matrix/synapse/storage/media-store/remote* + register: remote_media_size_before + when: matrix_purge_media_type == "Remote Media" + ignore_errors: yes + no_log: True + +- name: Purge local media with loop + include_tasks: purge_media_local.yml + loop: "{{ purge_dates.stdout_lines | flatten(levels=1) }}" + when: matrix_purge_media_type == "Local Media" + +- name: Purge remote media with loop + include_tasks: purge_media_remote.yml + loop: "{{ purge_dates.stdout_lines | flatten(levels=1) }}" + when: matrix_purge_media_type == "Remote Media" + +- name: Calculate final size of local media repository + shell: du -sh /matrix/synapse/storage/media-store/local* + register: local_media_size_after + when: matrix_purge_media_type == "Local Media" + ignore_errors: yes + no_log: True + +- name: Calculate final size of remote media repository + shell: du -sh /matrix/synapse/storage/media-store/remote* + register: remote_media_size_after + when: matrix_purge_media_type == "Remote Media" + ignore_errors: yes + no_log: True + +- name: Print size of local media repository before purge + debug: + msg: "{{ local_media_size_before.stdout.split('\n') }}" + when: matrix_purge_media_type == "Local Media" + +- name: Print size of local media repository after purge + debug: + msg: "{{ local_media_size_after.stdout.split('\n') }}" + when: matrix_purge_media_type == "Local Media" + +- name: Print size of remote media repository before purge + debug: + msg: "{{ remote_media_size_before.stdout.split('\n') }}" + when: matrix_purge_media_type == "Remote Media" + +- name: Print size of remote media repository after purge + debug: + msg: "{{ remote_media_size_after.stdout.split('\n') }}" + when: matrix_purge_media_type == "Remote Media" + +- name: Set boolean value to exit playbook + set_fact: + end_playbook: true + +- name: End playbook early if this task is called. + meta: end_play + when: end_playbook is defined and end_playbook|bool diff --git a/roles/matrix-awx/tasks/purge_media_remote.yml b/roles/matrix-awx/tasks/purge_media_remote.yml new file mode 100644 index 00000000..14f9c8d5 --- /dev/null +++ b/roles/matrix-awx/tasks/purge_media_remote.yml @@ -0,0 +1,18 @@ + +- name: Collect epoche time from date + shell: | + date -d '{{ item }}' +"%s" + register: epoche_time + +- name: Purge remote media to specific date + shell: | + curl -X POST --header "Authorization: Bearer {{ janitors_token.stdout[1:-1] }}" '{{ synapse_container_ip.stdout }}:8008/_synapse/admin/v1/purge_media_cache?before_ts={{ epoche_time.stdout }}' + register: purge_command + +- name: Print output of purge command + debug: + msg: "{{ purge_command.stdout }}" + +- name: Pause for 5 seconds to let Synapse breathe + pause: + seconds: 5 diff --git a/roles/matrix-awx/tasks/rename_variables.yml b/roles/matrix-awx/tasks/rename_variables.yml new file mode 100644 index 00000000..e8992bd8 --- /dev/null +++ b/roles/matrix-awx/tasks/rename_variables.yml @@ -0,0 +1,8 @@ + +- name: Rename synapse presence variable + delegate_to: 127.0.0.1 + replace: + path: "/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml" + regexp: 'matrix_synapse_use_presence' + replace: 'matrix_synapse_presence_enabled' + diff --git a/roles/matrix-awx/tasks/self_check.yml b/roles/matrix-awx/tasks/self_check.yml new file mode 100644 index 00000000..edf6b8b3 --- /dev/null +++ b/roles/matrix-awx/tasks/self_check.yml @@ -0,0 +1,105 @@ + +- name: Install prerequisite apt packages on target + apt: + name: + - sysstat + - curl + state: present + +- name: Install prerequisite yum packages on AWX + delegate_to: 127.0.0.1 + yum: + name: + - bind-utils + state: present + +- name: Install prerequisite pip packages on AWX + delegate_to: 127.0.0.1 + pip: + name: + - dnspython + state: present + +- name: Calculate MAU value + shell: | + curl -s localhost:9000 | grep "^synapse_admin_mau_current " + register: mau_stat + no_log: True + +- name: Print MAU value + debug: + msg: "{{ mau_stat.stdout.split('\n') }}" + when: mau_stat is defined + +- name: Calculate CPU usage statistics + shell: iostat -c + register: cpu_usage_stat + no_log: True + +- name: Print CPU usage statistics + debug: + msg: "{{ cpu_usage_stat.stdout.split('\n') }}" + when: cpu_usage_stat is defined + +- name: Calculate RAM usage statistics + shell: free -mh + register: ram_usage_stat + no_log: True + +- name: Print RAM usage statistics + debug: + msg: "{{ ram_usage_stat.stdout.split('\n') }}" + when: ram_usage_stat is defined + +- name: Calculate free disk space + shell: df -h + register: disk_space_stat + no_log: True + +- name: Print free disk space + debug: + msg: "{{ disk_space_stat.stdout.split('\n') }}" + when: disk_space_stat is defined + +- name: Calculate size of Synapse database + shell: du -sh /matrix/postgres/data + register: db_size_stat + no_log: True + +- name: Print size of Synapse database + debug: + msg: "{{ db_size_stat.stdout.split('\n') }}" + when: db_size_stat is defined + +- name: Calculate size of local media repository + shell: du -sh /matrix/synapse/storage/media-store/local* + register: local_media_size_stat + ignore_errors: yes + no_log: True + +- name: Print size of local media repository + debug: + msg: "{{ local_media_size_stat.stdout.split('\n') }}" + when: local_media_size_stat is defined + +- name: Calculate size of remote media repository + shell: du -sh /matrix/synapse/storage/media-store/remote* + register: remote_media_size_stat + ignore_errors: yes + no_log: True + +- name: Print size of remote media repository + debug: + msg: "{{ remote_media_size_stat.stdout.split('\n') }}" + when: remote_media_size_stat is defined + +- name: Calculate docker container statistics + shell: docker stats --all --no-stream + register: docker_stats + ignore_errors: yes + no_log: True + +- name: Print docker container statistics + debug: + msg: "{{ docker_stats.stdout.split('\n') }}" + when: docker_stats is defined diff --git a/roles/matrix-awx/tasks/set_variables_corporal.yml b/roles/matrix-awx/tasks/set_variables_corporal.yml new file mode 100755 index 00000000..6ae187c7 --- /dev/null +++ b/roles/matrix-awx/tasks/set_variables_corporal.yml @@ -0,0 +1,247 @@ + +- name: Record Corporal Enabled/Disabled variable + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Corporal Settings Start' + with_dict: + 'matrix_corporal_enabled': '{{ matrix_corporal_enabled }}' + +- name: Enable Shared Secret Auth if Corporal enabled + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Shared Secret Auth Settings Start' + with_dict: + 'matrix_synapse_ext_password_provider_shared_secret_auth_enabled': 'true' + when: matrix_corporal_enabled|bool + +- name: Disable Shared Secret Auth if Corporal disabled + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Shared Secret Auth Settings Start' + with_dict: + 'matrix_synapse_ext_password_provider_shared_secret_auth_enabled': 'false' + when: not matrix_corporal_enabled|bool + +- name: Enable Rest Auth Endpoint if Corporal enabled + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Extension Start' + with_dict: + 'matrix_synapse_ext_password_provider_rest_auth_enabled': 'true' + when: matrix_corporal_enabled|bool + +- name: Disable Rest Auth Endpoint if Corporal disabled + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Extension Start' + with_dict: + 'matrix_synapse_ext_password_provider_rest_auth_enabled': 'false' + when: not matrix_corporal_enabled|bool + +- name: Disable Corporal API if Simple Static File mode selected + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Corporal Settings Start' + with_dict: + 'matrix_corporal_http_api_enabled': 'false' + when: (matrix_corporal_policy_provider_mode == "Simple Static File") or (not matrix_corporal_enabled|bool) + +- name: Enable Corporal API if Push/Pull mode delected + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Corporal Settings Start' + with_dict: + 'matrix_corporal_http_api_enabled': 'true' + when: (matrix_corporal_policy_provider_mode != "Simple Static File") and (matrix_corporal_enabled|bool) + +- name: Record Corporal API Access Token if it's defined + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Corporal Settings Start' + with_dict: + 'matrix_corporal_http_api_auth_token': '{{ matrix_corporal_http_api_auth_token }}' + when: matrix_corporal_http_api_auth_token|length > 0 + +- name: Record 'Simple Static File' configuration variables in matrix_vars.yml + delegate_to: 127.0.0.1 + blockinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: "# Corporal Policy Provider Settings Start" + block: | + matrix_corporal_policy_provider_config: | + { + "Type": "static_file", + "Path": "/etc/matrix-corporal/corporal-policy.json" + } + when: matrix_corporal_policy_provider_mode == "Simple Static File" + +- name: Touch the /matrix/corporal/ directory + file: + path: "/matrix/corporal/" + state: directory + owner: matrix + group: matrix + mode: '750' + +- name: Touch the /matrix/corporal/config/ directory + file: + path: "/matrix/corporal/config/" + state: directory + owner: matrix + group: matrix + mode: '750' + +- name: Touch the /matrix/corporal/cache/ directory + file: + path: "/matrix/corporal/cache/" + state: directory + owner: matrix + group: matrix + mode: '750' + +- name: Touch the corporal-policy.json file to ensure it exists + file: + path: "/matrix/corporal/config/corporal-policy.json" + state: touch + owner: matrix + group: matrix + mode: '660' + +- name: Touch the last-policy.json file to ensure it exists + file: + path: "/matrix/corporal/config/last-policy.json" + state: touch + owner: matrix + group: matrix + mode: '660' + +- name: Record 'Simple Static File' configuration content in corporal-policy.json + copy: + content: "{{ matrix_corporal_simple_static_config | string }}" + dest: "/matrix/corporal/config/corporal-policy.json" + owner: matrix + group: matrix + mode: '660' + when: (matrix_corporal_policy_provider_mode == "Simple Static File") and (matrix_corporal_simple_static_config|length > 0) + +- name: Record 'HTTP Pull Mode' configuration variables in matrix_vars.yml + delegate_to: 127.0.0.1 + blockinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: "# Corporal Policy Provider Settings Start" + block: | + matrix_corporal_policy_provider_config: | + { + "Type": "http", + "Uri": "{{ matrix_corporal_pull_mode_uri }}", + "AuthorizationBearerToken": "{{ matrix_corporal_pull_mode_token }}", + "CachePath": "/var/cache/matrix-corporal/last-policy.json", + "ReloadIntervalSeconds": 1800, + "TimeoutMilliseconds": 30000 + } + when: (matrix_corporal_policy_provider_mode == "HTTP Pull Mode (API Enabled)") and (matrix_corporal_pull_mode_uri|length > 0) and (matrix_corporal_pull_mode_token|length > 0) + +- name: Record 'HTTP Push Mode' configuration variables in matrix_vars.yml + delegate_to: 127.0.0.1 + blockinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: "# Corporal Policy Provider Settings Start" + block: | + matrix_corporal_policy_provider_config: | + { + "Type": "last_seen_store_policy", + "CachePath": "/var/cache/matrix-corporal/last-policy.json" + } + when: (matrix_corporal_policy_provider_mode == "HTTP Push Mode (API Enabled)") + +- name: Lower RateLimit if set to 'Normal' + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: ' address:\n per_second: 50\n burst_count: 300\n account:\n per_second: 0.17\n burst_count: 300' + replace: ' address:\n per_second: 0.17\n burst_count: 3\n account:\n per_second: 0.17\n burst_count: 3' + when: matrix_corporal_raise_ratelimits == "Normal" + +- name: Raise RateLimit if set to 'Raised' + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: ' address:\n per_second: 0.17\n burst_count: 3\n account:\n per_second: 0.17\n burst_count: 3' + replace: ' address:\n per_second: 50\n burst_count: 300\n account:\n per_second: 0.17\n burst_count: 300' + when: matrix_corporal_raise_ratelimits == "Raised" + +- name: Save new 'Configure Corporal' survey.json to the AWX tower + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/configure_corporal.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_corporal.json' + +- name: Copy new 'Configure Corporal' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_corporal.json' + dest: '/matrix/awx/configure_corporal.json' + mode: '0660' + +- debug: + msg: "matrix_corporal_matrix_homeserver_api_endpoint: {{ matrix_corporal_matrix_homeserver_api_endpoint }}" + +- debug: + msg: "matrix_corporal_matrix_auth_shared_secret: {{ matrix_corporal_matrix_auth_shared_secret }}" + +- debug: + msg: "matrix_corporal_http_gateway_internal_rest_auth_enabled: {{ matrix_corporal_http_gateway_internal_rest_auth_enabled }}" + +- debug: + msg: "matrix_corporal_matrix_registration_shared_secret: {{ matrix_corporal_matrix_registration_shared_secret }}" + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure Corporal (Advanced)' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure Corporal (Advanced)" + description: "Configure Matrix Corporal, a tool that manages your Matrix server according to a configuration policy." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-corporal" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_corporal.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes diff --git a/roles/matrix-awx/tasks/set_variables_dimension.yml b/roles/matrix-awx/tasks/set_variables_dimension.yml new file mode 100644 index 00000000..53a4dbfc --- /dev/null +++ b/roles/matrix-awx/tasks/set_variables_dimension.yml @@ -0,0 +1,111 @@ + +- name: Include vars in matrix_vars.yml + include_vars: + file: '{{ awx_cached_matrix_vars }}' + no_log: True + +- name: Install jq and curl on remote machine + apt: + name: + - jq + - curl + state: present + +- name: Collect access token of Dimension user + shell: | + curl -X POST --header 'Content-Type: application/json' -d '{ "identifier": { "type": "m.id.user","user": "dimension" }, "password": "{{ matrix_awx_dimension_user_password }}", "type": "m.login.password"}' 'https://matrix.{{ matrix_domain }}/_matrix/client/r0/login' | jq -c '. | {access_token}' | sed 's/.*\":\"//' | sed 's/\"}//' + register: dimension_user_access_token + +- name: Record Synapse variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Dimension Settings Start' + with_dict: + 'matrix_dimension_enabled': '{{ matrix_dimension_enabled }}' + 'matrix_dimension_access_token': '"{{ dimension_user_access_token.stdout }}"' + +- name: Set final users list if users are defined + set_fact: + ext_dimension_users_raw_final: "{{ ext_dimension_users_raw }}" + when: ext_dimension_users_raw|length > 0 + +- name: Set final users list if no users are defined + set_fact: + ext_dimension_users_raw_final: '@dimension:{{ matrix_domain }}' + when: ext_dimension_users_raw|length == 0 + +- name: Remove Dimension Users + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: '^ - .*\n' + after: 'matrix_dimension_admins:' + before: '# Dimension Settings End' + +- name: Set Dimension Users Header + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + insertbefore: '# Dimension Settings End' + line: "matrix_dimension_admins:" + +- name: Set Dimension Users + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: '^matrix_dimension_admins:' + line: ' - "{{ item }}"' + with_items: "{{ ext_dimension_users_raw_final.splitlines() }}" + +- name: Record Dimension Custom variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Custom Settings Start' + with_dict: + 'ext_dimension_users_raw': '{{ ext_dimension_users_raw.splitlines() | to_json }}' + +- name: Save new 'Configure Dimension' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/configure_dimension.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}//configure_dimension.json' + +- name: Copy new 'Configure Dimension' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_dimension.json' + dest: '/matrix/awx/configure_dimension.json' + mode: '0660' + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure Dimension' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure Dimension" + description: "Configure Dimension, the self-hosted integrations server." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-all,setup-dimension" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_dimension.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes diff --git a/roles/matrix-awx/tasks/set_variables_element.yml b/roles/matrix-awx/tasks/set_variables_element.yml new file mode 100755 index 00000000..a0e41770 --- /dev/null +++ b/roles/matrix-awx/tasks/set_variables_element.yml @@ -0,0 +1,70 @@ + +- name: Record Element-Web variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Element Settings Start' + with_dict: + 'matrix_client_element_enabled': '{{ matrix_client_element_enabled }}' + 'matrix_client_element_jitsi_preferredDomain': '{{ matrix_client_element_jitsi_preferredDomain }}' + 'matrix_client_element_brand': '{{ matrix_client_element_brand }}' + 'matrix_client_element_default_theme': '{{ matrix_client_element_default_theme }}' + 'matrix_client_element_registration_enabled': '{{ matrix_client_element_registration_enabled }}' + 'matrix_server_fqn_element': "{{ element_subdomain }}.{{ matrix_domain }}" + +- name: Set fact for 'https' string + set_fact: + awx_https_string: "https" + +- name: Record Element-Web Background variable locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Element Settings Start' + with_dict: + 'matrix_client_element_branding_welcomeBackgroundUrl': '{{ matrix_client_element_branding_welcomeBackgroundUrl }}' + when: (awx_https_string in matrix_client_element_branding_welcomeBackgroundUrl) and ( matrix_client_element_branding_welcomeBackgroundUrl|length > 0 ) + +- name: Save new 'Configure Element' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/configure_element.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_element.json' + +- name: Copy new 'Configure Element' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_element.json' + dest: '/matrix/awx/configure_element.json' + mode: '0660' + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure Element' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure Element" + description: "Configure Element client via survey." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-client-element" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_element.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes diff --git a/roles/matrix-awx/tasks/set_variables_jitsi.yml b/roles/matrix-awx/tasks/set_variables_jitsi.yml new file mode 100755 index 00000000..9c610685 --- /dev/null +++ b/roles/matrix-awx/tasks/set_variables_jitsi.yml @@ -0,0 +1,51 @@ + +- name: Record Jitsi variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Jitsi Settings Start' + with_dict: + 'matrix_jitsi_enabled': '{{ matrix_jitsi_enabled }}' + 'matrix_jitsi_web_config_defaultLanguage': '{{ matrix_jitsi_web_config_defaultLanguage }}' + +- name: Save new 'Configure Jitsi' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/configure_jitsi.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_jitsi.json' + +- name: Copy new 'Configure Jitsi' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_jitsi.json' + dest: '/matrix/awx/configure_jitsi.json' + mode: '0660' + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure Jitsi' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure Jitsi" + description: "Configure Jitsi conferencing settings." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-jitsi" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_jitsi.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes diff --git a/roles/matrix-awx/tasks/set_variables_ma1sd.yml b/roles/matrix-awx/tasks/set_variables_ma1sd.yml new file mode 100755 index 00000000..853d8c09 --- /dev/null +++ b/roles/matrix-awx/tasks/set_variables_ma1sd.yml @@ -0,0 +1,122 @@ + +- name: Record ma1sd variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# ma1sd Settings Start' + with_dict: + 'matrix_ma1sd_enabled': '{{ matrix_ma1sd_enabled }}' + +- name: Disable REST auth (matrix-corporal/ma1sd) if using internal auth + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Extension Start' + with_dict: + 'matrix_synapse_ext_password_provider_rest_auth_enabled': 'false' + when: ext_matrix_ma1sd_auth_store == 'Synapse Internal' + +- name: Enable REST auth if using external LDAP/AD with ma1sd + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Extension Start' + with_dict: + 'matrix_synapse_ext_password_provider_rest_auth_enabled': 'true' + 'matrix_synapse_ext_password_provider_rest_auth_endpoint': 'http://matrix-ma1sd:8090' + when: ext_matrix_ma1sd_auth_store == 'LDAP/AD' + +- name: Strip header from ma1sd configuration extension if using internal auth + set_fact: + ext_matrix_ma1sd_configuration_extension_yaml_parsed: "{{ ext_matrix_ma1sd_configuration_extension_yaml.splitlines() | reject('search', '^matrix_client_element_configuration_extension_json:') | list }}" + when: ext_matrix_ma1sd_auth_store == 'LDAP/AD' + +- name: Remove entire ma1sd configuration extension + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: '^.*\n' + after: '# Start ma1sd Extension' + before: '# End ma1sd Extension' + +- name: Replace conjoined ma1sd configuration extension limiters + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: '^# Start ma1sd Extension# End ma1sd Extension' + replace: '# Start ma1sd Extension\n# End ma1sd Extension' + +- name: Insert ma1sd configuration extension header if using external LDAP/AD with ma1sd + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + line: "matrix_ma1sd_configuration_extension_yaml: |" + insertafter: '# Start ma1sd Extension' + when: ext_matrix_ma1sd_auth_store == 'LDAP/AD' + +- name: Set ma1sd configuration extension if using external LDAP/AD with ma1sd + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + insertbefore: '# End ma1sd Extension' + line: '{{ item }}' + with_items: "{{ ext_matrix_ma1sd_configuration_extension_yaml_parsed }}" + when: ext_matrix_ma1sd_auth_store == 'LDAP/AD' + +- name: Record ma1sd Custom variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertbefore: '# Custom Settings Start' + with_dict: + 'ext_matrix_ma1sd_auth_store': '{{ ext_matrix_ma1sd_auth_store }}' + 'ext_matrix_ma1sd_configuration_extension_yaml': '{{ ext_matrix_ma1sd_configuration_extension_yaml.splitlines() | to_json }}' + +- name: Save new 'Configure ma1sd' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/configure_ma1sd.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_ma1sd.json' + +- name: Copy new 'Configure ma1sd' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_ma1sd.json' + dest: '/matrix/awx/configure_ma1sd.json' + mode: '0660' + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure ma1sd (Advanced)' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure ma1sd (Advanced)" + description: "Configure Jitsi conferencing settings." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-ma1sd" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_ma1sd.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes + diff --git a/roles/matrix-awx/tasks/set_variables_synapse.yml b/roles/matrix-awx/tasks/set_variables_synapse.yml new file mode 100755 index 00000000..e1a7312c --- /dev/null +++ b/roles/matrix-awx/tasks/set_variables_synapse.yml @@ -0,0 +1,226 @@ + +- name: Limit max upload size to 100MB part 1 + set_fact: + matrix_synapse_max_upload_size_mb: "100" + when: matrix_synapse_max_upload_size_mb_raw|int >= 100 + +- name: Limit max upload size to 100MB part 2 + set_fact: + matrix_synapse_max_upload_size_mb: "{{ matrix_synapse_max_upload_size_mb_raw }}" + when: matrix_synapse_max_upload_size_mb_raw|int < 100 + +- name: Record Synapse variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Settings Start' + with_dict: + 'matrix_synapse_allow_public_rooms_over_federation': '{{ matrix_synapse_allow_public_rooms_over_federation }}' + 'matrix_synapse_enable_registration': '{{ matrix_synapse_enable_registration }}' + 'matrix_synapse_federation_enabled': '{{ matrix_synapse_federation_enabled }}' + 'matrix_synapse_enable_group_creation': '{{ matrix_synapse_enable_group_creation }}' + 'matrix_synapse_presence_enabled': '{{ matrix_synapse_presence_enabled }}' + 'matrix_synapse_max_upload_size_mb': '{{ matrix_synapse_max_upload_size_mb }}' + 'matrix_synapse_url_preview_enabled': '{{ matrix_synapse_url_preview_enabled }}' + 'matrix_synapse_allow_guest_access': '{{ matrix_synapse_allow_guest_access }}' + +- name: Empty Synapse variable 'matrix_synapse_auto_join_rooms' locally on AWX, if raw inputs empty + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^matrix_synapse_auto_join_rooms: .*$" + replace: "matrix_synapse_auto_join_rooms: []" + when: matrix_synapse_auto_join_rooms_raw|length == 0 + +- name: If the raw inputs is not empty start constructing parsed auto_join_rooms list + set_fact: + matrix_synapse_auto_join_rooms_array: |- + {{ matrix_synapse_auto_join_rooms_raw.splitlines() | to_json }} + when: matrix_synapse_auto_join_rooms_raw|length > 0 + +- name: Record Synapse variable 'matrix_synapse_auto_join_rooms' locally on AWX, if it's not blank + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Settings Start' + with_dict: + "matrix_synapse_auto_join_rooms": "{{ matrix_synapse_auto_join_rooms_array }}" + when: matrix_synapse_auto_join_rooms_raw|length > 0 + +- name: Record Synapse Shared Secret if it's defined + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Settings Start' + with_dict: + 'matrix_synapse_registration_shared_secret': '{{ matrix_synapse_registration_shared_secret }}' + when: matrix_synapse_registration_shared_secret|length > 0 + +- name: Record registations_require_3pid extra variable if true + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "{{ item }}:" + line: "{{ item }}" + insertbefore: '# Synapse Extension End' + with_items: + - " registrations_require_3pid:" + - " - email" + when: ext_registrations_require_3pid|bool + +- name: Remove registrations_require_3pid extra variable if false + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "{{ item }}:" + line: "{{ item }}" + insertbefore: '# Synapse Extension End' + state: absent + with_items: + - " registrations_require_3pid:" + - " - email" + when: not ext_registrations_require_3pid|bool + +- name: Remove URL Languages + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: '^(?!.*\bemail\b) - [a-zA-Z\-]{2,5}\n' + after: ' url_preview_accept_language:' + before: '# Synapse Extension End' + +- name: Set URL languages default if raw inputs empty + set_fact: + ext_url_preview_accept_language_default: 'en' + when: ext_url_preview_accept_language_raw|length == 0 + +- name: Set URL languages default if raw inputs not empty + set_fact: + ext_url_preview_accept_language_default: "{{ ext_url_preview_accept_language_raw }}" + when: ext_url_preview_accept_language_raw|length > 0 + +- name: Set URL languages if raw inputs empty + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: '^ url_preview_accept_language:' + line: " - {{ ext_url_preview_accept_language_default }}" + when: ext_url_preview_accept_language_raw|length == 0 + +- name: Set URL languages if raw inputs not empty + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: '^ url_preview_accept_language:' + line: " - {{ item }}" + with_items: "{{ ext_url_preview_accept_language_raw.splitlines() }}" + when: ext_url_preview_accept_language_raw|length > 0 + +- name: Remove Federation Whitelisting 1 + delegate_to: 127.0.0.1 + replace: + path: '{{ awx_cached_matrix_vars }}' + regexp: '^ - [a-z0-9]+\.[a-z0-9.]+\n' + after: ' federation_domain_whitelist:' + before: '# Synapse Extension End' + +- name: Remove Federation Whitelisting 2 + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + line: " federation_domain_whitelist:" + state: absent + +- name: Set Federation Whitelisting 1 + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: '^matrix_synapse_configuration_extension_yaml: \|' + line: " federation_domain_whitelist:" + when: ext_federation_whitelist_raw|length > 0 + +- name: Set Federation Whitelisting 2 + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + insertafter: '^ federation_domain_whitelist:' + line: " - {{ item }}" + with_items: "{{ ext_federation_whitelist_raw.splitlines() }}" + when: ext_federation_whitelist_raw|length > 0 + +- name: Record Synapse Custom variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Custom Settings Start' + with_dict: + 'ext_federation_whitelist_raw': '{{ ext_federation_whitelist_raw.splitlines() | to_json }}' + 'ext_url_preview_accept_language_default': '{{ ext_url_preview_accept_language_default.splitlines() | to_json }}' + +- name: Set ext_recaptcha_public_key to a 'public-key' if undefined + set_fact: ext_recaptcha_public_key="public-key" + when: (ext_recaptcha_public_key is not defined) or (ext_recaptcha_public_key|length == 0) + +- name: Set ext_recaptcha_private_key to a 'private-key' if undefined + set_fact: ext_recaptcha_private_key="private-key" + when: (ext_recaptcha_private_key is not defined) or (ext_recaptcha_private_key|length == 0) + +- name: Record Synapse Extension variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertbefore: '# Synapse Extension End' + with_dict: + ' enable_registration_captcha': '{{ ext_enable_registration_captcha }}' + ' recaptcha_public_key': '{{ ext_recaptcha_public_key }}' + ' recaptcha_private_key': '{{ ext_recaptcha_private_key }}' + +- name: Save new 'Configure Synapse' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/configure_synapse.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}//configure_synapse.json' + +- name: Copy new 'Configure Synapse' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_synapse.json' + dest: '/matrix/awx/configure_synapse.json' + mode: '0660' + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure Synapse' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure Synapse" + description: "Configure Synapse (homeserver) settings." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-synapse" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_synapse.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes diff --git a/roles/matrix-awx/tasks/set_variables_synapse_admin.yml b/roles/matrix-awx/tasks/set_variables_synapse_admin.yml new file mode 100644 index 00000000..fa922de4 --- /dev/null +++ b/roles/matrix-awx/tasks/set_variables_synapse_admin.yml @@ -0,0 +1,50 @@ + +- name: Record Synapse Admin variables locally on AWX + delegate_to: 127.0.0.1 + lineinfile: + path: '{{ awx_cached_matrix_vars }}' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: '# Synapse Admin Settings Start' + with_dict: + 'matrix_synapse_admin_enabled': '{{ matrix_synapse_admin_enabled }}' + +- name: Save new 'Configure Synapse Admin' survey.json to the AWX tower, template + delegate_to: 127.0.0.1 + template: + src: 'roles/matrix-awx/surveys/configure_synapse_admin.json.j2' + dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_synapse_admin.json' + +- name: Copy new 'Configure Synapse Admin' survey.json to target machine + copy: + src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_synapse_admin.json' + dest: '/matrix/awx/configure_synapse_admin.json' + mode: '0660' + +- name: Collect AWX admin token the hard way! + delegate_to: 127.0.0.1 + shell: | + curl -sku {{ tower_username }}:{{ tower_password }} -H "Content-Type: application/json" -X POST -d '{"description":"Tower CLI", "application":null, "scope":"write"}' https://{{ tower_host }}/api/v2/users/1/personal_tokens/ | jq '.token' | sed -r 's/\"//g' + register: tower_token + no_log: True + +- name: Recreate 'Configure Synapse Admin' job template + delegate_to: 127.0.0.1 + awx.awx.tower_job_template: + name: "{{ matrix_domain }} - 1 - Configure Synapse Admin" + description: "Configure 'Synapse Admin', a moderation tool to help you manage your server." + extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}" + job_type: run + job_tags: "start,setup-all" + inventory: "{{ member_id }}" + project: "{{ member_id }} - Matrix Docker Ansible Deploy" + playbook: setup.yml + credential: "{{ member_id }} - AWX SSH Key" + survey_enabled: true + survey_spec: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_synapse_admin.json') }}" + become_enabled: yes + state: present + verbosity: 1 + tower_host: "https://{{ tower_host }}" + tower_oauthtoken: "{{ tower_token.stdout }}" + validate_certs: yes diff --git a/roles/matrix-base/defaults/main.yml b/roles/matrix-base/defaults/main.yml index 39a8cffc..ef30ad67 100644 --- a/roles/matrix-base/defaults/main.yml +++ b/roles/matrix-base/defaults/main.yml @@ -15,15 +15,24 @@ matrix_server_fqn_matrix: "matrix.{{ matrix_domain }}" # This and the Matrix FQN (see above) are expected to be on the same server. matrix_server_fqn_element: "element.{{ matrix_domain }}" +# This is where you access the Hydrogen web client from (if enabled via matrix_client_hydrogen_enabled; disabled by default). +matrix_server_fqn_hydrogen: "hydrogen.{{ matrix_domain }}" + # This is where you access the Dimension. matrix_server_fqn_dimension: "dimension.{{ matrix_domain }}" +# For use with Go-NEB! (github callback url for example) +matrix_server_fqn_bot_go_neb: "goneb.{{ matrix_domain }}" + # This is where you access Jitsi. matrix_server_fqn_jitsi: "jitsi.{{ matrix_domain }}" # This is where you access Grafana. matrix_server_fqn_grafana: "stats.{{ matrix_domain }}" +# This is where you access the Sygnal push gateway. +matrix_server_fqn_sygnal: "sygnal.{{ matrix_domain }}" + matrix_federation_public_port: 8448 # The architecture that your server runs. diff --git a/roles/matrix-base/tasks/main.yml b/roles/matrix-base/tasks/main.yml index a1bb6754..4af3564c 100644 --- a/roles/matrix-base/tasks/main.yml +++ b/roles/matrix-base/tasks/main.yml @@ -32,10 +32,3 @@ - setup-ma1sd - setup-synapse - setup-nginx-proxy - -- import_tasks: "{{ role_path }}/tasks/self_check_dns.yml" - delegate_to: 127.0.0.1 - become: false - when: run_self_check|bool - tags: - - self-check diff --git a/roles/matrix-base/tasks/sanity_check.yml b/roles/matrix-base/tasks/sanity_check.yml index c31d9137..265dc282 100644 --- a/roles/matrix-base/tasks/sanity_check.yml +++ b/roles/matrix-base/tasks/sanity_check.yml @@ -52,3 +52,10 @@ when: - ansible_distribution == 'Archlinux' - ansible_python.version.major != 3 + +- name: Fail if architecture is set incorrectly + fail: + msg: "Detected that variable matrix_architecture {{ matrix_architecture }} appears to be set incorrectly. See docs/alternative-architectures.md. Server appears to be {{ ansible_architecture }}." + when: (ansible_architecture == "x86_64" and matrix_architecture != "amd64") or + (ansible_architecture == "aarch64" and matrix_architecture != "arm64") or + (ansible_architecture.startswith("armv") and matrix_architecture != "arm32") diff --git a/roles/matrix-base/tasks/self_check_dns.yml b/roles/matrix-base/tasks/self_check_dns.yml deleted file mode 100644 index 57c07b2b..00000000 --- a/roles/matrix-base/tasks/self_check_dns.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- - -- set_fact: - dns_srv_record_checks: [] - -- block: - - set_fact: - dns_srv_record_check_ma1sd: - service_and_protocol: "_matrix-identity._tcp" - domain: "{{ (matrix_domain + '.') }}" - expected_target: "{{ (matrix_server_fqn_matrix + '.') }}" - expected_port: 443 - - - name: Determine domains that we require certificates for (ma1sd) - set_fact: - dns_srv_record_checks: "{{ dns_srv_record_checks + [dns_srv_record_check_ma1sd] }}" - when: matrix_ma1sd_enabled|bool - -- name: Perform DNS SRV checks - include_tasks: "{{ role_path }}/tasks/self_check_dns_srv.yml" - with_items: "{{ dns_srv_record_checks }}" - loop_control: - loop_var: dns_srv_record_check diff --git a/roles/matrix-base/tasks/self_check_dns_srv.yml b/roles/matrix-base/tasks/self_check_dns_srv.yml deleted file mode 100644 index 559d9dba..00000000 --- a/roles/matrix-base/tasks/self_check_dns_srv.yml +++ /dev/null @@ -1,68 +0,0 @@ ---- - -# This requires the dnspython library which is usually unavailable. -- name: Check DNS SRV record for {{ dns_srv_record_check.service_and_protocol }} on {{ dns_srv_record_check.domain }} using Ansible dig lookup - set_fact: - lookup_dig_srv: "{{ lookup('dig', (dns_srv_record_check.service_and_protocol + '.' + dns_srv_record_check.domain + '/SRV'), 'flat=0', wantlist=False) }}" - register: result_lookup_dig_srv - ignore_errors: true - -- name: Fail if DNS SRV check via Ansible dig lookup failed for non-dependency reason - fail: - msg: "DNS SRV record check via Ansible dig lookup plugin (which uses the dnspython package) failed. Error is: {{ result_lookup_dig_srv.msg }}" - when: "result_lookup_dig_srv.failed and 'dnspython' not in result_lookup_dig_srv.msg" - -# Fallback to using the dig CLI tool if dnspython was unavailable. -- name: Check DNS SRV record for {{ dns_srv_record_check.service_and_protocol }} on {{ dns_srv_record_check.domain }} using dig CLI tool - shell: - cmd: "dig -t srv {{ (dns_srv_record_check.service_and_protocol + '.' + dns_srv_record_check.domain)|quote }}" - register: result_cli_dig_srv - changed_when: false - ignore_errors: true - when: "lookup_dig_srv is not defined" - -- name: Fail if dig CLI used and failed - fail: - msg: >- - Failed performing DNS SRV record check. - You neither have the `dnspython` Python package, nor the `dig` program installed locally. - You need to install one of those, so we could perform a DNS SRV record check. - Full error from trying to run `dig`: {{ result_cli_dig_srv }} - when: "lookup_dig_srv is not defined and result_cli_dig_srv.stderr != ''" - -# Some DNS servers may respond with '' (stands for "No Answer"). -# Most usually, a missing record would yield a 'NXDOMAIN' response. -# In any case, we consider any non-mapping response to mean "missing record". -- name: Fail if DNS SRV record missing (Ansible dig lookup) - fail: - msg: >- - It appears the DNS SRV record for {{ dns_srv_record_check.service_and_protocol }} on {{ dns_srv_record_check.domain }} is not set up correctly (the record is missing). - See the 'Configuring DNS' documentation for this playbook. - when: "lookup_dig_srv is defined and lookup_dig_srv is not mapping" - -- name: Fail if DNS SRV record incorrect (Ansible dig lookup) - fail: - msg: >- - It appears the DNS SRV record for {{ dns_srv_record_check.service_and_protocol }} on {{ dns_srv_record_check.domain }} is not set up correctly. - Expected it to point to `{{ dns_srv_record_check.expected_target }}` (port {{ dns_srv_record_check.expected_port }}). - Found it pointing to `{{ lookup_dig_srv.target }}` (port {{ lookup_dig_srv.port }}). - See the 'Configuring DNS' documentation for this playbook. - when: "lookup_dig_srv is defined and (lookup_dig_srv.target != dns_srv_record_check.expected_target or lookup_dig_srv.port != dns_srv_record_check.expected_port)" - -# We expect an answer like this: -# ;; ANSWER SECTION: -# _matrix._tcp.DOMAIN. 10800 IN SRV 10 0 8448 matrix.DOMAIN. -- name: Fail if DNS SRV record missing or incorrect (dig CLI tool) - fail: - msg: >- - It appears the DNS SRV record for {{ dns_srv_record_check.service_and_protocol }} on {{ dns_srv_record_check.domain }} is not set up correctly. - Expected it to point to `{{ dns_srv_record_check.expected_target }}` (port {{ dns_srv_record_check.expected_port }}). - See the 'Configuring DNS' documentation for this playbook. - Full response from the `dig` lookup was: {{ result_cli_dig_srv }} - when: "lookup_dig_srv is not defined and (dns_srv_record_check.expected_port|string + ' ' + dns_srv_record_check.expected_target) not in result_cli_dig_srv.stdout" - -- name: Report correct DNS SRV record - debug: - msg: >- - The DNS SRV record for `{{ dns_srv_record_check.service_and_protocol }}` on `{{ dns_srv_record_check.domain }}` - points to `{{ dns_srv_record_check.expected_target }}` (port {{ dns_srv_record_check.expected_port }}), as expected. diff --git a/roles/matrix-bot-go-neb/defaults/main.yml b/roles/matrix-bot-go-neb/defaults/main.yml new file mode 100644 index 00000000..4dd4f1f6 --- /dev/null +++ b/roles/matrix-bot-go-neb/defaults/main.yml @@ -0,0 +1,231 @@ +# Go-NEB is a Matrix bot written in Go. It is the successor to Matrix-NEB, the original Matrix bot written in Python. +# See: https://github.com/matrix-org/go-neb + +matrix_bot_go_neb_enabled: true +matrix_bot_go_neb_version: latest +matrix_bot_go_neb_docker_image: "matrixdotorg/go-neb:{{ matrix_bot_go_neb_version }}" +matrix_bot_go_neb_docker_image_force_pull: "{{ matrix_bot_go_neb_docker_image.endswith(':latest') }}" + +matrix_bot_go_neb_base_path: "{{ matrix_base_data_path }}/go-neb" +matrix_bot_go_neb_config_path: "{{ matrix_bot_go_neb_base_path }}/config" +matrix_bot_go_neb_config_path_in_container: "/config/config.yaml" +matrix_bot_go_neb_data_path: "{{ matrix_bot_go_neb_base_path }}/data" +matrix_bot_go_neb_data_store_path: "{{ matrix_bot_go_neb_data_path }}/store" + +# Controls whether the matrix-bot-go-neb container exposes its HTTP port (tcp/4050 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:4050"), or empty string to not expose. +matrix_bot_go_neb_container_http_host_bind_port: '' + +# A list of extra arguments to pass to the container +matrix_bot_go_neb_container_extra_arguments: [] + +# List of systemd services that matrix-bot-go-neb.service depends on +matrix_bot_go_neb_systemd_required_services_list: ['docker.service'] + +# List of systemd services that matrix-bot-go-neb.service wants +matrix_bot_go_neb_systemd_wanted_services_list: [] + +# Database-related configuration fields. +# +# MUST be "sqlite3". No other type is supported. +matrix_bot_go_neb_database_engine: 'sqlite3' + +matrix_bot_go_neb_sqlite_database_path_local: "{{ matrix_bot_go_neb_data_path }}/bot.db" +matrix_bot_go_neb_sqlite_database_path_in_container: "/data/bot.db" + +matrix_bot_go_neb_storage_database: "{{ + { + 'sqlite3': (matrix_bot_go_neb_sqlite_database_path_in_container + '?_busy_timeout=5000'), + }[matrix_bot_go_neb_database_engine] +}}" + +# The bot's username(s). These users need to be created manually beforehand. +# The access tokens that the bot uses to authenticate. +# Generate one as described in +# https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-dimension.md#access-token +# via curl. With the element method, you might run into decryption problems (see https://github.com/matrix-org/go-neb#quick-start) +matrix_bot_go_neb_clients: [] +# - UserID: "@goneb:{{ matrix_domain }}" +# AccessToken: "MDASDASJDIASDJASDAFGFRGER" +# DeviceID: "DEVICE1" +# HomeserverURL: "{{ matrix_homeserver_container_url }}" +# Sync: true +# AutoJoinRooms: true +# DisplayName: "Go-NEB!" +# AcceptVerificationFromUsers: [":{{ matrix_domain }}"] +# +# - UserID: "@another_goneb:{{ matrix_domain }}" +# AccessToken: "MDASDASJDIASDJASDAFGFRGER" +# DeviceID: "DEVICE2" +# HomeserverURL: "{{ matrix_homeserver_container_url }}" +# Sync: false +# AutoJoinRooms: false +# DisplayName: "Go-NEB!" +# AcceptVerificationFromUsers: ["^@admin:{{ matrix_domain }}"] + +# The list of realms which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# See the docs for /configureAuthRealm for the full list of options: +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureAuthRealmRequest +matrix_bot_go_neb_realms: [] +# - ID: "github_realm" +# Type: "github" +# Config: {} # No need for client ID or Secret as Go-NEB isn't generating OAuth URLs + +# The list of *authenticated* sessions which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# The full list of options are shown below: there is no single HTTP endpoint +# which maps to this section. +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#Session +matrix_bot_go_neb_sessions: [] +# - SessionID: "your_github_session" +# RealmID: "github_realm" +# UserID: "@YOUR_USER_ID:{{ matrix_domain }}" # This needs to be the username of the person that's allowed to use the !github commands +# Config: +# # Populate these fields by generating a "Personal Access Token" on github.com +# AccessToken: "YOUR_GITHUB_ACCESS_TOKEN" +# Scopes: "admin:org_hook,admin:repo_hook,repo,user" + +# The list of services which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# See the docs for /configureService for the full list of options: +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureServiceRequest +matrix_bot_go_neb_services: [] +# - ID: "echo_service" +# Type: "echo" +# UserID: "@goneb:{{ matrix_domain }}" +# Config: {} + +## Can be obtained from https://developers.giphy.com/dashboard/ +# - ID: "giphy_service" +# Type: "giphy" +# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client +# Config: +# api_key: "qwg4672vsuyfsfe" +# use_downsized: false +# +## This service has been dead for over a year :/ +# - ID: "guggy_service" +# Type: "guggy" +# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client +# Config: +# api_key: "2356saaqfhgfe" +# +## API Key via https://developers.google.com/custom-search/v1/introduction +## CX via http://www.google.com/cse/manage/all +## https://stackoverflow.com/questions/6562125/getting-a-cx-id-for-custom-search-google-api-python +## 'Search the entire web' and 'Image search' enabled for best results +# - ID: "google_service" +# Type: "google" +# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client +# Config: +# api_key: "AIzaSyA4FD39m9" +# cx: "AIASDFWSRRtrtr" +# +## Get a key via https://api.imgur.com/oauth2/addclient +## Select "oauth2 without callback url" +# - ID: "imgur_service" +# Type: "imgur" +# UserID: "@imgur:{{ matrix_domain }}" # requires a Syncing client +# Config: +# client_id: "AIzaSyA4FD39m9" +# client_secret: "somesecret" +# +# - ID: "wikipedia_service" +# Type: "wikipedia" +# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client +# Config: +# +# - ID: "rss_service" +# Type: "rssbot" +# UserID: "@another_goneb:{{ matrix_domain }}" +# Config: +# feeds: +# "http://lorem-rss.herokuapp.com/feed?unit=second&interval=60": +# rooms: ["!qmElAGdFYCHoCJuaNt:localhost"] +# must_include: +# author: +# - author1 +# description: +# - lorem +# - ipsum +# must_not_include: +# title: +# - Lorem +# - Ipsum +# +# - ID: "github_cmd_service" +# Type: "github" +# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client +# Config: +# RealmID: "github_realm" +# +# # Make sure your BASE_URL can be accessed by Github! +# - ID: "github_webhook_service" +# Type: "github-webhook" +# UserID: "@another_goneb:{{ matrix_domain }}" +# Config: +# RealmID: "github_realm" +# ClientUserID: "@YOUR_USER_ID:{{ matrix_domain }}" # needs to be an authenticated user so Go-NEB can create webhooks. Check the UserID field in the github_realm in matrix_bot_go_neb_sessions. +# Rooms: +# "!someroom:id": +# Repos: +# "matrix-org/synapse": +# Events: ["push", "issues"] +# "matrix-org/dendron": +# Events: ["pull_request"] +# "!anotherroom:id": +# Repos: +# "matrix-org/synapse": +# Events: ["push", "issues"] +# "matrix-org/dendron": +# Events: ["pull_request"] +# +# - ID: "slackapi_service" +# Type: "slackapi" +# UserID: "@slackapi:{{ matrix_domain }}" +# Config: +# Hooks: +# "hook1": +# RoomID: "!someroom:id" +# MessageType: "m.text" # default is m.text +# +# - ID: "alertmanager_service" +# Type: "alertmanager" +# UserID: "@alertmanager:{{ matrix_domain }}" +# Config: +# # This is for information purposes only. It should point to Go-NEB path as follows: +# # `/services/hooks/` +# # Where in this case "service ID" is "alertmanager_service" +# # Make sure your BASE_URL can be accessed by the Alertmanager instance! +# webhook_url: "http://localhost/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U" +# # Each room will get the notification with the alert rendered with the given template +# rooms: +# "!someroomid:domain.tld": +# text_template: "{{range .Alerts -}} [{{ .Status }}] {{index .Labels \"alertname\" }}: {{index .Annotations \"description\"}} {{ end -}}" +# html_template: "{{range .Alerts -}} {{ $severity := index .Labels \"severity\" }} {{ if eq .Status \"firing\" }} {{ if eq $severity \"critical\"}} [FIRING - CRITICAL] {{ else if eq $severity \"warning\"}} [FIRING - WARNING] {{ else }} [FIRING - {{ $severity }}] {{ end }} {{ else }} [RESOLVED] {{ end }} {{ index .Labels \"alertname\"}} : {{ index .Annotations \"description\"}} source
{{end -}}" +# msg_type: "m.text" # Must be either `m.text` or `m.notice` + +# Default configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_bot_go_neb_configuration_extension_yaml`) +# or completely replace this variable with your own template. +matrix_bot_go_neb_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" + +matrix_bot_go_neb_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bot_go_neb_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bot_go_neb_configuration_yaml`. + +matrix_bot_go_neb_configuration_extension: "{{ matrix_bot_go_neb_configuration_extension_yaml|from_yaml if matrix_bot_go_neb_configuration_extension_yaml|from_yaml is mapping else {} }}" + +# Holds the final configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_bot_go_neb_configuration_yaml`. +matrix_bot_go_neb_configuration: "{{ matrix_bot_go_neb_configuration_yaml|from_yaml|combine(matrix_bot_go_neb_configuration_extension, recursive=True) }}" + diff --git a/roles/matrix-bot-go-neb/tasks/init.yml b/roles/matrix-bot-go-neb/tasks/init.yml new file mode 100644 index 00000000..169f5978 --- /dev/null +++ b/roles/matrix-bot-go-neb/tasks/init.yml @@ -0,0 +1,3 @@ +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-bot-go-neb.service'] }}" + when: matrix_bot_go_neb_enabled|bool diff --git a/roles/matrix-bot-go-neb/tasks/main.yml b/roles/matrix-bot-go-neb/tasks/main.yml new file mode 100644 index 00000000..1a4fe70a --- /dev/null +++ b/roles/matrix-bot-go-neb/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_bot_go_neb_enabled|bool" + tags: + - setup-all + - setup-bot-go-neb + +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: "run_setup|bool and matrix_bot_go_neb_enabled|bool" + tags: + - setup-all + - setup-bot-go-neb + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: "run_setup|bool and not matrix_bot_go_neb_enabled|bool" + tags: + - setup-all + - setup-bot-go-neb diff --git a/roles/matrix-bot-go-neb/tasks/setup_install.yml b/roles/matrix-bot-go-neb/tasks/setup_install.yml new file mode 100644 index 00000000..e26be080 --- /dev/null +++ b/roles/matrix-bot-go-neb/tasks/setup_install.yml @@ -0,0 +1,50 @@ +--- + +- set_fact: + matrix_bot_go_neb_requires_restart: false + +- name: Ensure go-neb paths exist + file: + path: "{{ item.path }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - { path: "{{ matrix_bot_go_neb_config_path }}", when: true } + - { path: "{{ matrix_bot_go_neb_data_path }}", when: true } + - { path: "{{ matrix_bot_go_neb_data_store_path }}", when: true } + when: "item.when|bool" + +- name: Ensure go-neb image is pulled + docker_image: + name: "{{ matrix_bot_go_neb_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_bot_go_neb_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_go_neb_docker_image_force_pull }}" + +- name: Ensure go-neb config installed + copy: + content: "{{ matrix_bot_go_neb_configuration|to_nice_yaml }}" + dest: "{{ matrix_bot_go_neb_config_path }}/config.yaml" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + +- name: Ensure matrix-bot-go-neb.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-bot-go-neb.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-bot-go-neb.service" + mode: 0644 + register: matrix_bot_go_neb_systemd_service_result + +- name: Ensure systemd reloaded after matrix-bot-go-neb.service installation + service: + daemon_reload: yes + when: "matrix_bot_go_neb_systemd_service_result.changed|bool" + +- name: Ensure matrix-bot-go-neb.service restarted, if necessary + service: + name: "matrix-bot-go-neb.service" + state: restarted + when: "matrix_bot_go_neb_requires_restart|bool" diff --git a/roles/matrix-bot-go-neb/tasks/setup_uninstall.yml b/roles/matrix-bot-go-neb/tasks/setup_uninstall.yml new file mode 100644 index 00000000..49ad1fe7 --- /dev/null +++ b/roles/matrix-bot-go-neb/tasks/setup_uninstall.yml @@ -0,0 +1,35 @@ +--- + +- name: Check existence of matrix-go-neb service + stat: + path: "{{ matrix_systemd_path }}/matrix-bot-go-neb.service" + register: matrix_bot_go_neb_service_stat + +- name: Ensure matrix-go-neb is stopped + service: + name: matrix-bot-go-neb + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_bot_go_neb_service_stat.stat.exists|bool" + +- name: Ensure matrix-bot-go-neb.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-bot-go-neb.service" + state: absent + when: "matrix_bot_go_neb_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-bot-go-neb.service removal + service: + daemon_reload: yes + when: "matrix_bot_go_neb_service_stat.stat.exists|bool" + +- name: Ensure Matrix go-neb paths don't exist + file: + path: "{{ matrix_bot_go_neb_base_path }}" + state: absent + +- name: Ensure go-neb Docker image doesn't exist + docker_image: + name: "{{ matrix_bot_go_neb_docker_image }}" + state: absent diff --git a/roles/matrix-bot-go-neb/tasks/validate_config.yml b/roles/matrix-bot-go-neb/tasks/validate_config.yml new file mode 100644 index 00000000..7b292250 --- /dev/null +++ b/roles/matrix-bot-go-neb/tasks/validate_config.yml @@ -0,0 +1,13 @@ +--- + +- name: Fail if there's not at least 1 client + fail: + msg: >- + You need at least 1 client in the matrix_bot_go_neb_clients block. + when: matrix_bot_go_neb_clients is not defined or matrix_bot_go_neb_clients[0] is not defined + +- name: Fail if there's not at least 1 service + fail: + msg: >- + You need at least 1 service in the matrix_bot_go_neb_services block. + when: matrix_bot_go_neb_services is not defined or matrix_bot_go_neb_services[0] is not defined diff --git a/roles/matrix-bot-go-neb/templates/config.yaml.j2 b/roles/matrix-bot-go-neb/templates/config.yaml.j2 new file mode 100644 index 00000000..c72dbf8d --- /dev/null +++ b/roles/matrix-bot-go-neb/templates/config.yaml.j2 @@ -0,0 +1,44 @@ +# Go-NEB Configuration File +# +# This file provides an alternative way to configure Go-NEB which does not involve HTTP APIs. +# +# This file can be supplied to go-neb by the environment variable `CONFIG_FILE=config.yaml`. +# It will force Go-NEB to operate in "config" mode. This means: +# - Go-NEB will ONLY use the data contained inside this file. +# - All of Go-NEB's /admin HTTP listeners will be disabled. You will be unable to add new services at runtime. +# - The environment variable `DATABASE_URL` will be ignored and an in-memory database will be used instead. +# +# This file is broken down into 4 sections which matches the following HTTP APIs: +# - /configureClient +# - /configureAuthRealm +# - /configureService +# - /requestAuthSession (redirects not supported) + +# The list of clients which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# See the docs for /configureClient for the full list of options: +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ClientConfig +clients: + {{ matrix_bot_go_neb_clients|to_json }} + +# The list of realms which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# See the docs for /configureAuthRealm for the full list of options: +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureAuthRealmRequest +realms: + {{ matrix_bot_go_neb_realms|to_json }} + +# The list of *authenticated* sessions which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# The full list of options are shown below: there is no single HTTP endpoint +# which maps to this section. +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#Session +sessions: + {{ matrix_bot_go_neb_sessions|to_json }} + +# The list of services which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# See the docs for /configureService for the full list of options: +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureServiceRequest +services: + {{ matrix_bot_go_neb_services|to_json }} diff --git a/roles/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2 b/roles/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2 new file mode 100644 index 00000000..eabf1137 --- /dev/null +++ b/roles/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2 @@ -0,0 +1,49 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix Go-NEB bot +{% for service in matrix_bot_go_neb_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_bot_go_neb_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ matrix_systemd_unit_home_path }}" +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-bot-go-neb 2>/dev/null' +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-bot-go-neb 2>/dev/null' + +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-bot-go-neb \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --network={{ matrix_docker_network }} \ + {% if matrix_bot_go_neb_container_http_host_bind_port %} + -p {{ matrix_bot_go_neb_container_http_host_bind_port }}:4050 \ + {% endif %} + -e 'BIND_ADDRESS=:4050' \ + -e 'DATABASE_TYPE={{ matrix_bot_go_neb_database_engine }}' \ + -e 'BASE_URL=https://{{ matrix_server_fqn_bot_go_neb }}' \ + -e 'CONFIG_FILE={{ matrix_bot_go_neb_config_path_in_container }}' \ + -e 'DATABASE_URL={{ matrix_bot_go_neb_storage_database }}' \ + --mount type=bind,src={{ matrix_bot_go_neb_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bot_go_neb_data_path }},dst=/data \ + --entrypoint=/bin/sh \ + {% for arg in matrix_bot_go_neb_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_bot_go_neb_docker_image }} \ + -c "go-neb /config/config.yaml" + +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-bot-go-neb 2>/dev/null' +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-bot-go-neb 2>/dev/null' +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-bot-go-neb + +[Install] +WantedBy=multi-user.target diff --git a/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml b/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml index c3deb2f2..775dadcc 100644 --- a/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml +++ b/roles/matrix-bot-matrix-reminder-bot/defaults/main.yml @@ -2,8 +2,8 @@ # See: https://github.com/anoadragon453/matrix-reminder-bot matrix_bot_matrix_reminder_bot_enabled: true - -matrix_bot_matrix_reminder_bot_docker_image: "docker.io/anoa/matrix-reminder-bot:release-v0.2.0" +matrix_bot_matrix_reminder_bot_version: release-v0.2.0 +matrix_bot_matrix_reminder_bot_docker_image: "{{ matrix_container_global_registry_prefix }}anoa/matrix-reminder-bot:{{ matrix_bot_matrix_reminder_bot_version }}" 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" diff --git a/roles/matrix-bot-mjolnir/defaults/main.yml b/roles/matrix-bot-mjolnir/defaults/main.yml new file mode 100644 index 00000000..f97e997c --- /dev/null +++ b/roles/matrix-bot-mjolnir/defaults/main.yml @@ -0,0 +1,52 @@ +# A moderation tool for Matrix +# See: https://github.com/matrix-org/mjolnir + +matrix_bot_mjolnir_enabled: true +matrix_bot_mjolnir_version: "v0.1.17" +matrix_bot_mjolnir_docker_image: "{{ matrix_container_global_registry_prefix }}matrixdotorg/mjolnir:{{ matrix_bot_mjolnir_version }}" +matrix_bot_mjolnir_docker_image_force_pull: "{{ matrix_bot_mjolnir_docker_image.endswith(':latest') }}" + +matrix_bot_mjolnir_base_path: "{{ matrix_base_data_path }}/mjolnir" +matrix_bot_mjolnir_config_path: "{{ matrix_bot_mjolnir_base_path }}/config" +matrix_bot_mjolnir_data_path: "{{ matrix_bot_mjolnir_base_path }}/data" + +# A list of extra arguments to pass to the container +matrix_bot_mjolnir_container_extra_arguments: [] + +# List of systemd services that matrix-bot-mjolnir.service depends on +matrix_bot_mjolnir_systemd_required_services_list: ['docker.service'] + +# List of systemd services that matrix-bot-mjolnir.service wants +matrix_bot_mjolnir_systemd_wanted_services_list: [] + +# The access token for the bot user +matrix_bot_mjolnir_access_token: "" + +# The room ID where people can use the bot. The bot has no access controls, so +# anyone in this room can use the bot - secure your room! +# This should be a room alias or room ID - not a matrix.to URL. +# Note: Mjolnir is fairly verbose - expect a lot of messages from it. +matrix_bot_mjolnir_management_room: "" + +# Default configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_bot_mjolnir_configuration_extension_yaml`) +# or completely replace this variable with your own template. +matrix_bot_mjolnir_configuration_yaml: "{{ lookup('template', 'templates/production.yaml.j2') }}" + +matrix_bot_mjolnir_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bot_mjolnir_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bot_mjolnir_configuration_yaml`. + +matrix_bot_mjolnir_configuration_extension: "{{ matrix_bot_mjolnir_configuration_extension_yaml|from_yaml if matrix_bot_mjolnir_configuration_extension_yaml|from_yaml is mapping else {} }}" + +# Holds the final configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_bot_mjolnir_configuration_yaml`. +matrix_bot_mjolnir_configuration: "{{ matrix_bot_mjolnir_configuration_yaml|from_yaml|combine(matrix_bot_mjolnir_configuration_extension, recursive=True) }}" + diff --git a/roles/matrix-bot-mjolnir/tasks/init.yml b/roles/matrix-bot-mjolnir/tasks/init.yml new file mode 100644 index 00000000..d54684d2 --- /dev/null +++ b/roles/matrix-bot-mjolnir/tasks/init.yml @@ -0,0 +1,3 @@ +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-bot-mjolnir.service'] }}" + when: matrix_bot_mjolnir_enabled|bool diff --git a/roles/matrix-bot-mjolnir/tasks/main.yml b/roles/matrix-bot-mjolnir/tasks/main.yml new file mode 100644 index 00000000..eada8de5 --- /dev/null +++ b/roles/matrix-bot-mjolnir/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_bot_mjolnir_enabled|bool" + tags: + - setup-all + - setup-bot-mjolnir + +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: "run_setup|bool and matrix_bot_mjolnir_enabled|bool" + tags: + - setup-all + - setup-bot-mjolnir + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: "run_setup|bool and not matrix_bot_mjolnir_enabled|bool" + tags: + - setup-all + - setup-bot-mjolnir diff --git a/roles/matrix-bot-mjolnir/tasks/setup_install.yml b/roles/matrix-bot-mjolnir/tasks/setup_install.yml new file mode 100644 index 00000000..4c18bf6a --- /dev/null +++ b/roles/matrix-bot-mjolnir/tasks/setup_install.yml @@ -0,0 +1,50 @@ +--- + +- set_fact: + matrix_bot_mjolnir_requires_restart: false + +- name: Ensure matrix-bot-mjolnir paths exist + file: + path: "{{ item.path }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - { path: "{{ matrix_bot_mjolnir_base_path }}", when: true } + - { path: "{{ matrix_bot_mjolnir_config_path }}", when: true } + - { path: "{{ matrix_bot_mjolnir_data_path }}", when: true } + when: "item.when|bool" + +- name: Ensure mjolnir image is pulled + docker_image: + name: "{{ matrix_bot_mjolnir_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_bot_mjolnir_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_mjolnir_docker_image_force_pull }}" + +- name: Ensure matrix-bot-mjolnir config installed + copy: + content: "{{ matrix_bot_mjolnir_configuration|to_nice_yaml }}" + dest: "{{ matrix_bot_mjolnir_config_path }}/production.yaml" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + +- name: Ensure matrix-bot-mjolnir.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-bot-mjolnir.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-bot-mjolnir.service" + mode: 0644 + register: matrix_bot_mjolnir_systemd_service_result + +- name: Ensure systemd reloaded after matrix-bot-mjolnir.service installation + service: + daemon_reload: yes + when: "matrix_bot_mjolnir_systemd_service_result.changed|bool" + +- name: Ensure matrix-bot-mjolnir.service restarted, if necessary + service: + name: "matrix-bot-mjolnir.service" + state: restarted + when: "matrix_bot_mjolnir_requires_restart|bool" diff --git a/roles/matrix-bot-mjolnir/tasks/setup_uninstall.yml b/roles/matrix-bot-mjolnir/tasks/setup_uninstall.yml new file mode 100644 index 00000000..7127543e --- /dev/null +++ b/roles/matrix-bot-mjolnir/tasks/setup_uninstall.yml @@ -0,0 +1,35 @@ +--- + +- name: Check existence of matrix-bot-mjolnir service + stat: + path: "{{ matrix_systemd_path }}/matrix-bot-mjolnir.service" + register: matrix_bot_mjolnir_service_stat + +- name: Ensure matrix-bot-mjolnir is stopped + service: + name: matrix-bot-mjolnir + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_bot_mjolnir_service_stat.stat.exists|bool" + +- name: Ensure matrix-bot-mjolnir.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-bot-mjolnir.service" + state: absent + when: "matrix_bot_mjolnir_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-bot-mjolnir.service removal + service: + daemon_reload: yes + when: "matrix_bot_mjolnir_service_stat.stat.exists|bool" + +- name: Ensure matrix-bot-mjolnir paths don't exist + file: + path: "{{ matrix_bot_mjolnir_base_path }}" + state: absent + +- name: Ensure mjolnir Docker image doesn't exist + docker_image: + name: "{{ matrix_bot_mjolnir_docker_image }}" + state: absent diff --git a/roles/matrix-bot-mjolnir/tasks/validate_config.yml b/roles/matrix-bot-mjolnir/tasks/validate_config.yml new file mode 100644 index 00000000..cb961baf --- /dev/null +++ b/roles/matrix-bot-mjolnir/tasks/validate_config.yml @@ -0,0 +1,9 @@ +--- + +- name: Fail if required variables are undefined + fail: + msg: "The `{{ item }}` variable must be defined and have a non-null value." + with_items: + - "matrix_bot_mjolnir_access_token" + - "matrix_bot_mjolnir_management_room" + when: "vars[item] == '' or vars[item] is none" diff --git a/roles/matrix-bot-mjolnir/templates/production.yaml.j2 b/roles/matrix-bot-mjolnir/templates/production.yaml.j2 new file mode 100644 index 00000000..e5eb3aea --- /dev/null +++ b/roles/matrix-bot-mjolnir/templates/production.yaml.j2 @@ -0,0 +1,162 @@ +# Where the homeserver is located (client-server URL). This should point at +# pantalaimon if you're using that. +homeserverUrl: "{{ matrix_homeserver_url }}" + +# The access token for the bot to use. Do not populate if using Pantalaimon. +accessToken: "{{ matrix_bot_mjolnir_access_token }}" + +# Pantalaimon options (https://github.com/matrix-org/pantalaimon) +#pantalaimon: +# # If true, accessToken above is ignored and the username/password below will be +# # used instead. The access token of the bot will be stored in the dataPath. +# use: false +# +# # The username to login with. +# username: mjolnir +# +# # The password to login with. Can be removed after the bot has logged in once and +# # stored the access token. +# password: your_password + +# The directory the bot should store various bits of information in +dataPath: "/data" + +# If true (the default), only users in the `managementRoom` can invite the bot +# to new rooms. +autojoinOnlyIfManager: true + +# If `autojoinOnlyIfManager` is false, only the members in this group can invite +# the bot to new rooms. +#acceptInvitesFromGroup: '+example:example.org' + +# If the bot is invited to a room and it won't accept the invite (due to the +# conditions above), report it to the management room. Defaults to disabled (no +# reporting). +recordIgnoredInvites: false + +# The room ID where people can use the bot. The bot has no access controls, so +# anyone in this room can use the bot - secure your room! +# This should be a room alias or room ID - not a matrix.to URL. +# Note: Mjolnir is fairly verbose - expect a lot of messages from it. +managementRoom: "{{ matrix_bot_mjolnir_management_room }}" + +# Set to false to make the management room a bit quieter. +verboseLogging: false + +# The log level for the logs themselves. One of DEBUG, INFO, WARN, and ERROR. +# This should be at INFO or DEBUG in order to get support for Mjolnir problems. +logLevel: "INFO" + +# Set to false to disable synchronizing the ban lists on startup. If true, this +# is the same as running !mjolnir sync immediately after startup. +syncOnStartup: true + +# Set to false to prevent Mjolnir from checking its permissions on startup. This +# is recommended to be left as "true" to catch room permission problems (state +# resets, etc) before Mjolnir is needed. +verifyPermissionsOnStartup: true + +# If true, Mjolnir won't actually ban users or apply server ACLs, but will +# think it has. This is useful to see what it does in a scenario where the +# bot might not be trusted fully, yet. Default false (do bans/ACLs). +noop: false + +# Set to true to use /joined_members instead of /state to figure out who is +# in the room. Using /state is preferred because it means that users are +# banned when they are invited instead of just when they join, though if your +# server struggles with /state requests then set this to true. +fasterMembershipChecks: false + +# A case-insensitive list of ban reasons to automatically redact a user's +# messages for. Typically this is useful to avoid having to type two commands +# to the bot. Use asterisks to represent globs (ie: "spam*testing" would match +# "spam for testing" as well as "spamtesting"). +automaticallyRedactForReasons: + - "spam" + - "advertising" + +# A list of rooms to protect (matrix.to URLs) +#protectedRooms: +# - "https://matrix.to/#/#yourroom:example.org" + +# Set this option to true to protect every room the bot is joined to. Note that +# this effectively makes the protectedRooms and associated commands useless because +# the bot by nature must be joined to the room to protect it. +# +# Note: the management room is *excluded* from this condition. Add it to the +# protected rooms to protect it. +# +# Note: ban list rooms the bot is watching but didn't create will not be protected. +# Manually add these rooms to the protected rooms list if you want them protected. +protectAllJoinedRooms: false + +# Misc options for command handling and commands +commands: + # If true, Mjolnir will respond to commands like !help and !ban instead of + # requiring a prefix. This is useful if Mjolnir is the only bot running in + # your management room. + # + # Note that Mjolnir can be pinged by display name instead of having to use + # the !mjolnir prefix. For example, "my_moderator_bot: ban @spammer:example.org" + # will ban a user. + allowNoPrefix: false + + # In addition to the bot's display name, !mjolnir, and optionally no prefix + # above, the bot will respond to these names. The items here can be used either + # as display names or prefixed with exclamation points. + additionalPrefixes: + - "mjolnir_bot" + + # If true, ban commands that use wildcard characters require confirmation with + # an extra `--force` argument + confirmWildcardBan: true + +# Configuration specific to certain toggleable protections +#protections: +# # Configuration for the wordlist plugin, which can ban users based if they say certain +# # blocked words shortly after joining. +# wordlist: +# # A list of words which should be monitored by the bot. These will match if any part +# # of the word is present in the message in any case. e.g. "hello" also matches +# # "HEllO". Additionally, regular expressions can be used. +# words: +# - "CaSe" +# - "InSeNsAtIve" +# - "WoRd" +# - "LiSt" +# +# # How long after a user joins the server should the bot monitor their messages. After +# # this time, users can say words from the wordlist without being banned automatically. +# # Set to zero to disable (users will always be banned if they say a bad word) +# minutesBeforeTrusting: 20 + +# Options for monitoring the health of the bot +health: + # healthz options. These options are best for use in container environments + # like Kubernetes to detect how healthy the service is. The bot will report + # that it is unhealthy until it is able to process user requests. Typically + # this means that it'll flag itself as unhealthy for a number of minutes + # before saying "Now monitoring rooms" and flagging itself healthy. + # + # Health is flagged through HTTP status codes, defined below. + healthz: + # Whether the healthz integration should be enabled (default false) + enabled: false + + # The port to expose the webserver on. Defaults to 8080. + port: 8080 + + # The address to listen for requests on. Defaults to all addresses. + address: "0.0.0.0" + + # The path to expose the monitoring endpoint at. Defaults to `/healthz` + endpoint: "/healthz" + + # The HTTP status code which reports that the bot is healthy/ready to + # process requests. Typically this should not be changed. Defaults to + # 200. + healthyStatus: 200 + + # The HTTP status code which reports that the bot is not healthy/ready. + # Defaults to 418. + unhealthyStatus: 418 diff --git a/roles/matrix-bot-mjolnir/templates/systemd/matrix-bot-mjolnir.service.j2 b/roles/matrix-bot-mjolnir/templates/systemd/matrix-bot-mjolnir.service.j2 new file mode 100644 index 00000000..0b018f25 --- /dev/null +++ b/roles/matrix-bot-mjolnir/templates/systemd/matrix-bot-mjolnir.service.j2 @@ -0,0 +1,42 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix Mjolnir bot +{% for service in matrix_bot_mjolnir_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_bot_mjolnir_systemd_required_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ matrix_systemd_unit_home_path }}" +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-bot-mjolnir 2>/dev/null' +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-bot-mjolnir 2>/dev/null' + +# Intentional delay, so that the homeserver (we likely depend on) can manage to start. +ExecStartPre={{ matrix_host_command_sleep }} 5 + +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-bot-mjolnir \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --network={{ matrix_docker_network }} \ + --mount type=bind,src={{ matrix_bot_mjolnir_config_path }},dst=/data/config,ro \ + --mount type=bind,src={{ matrix_bot_mjolnir_data_path }},dst=/data \ + {% for arg in matrix_bot_mjolnir_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_bot_mjolnir_docker_image }} + +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-bot-mjolnir 2>/dev/null' +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-bot-mjolnir 2>/dev/null' +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-bot-mjolnir + +[Install] +WantedBy=multi-user.target diff --git a/roles/matrix-bridge-appservice-discord/defaults/main.yml b/roles/matrix-bridge-appservice-discord/defaults/main.yml index c7cdddb6..9b9284dc 100644 --- a/roles/matrix-bridge-appservice-discord/defaults/main.yml +++ b/roles/matrix-bridge-appservice-discord/defaults/main.yml @@ -3,7 +3,8 @@ matrix_appservice_discord_enabled: true -matrix_appservice_discord_docker_image: "docker.io/halfshot/matrix-appservice-discord:v1.0.0" +matrix_appservice_discord_version: v1.0.0 +matrix_appservice_discord_docker_image: "{{ matrix_container_global_registry_prefix }}halfshot/matrix-appservice-discord:{{ matrix_appservice_discord_version }}" 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" diff --git a/roles/matrix-bridge-appservice-irc/defaults/main.yml b/roles/matrix-bridge-appservice-irc/defaults/main.yml index ead4e8de..410299b7 100644 --- a/roles/matrix-bridge-appservice-irc/defaults/main.yml +++ b/roles/matrix-bridge-appservice-irc/defaults/main.yml @@ -7,7 +7,8 @@ matrix_appservice_irc_container_self_build: false matrix_appservice_irc_docker_repo: "https://github.com/matrix-org/matrix-appservice-irc.git" matrix_appservice_irc_docker_src_files_path: "{{ matrix_base_data_path }}/appservice-irc/docker-src" -matrix_appservice_irc_docker_image: "docker.io/matrixdotorg/matrix-appservice-irc:release-0.23.0" +matrix_appservice_irc_version: release-0.25.0 +matrix_appservice_irc_docker_image: "{{ matrix_container_global_registry_prefix }}matrixdotorg/matrix-appservice-irc:{{ matrix_appservice_irc_version }}" 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" diff --git a/roles/matrix-bridge-appservice-irc/tasks/init.yml b/roles/matrix-bridge-appservice-irc/tasks/init.yml index ddf1b031..b9a58e00 100644 --- a/roles/matrix-bridge-appservice-irc/tasks/init.yml +++ b/roles/matrix-bridge-appservice-irc/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_appservice_irc_container_self_build" + # If the matrix-synapse role is not used, `matrix_synapse_role_executed` won't exist. # We don't want to fail in such cases. - name: Fail if matrix-synapse role already executed diff --git a/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml b/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml index 09e1d4ba..75af882a 100644 --- a/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml +++ b/roles/matrix-bridge-appservice-irc/tasks/setup_install.yml @@ -71,11 +71,12 @@ register: matrix_appservice_irc_git_pull_results when: "matrix_appservice_irc_enabled|bool and matrix_appservice_irc_container_self_build|bool" -- name: Ensure matrix-appservice-irc Docker image is build +- name: Ensure matrix-appservice-irc Docker image is built docker_image: name: "{{ matrix_appservice_irc_docker_image }}" source: build - force_source: yes + force_source: "{{ matrix_appservice_irc_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_appservice_irc_docker_src_files_path }}" diff --git a/roles/matrix-bridge-appservice-slack/defaults/main.yml b/roles/matrix-bridge-appservice-slack/defaults/main.yml index 997cfa5e..bb801273 100644 --- a/roles/matrix-bridge-appservice-slack/defaults/main.yml +++ b/roles/matrix-bridge-appservice-slack/defaults/main.yml @@ -7,7 +7,8 @@ matrix_appservice_slack_container_self_build: false matrix_appservice_slack_docker_repo: "https://github.com/matrix-org/matrix-appservice-slack.git" matrix_appservice_slack_docker_src_files_path: "{{ matrix_base_data_path }}/appservice-slack/docker-src" -matrix_appservice_slack_docker_image: "docker.io/matrixdotorg/matrix-appservice-slack:release-1.5.0" +matrix_appservice_slack_version: release-1.5.0 +matrix_appservice_slack_docker_image: "{{ matrix_container_global_registry_prefix }}matrixdotorg/matrix-appservice-slack:{{ matrix_appservice_slack_version }}" 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" @@ -31,7 +32,7 @@ matrix_appservice_slack_slack_port: 9003 # Takes an ":" or "" value (e.g. "127.0.0.1:9999"), or empty string to not expose. matrix_appservice_slack_container_http_host_bind_port: '' -matrix_appservice_slack_homeserver_media_url: "matrix.{{ matrix_domain }}" +matrix_appservice_slack_homeserver_media_url: "{{ matrix_server_fqn_matrix }}" matrix_appservice_slack_homeserver_url: "http://matrix-synapse:8008" matrix_appservice_slack_homeserver_domain: "{{ matrix_domain }}" matrix_appservice_slack_appservice_url: 'http://matrix-appservice-slack' diff --git a/roles/matrix-bridge-appservice-slack/tasks/init.yml b/roles/matrix-bridge-appservice-slack/tasks/init.yml index 045b6b73..6a1bf869 100644 --- a/roles/matrix-bridge-appservice-slack/tasks/init.yml +++ b/roles/matrix-bridge-appservice-slack/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_appservice_slack_container_self_build" + # If the matrix-synapse role is not used, `matrix_synapse_role_executed` won't exist. # We don't want to fail in such cases. - name: Fail if matrix-synapse role already executed diff --git a/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml b/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml index 703d3fab..b170fcb8 100644 --- a/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml +++ b/roles/matrix-bridge-appservice-slack/tasks/setup_install.yml @@ -51,7 +51,8 @@ docker_image: name: "{{ matrix_appservice_slack_docker_image }}" source: build - force_source: yes + force_source: "{{ matrix_appservice_slack_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_appservice_slack_docker_src_files_path }}" diff --git a/roles/matrix-bridge-appservice-webhooks/defaults/main.yml b/roles/matrix-bridge-appservice-webhooks/defaults/main.yml index e668f918..7f26ea58 100644 --- a/roles/matrix-bridge-appservice-webhooks/defaults/main.yml +++ b/roles/matrix-bridge-appservice-webhooks/defaults/main.yml @@ -3,7 +3,8 @@ matrix_appservice_webhooks_enabled: true -matrix_appservice_webhooks_docker_image: "docker.io/turt2live/matrix-appservice-webhooks:latest" +matrix_appservice_webhooks_version: latest +matrix_appservice_webhooks_docker_image: "{{ matrix_container_global_registry_prefix }}turt2live/matrix-appservice-webhooks:{{ matrix_appservice_webhooks_version }}" 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" @@ -27,7 +28,7 @@ matrix_appservice_webhooks_matrix_port: 6789 # Takes an ":" or "" value (e.g. "127.0.0.1:9999"), or empty string to not expose. matrix_appservice_webhooks_container_http_host_bind_port: '' -matrix_appservice_webhooks_homeserver_media_url: "matrix.{{ matrix_domain }}" +matrix_appservice_webhooks_homeserver_media_url: "{{ matrix_server_fqn_matrix }}" matrix_appservice_webhooks_homeserver_url: "http://matrix-synapse:8008" matrix_appservice_webhooks_homeserver_domain: "{{ matrix_domain }}" matrix_appservice_webhooks_appservice_url: 'http://matrix-appservice-webhooks' diff --git a/roles/matrix-bridge-appservice-webhooks/tasks/init.yml b/roles/matrix-bridge-appservice-webhooks/tasks/init.yml index 53e2cce8..a42e14c9 100644 --- a/roles/matrix-bridge-appservice-webhooks/tasks/init.yml +++ b/roles/matrix-bridge-appservice-webhooks/tasks/init.yml @@ -44,16 +44,19 @@ - name: Generate Matrix Appservice webhooks proxying configuration for matrix-nginx-proxy set_fact: matrix_appservice_webhooks_matrix_nginx_proxy_configuration: | - location {{ matrix_appservice_webhooks_public_endpoint }}/ { {% if matrix_nginx_proxy_enabled|default(False) %} {# Use the embedded DNS resolver in Docker containers to discover the service #} + location ~ ^{{ matrix_appservice_webhooks_public_endpoint }}/(.*)$ { resolver 127.0.0.11 valid=5s; - proxy_pass {{ matrix_appservice_webhooks_appservice_url }}:{{ matrix_appservice_webhooks_matrix_port }}/; + set $backend "matrix-appservice-webhooks:{{ matrix_appservice_webhooks_matrix_port }}"; + proxy_pass http://$backend/$1; + } {% else %} - {# Generic configuration for use outside of our container setup #} + {# Generic configuration for use outside of our container setup #} + location {{ matrix_appservice_webhooks_public_endpoint }}/ { proxy_pass http://127.0.0.1:{{ matrix_appservice_webhooks_matrix_port }}/; - {% endif %} } + {% endif %} - name: Register webhooks Appservice proxying configuration with matrix-nginx-proxy set_fact: diff --git a/roles/matrix-bridge-heisenbridge/defaults/main.yml b/roles/matrix-bridge-heisenbridge/defaults/main.yml new file mode 100644 index 00000000..be95af8d --- /dev/null +++ b/roles/matrix-bridge-heisenbridge/defaults/main.yml @@ -0,0 +1,47 @@ +# heisenbridge is a bouncer-style Matrix IRC bridge +# See: https://github.com/hifi/heisenbridge + +matrix_heisenbridge_enabled: true + +matrix_heisenbridge_version: latest +matrix_heisenbridge_docker_image: "{{ matrix_container_global_registry_prefix }}hif1/heisenbridge:{{ matrix_heisenbridge_version }}" +matrix_heisenbridge_docker_image_force_pull: "{{ matrix_heisenbridge_docker_image.endswith(':latest') }}" + +# Set this to your Matrix ID if you want to enforce the owner, otherwise first _local_ user becomes one +matrix_heisenbridge_owner: "" + +# Enabling identd will bind to host port 113/TCP +matrix_heisenbridge_identd_enabled: false + +matrix_heisenbridge_base_path: "{{ matrix_base_data_path }}/heisenbridge" + +# A list of extra arguments to pass to the container +matrix_heisenbridge_container_extra_arguments: [] + +# List of systemd services that service depends on. +matrix_heisenbridge_systemd_required_services_list: ['docker.service'] + +# List of systemd services that service wants +matrix_heisenbridge_systemd_wanted_services_list: [] + +matrix_heisenbridge_homeserver_url: "{{ matrix_homeserver_container_url }}" + +matrix_heisenbridge_appservice_token: '' +matrix_heisenbridge_homeserver_token: '' + +# Default registration file +matrix_heisenbridge_registration_yaml: + id: heisenbridge + url: http://matrix-heisenbridge:9898 + as_token: "{{ matrix_heisenbridge_appservice_token }}" + hs_token: "{{ matrix_heisenbridge_homeserver_token }}" + rate_limited: false + sender_localpart: heisenbridge + namespaces: + users: + - regex: '@hbirc_.*' + exclusive: true + aliases: [] + rooms: [] + +matrix_heisenbridge_registration: "{{ matrix_heisenbridge_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-heisenbridge/tasks/init.yml b/roles/matrix-bridge-heisenbridge/tasks/init.yml new file mode 100644 index 00000000..18e89b68 --- /dev/null +++ b/roles/matrix-bridge-heisenbridge/tasks/init.yml @@ -0,0 +1,24 @@ +# If the matrix-synapse role is not used, `matrix_synapse_role_executed` won't exist. +# We don't want to fail in such cases. +- name: Fail if matrix-synapse role already executed + fail: + msg: >- + The matrix-bridge-heisenbridge role needs to execute before the matrix-synapse role. + when: "matrix_heisenbridge_enabled and matrix_synapse_role_executed|default(False)" + +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-heisenbridge.service'] }}" + when: matrix_heisenbridge_enabled|bool + +# If the matrix-synapse role is not used, these variables may not exist. +- set_fact: + matrix_synapse_container_extra_arguments: > + {{ matrix_synapse_container_extra_arguments|default([]) }} + + + ["--mount type=bind,src={{ matrix_heisenbridge_base_path }}/registration.yaml,dst=/heisenbridge-registration.yaml,ro"] + + matrix_synapse_app_service_config_files: > + {{ matrix_synapse_app_service_config_files|default([]) }} + + + {{ ["/heisenbridge-registration.yaml"] }} + when: matrix_heisenbridge_enabled|bool diff --git a/roles/matrix-bridge-heisenbridge/tasks/main.yml b/roles/matrix-bridge-heisenbridge/tasks/main.yml new file mode 100644 index 00000000..1358709d --- /dev/null +++ b/roles/matrix-bridge-heisenbridge/tasks/main.yml @@ -0,0 +1,15 @@ +- import_tasks: "{{ role_path }}/tasks/init.yml" + tags: + - always + +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: "run_setup|bool and matrix_heisenbridge_enabled|bool" + tags: + - setup-all + - setup-heisenbridge + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: "run_setup|bool and not matrix_heisenbridge_enabled|bool" + tags: + - setup-all + - setup-heisenbridge diff --git a/roles/matrix-bridge-heisenbridge/tasks/setup_install.yml b/roles/matrix-bridge-heisenbridge/tasks/setup_install.yml new file mode 100644 index 00000000..03cf9ec3 --- /dev/null +++ b/roles/matrix-bridge-heisenbridge/tasks/setup_install.yml @@ -0,0 +1,38 @@ +--- + +- name: Ensure heisenbridge image is pulled + docker_image: + name: "{{ matrix_heisenbridge_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_heisenbridge_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_heisenbridge_docker_image_force_pull }}" + +- name: Ensure heisenbridge paths exist + file: + path: "{{ item }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - "{{ matrix_heisenbridge_base_path }}" + +- name: Ensure heisenbridge registration.yaml installed if provided + copy: + content: "{{ matrix_heisenbridge_registration|to_nice_yaml }}" + dest: "{{ matrix_heisenbridge_base_path }}/registration.yaml" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + +- name: Ensure matrix-heisenbridge.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-heisenbridge.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-heisenbridge.service" + mode: 0644 + register: matrix_heisenbridge_systemd_service_result + +- name: Ensure systemd reloaded after matrix-heisenbridge.service installation + service: + daemon_reload: yes + when: matrix_heisenbridge_systemd_service_result.changed diff --git a/roles/matrix-bridge-heisenbridge/tasks/setup_uninstall.yml b/roles/matrix-bridge-heisenbridge/tasks/setup_uninstall.yml new file mode 100644 index 00000000..d5526f8a --- /dev/null +++ b/roles/matrix-bridge-heisenbridge/tasks/setup_uninstall.yml @@ -0,0 +1,24 @@ +--- + +- name: Check existence of matrix-heisenbridge service + stat: + path: "{{ matrix_systemd_path }}/matrix-heisenbridge.service" + register: matrix_heisenbridge_service_stat + +- name: Ensure matrix-heisenbridge is stopped + service: + name: heisenbridge + state: stopped + daemon_reload: yes + when: "matrix_heisenbridge_service_stat.stat.exists" + +- name: Ensure matrix-heisenbridge.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-heisenbridge.service" + state: absent + when: "matrix_heisenbridge_service_stat.stat.exists" + +- name: Ensure systemd reloaded after matrix-heisenbridge.service removal + service: + daemon_reload: yes + when: "matrix_heisenbridge_service_stat.stat.exists" diff --git a/roles/matrix-bridge-heisenbridge/templates/systemd/matrix-heisenbridge.service.j2 b/roles/matrix-bridge-heisenbridge/templates/systemd/matrix-heisenbridge.service.j2 new file mode 100644 index 00000000..91ba39b3 --- /dev/null +++ b/roles/matrix-bridge-heisenbridge/templates/systemd/matrix-heisenbridge.service.j2 @@ -0,0 +1,50 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=a bouncer-style Matrix IRC bridge +{% for service in matrix_heisenbridge_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_heisenbridge_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ matrix_systemd_unit_home_path }}" +ExecStartPre=-{{ matrix_host_command_docker }} kill matrix-heisenbridge +ExecStartPre=-{{ matrix_host_command_docker }} rm matrix-heisenbridge + +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-heisenbridge \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --network={{ matrix_docker_network }} \ + {% if matrix_heisenbridge_identd_enabled %} + -p 113:113 \ + {% endif %} + -v {{ matrix_heisenbridge_base_path }}:/config:z \ + {% for arg in matrix_heisenbridge_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_heisenbridge_docker_image }} \ + {% if matrix_heisenbridge_identd_enabled %} + --identd \ + {% endif %} + {% if matrix_heisenbridge_owner %} + -o {{ matrix_heisenbridge_owner }} \ + {% endif %} + --config /config/registration.yaml \ + --listen-address 0.0.0.0 \ + --listen-port 9898 \ + {{ matrix_heisenbridge_homeserver_url }} + +ExecStop=-{{ matrix_host_command_docker }} kill matrix-heisenbridge +ExecStop=-{{ matrix_host_command_docker }} rm matrix-heisenbridge +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-heisenbridge + +[Install] +WantedBy=multi-user.target diff --git a/roles/matrix-bridge-mautrix-facebook/defaults/main.yml b/roles/matrix-bridge-mautrix-facebook/defaults/main.yml index acd3ee58..71a225f7 100644 --- a/roles/matrix-bridge-mautrix-facebook/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-facebook/defaults/main.yml @@ -6,8 +6,9 @@ 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" +matrix_mautrix_facebook_version: latest # See: https://mau.dev/tulir/mautrix-facebook/container_registry -matrix_mautrix_facebook_docker_image: "{{ matrix_mautrix_facebook_docker_image_name_prefix }}tulir/mautrix-facebook:latest" +matrix_mautrix_facebook_docker_image: "{{ matrix_mautrix_facebook_docker_image_name_prefix }}tulir/mautrix-facebook:{{ matrix_mautrix_facebook_version }}" 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') }}" @@ -109,5 +110,6 @@ matrix_mautrix_facebook_registration_yaml: | # See https://github.com/tulir/mautrix-signal/issues/43 sender_localpart: _bot_{{ matrix_mautrix_facebook_appservice_bot_username }} rate_limited: false + de.sorunome.msc2409.push_ephemeral: true matrix_mautrix_facebook_registration: "{{ matrix_mautrix_facebook_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mautrix-facebook/tasks/init.yml b/roles/matrix-bridge-mautrix-facebook/tasks/init.yml index 9e127316..83e54cb4 100644 --- a/roles/matrix-bridge-mautrix-facebook/tasks/init.yml +++ b/roles/matrix-bridge-mautrix-facebook/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mautrix_facebook_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mautrix-facebook.service'] }}" when: matrix_mautrix_facebook_enabled|bool @@ -16,7 +23,7 @@ when: matrix_mautrix_facebook_enabled|bool # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Mautrix Facebook image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." diff --git a/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml index 59998463..4cfbde9e 100644 --- a/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-facebook/tasks/setup_install.yml @@ -69,7 +69,8 @@ docker_image: name: "{{ matrix_mautrix_facebook_docker_image }}" source: build - force_source: "{{ matrix_mautrix_facebook_git_pull_results.changed }}" + force_source: "{{ matrix_mautrix_facebook_git_pull_results.changed 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_mautrix_facebook_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mautrix_facebook_docker_src_files_path }}" 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 acd2c885..f3af4b9f 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 @@ -16,20 +16,6 @@ Environment="HOME={{ matrix_systemd_unit_home_path }}" ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-mautrix-facebook 2>/dev/null' ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-mautrix-facebook 2>/dev/null' -# This bridge uses another mechanism for migrations now (migrations happen automatically during regular startup), -# so going forward, running this alembic stuff will not necessary. -# People who are upgrading from an older version of the bridge should go through this migration -# first though, so we're keeping it around for now. -ExecStartPre={{ matrix_host_command_docker }} run --rm --name matrix-mautrix-facebook-db \ - --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 }} \ - alembic -x config=/config/config.yaml upgrade head - # Intentional delay, so that the homeserver (we likely depend on) can manage to start. ExecStartPre={{ matrix_host_command_sleep }} 5 diff --git a/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml b/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml index 0ed519cd..48b66b8d 100644 --- a/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-hangouts/defaults/main.yml @@ -6,8 +6,9 @@ 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" +matrix_mautrix_hangouts_version: latest # See: https://mau.dev/tulir/mautrix-hangouts/container_registry -matrix_mautrix_hangouts_docker_image: "{{ matrix_mautrix_hangouts_docker_image_name_prefix }}tulir/mautrix-hangouts:latest" +matrix_mautrix_hangouts_docker_image: "{{ matrix_mautrix_hangouts_docker_image_name_prefix }}tulir/mautrix-hangouts:{{ matrix_mautrix_hangouts_version }}" 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') }}" @@ -109,5 +110,6 @@ matrix_mautrix_hangouts_registration_yaml: | # See https://github.com/tulir/mautrix-signal/issues/43 sender_localpart: _bot_{{ matrix_mautrix_hangouts_appservice_bot_username }} rate_limited: false + de.sorunome.msc2409.push_ephemeral: true matrix_mautrix_hangouts_registration: "{{ matrix_mautrix_hangouts_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mautrix-hangouts/tasks/init.yml b/roles/matrix-bridge-mautrix-hangouts/tasks/init.yml index 9209fa40..07fb254d 100644 --- a/roles/matrix-bridge-mautrix-hangouts/tasks/init.yml +++ b/roles/matrix-bridge-mautrix-hangouts/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mautrix_hangouts_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mautrix-hangouts.service'] }}" when: matrix_mautrix_hangouts_enabled|bool @@ -62,7 +69,7 @@ when: "matrix_mautrix_hangouts_enabled|bool and (matrix_nginx_proxy_enabled is not defined or matrix_nginx_proxy_enabled|bool == false)" # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Mautrix Hangouts image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." diff --git a/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml index 2ce8a441..14ae255f 100644 --- a/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-hangouts/tasks/setup_install.yml @@ -68,7 +68,8 @@ docker_image: name: "{{ matrix_mautrix_hangouts_docker_image }}" source: build - force_source: "{{ matrix_mautrix_hangouts_git_pull_results.changed }}" + force_source: "{{ matrix_mautrix_hangouts_git_pull_results.changed 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_mautrix_hangouts_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mautrix_hangouts_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mautrix-instagram/defaults/main.yml b/roles/matrix-bridge-mautrix-instagram/defaults/main.yml index 411ec7ed..5204386d 100644 --- a/roles/matrix-bridge-mautrix-instagram/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-instagram/defaults/main.yml @@ -6,8 +6,9 @@ matrix_mautrix_instagram_enabled: true matrix_mautrix_instagram_container_image_self_build: false matrix_mautrix_instagram_container_image_self_build_repo: "https://github.com/tulir/mautrix-instagram.git" +matrix_mautrix_instagram_version: latest # See: https://mau.dev/tulir/mautrix-instagram/container_registry -matrix_mautrix_instagram_docker_image: "{{ matrix_mautrix_instagram_docker_image_name_prefix }}tulir/mautrix-instagram:latest" +matrix_mautrix_instagram_docker_image: "{{ matrix_mautrix_instagram_docker_image_name_prefix }}tulir/mautrix-instagram:{{ matrix_mautrix_instagram_version }}" matrix_mautrix_instagram_docker_image_name_prefix: "{{ 'localhost/' if matrix_mautrix_instagram_container_image_self_build else 'dock.mau.dev/' }}" matrix_mautrix_instagram_docker_image_force_pull: "{{ matrix_mautrix_instagram_docker_image.endswith(':latest') }}" @@ -16,7 +17,7 @@ matrix_mautrix_instagram_config_path: "{{ matrix_mautrix_instagram_base_path }}/ matrix_mautrix_instagram_data_path: "{{ matrix_mautrix_instagram_base_path }}/data" matrix_mautrix_instagram_docker_src_files_path: "{{ matrix_mautrix_instagram_base_path }}/docker-src" -matrix_mautrix_instagram_homeserver_address: 'http://matrix-synapse:8008' +matrix_mautrix_instagram_homeserver_address: "{{ matrix_homeserver_container_url }}" matrix_mautrix_instagram_homeserver_domain: '{{ matrix_domain }}' matrix_mautrix_instagram_appservice_address: 'http://matrix-mautrix-instagram:29330' @@ -34,7 +35,7 @@ matrix_mautrix_instagram_homeserver_token: '' # Database-related configuration fields. -# +# # To use Postgres: # - adjust your database credentials via the `matrix_mautrix_instagram_postgres_*` variables matrix_mautrix_instagram_database_engine: 'postgres' @@ -99,5 +100,6 @@ matrix_mautrix_instagram_registration_yaml: | # See https://github.com/tulir/mautrix-signal/issues/43 sender_localpart: _bot_{{ matrix_mautrix_instagram_appservice_bot_username }} rate_limited: false + de.sorunome.msc2409.push_ephemeral: true matrix_mautrix_instagram_registration: "{{ matrix_mautrix_instagram_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mautrix-instagram/tasks/init.yml b/roles/matrix-bridge-mautrix-instagram/tasks/init.yml index 2b407358..6944003e 100644 --- a/roles/matrix-bridge-mautrix-instagram/tasks/init.yml +++ b/roles/matrix-bridge-mautrix-instagram/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mautrix_instagram_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mautrix-instagram.service'] }}" when: matrix_mautrix_instagram_enabled|bool @@ -16,7 +23,7 @@ when: matrix_mautrix_instagram_enabled|bool # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Mautrix instagram image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." diff --git a/roles/matrix-bridge-mautrix-instagram/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-instagram/tasks/setup_install.yml index b83deab3..60474230 100644 --- a/roles/matrix-bridge-mautrix-instagram/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-instagram/tasks/setup_install.yml @@ -44,7 +44,8 @@ docker_image: name: "{{ matrix_mautrix_instagram_docker_image }}" source: build - force_source: "{{ matrix_mautrix_instagram_git_pull_results.changed }}" + force_source: "{{ matrix_mautrix_instagram_git_pull_results.changed 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_mautrix_instagram_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mautrix_instagram_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mautrix-signal/defaults/main.yml b/roles/matrix-bridge-mautrix-signal/defaults/main.yml index aaa0a166..50240548 100644 --- a/roles/matrix-bridge-mautrix-signal/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-signal/defaults/main.yml @@ -3,11 +3,13 @@ matrix_mautrix_signal_enabled: true +matrix_mautrix_signal_version: latest +matrix_mautrix_signal_daemon_version: latest # See: https://mau.dev/tulir/mautrix-signal/container_registry -matrix_mautrix_signal_docker_image: "dock.mau.dev/tulir/mautrix-signal:latest" +matrix_mautrix_signal_docker_image: "dock.mau.dev/tulir/mautrix-signal:{{ matrix_mautrix_signal_version }}" matrix_mautrix_signal_docker_image_force_pull: "{{ matrix_mautrix_signal_docker_image.endswith(':latest') }}" -matrix_mautrix_signal_daemon_docker_image: "dock.mau.dev/maunium/signald:latest" +matrix_mautrix_signal_daemon_docker_image: "dock.mau.dev/maunium/signald:{{ matrix_mautrix_signal_daemon_version }}" matrix_mautrix_signal_daemon_docker_image_force_pull: "{{ matrix_mautrix_signal_daemon_docker_image.endswith(':latest') }}" matrix_mautrix_signal_base_path: "{{ matrix_base_data_path }}/mautrix-signal" diff --git a/roles/matrix-bridge-mautrix-signal/templates/config.yaml.j2 b/roles/matrix-bridge-mautrix-signal/templates/config.yaml.j2 index dc2cff36..ca5060a7 100644 --- a/roles/matrix-bridge-mautrix-signal/templates/config.yaml.j2 +++ b/roles/matrix-bridge-mautrix-signal/templates/config.yaml.j2 @@ -28,6 +28,11 @@ appservice: # The full URI to the database. Only Postgres is currently supported. database: {{ matrix_mautrix_signal_database_connection_string }} + # Additional arguments for asyncpg.create_pool() + # https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.pool.create_pool + database_opts: + min_size: 5 + max_size: 10 # Provisioning API part of the web server for automated portal creation and fetching information. # Used by things like mautrix-manager (https://github.com/tulir/mautrix-manager). @@ -88,9 +93,11 @@ bridge: # available variable in displayname_preference. The variables in displayname_preference # can also be used here directly. displayname_template: "{displayname} (Signal)" - # Whether or not contact list displaynames should be used. - # Using this isn't recommended on multi-user instances. - allow_contact_list_name_updates: false + # Possible values: disallow, allow, prefer + # + # Multi-user instances are recommended to disallow contact list names, as otherwise there can + # be conflicts between names from different users' contact lists. + contact_list_names: disallow # Available variables: full_name, first_name, last_name, phone, uuid displayname_preference: - full_name @@ -123,11 +130,8 @@ bridge: # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. federate_rooms: true - # End-to-bridge encryption support options. These require matrix-nio to be installed with pip - # and login_shared_secret to be configured in order to get a device for the bridge bot. - # - # Additionally, https://github.com/matrix-org/synapse/pull/5758 is required if using a normal - # application service. + # End-to-bridge encryption support options. You must install the e2be optional dependency for + # this to work. See https://github.com/tulir/mautrix-telegram/wiki/End‐to‐bridge-encryption encryption: # Allow encryption, work in group chat rooms with e2ee enabled allow: false diff --git a/roles/matrix-bridge-mautrix-signal/templates/registration.yaml.j2 b/roles/matrix-bridge-mautrix-signal/templates/registration.yaml.j2 index 6891c2b5..54df82da 100644 --- a/roles/matrix-bridge-mautrix-signal/templates/registration.yaml.j2 +++ b/roles/matrix-bridge-mautrix-signal/templates/registration.yaml.j2 @@ -15,3 +15,4 @@ url: {{ matrix_mautrix_signal_appservice_address }} # See https://github.com/tulir/mautrix-signal/issues/43 sender_localpart: _bot_{{ matrix_mautrix_signal_appservice_bot_username }} rate_limited: false +de.sorunome.msc2409.push_ephemeral: true diff --git a/roles/matrix-bridge-mautrix-telegram/defaults/main.yml b/roles/matrix-bridge-mautrix-telegram/defaults/main.yml index b1f1b8fc..e4c7696a 100644 --- a/roles/matrix-bridge-mautrix-telegram/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-telegram/defaults/main.yml @@ -7,8 +7,9 @@ matrix_mautrix_telegram_container_self_build: false matrix_mautrix_telegram_docker_repo: "https://mau.dev/tulir/mautrix-telegram.git" matrix_mautrix_telegram_docker_src_files_path: "{{ matrix_base_data_path }}/mautrix-telegram/docker-src" +matrix_mautrix_telegram_version: v0.9.0 # See: https://mau.dev/tulir/mautrix-telegram/container_registry -matrix_mautrix_telegram_docker_image: "dock.mau.dev/tulir/mautrix-telegram:v0.9.0" +matrix_mautrix_telegram_docker_image: "dock.mau.dev/tulir/mautrix-telegram:{{ matrix_mautrix_telegram_version }}" 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" @@ -120,5 +121,6 @@ matrix_mautrix_telegram_registration_yaml: | sender_localpart: _bot_{{ matrix_mautrix_telegram_appservice_bot_username }} url: {{ matrix_mautrix_telegram_appservice_address }} rate_limited: false + de.sorunome.msc2409.push_ephemeral: true matrix_mautrix_telegram_registration: "{{ matrix_mautrix_telegram_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mautrix-telegram/tasks/init.yml b/roles/matrix-bridge-mautrix-telegram/tasks/init.yml index 721e98da..c8f7f895 100644 --- a/roles/matrix-bridge-mautrix-telegram/tasks/init.yml +++ b/roles/matrix-bridge-mautrix-telegram/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mautrix_telegram_container_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mautrix-telegram.service'] }}" when: matrix_mautrix_telegram_enabled|bool diff --git a/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml b/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml index 04267161..704f0e26 100644 --- a/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml +++ b/roles/matrix-bridge-mautrix-telegram/tasks/setup_install.yml @@ -64,11 +64,12 @@ register: matrix_mautrix_telegram_git_pull_results when: "matrix_mautrix_telegram_container_self_build|bool" -- name: Ensure matrix-mautrix-telegram Docker image is build +- name: Ensure matrix-mautrix-telegram Docker image is built docker_image: name: "{{ matrix_mautrix_telegram_docker_image }}" source: build - force_source: yes + force_source: "{{ matrix_mautrix_telegram_git_pull_results.changed 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_mautrix_telegram_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mautrix_telegram_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml b/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml index 581d47de..f8ae7d87 100644 --- a/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml +++ b/roles/matrix-bridge-mautrix-whatsapp/defaults/main.yml @@ -3,15 +3,16 @@ matrix_mautrix_whatsapp_enabled: true +matrix_mautrix_whatsapp_version: latest # See: https://mau.dev/tulir/mautrix-whatsapp/container_registry -matrix_mautrix_whatsapp_docker_image: "dock.mau.dev/tulir/mautrix-whatsapp:latest" +matrix_mautrix_whatsapp_docker_image: "dock.mau.dev/tulir/mautrix-whatsapp:{{ matrix_mautrix_whatsapp_version }}" matrix_mautrix_whatsapp_docker_image_force_pull: "{{ matrix_mautrix_whatsapp_docker_image.endswith(':latest') }}" matrix_mautrix_whatsapp_base_path: "{{ matrix_base_data_path }}/mautrix-whatsapp" matrix_mautrix_whatsapp_config_path: "{{ matrix_mautrix_whatsapp_base_path }}/config" matrix_mautrix_whatsapp_data_path: "{{ matrix_mautrix_whatsapp_base_path }}/data" -matrix_mautrix_whatsapp_homeserver_address: "http://matrix-synapse:8008" +matrix_mautrix_whatsapp_homeserver_address: "{{ matrix_homeserver_container_url }}" matrix_mautrix_whatsapp_homeserver_domain: "{{ matrix_domain }}" matrix_mautrix_whatsapp_appservice_address: "http://matrix-mautrix-whatsapp:8080" @@ -104,5 +105,6 @@ matrix_mautrix_whatsapp_registration_yaml: | exclusive: true - exclusive: true regex: '^@{{ matrix_mautrix_whatsapp_appservice_bot_username|regex_escape }}:{{ matrix_mautrix_whatsapp_homeserver_domain|regex_escape }}$' + de.sorunome.msc2409.push_ephemeral: true matrix_mautrix_whatsapp_registration: "{{ matrix_mautrix_whatsapp_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml b/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml index 8e278041..e24d35da 100644 --- a/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-discord/defaults/main.yml @@ -11,8 +11,9 @@ matrix_mx_puppet_discord_container_image_self_build_repo: "https://github.com/ma # 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: "{{ 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_version: latest +matrix_mx_puppet_discord_docker_image: "{{ matrix_mx_puppet_discord_docker_image_name_prefix }}sorunome/mx-puppet-discord:{{ matrix_mx_puppet_discord_version }}" +matrix_mx_puppet_discord_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_discord_container_image_self_build else matrix_container_global_registry_prefix }}" 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" @@ -108,5 +109,6 @@ matrix_mx_puppet_discord_registration_yaml: | rate_limited: false sender_localpart: _discordpuppet_bot url: {{ matrix_mx_puppet_discord_appservice_address }} + de.sorunome.msc2409.push_ephemeral: true matrix_mx_puppet_discord_registration: "{{ matrix_mx_puppet_discord_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-discord/tasks/init.yml b/roles/matrix-bridge-mx-puppet-discord/tasks/init.yml index 4d8444e1..983e3895 100644 --- a/roles/matrix-bridge-mx-puppet-discord/tasks/init.yml +++ b/roles/matrix-bridge-mx-puppet-discord/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mx_puppet_discord_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mx-puppet-discord.service'] }}" when: matrix_mx_puppet_discord_enabled|bool @@ -16,7 +23,7 @@ when: matrix_mx_puppet_discord_enabled|bool # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Puppet Slack image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." 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 c7865e98..f9985ed8 100644 --- a/roles/matrix-bridge-mx-puppet-discord/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-discord/tasks/setup_install.yml @@ -85,7 +85,8 @@ docker_image: name: "{{ matrix_mx_puppet_discord_docker_image }}" source: build - force_source: "{{ matrix_mx_puppet_discord_git_pull_results.changed }}" + force_source: "{{ matrix_mx_puppet_discord_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_discord_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mx-puppet-groupme/defaults/main.yml b/roles/matrix-bridge-mx-puppet-groupme/defaults/main.yml index c0bafcf0..898768bf 100644 --- a/roles/matrix-bridge-mx-puppet-groupme/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-groupme/defaults/main.yml @@ -11,8 +11,9 @@ matrix_mx_puppet_groupme_container_image_self_build_repo: "https://gitlab.com/ro # Takes an ":" or "" value (e.g. "127.0.0.1:8437"), or empty string to not expose. matrix_mx_puppet_groupme_container_http_host_bind_port: '' -matrix_mx_puppet_groupme_docker_image: "{{ matrix_mx_puppet_groupme_docker_image_name_prefix }}xangelix/mx-puppet-groupme:latest" -matrix_mx_puppet_groupme_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_groupme_container_image_self_build else 'docker.io/' }}" +matrix_mx_puppet_groupme_version: latest +matrix_mx_puppet_groupme_docker_image: "{{ matrix_mx_puppet_groupme_docker_image_name_prefix }}xangelix/mx-puppet-groupme:{{ matrix_mx_puppet_groupme_version }}" +matrix_mx_puppet_groupme_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_groupme_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_mx_puppet_groupme_docker_image_force_pull: "{{ matrix_mx_puppet_groupme_docker_image.endswith(':latest') }}" matrix_mx_puppet_groupme_base_path: "{{ matrix_base_data_path }}/mx-puppet-groupme" @@ -22,7 +23,7 @@ matrix_mx_puppet_groupme_docker_src_files_path: "{{ matrix_mx_puppet_groupme_bas matrix_mx_puppet_groupme_appservice_port: "8437" -matrix_mx_puppet_groupme_homeserver_address: 'http://matrix-synapse:8008' +matrix_mx_puppet_groupme_homeserver_address: "{{ matrix_homeserver_container_url }}" matrix_mx_puppet_groupme_homeserver_domain: '{{ matrix_domain }}' matrix_mx_puppet_groupme_appservice_address: 'http://matrix-mx-puppet-groupme:{{ matrix_mx_puppet_groupme_appservice_port }}' @@ -106,5 +107,6 @@ matrix_mx_puppet_groupme_registration_yaml: | rate_limited: false sender_localpart: _groupmepuppet_bot url: {{ matrix_mx_puppet_groupme_appservice_address }} + de.sorunome.msc2409.push_ephemeral: true matrix_mx_puppet_groupme_registration: "{{ matrix_mx_puppet_groupme_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-groupme/tasks/init.yml b/roles/matrix-bridge-mx-puppet-groupme/tasks/init.yml index 1f00e8a5..eb598ecb 100644 --- a/roles/matrix-bridge-mx-puppet-groupme/tasks/init.yml +++ b/roles/matrix-bridge-mx-puppet-groupme/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mx_puppet_groupme_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mx-puppet-groupme.service'] }}" when: matrix_mx_puppet_groupme_enabled|bool @@ -16,7 +23,7 @@ when: matrix_mx_puppet_groupme_enabled|bool # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Puppet Slack image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." diff --git a/roles/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml b/roles/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml index 58fe9485..b1d5f0b5 100644 --- a/roles/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml @@ -85,7 +85,8 @@ docker_image: name: "{{ matrix_mx_puppet_groupme_docker_image }}" source: build - force_source: "{{ matrix_mx_puppet_groupme_git_pull_results.changed }}" + force_source: "{{ matrix_mx_puppet_groupme_git_pull_results.changed 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_groupme_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_groupme_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml b/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml index 4c9fbd98..27210360 100644 --- a/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-instagram/defaults/main.yml @@ -6,8 +6,9 @@ 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: "{{ 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_version: latest +matrix_mx_puppet_instagram_docker_image: "{{ matrix_mx_puppet_instagram_docker_image_name_prefix }}sorunome/mx-puppet-instagram:{{ matrix_mx_puppet_instagram_version }}" +matrix_mx_puppet_instagram_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_instagram_container_image_self_build else matrix_container_global_registry_prefix }}" 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" @@ -97,5 +98,6 @@ matrix_mx_puppet_instagram_registration_yaml: | rate_limited: false sender_localpart: _instagrampuppet_bot url: {{ matrix_mx_puppet_instagram_appservice_address }} + de.sorunome.msc2409.push_ephemeral: true matrix_mx_puppet_instagram_registration: "{{ matrix_mx_puppet_instagram_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-instagram/tasks/init.yml b/roles/matrix-bridge-mx-puppet-instagram/tasks/init.yml index 0d319bc8..2ef99f02 100644 --- a/roles/matrix-bridge-mx-puppet-instagram/tasks/init.yml +++ b/roles/matrix-bridge-mx-puppet-instagram/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mx_puppet_instagram_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mx-puppet-instagram.service'] }}" when: matrix_mx_puppet_instagram_enabled|bool 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 5701a916..cdbaa18e 100644 --- a/roles/matrix-bridge-mx-puppet-instagram/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-instagram/tasks/setup_install.yml @@ -69,7 +69,8 @@ docker_image: name: "{{ matrix_mx_puppet_instagram_docker_image }}" source: build - force_source: "{{ matrix_mx_puppet_instagram_git_pull_results.changed }}" + force_source: "{{ matrix_mx_puppet_instagram_git_pull_results.changed 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_instagram_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_instagram_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml b/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml index 53c8e379..8dcb2faf 100644 --- a/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-skype/defaults/main.yml @@ -6,8 +6,9 @@ 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: "{{ 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_version: latest +matrix_mx_puppet_skype_docker_image: "{{ matrix_mx_puppet_skype_docker_image_name_prefix }}sorunome/mx-puppet-skype:{{ matrix_mx_puppet_skype_version }}" +matrix_mx_puppet_skype_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_skype_container_image_self_build else matrix_container_global_registry_prefix }}" 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" @@ -105,5 +106,6 @@ matrix_mx_puppet_skype_registration_yaml: | rate_limited: false sender_localpart: _skypepuppet_bot url: {{ matrix_mx_puppet_skype_appservice_address }} + de.sorunome.msc2409.push_ephemeral: true matrix_mx_puppet_skype_registration: "{{ matrix_mx_puppet_skype_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-skype/tasks/init.yml b/roles/matrix-bridge-mx-puppet-skype/tasks/init.yml index 605ea492..1bdc4c2b 100644 --- a/roles/matrix-bridge-mx-puppet-skype/tasks/init.yml +++ b/roles/matrix-bridge-mx-puppet-skype/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mx_puppet_skype_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mx-puppet-skype.service'] }}" when: matrix_mx_puppet_skype_enabled|bool @@ -16,7 +23,7 @@ when: matrix_mx_puppet_skype_enabled|bool # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Puppet Skype image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." 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 68a1d7f4..997a6317 100644 --- a/roles/matrix-bridge-mx-puppet-skype/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-skype/tasks/setup_install.yml @@ -85,7 +85,8 @@ docker_image: name: "{{ matrix_mx_puppet_skype_docker_image }}" source: build - force_source: "{{ matrix_mx_puppet_skype_git_pull_results.changed }}" + force_source: "{{ matrix_mx_puppet_skype_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_skype_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml b/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml index b1fb7487..65b295c9 100644 --- a/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-slack/defaults/main.yml @@ -11,8 +11,9 @@ matrix_mx_puppet_slack_container_image_self_build_repo: "https://github.com/Soru # 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: "{{ 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_version: latest +matrix_mx_puppet_slack_docker_image: "{{ matrix_mx_puppet_slack_docker_image_name_prefix }}sorunome/mx-puppet-slack:{{ matrix_mx_puppet_slack_version }}" +matrix_mx_puppet_slack_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_slack_container_image_self_build else matrix_container_global_registry_prefix }}" 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" @@ -109,5 +110,6 @@ matrix_mx_puppet_slack_registration_yaml: | rate_limited: false sender_localpart: _slackpuppet_bot url: {{ matrix_mx_puppet_slack_appservice_address }} + de.sorunome.msc2409.push_ephemeral: true matrix_mx_puppet_slack_registration: "{{ matrix_mx_puppet_slack_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-slack/tasks/init.yml b/roles/matrix-bridge-mx-puppet-slack/tasks/init.yml index 16afef20..de3ffd7c 100644 --- a/roles/matrix-bridge-mx-puppet-slack/tasks/init.yml +++ b/roles/matrix-bridge-mx-puppet-slack/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mx_puppet_slack_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mx-puppet-slack.service'] }}" when: matrix_mx_puppet_slack_enabled|bool @@ -63,7 +70,7 @@ when: "matrix_mx_puppet_slack_enabled|bool and matrix_nginx_proxy_enabled is not defined" # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Puppet Slack image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." 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 04eab20a..d816ceeb 100644 --- a/roles/matrix-bridge-mx-puppet-slack/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-slack/tasks/setup_install.yml @@ -81,7 +81,8 @@ docker_image: name: "{{ matrix_mx_puppet_slack_docker_image }}" source: build - force_source: "{{ matrix_mx_puppet_slack_git_pull_results.changed }}" + force_source: "{{ matrix_mx_puppet_slack_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_slack_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml b/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml index c3ac977e..e4df90a5 100644 --- a/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-steam/defaults/main.yml @@ -11,8 +11,9 @@ matrix_mx_puppet_steam_container_image_self_build_repo: "https://github.com/icew # 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: "{{ 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_version: latest +matrix_mx_puppet_steam_docker_image: "{{ matrix_mx_puppet_steam_docker_image_name_prefix }}icewind1991/mx-puppet-steam:{{ matrix_mx_puppet_steam_version }}" +matrix_mx_puppet_steam_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_steam_container_image_self_build else matrix_container_global_registry_prefix }}" 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" @@ -106,5 +107,6 @@ matrix_mx_puppet_steam_registration_yaml: | rate_limited: false sender_localpart: _steampuppet_bot url: {{ matrix_mx_puppet_steam_appservice_address }} + de.sorunome.msc2409.push_ephemeral: true matrix_mx_puppet_steam_registration: "{{ matrix_mx_puppet_steam_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-steam/tasks/init.yml b/roles/matrix-bridge-mx-puppet-steam/tasks/init.yml index 9687944f..c7b3d67f 100644 --- a/roles/matrix-bridge-mx-puppet-steam/tasks/init.yml +++ b/roles/matrix-bridge-mx-puppet-steam/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mx_puppet_steam_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mx-puppet-steam.service'] }}" when: matrix_mx_puppet_steam_enabled|bool @@ -16,7 +23,7 @@ when: matrix_mx_puppet_steam_enabled|bool # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Puppet Slack image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." 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 6b574656..3bcef36e 100644 --- a/roles/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml @@ -85,7 +85,8 @@ docker_image: name: "{{ matrix_mx_puppet_steam_docker_image }}" source: build - force_source: "{{ matrix_mx_puppet_steam_git_pull_results.changed }}" + force_source: "{{ matrix_mx_puppet_steam_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_steam_docker_src_files_path }}" diff --git a/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml b/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml index d8582e53..0e37d51f 100644 --- a/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml +++ b/roles/matrix-bridge-mx-puppet-twitter/defaults/main.yml @@ -11,8 +11,9 @@ matrix_mx_puppet_twitter_container_image_self_build_repo: "https://github.com/So # 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: "{{ 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_version: latest +matrix_mx_puppet_twitter_docker_image: "{{ matrix_mx_puppet_twitter_docker_image_name_prefix }}sorunome/mx-puppet-twitter:{{ matrix_mx_puppet_twitter_version }}" +matrix_mx_puppet_twitter_docker_image_name_prefix: "{{ 'localhost/' if matrix_mx_puppet_twitter_container_image_self_build else matrix_container_global_registry_prefix }}" 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" @@ -116,5 +117,6 @@ matrix_mx_puppet_twitter_registration_yaml: | rate_limited: false sender_localpart: "{{ matrix_mx_puppet_twitter_bot_localpart }}" url: {{ matrix_mx_puppet_twitter_appservice_address }} + de.sorunome.msc2409.push_ephemeral: true matrix_mx_puppet_twitter_registration: "{{ matrix_mx_puppet_twitter_registration_yaml|from_yaml }}" diff --git a/roles/matrix-bridge-mx-puppet-twitter/tasks/init.yml b/roles/matrix-bridge-mx-puppet-twitter/tasks/init.yml index 86f30237..94fafd90 100644 --- a/roles/matrix-bridge-mx-puppet-twitter/tasks/init.yml +++ b/roles/matrix-bridge-mx-puppet-twitter/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mx_puppet_twitter_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mx-puppet-twitter.service'] }}" when: matrix_mx_puppet_twitter_enabled|bool @@ -63,7 +70,7 @@ when: "matrix_mx_puppet_twitter_enabled|bool and matrix_nginx_proxy_enabled is not defined" # ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here +# for self building it is explicitly needed, so we rather fail here - name: Fail if running on Ansible lower than 2.8 and trying self building fail: msg: "To self build Puppet Twitter image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." 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 1c48c030..5767ed17 100644 --- a/roles/matrix-bridge-mx-puppet-twitter/tasks/setup_install.yml +++ b/roles/matrix-bridge-mx-puppet-twitter/tasks/setup_install.yml @@ -85,7 +85,8 @@ docker_image: name: "{{ matrix_mx_puppet_twitter_docker_image }}" source: build - force_source: "{{ matrix_mx_puppet_twitter_git_pull_results.changed }}" + force_source: "{{ matrix_mx_puppet_twitter_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_mx_puppet_twitter_docker_src_files_path }}" diff --git a/roles/matrix-bridge-sms/defaults/main.yml b/roles/matrix-bridge-sms/defaults/main.yml index 3c6b4c61..55f99101 100644 --- a/roles/matrix-bridge-sms/defaults/main.yml +++ b/roles/matrix-bridge-sms/defaults/main.yml @@ -3,7 +3,8 @@ matrix_sms_bridge_enabled: true -matrix_sms_bridge_docker_image: "docker.io/folivonet/matrix-sms-bridge:0.5.5" +matrix_sms_bridge_version: 0.5.7 +matrix_sms_bridge_docker_image: "{{ matrix_container_global_registry_prefix }}folivonet/matrix-sms-bridge:{{ matrix_sms_bridge_version }}" 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" diff --git a/roles/matrix-client-element/defaults/main.yml b/roles/matrix-client-element/defaults/main.yml index db2e7945..c2a546c6 100644 --- a/roles/matrix-client-element/defaults/main.yml +++ b/roles/matrix-client-element/defaults/main.yml @@ -3,8 +3,9 @@ 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: "{{ matrix_client_element_docker_image_name_prefix }}vectorim/element-web:v1.7.21" -matrix_client_element_docker_image_name_prefix: "{{ 'localhost/' if matrix_client_element_container_image_self_build else 'docker.io/' }}" +matrix_client_element_version: v1.7.28 +matrix_client_element_docker_image: "{{ matrix_client_element_docker_image_name_prefix }}vectorim/element-web:{{ matrix_client_element_version }}" +matrix_client_element_docker_image_name_prefix: "{{ 'localhost/' if matrix_client_element_container_image_self_build else matrix_container_global_registry_prefix }}" 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/init.yml b/roles/matrix-client-element/tasks/init.yml index a42e3143..102cae38 100644 --- a/roles/matrix-client-element/tasks/init.yml +++ b/roles/matrix-client-element/tasks/init.yml @@ -2,9 +2,9 @@ matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-client-element.service'] }}" when: matrix_client_element_enabled|bool -# ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here -- name: Fail if running on Ansible lower than 2.8 and trying self building +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 fail: - msg: "To self build the Element image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_client_element_container_image_self_build" diff --git a/roles/matrix-client-element/tasks/setup.yml b/roles/matrix-client-element/tasks/setup.yml index c4ed0847..117a09f4 100644 --- a/roles/matrix-client-element/tasks/setup.yml +++ b/roles/matrix-client-element/tasks/setup.yml @@ -37,7 +37,8 @@ docker_image: name: "{{ matrix_client_element_docker_image }}" source: build - force_source: "{{ matrix_client_element_git_pull_results.changed }}" + force_source: "{{ matrix_client_element_git_pull_results.changed 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_client_element_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_client_element_docker_src_files_path }}" diff --git a/roles/matrix-client-hydrogen/defaults/main.yml b/roles/matrix-client-hydrogen/defaults/main.yml new file mode 100644 index 00000000..f7a3059e --- /dev/null +++ b/roles/matrix-client-hydrogen/defaults/main.yml @@ -0,0 +1,68 @@ +matrix_client_hydrogen_enabled: true + +# Self building is used by default because the `config.json` file is only read at build time. +# The pre-built images also were not functional as of 2021-05-15. +matrix_client_hydrogen_container_image_self_build: true +matrix_client_hydrogen_container_image_self_build_repo: "https://github.com/vector-im/hydrogen-web.git" + +matrix_client_hydrogen_version: v0.1.53 +matrix_client_hydrogen_docker_image: "{{ matrix_client_hydrogen_docker_image_name_prefix }}vectorim/hydrogen-web:{{ matrix_client_hydrogen_version }}" +matrix_client_hydrogen_docker_image_name_prefix: "{{ 'localhost/' if matrix_client_hydrogen_container_image_self_build }}" +matrix_client_hydrogen_docker_image_force_pull: "{{ matrix_client_hydrogen_docker_image.endswith(':latest') }}" + +matrix_client_hydrogen_data_path: "{{ matrix_base_data_path }}/client-hydrogen" +matrix_client_hydrogen_docker_src_files_path: "{{ matrix_client_hydrogen_data_path }}/docker-src" + +# Controls whether the container exposes its HTTP port (tcp/8080 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:8768"), or empty string to not expose. +matrix_client_hydrogen_container_http_host_bind_port: '' + +# A list of extra arguments to pass to the container +matrix_client_hydrogen_container_extra_arguments: [] + +# List of systemd services that matrix-client-hydrogen.service depends on +matrix_client_hydrogen_systemd_required_services_list: ['docker.service'] + +# Controls whether the self-check feature should validate SSL certificates. +matrix_client_hydrogen_self_check_validate_certificates: true + +# config.json +matrix_client_hydrogen_default_hs_url: "" + +# Default Hydrogen configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_client_hydrogen_configuration_extension_json`) +# or completely replace this variable with your own template. +# +# The side-effect of this lookup is that Ansible would even parse the JSON for us, returning a dict. +# This is unlike what it does when looking up YAML template files (no automatic parsing there). +matrix_client_hydrogen_configuration_default: "{{ lookup('template', 'templates/config.json.j2') }}" + +# Your custom JSON configuration for Hydrogen should go to `matrix_client_hydrogen_configuration_extension_json`. +# This configuration extends the default starting configuration (`matrix_client_hydrogen_configuration_default`). +# +# You can override individual variables from the default configuration, or introduce new ones. +# +# If you need something more special, you can take full control by +# completely redefining `matrix_client_hydrogen_configuration_default`. +# +# Example configuration extension follows: +# +# matrix_client_hydrogen_configuration_extension_json: | +# { +# "push": { +# "appId": "io.element.hydrogen.web", +# "gatewayUrl": "https://matrix.org", +# "applicationServerKey": "BC-gpSdVHEXhvHSHS0AzzWrQoukv2BE7KzpoPO_FfPacqOo3l1pdqz7rSgmB04pZCWaHPz7XRe6fjLaC-WPDopM" +# }, +# "defaultHomeServer": "matrix.org" +# } +matrix_client_hydrogen_configuration_extension_json: '{}' + +matrix_client_hydrogen_configuration_extension: "{{ matrix_client_hydrogen_configuration_extension_json|from_json if matrix_client_hydrogen_configuration_extension_json|from_json is mapping else {} }}" + +# Holds the final Hydrogen configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_client_hydrogen_configuration_default`. +matrix_client_hydrogen_configuration: "{{ matrix_client_hydrogen_configuration_default|combine(matrix_client_hydrogen_configuration_extension, recursive=True) }}" diff --git a/roles/matrix-client-hydrogen/tasks/init.yml b/roles/matrix-client-hydrogen/tasks/init.yml new file mode 100644 index 00000000..1115f63d --- /dev/null +++ b/roles/matrix-client-hydrogen/tasks/init.yml @@ -0,0 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Hydrogen image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_client_hydrogen_container_image_self_build" + +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-client-hydrogen.service'] }}" + when: matrix_client_hydrogen_enabled|bool diff --git a/roles/matrix-client-hydrogen/tasks/main.yml b/roles/matrix-client-hydrogen/tasks/main.yml new file mode 100644 index 00000000..6534db05 --- /dev/null +++ b/roles/matrix-client-hydrogen/tasks/main.yml @@ -0,0 +1,15 @@ +- import_tasks: "{{ role_path }}/tasks/init.yml" + tags: + - always + +- import_tasks: "{{ role_path }}/tasks/validate_config.yml" + when: "run_setup|bool and matrix_client_hydrogen_enabled|bool" + tags: + - setup-all + - setup-client-hydrogen + +- import_tasks: "{{ role_path }}/tasks/setup.yml" + when: run_setup|bool + tags: + - setup-all + - setup-client-hydrogen diff --git a/roles/matrix-client-hydrogen/tasks/self_check.yml b/roles/matrix-client-hydrogen/tasks/self_check.yml new file mode 100644 index 00000000..c7407dcd --- /dev/null +++ b/roles/matrix-client-hydrogen/tasks/self_check.yml @@ -0,0 +1,22 @@ +--- + +- set_fact: + matrix_client_hydrogen_url_endpoint_public: "https://{{ matrix_server_fqn_hydrogen }}" + +- name: Check Hydrogen + uri: + url: "{{ matrix_client_hydrogen_url_endpoint_public }}" + follow_redirects: none + validate_certs: "{{ matrix_client_hydrogen_self_check_validate_certificates }}" + register: matrix_client_hydrogen_self_check_result + check_mode: no + ignore_errors: true + +- name: Fail if Hydrogen not working + fail: + msg: "Failed checking Hydrogen is up at `{{ matrix_server_fqn_hydrogen }}` (checked endpoint: `{{ matrix_client_hydrogen_url_endpoint_public }}`). Is Hydrogen running? Is port 443 open in your firewall? Full error: {{ matrix_client_hydrogen_self_check_result }}" + when: "matrix_client_hydrogen_self_check_result.failed or 'json' not in matrix_client_hydrogen_self_check_result" + +- name: Report working Hydrogen + debug: + msg: "Hydrogen at `{{ matrix_server_fqn_hydrogen }}` is working (checked endpoint: `{{ matrix_client_hydrogen_url_endpoint_public }}`)" diff --git a/roles/matrix-client-hydrogen/tasks/setup.yml b/roles/matrix-client-hydrogen/tasks/setup.yml new file mode 100644 index 00000000..205fa3ce --- /dev/null +++ b/roles/matrix-client-hydrogen/tasks/setup.yml @@ -0,0 +1,119 @@ +--- + +# +# Tasks related to setting up Hydrogen +# + +- name: Ensure Hydrogen paths exists + file: + path: "{{ item.path }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - { path: "{{ matrix_client_hydrogen_data_path }}", when: true } + - { path: "{{ matrix_client_hydrogen_docker_src_files_path }}", when: "{{ matrix_client_hydrogen_container_image_self_build }}" } + when: matrix_client_hydrogen_enabled|bool and item.when + +- name: Ensure Hydrogen Docker image is pulled + docker_image: + name: "{{ matrix_client_hydrogen_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_client_hydrogen_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_client_hydrogen_docker_image_force_pull }}" + when: matrix_client_hydrogen_enabled|bool and not matrix_client_hydrogen_container_image_self_build + +- name: Ensure Hydrogen repository is present on self-build + git: + repo: "{{ matrix_client_hydrogen_container_image_self_build_repo }}" + dest: "{{ matrix_client_hydrogen_docker_src_files_path }}" + version: "{{ matrix_client_hydrogen_docker_image.split(':')[1] }}" + force: "yes" + register: matrix_client_hydrogen_git_pull_results + when: "matrix_client_hydrogen_enabled|bool and matrix_client_hydrogen_container_image_self_build|bool" + +- name: Ensure Hydrogen configuration installed + copy: + content: "{{ matrix_client_hydrogen_configuration|to_nice_json }}" + dest: "{{ matrix_client_hydrogen_docker_src_files_path }}/assets/config.json" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + when: "matrix_client_hydrogen_enabled|bool and matrix_client_hydrogen_container_image_self_build|bool" + +- name: Ensure Hydrogen additional config files installed + template: + src: "{{ item.src }}" + dest: "{{ matrix_client_hydrogen_data_path }}/{{ item.name }}" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - {src: "{{ role_path }}/templates/nginx.conf.j2", name: "nginx.conf"} + when: "matrix_client_hydrogen_enabled|bool and item.src is not none" + +- name: Ensure Hydrogen Docker image is built + docker_image: + name: "{{ matrix_client_hydrogen_docker_image }}" + source: build + force_source: "{{ matrix_client_hydrogen_git_pull_results.changed }}" + build: + dockerfile: Dockerfile + path: "{{ matrix_client_hydrogen_docker_src_files_path }}" + pull: yes + when: "matrix_client_hydrogen_enabled|bool and matrix_client_hydrogen_container_image_self_build|bool" + +- name: Ensure matrix-client-hydrogen.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-client-hydrogen.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-client-hydrogen.service" + mode: 0644 + register: matrix_client_hydrogen_systemd_service_result + when: matrix_client_hydrogen_enabled|bool + +- name: Ensure systemd reloaded after matrix-client-hydrogen.service installation + service: + daemon_reload: yes + when: "matrix_client_hydrogen_enabled and matrix_client_hydrogen_systemd_service_result.changed" + +# +# Tasks related to getting rid of Hydrogen (if it was previously enabled) +# + +- name: Check existence of matrix-client-hydrogen.service + stat: + path: "{{ matrix_systemd_path }}/matrix-client-hydrogen.service" + register: matrix_client_hydrogen_service_stat + when: "not matrix_client_hydrogen_enabled|bool" + +- name: Ensure matrix-client-hydrogen is stopped + service: + name: matrix-client-hydrogen + state: stopped + daemon_reload: yes + register: stopping_result + when: "not matrix_client_hydrogen_enabled|bool and matrix_client_hydrogen_service_stat.stat.exists" + +- name: Ensure matrix-client-hydrogen.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-client-hydrogen.service" + state: absent + when: "not matrix_client_hydrogen_enabled|bool and matrix_client_hydrogen_service_stat.stat.exists" + +- name: Ensure systemd reloaded after matrix-client-hydrogen.service removal + service: + daemon_reload: yes + when: "not matrix_client_hydrogen_enabled|bool and matrix_client_hydrogen_service_stat.stat.exists" + +- name: Ensure Hydrogen paths doesn't exist + file: + path: "{{ matrix_client_hydrogen_data_path }}" + state: absent + when: "not matrix_client_hydrogen_enabled|bool" + +- name: Ensure Hydrogen Docker image doesn't exist + docker_image: + name: "{{ matrix_client_hydrogen_docker_image }}" + state: absent + when: "not matrix_client_hydrogen_enabled|bool" diff --git a/roles/matrix-client-hydrogen/tasks/validate_config.yml b/roles/matrix-client-hydrogen/tasks/validate_config.yml new file mode 100644 index 00000000..d3b9a709 --- /dev/null +++ b/roles/matrix-client-hydrogen/tasks/validate_config.yml @@ -0,0 +1,9 @@ +--- + +- name: Fail if required Hydrogen settings not defined + fail: + msg: > + You need to define a required configuration setting (`{{ item }}`) to use Hydrogen. + when: "(vars[item] == '' or vars[item] is none) and matrix_client_hydrogen_container_image_self_build|bool" + with_items: + - "matrix_client_hydrogen_default_hs_url" diff --git a/roles/matrix-client-hydrogen/templates/config.json.j2 b/roles/matrix-client-hydrogen/templates/config.json.j2 new file mode 100644 index 00000000..62a849b0 --- /dev/null +++ b/roles/matrix-client-hydrogen/templates/config.json.j2 @@ -0,0 +1,3 @@ +{ + "defaultHomeServer": {{ matrix_client_hydrogen_default_hs_url|string|to_json }} +} diff --git a/roles/matrix-client-hydrogen/templates/nginx.conf.j2 b/roles/matrix-client-hydrogen/templates/nginx.conf.j2 new file mode 100644 index 00000000..fba16bbd --- /dev/null +++ b/roles/matrix-client-hydrogen/templates/nginx.conf.j2 @@ -0,0 +1,66 @@ +#jinja2: lstrip_blocks: "True" +# This is a custom nginx configuration file that we use in the container (instead of the default one), +# because it allows us to run nginx with a non-root user. +# +# For this to work, the default vhost file (`/etc/nginx/conf.d/default.conf`) also needs to be removed. +# (mounting `/dev/null` over `/etc/nginx/conf.d/default.conf` works well) +# +# The following changes have been done compared to a default nginx configuration file: +# - default server port is changed (80 -> 8080), so that a non-root user can bind it +# - various temp paths are changed to `/tmp`, so that a non-root user can write to them +# - the `user` directive was removed, as we don't want nginx to switch users + +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /tmp/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + proxy_temp_path /tmp/proxy_temp; + client_body_temp_path /tmp/client_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + server { + listen 8080; + server_name localhost; + + root /usr/share/nginx/html; + + location / { + index index.html index.htm; + } + + location ~* ^/(config(.+)?\.json$|(.+)\.html$|i18n) { + expires -1; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } +} diff --git a/roles/matrix-client-hydrogen/templates/systemd/matrix-client-hydrogen.service.j2 b/roles/matrix-client-hydrogen/templates/systemd/matrix-client-hydrogen.service.j2 new file mode 100644 index 00000000..c85aeb97 --- /dev/null +++ b/roles/matrix-client-hydrogen/templates/systemd/matrix-client-hydrogen.service.j2 @@ -0,0 +1,39 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix Hydrogen Client +{% for service in matrix_client_hydrogen_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ matrix_systemd_unit_home_path }}" +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-client-hydrogen 2>/dev/null' +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-client-hydrogen 2>/dev/null' + +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-client-hydrogen \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --network={{ matrix_docker_network }} \ + {% if matrix_client_hydrogen_container_http_host_bind_port %} + -p {{ matrix_client_hydrogen_container_http_host_bind_port }}:8080 \ + {% endif %} + --tmpfs=/tmp:rw,noexec,nosuid,size=10m \ + --mount type=bind,src={{ matrix_client_hydrogen_data_path }}/nginx.conf,dst=/etc/nginx/nginx.conf,ro \ + {% for arg in matrix_client_hydrogen_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_client_hydrogen_docker_image }} + +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-client-hydrogen 2>/dev/null' +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-client-hydrogen 2>/dev/null' +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-client-hydrogen + +[Install] +WantedBy=multi-user.target diff --git a/roles/matrix-common-after/defaults/main.yml b/roles/matrix-common-after/defaults/main.yml new file mode 100644 index 00000000..8112191a --- /dev/null +++ b/roles/matrix-common-after/defaults/main.yml @@ -0,0 +1,16 @@ +# Specifies how long to wait between starting systemd services and checking if they're started. +# +# A too low value may lead to a failure, as services may not have enough time to start and potentially fail. +# +# A value higher than 30 seconds (or any multiple of that) may also not work well, because a failing systemd service +# auto-restarts after 30 seconds (`RestartSec=30` in systemd service files). +# Checking if a service is running right after it had potentially restarted in such a way will lead us to +# thinking it's running, while it's merely starting again (and likely to fail again, given that it already did once). +# +# All of the services we manage are also started sequentially, which in itself can take a long time. +# There may be a ~10 second (or even larger) interval between starting the first service and starting the last one. +# This makes it even harder to pick a correct value. Such a 10 second gap and a waiting time of 20 seconds will +# put us right at the "dangerous" 30-second mark. +# +# We can try to measure this gap and adjust our waiting time accordingly, but we currently don't. +matrix_common_after_systemd_service_start_wait_for_timeout_seconds: 15 diff --git a/roles/matrix-common-after/tasks/awx_post.yml b/roles/matrix-common-after/tasks/awx_post.yml new file mode 100644 index 00000000..1e194046 --- /dev/null +++ b/roles/matrix-common-after/tasks/awx_post.yml @@ -0,0 +1,70 @@ +--- + +- name: Create user account @janitor + command: | + /usr/local/bin/matrix-synapse-register-user janitor {{ matrix_awx_janitor_user_password | quote }} 1 + register: cmd + when: not matrix_awx_janitor_user_created|bool + no_log: True + +- name: Update AWX janitor user created variable + delegate_to: 127.0.0.1 + lineinfile: + path: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: 'AWX Settings' + with_dict: + 'matrix_awx_janitor_user_created': 'true' + when: not matrix_awx_janitor_user_created|bool + +- name: Create user account @dimension + command: | + /usr/local/bin/matrix-synapse-register-user dimension {{ matrix_awx_dimension_user_password | quote }} 0 + register: cmd + when: not matrix_awx_dimension_user_created|bool + no_log: True + +- name: Update AWX dimension user created variable + delegate_to: 127.0.0.1 + lineinfile: + path: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: 'AWX Settings' + with_dict: + 'matrix_awx_dimension_user_created': 'true' + when: not matrix_awx_dimension_user_created|bool + +- name: Create user account @mjolnir + command: | + /usr/local/bin/matrix-synapse-register-user mjolnir {{ matrix_awx_mjolnir_user_password | quote }} 0 + register: cmd + when: not matrix_awx_mjolnir_user_created|bool + no_log: True + +- name: Update AWX dimension user created variable + delegate_to: 127.0.0.1 + lineinfile: + path: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/matrix_vars.yml' + regexp: "^#? *{{ item.key | regex_escape() }}:" + line: "{{ item.key }}: {{ item.value }}" + insertafter: 'AWX Settings' + with_dict: + 'matrix_awx_mjolnir_user_created': 'true' + when: not matrix_awx_mjolnir_user_created|bool + +- name: Ensure /chroot/website location has correct permissions + file: + path: /chroot/website + state: directory + owner: matrix + group: matrix + mode: '0574' + when: customise_base_domain_website is defined + +- name: Ensure erroneous /chroot/website/matrix-domain location doesn't exist + file: + path: /chroot/website/matrix-domain + state: absent + when: customise_base_domain_website is defined diff --git a/roles/matrix-common-after/tasks/main.yml b/roles/matrix-common-after/tasks/main.yml index d77d56a1..b4503ae1 100644 --- a/roles/matrix-common-after/tasks/main.yml +++ b/roles/matrix-common-after/tasks/main.yml @@ -1,3 +1,4 @@ + - import_tasks: "{{ role_path }}/tasks/start.yml" when: run_start|bool tags: @@ -11,7 +12,14 @@ - import_tasks: "{{ role_path }}/tasks/dump_runtime_results.yml" tags: - always + +- import_tasks: "{{ role_path }}/tasks/awx_post.yml" + when: run_setup|bool and matrix_awx_enabled|bool + tags: + - always - import_tasks: "{{ role_path }}/tasks/run_docker_prune.yml" tags: - run-docker-prune + + diff --git a/roles/matrix-common-after/tasks/start.yml b/roles/matrix-common-after/tasks/start.yml index b1477cf6..64ab4d99 100644 --- a/roles/matrix-common-after/tasks/start.yml +++ b/roles/matrix-common-after/tasks/start.yml @@ -30,7 +30,7 @@ # as we may run into systemd's automatic restart logic retrying the service. - name: Wait a bit, so that services can start (or fail) wait_for: - timeout: 5 + timeout: "{{ matrix_common_after_systemd_service_start_wait_for_timeout_seconds }}" delegate_to: 127.0.0.1 become: false @@ -44,6 +44,9 @@ {{ item }} was not detected to be running. It's possible that there's a configuration problem or another service on your server interferes with it (uses the same ports, etc.). Try running `systemctl status {{ item }}` and `journalctl -fu {{ item }}` on the server to investigate. + If you're on a slow or overloaded server, it may be that services take a longer time to start and that this error is a false-positive. + You can consider raising the value of the `matrix_common_after_systemd_service_start_wait_for_timeout_seconds` variable. + See `roles/matrix-common-after/defaults/main.yml` for more details about that. with_items: "{{ matrix_systemd_services_list }}" when: - "item.endswith('.service') and (ansible_facts.services[item]|default(none) is none or ansible_facts.services[item].state != 'running')" diff --git a/roles/matrix-corporal/defaults/main.yml b/roles/matrix-corporal/defaults/main.yml index 4b4c46c9..05af8046 100644 --- a/roles/matrix-corporal/defaults/main.yml +++ b/roles/matrix-corporal/defaults/main.yml @@ -22,9 +22,10 @@ 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_version: 2.1.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: "2.1.0" +matrix_corporal_docker_image_name_prefix: "{{ 'localhost/' if matrix_corporal_container_image_self_build else matrix_container_global_registry_prefix }}" +matrix_corporal_docker_image_tag: "{{ matrix_corporal_version }}" # for backward-compatibility matrix_corporal_docker_image_force_pull: "{{ matrix_corporal_docker_image.endswith(':latest') }}" matrix_corporal_base_path: "{{ matrix_base_data_path }}/corporal" diff --git a/roles/matrix-corporal/tasks/init.yml b/roles/matrix-corporal/tasks/init.yml index ffe5d5da..993ace81 100644 --- a/roles/matrix-corporal/tasks/init.yml +++ b/roles/matrix-corporal/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_corporal_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-corporal.service'] }}" when: matrix_corporal_enabled|bool diff --git a/roles/matrix-corporal/tasks/setup_corporal.yml b/roles/matrix-corporal/tasks/setup_corporal.yml index 188f09bf..e668de27 100644 --- a/roles/matrix-corporal/tasks/setup_corporal.yml +++ b/roles/matrix-corporal/tasks/setup_corporal.yml @@ -30,7 +30,8 @@ docker_image: name: "{{ matrix_corporal_docker_image }}" source: build - force_source: "{{ matrix_corporal_git_pull_results.changed }}" + force_source: "{{ matrix_corporal_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: etc/docker/Dockerfile path: "{{ matrix_corporal_container_src_files_path }}" diff --git a/roles/matrix-coturn/defaults/main.yml b/roles/matrix-coturn/defaults/main.yml index 8e781306..ad8735fe 100644 --- a/roles/matrix-coturn/defaults/main.yml +++ b/roles/matrix-coturn/defaults/main.yml @@ -1,10 +1,13 @@ 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_container_image_self_build_repo: "https://github.com/coturn/coturn" +matrix_coturn_container_image_self_build_repo_version: "docker/{{ matrix_coturn_version }}-r0" +matrix_coturn_container_image_self_build_repo_dockerfile_path: "docker/coturn/alpine/Dockerfile" -matrix_coturn_docker_image: "{{ matrix_coturn_docker_image_name_prefix }}instrumentisto/coturn:4.5.2" -matrix_coturn_docker_image_name_prefix: "{{ 'localhost/' if matrix_coturn_container_image_self_build else 'docker.io/' }}" +matrix_coturn_version: 4.5.2 +matrix_coturn_docker_image: "{{ matrix_coturn_docker_image_name_prefix }}coturn/coturn:{{ matrix_coturn_version }}-alpine" +matrix_coturn_docker_image_name_prefix: "{{ 'localhost/' if matrix_coturn_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_coturn_docker_image_force_pull: "{{ matrix_coturn_docker_image.endswith(':latest') }}" # The Docker network that Coturn would be put into. @@ -72,3 +75,6 @@ matrix_coturn_total_quota: null matrix_coturn_tls_enabled: false matrix_coturn_tls_cert_path: ~ matrix_coturn_tls_key_path: ~ + +matrix_coturn_tls_v1_enabled: false +matrix_coturn_tls_v1_1_enabled: false diff --git a/roles/matrix-coturn/tasks/init.yml b/roles/matrix-coturn/tasks/init.yml index be011b7f..c645c06b 100644 --- a/roles/matrix-coturn/tasks/init.yml +++ b/roles/matrix-coturn/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_coturn_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-coturn.service'] }}" when: matrix_coturn_enabled|bool @@ -5,10 +12,3 @@ - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-coturn-reload.timer'] }}" when: "matrix_coturn_enabled|bool and matrix_coturn_tls_enabled|bool" - -# ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here -- name: Fail if running on Ansible lower than 2.8 and trying self building - fail: - msg: "To self build Coturn image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." - when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_coturn_container_image_self_build" diff --git a/roles/matrix-coturn/tasks/setup_install.yml b/roles/matrix-coturn/tasks/setup_install.yml index 2f3664f1..c31406b1 100644 --- a/roles/matrix-coturn/tasks/setup_install.yml +++ b/roles/matrix-coturn/tasks/setup_install.yml @@ -30,7 +30,7 @@ git: repo: "{{ matrix_coturn_container_image_self_build_repo }}" dest: "{{ matrix_coturn_docker_src_files_path }}" - version: "{{ matrix_coturn_docker_image.split(':')[1] }}" + version: "{{ matrix_coturn_container_image_self_build_repo_version }}" force: "yes" register: matrix_coturn_git_pull_results @@ -38,9 +38,10 @@ docker_image: name: "{{ matrix_coturn_docker_image }}" source: build - force_source: "{{ matrix_coturn_git_pull_results.changed }}" + force_source: "{{ matrix_coturn_git_pull_results.changed 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_coturn_git_pull_results.changed }}" build: - dockerfile: Dockerfile + dockerfile: "{{ matrix_coturn_container_image_self_build_repo_dockerfile_path }}" path: "{{ matrix_coturn_docker_src_files_path }}" pull: yes when: "matrix_coturn_container_image_self_build|bool" diff --git a/roles/matrix-coturn/templates/systemd/matrix-coturn-reload.timer.j2 b/roles/matrix-coturn/templates/systemd/matrix-coturn-reload.timer.j2 index 622cd80a..52894541 100644 --- a/roles/matrix-coturn/templates/systemd/matrix-coturn-reload.timer.j2 +++ b/roles/matrix-coturn/templates/systemd/matrix-coturn-reload.timer.j2 @@ -3,8 +3,8 @@ Description=Reloads matrix-coturn periodically so that new SSL certificates can [Timer] Unit=matrix-coturn-reload.service -OnCalendar=Sunday *-*-* 13:00:00 -RandomizedDelaySec=3h +OnCalendar=*-*-* 06:30:00 +RandomizedDelaySec=1h [Install] WantedBy=timers.target diff --git a/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 b/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 index 930db7c1..a39030af 100644 --- a/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 +++ b/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 @@ -17,6 +17,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-coturn \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ + --cap-add=NET_BIND_SERVICE \ --entrypoint=turnserver \ --read-only \ --tmpfs=/var/tmp:rw,noexec,nosuid,size=100m \ diff --git a/roles/matrix-coturn/templates/turnserver.conf.j2 b/roles/matrix-coturn/templates/turnserver.conf.j2 index 3fcf0b67..ba662587 100644 --- a/roles/matrix-coturn/templates/turnserver.conf.j2 +++ b/roles/matrix-coturn/templates/turnserver.conf.j2 @@ -16,6 +16,12 @@ no-cli {% if matrix_coturn_tls_enabled %} cert={{ matrix_coturn_tls_cert_path }} pkey={{ matrix_coturn_tls_key_path }} +{% if not matrix_coturn_tls_v1_enabled %} +no-tlsv1 +{% endif %} +{% if not matrix_coturn_tls_v1_1_enabled %} +no-tlsv1_1 +{% endif %} {% else %} no-tls no-dtls diff --git a/roles/matrix-dimension/defaults/main.yml b/roles/matrix-dimension/defaults/main.yml index 8a691946..f7a84ca1 100644 --- a/roles/matrix-dimension/defaults/main.yml +++ b/roles/matrix-dimension/defaults/main.yml @@ -12,7 +12,8 @@ matrix_dimension_widgets_allow_self_signed_ssl_certificates: false matrix_dimension_base_path: "{{ matrix_base_data_path }}/dimension" -matrix_dimension_docker_image: "docker.io/turt2live/matrix-dimension:latest" +matrix_dimension_version: latest +matrix_dimension_docker_image: "{{ matrix_container_global_registry_prefix }}turt2live/matrix-dimension:{{ matrix_dimension_version }}" matrix_dimension_docker_image_force_pull: "{{ matrix_dimension_docker_image.endswith(':latest') }}" # List of systemd services that matrix-dimension.service depends on. diff --git a/roles/matrix-dimension/tasks/setup_install.yml b/roles/matrix-dimension/tasks/setup_install.yml index 26a75bcb..804be88d 100644 --- a/roles/matrix-dimension/tasks/setup_install.yml +++ b/roles/matrix-dimension/tasks/setup_install.yml @@ -40,6 +40,7 @@ - {'table': 'dimension_sticker_packs', 'column': 'isPublic', 'default': ''} - {'table': 'dimension_slack_bridges', 'column': 'isEnabled', 'default': ''} - {'table': 'dimension_neb_integrations', 'column': 'isPublic', 'default': ''} + - {'table': 'dimension_neb_integrations', 'column': 'isEnabled', 'default': ''} - {'table': 'dimension_irc_bridges', 'column': 'isEnabled', 'default': ''} - {'table': 'dimension_irc_bridge_networks', 'column': 'isEnabled', 'default': ''} - {'table': 'dimension_gitter_bridges', 'column': 'isEnabled', 'default': ''} diff --git a/roles/matrix-dynamic-dns/defaults/main.yml b/roles/matrix-dynamic-dns/defaults/main.yml index b33961c1..3411d0f8 100644 --- a/roles/matrix-dynamic-dns/defaults/main.yml +++ b/roles/matrix-dynamic-dns/defaults/main.yml @@ -4,10 +4,12 @@ matrix_dynamic_dns_enabled: true # The dynamic dns daemon interval matrix_dynamic_dns_daemon_interval: '300' +matrix_dynamic_dns_version: v3.9.1-ls45 + # 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: "{{ matrix_dynamic_dns_docker_image_name_prefix }}linuxserver/ddclient:{{ matrix_dynamic_dns_version }}" -matrix_dynamic_dns_docker_image_name_prefix: "{{ 'localhost/' if matrix_dynamic_dns_container_image_self_build else 'docker.io/' }}" +matrix_dynamic_dns_docker_image_name_prefix: "{{ 'localhost/' if matrix_dynamic_dns_container_image_self_build else matrix_container_global_registry_prefix }}" # The image to force pull matrix_dynamic_dns_docker_image_force_pull: "{{ matrix_dynamic_dns_docker_image.endswith(':latest') }}" diff --git a/roles/matrix-dynamic-dns/tasks/init.yml b/roles/matrix-dynamic-dns/tasks/init.yml index 1a0f1b3d..039b5b02 100644 --- a/roles/matrix-dynamic-dns/tasks/init.yml +++ b/roles/matrix-dynamic-dns/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_dynamic_dns_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-dynamic-dns.service'] }}" when: "matrix_dynamic_dns_enabled|bool" diff --git a/roles/matrix-dynamic-dns/tasks/install.yml b/roles/matrix-dynamic-dns/tasks/install.yml index e7b06d95..ac69ec89 100644 --- a/roles/matrix-dynamic-dns/tasks/install.yml +++ b/roles/matrix-dynamic-dns/tasks/install.yml @@ -33,7 +33,8 @@ docker_image: name: "{{ matrix_dynamic_dns_docker_image }}" source: build - force_source: "{{ matrix_dynamic_dns_git_pull_results.changed }}" + force_source: "{{ matrix_dynamic_dns_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_dynamic_dns_docker_src_files_path }}" diff --git a/roles/matrix-email2matrix/defaults/main.yml b/roles/matrix-email2matrix/defaults/main.yml index 7917decf..e6bfa0fe 100644 --- a/roles/matrix-email2matrix/defaults/main.yml +++ b/roles/matrix-email2matrix/defaults/main.yml @@ -3,7 +3,8 @@ 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: "docker.io/devture/email2matrix:1.0.1" +matrix_email2matrix_version: 1.0.1 +matrix_email2matrix_docker_image: "{{ matrix_container_global_registry_prefix }}devture/email2matrix:{{ matrix_email2matrix_version }}" 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-etherpad/defaults/main.yml b/roles/matrix-etherpad/defaults/main.yml index 7c63fe03..45f8f8b2 100644 --- a/roles/matrix-etherpad/defaults/main.yml +++ b/roles/matrix-etherpad/defaults/main.yml @@ -2,7 +2,8 @@ matrix_etherpad_enabled: false matrix_etherpad_base_path: "{{ matrix_base_data_path }}/etherpad" -matrix_etherpad_docker_image: "docker.io/etherpad/etherpad:1.8.7" +matrix_etherpad_version: 1.8.12 +matrix_etherpad_docker_image: "{{ matrix_container_global_registry_prefix }}etherpad/etherpad:{{ matrix_etherpad_version }}" matrix_etherpad_docker_image_force_pull: "{{ matrix_etherpad_docker_image.endswith(':latest') }}" # List of systemd services that matrix-etherpad.service depends on. @@ -22,12 +23,7 @@ matrix_etherpad_user_gid: '5001' matrix_etherpad_container_http_host_bind_port: '' # A list of extra arguments to pass to the container -# -# We assume that a reverse proxy is used and tell the container to trust it -# Details: https://github.com/ether/etherpad-lite/blob/develop/doc/docker.md -matrix_etherpad_container_extra_arguments: [ - '--env TRUST_PROXY=true' -] +matrix_etherpad_container_extra_arguments: [] matrix_etherpad_public_endpoint: '/etherpad' diff --git a/roles/matrix-etherpad/templates/settings.json.j2 b/roles/matrix-etherpad/templates/settings.json.j2 index b3b87f43..377bad98 100644 --- a/roles/matrix-etherpad/templates/settings.json.j2 +++ b/roles/matrix-etherpad/templates/settings.json.j2 @@ -42,6 +42,9 @@ "percentageToScrollWhenUserPressesArrowUp": 0 }, "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], + "socketIo": { + "maxHttpBufferSize": 10000 + }, "loadTest": false, "importExportRateLimiting": { "windowMs": 90000, diff --git a/roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 b/roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 index b8a26664..b579036b 100644 --- a/roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 +++ b/roles/matrix-etherpad/templates/systemd/matrix-etherpad.service.j2 @@ -29,7 +29,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-etherpad \ {{ arg }} \ {% endfor %} {{ matrix_etherpad_docker_image }} \ - node --experimental-worker /opt/etherpad-lite/node_modules/ep_etherpad-lite/node/server.js \ + node --experimental-worker src/node/server.js \ --settings /data/settings.json --credentials /data/credentials.json \ --sessionkey /data/sessionkey.json --apikey /data/apijey.json diff --git a/roles/matrix-grafana/defaults/main.yml b/roles/matrix-grafana/defaults/main.yml index 00ed947e..7c5c217c 100644 --- a/roles/matrix-grafana/defaults/main.yml +++ b/roles/matrix-grafana/defaults/main.yml @@ -3,7 +3,8 @@ matrix_grafana_enabled: false -matrix_grafana_docker_image: "docker.io/grafana/grafana:7.4.0" +matrix_grafana_version: 7.5.7 +matrix_grafana_docker_image: "{{ matrix_container_global_registry_prefix }}grafana/grafana:{{ matrix_grafana_version }}" matrix_grafana_docker_image_force_pull: "{{ matrix_grafana_docker_image.endswith(':latest') }}" # Not conditional, because when someone disables metrics @@ -30,6 +31,19 @@ matrix_grafana_anonymous_access_org_name: 'Main Org.' matrix_grafana_default_admin_user: admin matrix_grafana_default_admin_password: admin +# Set to true to add the Content-Security-Policy header to your requests. +# CSP allows to control resources that the user agent can load and helps +# prevent XSS attacks. +# [Content Security Policy](https://grafana.com/docs/grafana/latest/administration/configuration/#content_security_policy) +matrix_grafana_content_security_policy: true + +# specify content security policy template to customized template +# added 'unsafe-inline' (ignored by browsers supporting nonces/hashes) to be backward compatible with older browsers. +# added https: and http: url schemes (ignored by browsers supporting 'strict-dynamic') to be backward compatible with older browsers. +# [Content Security Policy Browser Test] (https://content-security-policy.com/browser-test/) +# [Content Security Policy Reference](https://content-security-policy.com/script-src/) +matrix_grafana_content_security_policy_customized: true + # A list of extra arguments to pass to the container matrix_grafana_container_extra_arguments: [] @@ -43,5 +57,3 @@ matrix_grafana_systemd_wanted_services_list: [] # # Takes an ":" or "" value (e.g. "127.0.0.1:3000"), or empty string to not expose. matrix_grafana_container_http_host_bind_port: '' - - diff --git a/roles/matrix-grafana/tasks/setup.yml b/roles/matrix-grafana/tasks/setup.yml index 581e6617..c2eea348 100644 --- a/roles/matrix-grafana/tasks/setup.yml +++ b/roles/matrix-grafana/tasks/setup.yml @@ -28,7 +28,7 @@ - "{{ matrix_grafana_config_path }}/dashboards" - "{{ matrix_grafana_data_path }}" when: matrix_grafana_enabled|bool - + - name: Ensure grafana.ini present template: src: "{{ role_path }}/templates/grafana.ini.j2" @@ -37,7 +37,7 @@ owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" when: matrix_grafana_enabled|bool - + - name: Ensure provisioning/datasources/default.yaml present template: src: "{{ role_path }}/templates/datasources.yaml.j2" @@ -46,7 +46,7 @@ owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" when: matrix_grafana_enabled|bool - + - name: Ensure provisioning/dashboards/default.yaml present template: src: "{{ role_path }}/templates/dashboards.yaml.j2" @@ -55,7 +55,7 @@ owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" when: matrix_grafana_enabled|bool - + - name: Ensure dashboard(s) downloaded get_url: url: "{{ item }}" @@ -108,8 +108,3 @@ daemon_reload: yes when: "not matrix_grafana_enabled|bool and matrix_grafana_service_stat.stat.exists" -- name: Ensure matrix-grafana Docker image doesn't exist - docker_image: - name: "{{ matrix_grafana_docker_image }}" - state: absent - when: "not matrix_grafana_enabled|bool" diff --git a/roles/matrix-grafana/templates/grafana.ini.j2 b/roles/matrix-grafana/templates/grafana.ini.j2 index 694bf7d7..322762b4 100644 --- a/roles/matrix-grafana/templates/grafana.ini.j2 +++ b/roles/matrix-grafana/templates/grafana.ini.j2 @@ -1,16 +1,27 @@ +[server] +root_url = "https://{{ matrix_server_fqn_grafana }}" + [security] # default admin user, created on startup -admin_user = {{ matrix_grafana_default_admin_user }} +admin_user = "{{ matrix_grafana_default_admin_user }}" + +# default admin password, can be changed before first start of grafana, or in profile settings +admin_password = """{{ matrix_grafana_default_admin_password }}""" -# default admin password, can be changed before first start of grafana, or in profile settings -admin_password = {{ matrix_grafana_default_admin_password }} +# specify content_security_policy to add the Content-Security-Policy header to your requests +content_security_policy = "{{ matrix_grafana_content_security_policy }}" + +# specify content security policy template to customized template +{% if matrix_grafana_content_security_policy_customized %} +content_security_policy_template = """script-src http: https: 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data:;base-uri 'self';connect-src 'self' grafana.com;manifest-src 'self';media-src 'none';form-action 'self';""" +{% endif %} [auth.anonymous] # enable anonymous access enabled = {{ matrix_grafana_anonymous_access }} # specify organization name that should be used for unauthenticated users -org_name = {{ matrix_grafana_anonymous_access_org_name }} +org_name = "{{ matrix_grafana_anonymous_access_org_name }}" [dashboards] {% if matrix_synapse_metrics_enabled %} diff --git a/roles/matrix-jitsi/defaults/main.yml b/roles/matrix-jitsi/defaults/main.yml index 028d9c19..7dcff987 100644 --- a/roles/matrix-jitsi/defaults/main.yml +++ b/roles/matrix-jitsi/defaults/main.yml @@ -52,9 +52,10 @@ matrix_jitsi_jibri_recorder_password: '' matrix_jitsi_enable_lobby: false -matrix_jitsi_container_image_tag: "stable-5142" +matrix_jitsi_version: stable-5765-1 +matrix_jitsi_container_image_tag: "{{ matrix_jitsi_version }}" # for backward-compatibility -matrix_jitsi_web_docker_image: "docker.io/jitsi/web:{{ matrix_jitsi_container_image_tag }}" +matrix_jitsi_web_docker_image: "{{ matrix_container_global_registry_prefix }}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" @@ -72,7 +73,7 @@ matrix_jitsi_etherpad_enabled: false # Controls whether the matrix-jitsi-web container exposes its HTTP port (tcp/80 in the container). # -# Takes an ":" or "" value (e.g. "127.0.0.1:12080"), or empty string to not expose. +# Takes an ":" or "" value (e.g. "127.0.0.1:13080"), or empty string to not expose. matrix_jitsi_web_container_http_host_bind_port: '' # A list of extra arguments to pass to the container @@ -99,7 +100,7 @@ matrix_jitsi_web_interface_config_native_app_name: "Jitsi Meet" matrix_jitsi_web_interface_config_provider_name: "Jitsi" 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 +matrix_jitsi_web_interface_config_show_deep_linking_image: false # 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. @@ -162,7 +163,7 @@ matrix_jitsi_web_custom_config_extension: '' 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: "{{ matrix_container_global_registry_prefix }}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" @@ -176,7 +177,7 @@ matrix_jitsi_prosody_container_extra_arguments: [] matrix_jitsi_prosody_systemd_required_services_list: ['docker.service'] -matrix_jitsi_jicofo_docker_image: "docker.io/jitsi/jicofo:{{ matrix_jitsi_container_image_tag }}" +matrix_jitsi_jicofo_docker_image: "{{ matrix_container_global_registry_prefix }}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" @@ -193,7 +194,7 @@ matrix_jitsi_jicofo_auth_user: focus matrix_jitsi_jicofo_auth_password: '' -matrix_jitsi_jvb_docker_image: "docker.io/jitsi/jvb:{{ matrix_jitsi_container_image_tag }}" +matrix_jitsi_jvb_docker_image: "{{ matrix_container_global_registry_prefix }}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" diff --git a/roles/matrix-jitsi/tasks/validate_config.yml b/roles/matrix-jitsi/tasks/validate_config.yml index bd939d3a..cc8a4b22 100644 --- a/roles/matrix-jitsi/tasks/validate_config.yml +++ b/roles/matrix-jitsi/tasks/validate_config.yml @@ -40,3 +40,4 @@ - {'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': ''} + - {'old': 'matrix_jisti_web_interface_config_show_deep_linking_image', 'new': 'matrix_jitsi_web_interface_config_show_deep_linking_image'} diff --git a/roles/matrix-jitsi/templates/prosody/env.j2 b/roles/matrix-jitsi/templates/prosody/env.j2 index a09fa0f8..0c977d45 100644 --- a/roles/matrix-jitsi/templates/prosody/env.j2 +++ b/roles/matrix-jitsi/templates/prosody/env.j2 @@ -3,6 +3,8 @@ AUTH_TYPE={{ matrix_jitsi_auth_type }} ENABLE_AUTH={{ 1 if matrix_jitsi_enable_auth else 0 }} ENABLE_GUESTS={{ 1 if matrix_jitsi_enable_guests else 0 }} +PUBLIC_URL={{ matrix_jitsi_web_public_url }} + LDAP_URL={{ matrix_jitsi_ldap_url }} LDAP_BASE={{ matrix_jitsi_ldap_base }} LDAP_BINDDN={{ matrix_jitsi_ldap_binddn }} diff --git a/roles/matrix-jitsi/templates/web/interface_config.js.j2 b/roles/matrix-jitsi/templates/web/interface_config.js.j2 index a12ca973..08ac02fe 100644 --- a/roles/matrix-jitsi/templates/web/interface_config.js.j2 +++ b/roles/matrix-jitsi/templates/web/interface_config.js.j2 @@ -177,7 +177,7 @@ var interfaceConfig = { */ SHOW_CHROME_EXTENSION_BANNER: false, - SHOW_DEEP_LINKING_IMAGE: {{ matrix_jisti_web_interface_config_show_deep_linking_image|to_json }}, + SHOW_DEEP_LINKING_IMAGE: {{ matrix_jitsi_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, diff --git a/roles/matrix-ma1sd/defaults/main.yml b/roles/matrix-ma1sd/defaults/main.yml index 62828d95..7ab0d15e 100644 --- a/roles/matrix-ma1sd/defaults/main.yml +++ b/roles/matrix-ma1sd/defaults/main.yml @@ -12,7 +12,7 @@ matrix_ma1sd_architecture: "amd64" matrix_ma1sd_version: "2.4.0" matrix_ma1sd_docker_image: "{{ matrix_ma1sd_docker_image_name_prefix }}ma1uta/ma1sd:{{ matrix_ma1sd_version }}-{{ matrix_ma1sd_architecture }}" -matrix_ma1sd_docker_image_name_prefix: "{{ 'localhost/' if matrix_ma1sd_container_image_self_build else 'docker.io/' }}" +matrix_ma1sd_docker_image_name_prefix: "{{ 'localhost/' if matrix_ma1sd_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_ma1sd_docker_image_force_pull: "{{ matrix_ma1sd_docker_image.endswith(':latest') }}" matrix_ma1sd_base_path: "{{ matrix_base_data_path }}/ma1sd" diff --git a/roles/matrix-ma1sd/tasks/init.yml b/roles/matrix-ma1sd/tasks/init.yml index 89283a1f..f09cfcfd 100644 --- a/roles/matrix-ma1sd/tasks/init.yml +++ b/roles/matrix-ma1sd/tasks/init.yml @@ -1,10 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_ma1sd_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-ma1sd.service'] }}" when: matrix_ma1sd_enabled|bool - -# ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here -- name: Fail if running on Ansible lower than 2.8 and trying self building - fail: - msg: "To self build ma1sd image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." - when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_ma1sd_container_image_self_build" diff --git a/roles/matrix-mailer/defaults/main.yml b/roles/matrix-mailer/defaults/main.yml index 18608ef4..1340cc70 100644 --- a/roles/matrix-mailer/defaults/main.yml +++ b/roles/matrix-mailer/defaults/main.yml @@ -7,8 +7,9 @@ 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: "{{ matrix_mailer_docker_image_name_prefix }}devture/exim-relay:4.93-r1" -matrix_mailer_docker_image_name_prefix: "{{ 'localhost/' if matrix_mailer_container_image_self_build else 'docker.io/' }}" +matrix_mailer_version: 4.94.2-r0-1 +matrix_mailer_docker_image: "{{ matrix_mailer_docker_image_name_prefix }}devture/exim-relay:{{ matrix_mailer_version }}" +matrix_mailer_docker_image_name_prefix: "{{ 'localhost/' if matrix_mailer_container_image_self_build else matrix_container_global_registry_prefix }}" 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/init.yml b/roles/matrix-mailer/tasks/init.yml index e48e2a85..5895343e 100644 --- a/roles/matrix-mailer/tasks/init.yml +++ b/roles/matrix-mailer/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_mailer_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-mailer.service'] }}" when: matrix_mailer_enabled|bool diff --git a/roles/matrix-mailer/tasks/setup_mailer.yml b/roles/matrix-mailer/tasks/setup_mailer.yml index cb979080..251a52da 100644 --- a/roles/matrix-mailer/tasks/setup_mailer.yml +++ b/roles/matrix-mailer/tasks/setup_mailer.yml @@ -36,7 +36,8 @@ docker_image: name: "{{ matrix_mailer_docker_image }}" source: build - force_source: "{{ matrix_mailer_git_pull_results.changed }}" + force_source: "{{ matrix_mailer_git_pull_results.changed 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_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 14712935..bf5a2e42 100644 --- a/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 +++ b/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 @@ -18,7 +18,6 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-mailer \ --user={{ matrix_mailer_container_user_uid }}:{{ matrix_mailer_container_user_gid }} \ --cap-drop=ALL \ --read-only \ - --init \ --tmpfs=/var/spool/exim:rw,noexec,nosuid,size=100m \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_mailer_base_path }}/env-mailer \ diff --git a/roles/matrix-nginx-proxy/defaults/main.yml b/roles/matrix-nginx-proxy/defaults/main.yml index d46d5480..c0ee3b51 100644 --- a/roles/matrix-nginx-proxy/defaults/main.yml +++ b/roles/matrix-nginx-proxy/defaults/main.yml @@ -1,13 +1,15 @@ matrix_nginx_proxy_enabled: true +matrix_nginx_proxy_version: 1.20.0-alpine # 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: "docker.io/nginx:1.19.6-alpine" +matrix_nginx_proxy_docker_image: "{{ matrix_container_global_registry_prefix }}nginx:{{ matrix_nginx_proxy_version }}" 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" matrix_nginx_proxy_data_path: "{{ matrix_nginx_proxy_base_path }}/data" +matrix_nginx_proxy_data_path_in_container: "/nginx-data" matrix_nginx_proxy_confd_path: "{{ matrix_nginx_proxy_base_path }}/conf.d" # List of systemd services that matrix-nginx-proxy.service depends on @@ -102,19 +104,35 @@ matrix_nginx_proxy_proxy_riot_compat_redirect_hostname: "riot.{{ matrix_domain } # Controls whether proxying the Synapse domain should be done. matrix_nginx_proxy_proxy_synapse_enabled: false matrix_nginx_proxy_proxy_synapse_hostname: "matrix-nginx-proxy" +matrix_nginx_proxy_proxy_synapse_federation_api_enabled: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_enabled }}" +# The addresses where the Federation API is, when using Synapse. +matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container: "matrix-synapse:8048" +matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container: "localhost:8048" # Controls whether proxying the Element domain should be done. matrix_nginx_proxy_proxy_element_enabled: false matrix_nginx_proxy_proxy_element_hostname: "{{ matrix_server_fqn_element }}" +# Controls whether proxying the Hydrogen domain should be done. +matrix_nginx_proxy_proxy_hydrogen_enabled: false +matrix_nginx_proxy_proxy_hydrogen_hostname: "{{ matrix_server_fqn_hydrogen }}" + # Controls whether proxying the matrix domain should be done. matrix_nginx_proxy_proxy_matrix_enabled: false matrix_nginx_proxy_proxy_matrix_hostname: "{{ matrix_server_fqn_matrix }}" +# The port name used for federation in the nginx configuration. +# This is not necessarily the port that it's actually on, +# as port-mapping happens (`-p ..`) for the `matrix-nginx-proxy` container. +matrix_nginx_proxy_proxy_matrix_federation_port: 8448 # Controls whether proxying the dimension domain should be done. matrix_nginx_proxy_proxy_dimension_enabled: false matrix_nginx_proxy_proxy_dimension_hostname: "{{ matrix_server_fqn_dimension }}" +# Controls whether proxying the goneb domain should be done. +matrix_nginx_proxy_proxy_bot_go_neb_enabled: false +matrix_nginx_proxy_proxy_bot_go_neb_hostname: "{{ matrix_server_fqn_bot_go_neb }}" + # Controls whether proxying the jitsi domain should be done. matrix_nginx_proxy_proxy_jitsi_enabled: false matrix_nginx_proxy_proxy_jitsi_hostname: "{{ matrix_server_fqn_jitsi }}" @@ -123,6 +141,10 @@ matrix_nginx_proxy_proxy_jitsi_hostname: "{{ matrix_server_fqn_jitsi }}" matrix_nginx_proxy_proxy_grafana_enabled: false matrix_nginx_proxy_proxy_grafana_hostname: "{{ matrix_server_fqn_grafana }}" +# Controls whether proxying the sygnal domain should be done. +matrix_nginx_proxy_proxy_sygnal_enabled: false +matrix_nginx_proxy_proxy_sygnal_hostname: "{{ matrix_server_fqn_sygnal }}" + # Controls whether proxying for the matrix-corporal API (`/_matrix/corporal`) should be done (on the matrix domain) matrix_nginx_proxy_proxy_matrix_corporal_api_enabled: false matrix_nginx_proxy_proxy_matrix_corporal_api_addr_with_container: "matrix-corporal:41081" @@ -188,6 +210,8 @@ matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefix_regexes: | (['/_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 []) + + + (['/_synapse/metrics'] if matrix_nginx_proxy_proxy_synapse_metrics else []) }} # Specifies where requests for the root URI (`/`) on the `matrix.` domain should be redirected. @@ -203,14 +227,20 @@ matrix_nginx_proxy_proxy_matrix_federation_api_addr_sans_container: "localhost:1 matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb: "{{ (matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb | int) * 3 }}" matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/fullchain.pem" matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/privkey.pem" - -# The addresses where the Federation API is, when using Synapse. -matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container: "matrix-synapse:8048" -matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container: "localhost:8048" +matrix_nginx_proxy_proxy_matrix_federation_api_ssl_trusted_certificate: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/chain.pem" # The tmpfs at /tmp needs to be large enough to handle multiple concurrent file uploads. matrix_nginx_proxy_tmp_directory_size_mb: "{{ (matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb | int) * 50 }}" +# A list of strings containing additional configuration blocks to add to the nginx server configuration (nginx.conf). +# for big matrixservers to enlarge the number of open files to prevent timeouts +# matrix_nginx_proxy_proxy_additional_configuration_blocks: +# - 'worker_rlimit_nofile 30000;' +matrix_nginx_proxy_proxy_additional_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to the nginx event server configuration (nginx.conf). +matrix_nginx_proxy_proxy_event_additional_configuration_blocks: [] + # A list of strings containing additional configuration blocks to add to the nginx http's server configuration (nginx-http.conf). matrix_nginx_proxy_proxy_http_additional_server_configuration_blocks: [] @@ -226,18 +256,37 @@ matrix_nginx_proxy_proxy_riot_additional_server_configuration_blocks: [] # A list of strings containing additional configuration blocks to add to Element's server configuration (matrix-client-element.conf). matrix_nginx_proxy_proxy_element_additional_server_configuration_blocks: [] +# A list of strings containing additional configuration blocks to add to Element's server configuration (matrix-client-element.conf). +matrix_nginx_proxy_proxy_hydrogen_additional_server_configuration_blocks: [] + # A list of strings containing additional configuration blocks to add to Dimension's server configuration (matrix-dimension.conf). matrix_nginx_proxy_proxy_dimension_additional_server_configuration_blocks: [] +# A list of strings containing additional configuration blocks to add to GoNEB's server configuration (matrix-bot-go-neb.conf). +matrix_nginx_proxy_proxy_bot_go_neb_additional_server_configuration_blocks: [] + # A list of strings containing additional configuration blocks to add to Jitsi's server configuration (matrix-jitsi.conf). matrix_nginx_proxy_proxy_jitsi_additional_server_configuration_blocks: [] # A list of strings containing additional configuration blocks to add to Grafana's server configuration (matrix-grafana.conf). matrix_nginx_proxy_proxy_grafana_additional_server_configuration_blocks: [] +# A list of strings containing additional configuration blocks to add to Sygnal's server configuration (matrix-sygnal.conf). +matrix_nginx_proxy_proxy_sygnal_additional_server_configuration_blocks: [] + # A list of strings containing additional configuration blocks to add to the base domain server configuration (matrix-base-domain.conf). matrix_nginx_proxy_proxy_domain_additional_server_configuration_blocks: [] +# Controls whether to send a "Permissions-Policy interest-cohort=();" header along with all responses for all vhosts meant to be accessed by users. +# +# Learn more about what it is here: +# - https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea +# - https://paramdeo.com/blog/opting-your-website-out-of-googles-floc-network +# - https://amifloced.org/ +# +# Of course, a better solution is to just stop using browsers (like Chrome), which participate in such tracking practices. +matrix_nginx_proxy_floc_optout_enabled: true + # Specifies the SSL configuration that should be used for the SSL protocols and ciphers # This is based on the Mozilla Server Side TLS Recommended configurations. # @@ -323,7 +372,7 @@ matrix_ssl_additional_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: "docker.io/certbot/certbot:{{ matrix_ssl_architecture }}-v1.11.0" +matrix_ssl_lets_encrypt_certbot_docker_image: "{{ matrix_container_global_registry_prefix }}certbot/certbot:{{ matrix_ssl_architecture }}-v1.14.0" 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: ~ @@ -344,6 +393,47 @@ matrix_ssl_log_dir_path: "{{ matrix_ssl_base_path }}/log" matrix_ssl_pre_obtaining_required_service_name: ~ matrix_ssl_pre_obtaining_required_service_start_wait_time_seconds: 60 +# Nginx Optimize SSL Session +# +# ssl_session_cache: +# - Creating a cache of TLS connection parameters reduces the number of handshakes +# and thus can improve the performance of application. +# - Default session cache is not optimal as it can be used by only one worker process +# and can cause memory fragmentation. It is much better to use shared cache. +# - Learn More: https://nginx.org/en/docs/http/ngx_http_ssl_module.html +# +# ssl_session_timeout: +# - Nginx by default it is set to 5 minutes which is very low. +# should be like 4h or 1d but will require you to increase the size of cache. +# - Learn More: +# https://github.com/certbot/certbot/issues/6903 +# https://github.com/mozilla/server-side-tls/issues/198 +# +# ssl_session_tickets: +# - In case of session tickets, information about session is given to the client. +# Enabling this improve performance also make Perfect Forward Secrecy useless. +# - If you would instead like to use ssl_session_tickets by yourself, you can set +# matrix_nginx_proxy_ssl_session_tickets_off false. +# - Learn More: https://github.com/mozilla/server-side-tls/issues/135 +# +# Presets are taken from Mozilla's Server Side TLS Recommended configurations +matrix_nginx_proxy_ssl_session_cache: "shared:MozSSL:10m" +matrix_nginx_proxy_ssl_session_timeout: "1d" +matrix_nginx_proxy_ssl_session_tickets_off: true + +# OCSP Stapling eliminating the need for clients to contact the CA, with the aim of improving both security and performance. +# OCSP stapling can provide a performance boost of up to 30% +# nginx web server supports OCSP stapling since version 1.3.7. +# +# *warning* Nginx is lazy loading OCSP responses, which means that for the first few web requests it is unable to add the OCSP response. +# set matrix_nginx_proxy_ocsp_stapling_enabled false to disable OCSP Stapling +# +# Learn more about what it is here: +# - https://en.wikipedia.org/wiki/OCSP_stapling +# - https://blog.cloudflare.com/high-reliability-ocsp-stapling/ +# - https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ +matrix_nginx_proxy_ocsp_stapling_enabled: true + # nginx status page configurations. matrix_nginx_proxy_proxy_matrix_nginx_status_enabled: false matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses: ['{{ ansible_default_ipv4.address }}'] @@ -357,3 +447,9 @@ matrix_nginx_proxy_synapse_generic_worker_federation_locations: [] matrix_nginx_proxy_synapse_media_repository_locations: [] matrix_nginx_proxy_synapse_user_dir_locations: [] matrix_nginx_proxy_synapse_frontend_proxy_locations: [] + +# The amount of worker processes and connections +# Consider increasing these when you are expecting high amounts of traffic +# http://nginx.org/en/docs/ngx_core_module.html#worker_connections +matrix_nginx_proxy_worker_processes: 1 +matrix_nginx_proxy_worker_connections: 1024 diff --git a/roles/matrix-nginx-proxy/tasks/self_check_well_known_file.yml b/roles/matrix-nginx-proxy/tasks/self_check_well_known_file.yml index 2cf1ef06..6f831a29 100644 --- a/roles/matrix-nginx-proxy/tasks/self_check_well_known_file.yml +++ b/roles/matrix-nginx-proxy/tasks/self_check_well_known_file.yml @@ -12,6 +12,8 @@ follow_redirects: none return_content: true validate_certs: "{{ well_known_file_check.validate_certs }}" + headers: + Origin: example.com check_mode: no register: result_well_known_matrix ignore_errors: true @@ -40,6 +42,8 @@ follow_redirects: "{{ well_known_file_check.follow_redirects }}" return_content: true validate_certs: "{{ well_known_file_check.validate_certs }}" + headers: + Origin: example.com check_mode: no register: result_well_known_identity ignore_errors: true diff --git a/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml b/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml index 233fe4a9..1d59f567 100644 --- a/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml +++ b/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml @@ -72,6 +72,13 @@ mode: 0644 when: matrix_nginx_proxy_proxy_riot_compat_redirect_enabled|bool +- name: Ensure Matrix nginx-proxy configuration for Hydrogen domain exists + template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-client-hydrogen.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_hydrogen_enabled|bool + - name: Ensure Matrix nginx-proxy configuration for dimension domain exists template: src: "{{ role_path }}/templates/nginx/conf.d/matrix-dimension.conf.j2" @@ -79,6 +86,13 @@ mode: 0644 when: matrix_nginx_proxy_proxy_dimension_enabled|bool +- name: Ensure Matrix nginx-proxy configuration for goneb domain exists + template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-bot-go-neb.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_bot_go_neb_enabled|bool + - name: Ensure Matrix nginx-proxy configuration for jitsi domain exists template: src: "{{ role_path }}/templates/nginx/conf.d/matrix-jitsi.conf.j2" @@ -93,6 +107,13 @@ mode: 0644 when: matrix_nginx_proxy_proxy_grafana_enabled|bool +- name: Ensure Matrix nginx-proxy configuration for sygnal domain exists + template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-sygnal.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-sygnal.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_sygnal_enabled|bool + - name: Ensure Matrix nginx-proxy configuration for Matrix domain exists template: src: "{{ role_path }}/templates/nginx/conf.d/matrix-domain.conf.j2" @@ -190,12 +211,24 @@ state: absent when: "not matrix_nginx_proxy_proxy_riot_compat_redirect_enabled|bool" +- name: Ensure Matrix nginx-proxy configuration for Hydrogen domain deleted + file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-client-hydrogen.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_hydrogen_enabled|bool" + - name: Ensure Matrix nginx-proxy configuration for dimension domain deleted file: path: "{{ matrix_nginx_proxy_confd_path }}/matrix-dimension.conf" state: absent when: "not matrix_nginx_proxy_proxy_dimension_enabled|bool" +- name: Ensure Matrix nginx-proxy configuration for goneb domain deleted + file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-bot-go-neb.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_bot_go_neb_enabled|bool" + - name: Ensure Matrix nginx-proxy configuration for jitsi domain deleted file: path: "{{ matrix_nginx_proxy_confd_path }}/matrix-jitsi.conf" @@ -208,6 +241,12 @@ state: absent when: "not matrix_nginx_proxy_proxy_grafana_enabled|bool" +- name: Ensure Matrix nginx-proxy configuration for sygnal domain deleted + file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-sygnal.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_sygnal_enabled|bool" + - name: Ensure Matrix nginx-proxy homepage for base domain deleted file: path: "{{ matrix_nginx_proxy_data_path }}/matrix-domain/index.html" diff --git a/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml b/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml index f0b14327..5bf9102d 100644 --- a/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml +++ b/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml @@ -11,7 +11,6 @@ - "{{ matrix_cron_path }}/matrix-ssl-certificate-renewal" - "{{ matrix_cron_path }}/matrix-nginx-proxy-periodic-restarter" - "/etc/cron.d/matrix-ssl-lets-encrypt" - - "{{ matrix_local_bin_path }}/matrix-ssl-lets-encrypt-certificates-renew" # # Tasks related to setting up Let's Encrypt's management of certificates diff --git a/roles/matrix-nginx-proxy/tasks/validate_config.yml b/roles/matrix-nginx-proxy/tasks/validate_config.yml index 3197bd97..9661ae5e 100644 --- a/roles/matrix-nginx-proxy/tasks/validate_config.yml +++ b/roles/matrix-nginx-proxy/tasks/validate_config.yml @@ -40,8 +40,8 @@ - name: Fail if required variables are undefined fail: - msg: "Detected an undefined required variable" + msg: "The `{{ item }}` variable must be defined and have a non-null value" with_items: - "matrix_ssl_lets_encrypt_support_email" - when: "vars[item] is none" + when: "vars[item] == '' or vars[item] is none" when: "matrix_ssl_retrieval_method == 'lets-encrypt'" diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 index 227747a5..55f5b266 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 @@ -5,6 +5,11 @@ gzip on; gzip_types text/plain application/json; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + {% for configuration_block in matrix_nginx_proxy_proxy_domain_additional_server_configuration_blocks %} {{- configuration_block }} {% endfor %} @@ -64,6 +69,18 @@ server { ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; {{ render_vhost_directives() }} } diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2 new file mode 100644 index 00000000..da3c7b1d --- /dev/null +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2 @@ -0,0 +1,91 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Content-Type-Options nosniff; + +{% for configuration_block in matrix_nginx_proxy_proxy_bot_go_neb_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% 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-bot-go-neb:4050"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:4050; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + server_name {{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% 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-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 index f56d7fd5..e79fb1fb 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 @@ -3,9 +3,14 @@ {% macro render_vhost_directives() %} gzip on; gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + {% for configuration_block in matrix_nginx_proxy_proxy_element_additional_server_configuration_blocks %} {{- configuration_block }} {% endfor %} @@ -74,6 +79,18 @@ server { {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_element_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {{ render_vhost_directives() }} } {% endif %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2 new file mode 100644 index 00000000..5ad99603 --- /dev/null +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2 @@ -0,0 +1,98 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options SAMEORIGIN; + add_header X-XSS-Protection "1; mode=block"; + add_header Content-Security-Policy "frame-ancestors 'none'"; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + {% for configuration_block in matrix_nginx_proxy_proxy_hydrogen_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% 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-client-hydrogen:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8768; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_hydrogen_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% 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-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_hydrogen_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_hydrogen_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_hydrogen_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_element_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 index 038d3557..67161745 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 @@ -3,8 +3,13 @@ {% macro render_vhost_directives() %} gzip on; gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options nosniff; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + {% for configuration_block in matrix_nginx_proxy_proxy_dimension_additional_server_configuration_blocks %} {{- configuration_block }} {% endfor %} @@ -72,6 +77,18 @@ server { {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {{ render_vhost_directives() }} } {% endif %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 index 2ab78a1b..fc0d54b5 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 @@ -17,6 +17,10 @@ gzip on; gzip_types text/plain application/json; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + location /.well-known/matrix { root {{ matrix_static_files_base_path }}; {# @@ -47,6 +51,7 @@ proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; } {% endif %} @@ -64,6 +69,7 @@ proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; } {% endif %} @@ -98,6 +104,7 @@ proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; } {% endif %} @@ -122,13 +129,20 @@ proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; 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; } - location / { + {# + We only handle the root URI for this redirect or homepage serving. + Unhandled URIs (mostly by `matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefix_regexes` above) should result in a 404, + instead of causing a redirect. + See: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1058 + #} + location ~* ^/$ { {% 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 %} @@ -188,6 +202,18 @@ server { {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {{ render_vhost_directives() }} } {% endif %} @@ -199,10 +225,10 @@ server { #} server { {% if matrix_nginx_proxy_https_enabled %} - listen 8448 ssl http2; - listen [::]:8448 ssl http2; + listen {{ matrix_nginx_proxy_proxy_matrix_federation_port }} ssl http2; + listen [::]:{{ matrix_nginx_proxy_proxy_matrix_federation_port }} ssl http2; {% else %} - listen 8448; + listen {{ matrix_nginx_proxy_proxy_matrix_federation_port }}; {% endif %} server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; @@ -222,6 +248,18 @@ server { ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_trusted_certificate }}; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; {% endif %} location / { @@ -237,6 +275,7 @@ server { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; client_body_buffer_size 25M; client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb }}M; diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 index 0e1f1c2d..08df8050 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 @@ -3,9 +3,20 @@ {% macro render_vhost_directives() %} gzip on; gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - add_header X-Content-Type-Options nosniff; - add_header X-Frame-Options SAMEORIGIN; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + # duplicate X-Content-Type-Options & X-Frame-Options header + # Enabled by grafana by default + # add_header X-Content-Type-Options nosniff; + # add_header X-Frame-Options SAMEORIGIN; + add_header Referrer-Policy "strict-origin-when-cross-origin"; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + proxy_cookie_path / "/; HTTPOnly; Secure"; + {% for configuration_block in matrix_nginx_proxy_proxy_grafana_additional_server_configuration_blocks %} {{- configuration_block }} {% endfor %} @@ -74,6 +85,18 @@ server { {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_grafana_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {{ render_vhost_directives() }} } {% endif %} 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 eb3d67b1..0949cb26 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 @@ -3,8 +3,13 @@ {% macro render_vhost_directives() %} gzip on; gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options nosniff; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + {% for configuration_block in matrix_nginx_proxy_proxy_jitsi_additional_server_configuration_blocks %} {{- configuration_block }} {% endfor %} @@ -17,7 +22,7 @@ proxy_pass http://$backend; {% else %} {# Generic configuration for use outside of our container setup #} - proxy_pass http://127.0.0.1:12080; + proxy_pass http://127.0.0.1:13080; {% endif %} proxy_set_header Host $host; @@ -32,7 +37,7 @@ proxy_pass http://$backend; {% else %} {# Generic configuration for use outside of our container setup #} - proxy_pass http://127.0.0.1:12090; + proxy_pass http://127.0.0.1:13090; {% endif %} proxy_set_header Host $host; @@ -44,6 +49,27 @@ tcp_nodelay on; } + + # XMPP websocket + location = /xmpp-websocket { + {% if matrix_nginx_proxy_enabled %} + resolver 127.0.0.11 valid=5s; + set $backend {{ matrix_jitsi_xmpp_bosh_url_base }}; + proxy_pass $backend/xmpp-websocket; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:5280; + {% endif %} + proxy_set_header Host $host; + + proxy_http_version 1.1; + proxy_read_timeout 900s; + proxy_set_header Connection "upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + tcp_nodelay on; + } {% endmacro %} server { @@ -93,6 +119,18 @@ server { {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_jitsi_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {{ render_vhost_directives() }} } {% endif %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 index a70dcea3..36a28039 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 @@ -1,6 +1,10 @@ #jinja2: lstrip_blocks: "True" {% macro render_vhost_directives() %} + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + {% for configuration_block in matrix_nginx_proxy_proxy_riot_additional_server_configuration_blocks %} {{- configuration_block }} {% endfor %} @@ -58,6 +62,18 @@ server { {% endif %} ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_compat_redirect_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {{ render_vhost_directives() }} } {% endif %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-sygnal.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-sygnal.conf.j2 new file mode 100644 index 00000000..5482fa8e --- /dev/null +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-sygnal.conf.j2 @@ -0,0 +1,93 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options DENY; + +{% for configuration_block in matrix_nginx_proxy_proxy_sygnal_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% 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-sygnal:6000"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:6000; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + server_name {{ matrix_nginx_proxy_proxy_sygnal_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% 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-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_sygnal_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_sygnal_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_sygnal_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_sygnal_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} 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 7041468e..db111090 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 @@ -11,7 +11,7 @@ upstream generic_worker_upstream { # ensures that requests from the same client will always be passed # to the same server (except when this server is unavailable) - ip_hash; + hash $http_x_forwarded_for; {% for worker in generic_workers %} {% if matrix_nginx_proxy_enabled %} @@ -79,7 +79,6 @@ server { location ~ {{ location }} { proxy_pass http://generic_worker_upstream$request_uri; proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; } {% endfor %} {% endif %} @@ -90,7 +89,6 @@ server { location ~ {{ location }} { proxy_pass http://media_repository_upstream$request_uri; 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; @@ -106,7 +104,6 @@ server { location ~ {{ location }} { proxy_pass http://user_dir_upstream$request_uri; proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; } {% endfor %} {% endif %} @@ -117,7 +114,6 @@ server { location ~ {{ location }} { proxy_pass http://frontend_proxy_upstream$request_uri; proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; } {% endfor %} {% if matrix_nginx_proxy_synapse_presence_disabled %} @@ -125,7 +121,6 @@ server { location ~ ^/_matrix/client/(api/v1|r0|unstable)/presence/[^/]+/status { proxy_pass http://frontend_proxy_upstream$request_uri; proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; } {% endif %} {% endif %} @@ -150,7 +145,6 @@ server { {% endif %} proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; {% if matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_enabled %} auth_basic "protected"; @@ -172,7 +166,6 @@ server { {% 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; @@ -199,7 +192,6 @@ server { location ~ {{ location }} { proxy_pass http://generic_worker_upstream$request_uri; proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; } {% endfor %} {% endif %} @@ -209,7 +201,6 @@ server { location ~ {{ location }} { proxy_pass http://media_repository_upstream$request_uri; 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_federation_api_client_max_body_size_mb }}M; @@ -231,7 +222,6 @@ server { {% 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_federation_api_client_max_body_size_mb }}M; diff --git a/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 index facb0901..9ec7fa56 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 @@ -8,14 +8,18 @@ # - various temp paths are changed to `/tmp`, so that a non-root user can write to them # - the `user` directive was removed, as we don't want nginx to switch users -worker_processes 1; - +worker_processes {{ matrix_nginx_proxy_worker_processes }}; error_log /var/log/nginx/error.log warn; pid /tmp/nginx.pid; - +{% for configuration_block in matrix_nginx_proxy_proxy_additional_configuration_blocks %} + {{- configuration_block }} +{% endfor %} events { - worker_connections 1024; + worker_connections {{ matrix_nginx_proxy_worker_connections }}; +{% for configuration_block in matrix_nginx_proxy_proxy_event_additional_configuration_blocks %} + {{- configuration_block }} +{% endfor %} } @@ -44,6 +48,8 @@ http { keepalive_timeout 65; + server_tokens off; + #gzip on; {# Map directive needed for proxied WebSocket upgrades #} map $http_upgrade $connection_upgrade { 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 old mode 100644 new mode 100755 index bd3070ac..c4000fa9 --- a/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 +++ b/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 @@ -30,10 +30,10 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-nginx-proxy \ -p {{ matrix_nginx_proxy_container_https_host_bind_port }}:8443 \ {% endif %} {% 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 \ + -p {{ matrix_nginx_proxy_container_federation_host_bind_port }}:{{ matrix_nginx_proxy_proxy_matrix_federation_port }} \ {% endif %} --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_data_path }},dst={{ matrix_nginx_proxy_data_path_in_container }},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 \ diff --git a/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 b/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 index 91b13b29..b1e1c21e 100644 --- a/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 +++ b/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 @@ -3,8 +3,8 @@ Description=Renews Let's Encrypt SSL certificates periodically [Timer] Unit=matrix-ssl-lets-encrypt-certificates-renew.service -OnCalendar=Sunday *-*-* 05:00:00 -RandomizedDelaySec=3h +OnCalendar=*-*-* 04:00:00 +RandomizedDelaySec=2h [Install] WantedBy=timers.target diff --git a/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 b/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 index 73c1848e..09cb6dad 100644 --- a/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 +++ b/roles/matrix-nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 @@ -3,8 +3,8 @@ Description=Reloads matrix-nginx-proxy periodically so that new SSL certificates [Timer] Unit=matrix-ssl-nginx-proxy-reload.service -OnCalendar=Sunday *-*-* 13:00:00 -RandomizedDelaySec=3h +OnCalendar=*-*-* 06:30:00 +RandomizedDelaySec=1h [Install] WantedBy=timers.target diff --git a/roles/matrix-postgres-backup/defaults/main.yml b/roles/matrix-postgres-backup/defaults/main.yml new file mode 100644 index 00000000..522764ac --- /dev/null +++ b/roles/matrix-postgres-backup/defaults/main.yml @@ -0,0 +1,40 @@ +matrix_postgres_backup_enabled: false + +matrix_postgres_backup_connection_hostname: "matrix-postgres" +matrix_postgres_backup_connection_port: 5432 +matrix_postgres_backup_connection_username: "matrix" +matrix_postgres_backup_connection_password: "" + +matrix_postgres_backup_extra_opts: "-Z9 --schema=public --blobs" +matrix_postgres_backup_schedule: "@daily" +matrix_postgres_backup_keep_days: 7 +matrix_postgres_backup_keep_weeks: 4 +matrix_postgres_backup_keep_months: 12 +matrix_postgres_backup_healthcheck_port: "8080" +matrix_postgres_backup_databases: [] +matrix_postgres_backup_path: "{{ matrix_base_data_path }}/postgres-backup" + +# Specifies where the Postgres data is. +# We use this to autodetect the Postgres version during playbook runtime (by parsing the `PG_VERSION` file contained there). +# You can leave this empty to prevent auto-detection. +matrix_postgres_backup_postgres_data_path: "" + +matrix_postgres_backup_architecture: amd64 + +# matrix_postgres_docker_image_suffix controls whether we use Alpine-based images (`-alpine`) or the normal Debian-based images. +# Alpine-based Postgres images are smaller and we usually prefer them, but they don't work on ARM32 (tested on a Raspberry Pi 3 running Raspbian 10.7). +# On ARM32, `-alpine` images fail with the following error: +# > LOG: startup process (PID 37) was terminated by signal 11: Segmentation fault +matrix_postgres_backup_docker_image_suffix: "{{ '-alpine' if matrix_postgres_backup_architecture in ['amd64', 'arm64'] else '' }}" + +matrix_postgres_backup_docker_image_v9: "{{ matrix_container_global_registry_prefix }}prodrigestivill/postgres-backup-local:9.6{{ matrix_postgres_backup_docker_image_suffix }}" +matrix_postgres_backup_docker_image_v10: "{{ matrix_container_global_registry_prefix }}prodrigestivill/postgres-backup-local:10{{ matrix_postgres_backup_docker_image_suffix }}" +matrix_postgres_backup_docker_image_v11: "{{ matrix_container_global_registry_prefix }}prodrigestivill/postgres-backup-local:11{{ matrix_postgres_backup_docker_image_suffix }}" +matrix_postgres_backup_docker_image_v12: "{{ matrix_container_global_registry_prefix }}prodrigestivill/postgres-backup-local:12{{ matrix_postgres_backup_docker_image_suffix }}" +matrix_postgres_backup_docker_image_v13: "{{ matrix_container_global_registry_prefix }}prodrigestivill/postgres-backup-local:13{{ matrix_postgres_backup_docker_image_suffix }}" +matrix_postgres_backup_docker_image_latest: "{{ matrix_postgres_backup_docker_image_v13 }}" + +# This variable is assigned at runtime. Overriding its value has no effect. +matrix_postgres_backup_docker_image_to_use: '{{ matrix_postgres_backup_docker_image_latest }}' + +matrix_postgres_backup_docker_image_force_pull: "{{ matrix_postgres_backup_docker_image_to_use.endswith(':latest') }}" diff --git a/roles/matrix-postgres-backup/tasks/init.yml b/roles/matrix-postgres-backup/tasks/init.yml new file mode 100644 index 00000000..c6a9bd7e --- /dev/null +++ b/roles/matrix-postgres-backup/tasks/init.yml @@ -0,0 +1,3 @@ +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-postgres-backup.service'] }}" + when: matrix_postgres_backup_enabled|bool diff --git a/roles/matrix-postgres-backup/tasks/main.yml b/roles/matrix-postgres-backup/tasks/main.yml new file mode 100644 index 00000000..19e3db5b --- /dev/null +++ b/roles/matrix-postgres-backup/tasks/main.yml @@ -0,0 +1,17 @@ +--- + +- import_tasks: "{{ role_path }}/tasks/init.yml" + tags: + - always + +- import_tasks: "{{ role_path }}/tasks/validate_config.yml" + when: "run_setup|bool and matrix_postgres_backup_enabled|bool" + tags: + - setup-all + - setup-postgres-backup + +- import_tasks: "{{ role_path }}/tasks/setup_postgres_backup.yml" + when: run_setup|bool + tags: + - setup-all + - setup-postgres-backup diff --git a/roles/matrix-postgres-backup/tasks/setup_postgres_backup.yml b/roles/matrix-postgres-backup/tasks/setup_postgres_backup.yml new file mode 100644 index 00000000..9761088d --- /dev/null +++ b/roles/matrix-postgres-backup/tasks/setup_postgres_backup.yml @@ -0,0 +1,103 @@ +--- + +# +# Tasks related to setting up an internal postgres server +# +- import_tasks: "{{ role_path }}/tasks/util/detect_existing_postgres_version.yml" + when: 'matrix_postgres_backup_enabled|bool and matrix_postgres_backup_postgres_data_path != ""' + +# If we have found an existing version (installed from before), we use its corresponding Docker image. +# If not, we install using the latest Postgres. +# +# Upgrading is supposed to be performed separately and explicitly (see `upgrade_postgres.yml`). +- set_fact: + matrix_postgres_backup_docker_image_to_use: "{{ matrix_postgres_backup_docker_image_latest if matrix_postgres_backup_detected_version_corresponding_docker_image|default('') == '' else matrix_postgres_backup_detected_version_corresponding_docker_image }}" + when: matrix_postgres_backup_enabled|bool + +- name: Ensure postgres backup Docker image is pulled + docker_image: + name: "{{ matrix_postgres_backup_docker_image_to_use }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_postgres_backup_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_backup_docker_image_force_pull }}" + when: matrix_postgres_backup_enabled|bool + +- name: Ensure Postgres backup paths exist + file: + path: "{{ item }}" + state: directory + mode: 0700 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - "{{ matrix_postgres_backup_path }}" + when: matrix_postgres_backup_enabled|bool + +- name: Ensure Postgres environment variables file created + template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_postgres_backup_path }}/{{ item }}" + mode: 0640 + with_items: + - "env-postgres-backup" + when: matrix_postgres_backup_enabled|bool + +- name: Ensure matrix-postgres-backup.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-postgres-backup.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-postgres-backup.service" + mode: 0644 + register: matrix_postgres_backup_systemd_service_result + when: matrix_postgres_backup_enabled|bool + +- name: Ensure systemd reloaded after matrix-postgres-backup.service installation + service: + daemon_reload: yes + when: "matrix_postgres_backup_enabled|bool and matrix_postgres_backup_systemd_service_result.changed" + +# +# Tasks related to getting rid of the internal postgres backup server (if it was previously enabled) +# + +- name: Check existence of matrix-postgres-backup service + stat: + path: "{{ matrix_systemd_path }}/matrix-postgres-backup.service" + register: matrix_postgres_backup_service_stat + when: "not matrix_postgres_backup_enabled|bool" + +- name: Ensure matrix-postgres-backup is stopped + service: + name: matrix-postgres-backup + state: stopped + daemon_reload: yes + when: "not matrix_postgres_backup_enabled|bool and matrix_postgres_backup_service_stat.stat.exists" + +- name: Ensure matrix-postgres-backup.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-postgres-backup.service" + state: absent + when: "not matrix_postgres_backup_enabled|bool and matrix_postgres_backup_service_stat.stat.exists" + +- name: Ensure systemd reloaded after matrix-postgres-backup.service removal + service: + daemon_reload: yes + when: "not matrix_postgres_backup_enabled|bool and matrix_postgres_backup_service_stat.stat.exists" + +- name: Check existence of matrix-postgres-backup backup path + stat: + path: "{{ matrix_postgres_backup_path }}" + register: matrix_postgres_backup_path_stat + when: "not matrix_postgres_backup_enabled|bool" + +# We just want to notify the user. Deleting data is too destructive. +- name: Inject warning if matrix-postgres backup data remains + set_fact: + matrix_playbook_runtime_results: | + {{ + matrix_playbook_runtime_results|default([]) + + + [ + "NOTE: You are not using the local backup service to backup the PostgreSQL database, but some old data remains from before in `{{ matrix_postgres_backup_path }}`. Feel free to delete it." + ] + }} + when: "not matrix_postgres_backup_enabled|bool and matrix_postgres_backup_path_stat.stat.exists" diff --git a/roles/matrix-postgres-backup/tasks/util/detect_existing_postgres_version.yml b/roles/matrix-postgres-backup/tasks/util/detect_existing_postgres_version.yml new file mode 100644 index 00000000..87a81f74 --- /dev/null +++ b/roles/matrix-postgres-backup/tasks/util/detect_existing_postgres_version.yml @@ -0,0 +1,56 @@ +--- + +# This utility aims to determine if there is some existing Postgres version in use or not. +# If there is, it also tries to detect the Docker image that corresponds to that version. + +- name: Initialize Postgres version determination variables (default to empty) + set_fact: + matrix_postgres_backup_detection_pg_version_path: "{{ matrix_postgres_data_path }}/PG_VERSION" + matrix_postgres_backup_detected_existing: false + matrix_postgres_backup_detected_version: "" + matrix_postgres_backup_detected_version_corresponding_docker_image: "" + +- name: Determine existing Postgres version (check PG_VERSION file) + stat: + path: "{{ matrix_postgres_backup_detection_pg_version_path }}" + register: result_pg_version_stat + +- set_fact: + matrix_postgres_backup_detected_existing: true + when: "result_pg_version_stat.stat.exists" + +- name: Determine existing Postgres version (read PG_VERSION file) + slurp: + src: "{{ matrix_postgres_backup_detection_pg_version_path }}" + register: result_pg_version + when: matrix_postgres_backup_detected_existing|bool + +- name: Determine existing Postgres version (make sense of PG_VERSION file) + set_fact: + matrix_postgres_backup_detected_version: "{{ result_pg_version['content']|b64decode|replace('\n', '') }}" + when: matrix_postgres_backup_detected_existing|bool + +- name: Determine corresponding Docker image to detected version (assume default of latest) + set_fact: + matrix_postgres_backup_detected_version_corresponding_docker_image: "{{ matrix_postgres_backup_docker_image_latest }}" + when: "matrix_postgres_backup_detected_version != ''" + +- name: Determine corresponding Docker image to detected version (use 9.x, if detected) + set_fact: + matrix_postgres_backup_detected_version_corresponding_docker_image: "{{ matrix_postgres_backup_docker_image_v9 }}" + when: "matrix_postgres_backup_detected_version.startswith('9.')" + +- name: Determine corresponding Docker image to detected version (use 10.x, if detected) + set_fact: + matrix_postgres_backup_detected_version_corresponding_docker_image: "{{ matrix_postgres_backup_docker_image_v10 }}" + when: "matrix_postgres_backup_detected_version == '10' or matrix_postgres_backup_detected_version.startswith('10.')" + +- name: Determine corresponding Docker image to detected version (use 11.x, if detected) + set_fact: + matrix_postgres_backup_detected_version_corresponding_docker_image: "{{ matrix_postgres_backup_docker_image_v11 }}" + when: "matrix_postgres_backup_detected_version == '11' or matrix_postgres_backup_detected_version.startswith('11.')" + +- name: Determine corresponding Docker image to detected version (use 12.x, if detected) + set_fact: + matrix_postgres_backup_detected_version_corresponding_docker_image: "{{ matrix_postgres_backup_docker_image_v12 }}" + when: "matrix_postgres_backup_detected_version == '12' or matrix_postgres_backup_detected_version.startswith('12.')" diff --git a/roles/matrix-postgres-backup/tasks/validate_config.yml b/roles/matrix-postgres-backup/tasks/validate_config.yml new file mode 100644 index 00000000..fda9b919 --- /dev/null +++ b/roles/matrix-postgres-backup/tasks/validate_config.yml @@ -0,0 +1,18 @@ +--- + +- name: Fail if required Postgres settings not defined + fail: + msg: >- + You need to define a required configuration setting (`{{ item }}`). + when: "vars[item] == ''" + with_items: + - "matrix_postgres_backup_connection_hostname" + - "matrix_postgres_backup_connection_username" + - "matrix_postgres_backup_connection_password" + - "matrix_postgres_backup_connection_port" + - "matrix_postgres_backup_schedule" + - "matrix_postgres_backup_keep_days" + - "matrix_postgres_backup_keep_weeks" + - "matrix_postgres_backup_keep_months" + - "matrix_postgres_backup_path" + - "matrix_postgres_backup_databases" diff --git a/roles/matrix-postgres-backup/templates/env-postgres-backup.j2 b/roles/matrix-postgres-backup/templates/env-postgres-backup.j2 new file mode 100644 index 00000000..5a3a1ffd --- /dev/null +++ b/roles/matrix-postgres-backup/templates/env-postgres-backup.j2 @@ -0,0 +1,12 @@ +#jinja2: lstrip_blocks: "True" +POSTGRES_USER={{ matrix_postgres_backup_connection_username }} +POSTGRES_PASSWORD={{ matrix_postgres_backup_connection_password }} +POSTGRES_HOST={{ matrix_postgres_backup_connection_hostname }} +POSTGRES_DB={{ matrix_postgres_backup_databases|join(', ') }} +POSTGRES_EXTRA_OPTS={{ matrix_postgres_backup_extra_opts }} +SCHEDULE={{ matrix_postgres_backup_schedule }} +BACKUP_KEEP_DAYS={{ matrix_postgres_backup_keep_days }} +BACKUP_KEEP_WEEKS={{ matrix_postgres_backup_keep_weeks }} +BACKUP_KEEP_MONTHS={{ matrix_postgres_backup_keep_months }} +HEALTHCHECK_PORT={{ matrix_postgres_backup_healthcheck_port }} +POSTGRES_PORT={{ matrix_postgres_backup_connection_port }} \ No newline at end of file diff --git a/roles/matrix-postgres-backup/templates/systemd/matrix-postgres-backup.service.j2 b/roles/matrix-postgres-backup/templates/systemd/matrix-postgres-backup.service.j2 new file mode 100644 index 00000000..97c9ae7f --- /dev/null +++ b/roles/matrix-postgres-backup/templates/systemd/matrix-postgres-backup.service.j2 @@ -0,0 +1,31 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Automatic Backup of Matrix Postgres server +After=docker.service +Requires=docker.service +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ matrix_systemd_unit_home_path }}" +ExecStartPre=-{{ matrix_host_command_docker }} stop matrix-postgres-backup +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-postgres-backup 2>/dev/null' + +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-postgres-backup \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --network={{ matrix_docker_network }} \ + --env-file={{ matrix_postgres_backup_path }}/env-postgres-backup \ + --mount type=bind,src={{ matrix_postgres_backup_path }},dst=/backups \ + {{ matrix_postgres_backup_docker_image_to_use }} + +ExecStop=-{{ matrix_host_command_docker }} stop matrix-postgres-backup +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-postgres-backup 2>/dev/null' +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-postgres-backup + +[Install] +WantedBy=multi-user.target diff --git a/roles/matrix-postgres/defaults/main.yml b/roles/matrix-postgres/defaults/main.yml index 8e1d2a8e..72e42021 100644 --- a/roles/matrix-postgres/defaults/main.yml +++ b/roles/matrix-postgres/defaults/main.yml @@ -17,11 +17,11 @@ matrix_postgres_architecture: amd64 # > LOG: startup process (PID 37) was terminated by signal 11: Segmentation fault matrix_postgres_docker_image_suffix: "{{ '-alpine' if matrix_postgres_architecture in ['amd64', 'arm64'] else '' }}" -matrix_postgres_docker_image_v9: "docker.io/postgres:9.6.21{{ matrix_postgres_docker_image_suffix }}" -matrix_postgres_docker_image_v10: "docker.io/postgres:10.16{{ matrix_postgres_docker_image_suffix }}" -matrix_postgres_docker_image_v11: "docker.io/postgres:11.11{{ matrix_postgres_docker_image_suffix }}" -matrix_postgres_docker_image_v12: "docker.io/postgres:12.6{{ matrix_postgres_docker_image_suffix }}" -matrix_postgres_docker_image_v13: "docker.io/postgres:13.2{{ matrix_postgres_docker_image_suffix }}" +matrix_postgres_docker_image_v9: "{{ matrix_container_global_registry_prefix }}postgres:9.6.21{{ matrix_postgres_docker_image_suffix }}" +matrix_postgres_docker_image_v10: "{{ matrix_container_global_registry_prefix }}postgres:10.16{{ matrix_postgres_docker_image_suffix }}" +matrix_postgres_docker_image_v11: "{{ matrix_container_global_registry_prefix }}postgres:11.11{{ matrix_postgres_docker_image_suffix }}" +matrix_postgres_docker_image_v12: "{{ matrix_container_global_registry_prefix }}postgres:12.6{{ matrix_postgres_docker_image_suffix }}" +matrix_postgres_docker_image_v13: "{{ matrix_container_global_registry_prefix }}postgres:13.2{{ matrix_postgres_docker_image_suffix }}" matrix_postgres_docker_image_latest: "{{ matrix_postgres_docker_image_v13 }}" # This variable is assigned at runtime. Overriding its value has no effect. @@ -90,6 +90,6 @@ matrix_postgres_pgloader_container_image_self_build_src_path: "{{ matrix_postgre # 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_name_prefix: "{{ 'localhost/' if matrix_postgres_pgloader_container_image_self_build else matrix_container_global_registry_prefix }}" 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/util/migrate_db_to_postgres.yml b/roles/matrix-postgres/tasks/util/migrate_db_to_postgres.yml index d3429c97..cf595ade 100644 --- a/roles/matrix-postgres/tasks/util/migrate_db_to_postgres.yml +++ b/roles/matrix-postgres/tasks/util/migrate_db_to_postgres.yml @@ -61,7 +61,8 @@ docker_image: name: "{{ matrix_postgres_pgloader_docker_image }}" source: build - force_source: "{{ matrix_postgres_pgloader_git_pull_results.changed }}" + force_source: "{{ matrix_postgres_pgloader_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_postgres_pgloader_container_image_self_build_src_path }}" diff --git a/roles/matrix-prometheus-node-exporter/defaults/main.yml b/roles/matrix-prometheus-node-exporter/defaults/main.yml index 29dce364..492d48b1 100644 --- a/roles/matrix-prometheus-node-exporter/defaults/main.yml +++ b/roles/matrix-prometheus-node-exporter/defaults/main.yml @@ -3,7 +3,8 @@ matrix_prometheus_node_exporter_enabled: false -matrix_prometheus_node_exporter_docker_image: "docker.io/prom/node-exporter:v1.1.0" +matrix_prometheus_node_exporter_version: v1.1.2 +matrix_prometheus_node_exporter_docker_image: "{{ matrix_container_global_registry_prefix }}prom/node-exporter:{{ matrix_prometheus_node_exporter_version }}" matrix_prometheus_node_exporter_docker_image_force_pull: "{{ matrix_prometheus_node_exporter_docker_image.endswith(':latest') }}" # A list of extra arguments to pass to the container @@ -17,5 +18,17 @@ matrix_prometheus_node_exporter_systemd_wanted_services_list: [] # Controls whether the matrix-prometheus container exposes its HTTP port (tcp/9100 in the container). # -# Takes an ":" or "" value (e.g. "127.0.0.1:9100"), or empty string to not expose. +# Takes an ":" value (e.g. "127.0.0.1:9100"), or empty string to not expose. +# +# Official recommendations are to run this container with `--net=host`, +# but we don't do that, since it: +# - likely exposes the metrics web server way too publicly (before applying https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1008) +# - or listens on a loopback interface only (--net=host and 127.0.0.1:9100), which is not reachable from another container (like `matrix-prometheus`) +# +# Using `--net=host` and binding to Docker's `matrix` bridge network may be a solution to both, +# but that's trickier to accomplish and won't necessarily work (hasn't been tested). +# +# Not using `--net=host` means that our network statistic reports are likely broken (inaccurate), +# because node-exporter can't see all interfaces, etc. +# For now, we'll live with that, until someone develops a better solution. matrix_prometheus_node_exporter_container_http_host_bind_port: '' diff --git a/roles/matrix-prometheus-node-exporter/tasks/setup.yml b/roles/matrix-prometheus-node-exporter/tasks/setup.yml index 6f03fbaa..34086e6c 100644 --- a/roles/matrix-prometheus-node-exporter/tasks/setup.yml +++ b/roles/matrix-prometheus-node-exporter/tasks/setup.yml @@ -52,9 +52,3 @@ service: daemon_reload: yes when: "not matrix_prometheus_node_exporter_enabled|bool and matrix_prometheus_node_exporter_service_stat.stat.exists" - -- name: Ensure matrix-prometheus-node-exporter Docker image doesn't exist - docker_image: - name: "{{ matrix_prometheus_node_exporter_docker_image }}" - state: absent - when: "not matrix_prometheus_node_exporter_enabled|bool" diff --git a/roles/matrix-prometheus-node-exporter/templates/systemd/matrix-prometheus-node-exporter.service.j2 b/roles/matrix-prometheus-node-exporter/templates/systemd/matrix-prometheus-node-exporter.service.j2 index 93638c19..210a0d97 100644 --- a/roles/matrix-prometheus-node-exporter/templates/systemd/matrix-prometheus-node-exporter.service.j2 +++ b/roles/matrix-prometheus-node-exporter/templates/systemd/matrix-prometheus-node-exporter.service.j2 @@ -22,13 +22,13 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-prometheus-nod --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ --read-only \ - {% if matrix_prometheus_node_exporter_container_http_host_bind_port %} - -p {{ matrix_prometheus_node_exporter_container_http_host_bind_port }}:9100 \ - {% endif %} {% for arg in matrix_prometheus_node_exporter_container_extra_arguments %} {{ arg }} \ {% endfor %} - --net=host \ + --network={{ matrix_docker_network }} \ + {% if matrix_prometheus_node_exporter_container_http_host_bind_port %} + -p {{ matrix_prometheus_node_exporter_container_http_host_bind_port }}:9100 \ + {% endif %} --pid=host \ --mount type=bind,src=/,dst=/host,ro,bind-propagation=rslave \ {{ matrix_prometheus_node_exporter_docker_image }} \ diff --git a/roles/matrix-prometheus/defaults/main.yml b/roles/matrix-prometheus/defaults/main.yml index 56018ba6..02afd9e9 100644 --- a/roles/matrix-prometheus/defaults/main.yml +++ b/roles/matrix-prometheus/defaults/main.yml @@ -3,7 +3,8 @@ matrix_prometheus_enabled: false -matrix_prometheus_docker_image: "docker.io/prom/prometheus:v2.24.1" +matrix_prometheus_version: v2.27.0 +matrix_prometheus_docker_image: "{{ matrix_container_global_registry_prefix }}prom/prometheus:{{ matrix_prometheus_version }}" matrix_prometheus_docker_image_force_pull: "{{ matrix_prometheus_docker_image.endswith(':latest') }}" matrix_prometheus_base_path: "{{ matrix_base_data_path }}/prometheus" @@ -63,4 +64,3 @@ matrix_prometheus_configuration_extension: "{{ matrix_prometheus_configuration_e # Holds the final configuration (a combination of the default and its extension). # You most likely don't need to touch this variable. Instead, see `matrix_prometheus_configuration_yaml`. matrix_prometheus_configuration: "{{ matrix_prometheus_configuration_yaml|from_yaml|combine(matrix_prometheus_configuration_extension, recursive=True) }}" - diff --git a/roles/matrix-prometheus/tasks/setup_install.yml b/roles/matrix-prometheus/tasks/setup_install.yml index 8aee5178..15a69279 100644 --- a/roles/matrix-prometheus/tasks/setup_install.yml +++ b/roles/matrix-prometheus/tasks/setup_install.yml @@ -19,22 +19,6 @@ - "{{ matrix_prometheus_config_path }}" - "{{ matrix_prometheus_data_path }}" -- block: - # Well, this actually creates the network if it doesn't exist, but.. - # The network should have been created by `matrix-base` already. - # We don't rely on that other call and its result, because it runs - # on `--tags=setup-all`, but will get skipped during `--tags=setup-prometheus`. - - name: Fetch Matrix Docker network details - docker_network: - name: "{{ matrix_docker_network }}" - driver: bridge - register: matrix_docker_network_info - - - set_fact: - matrix_prometheus_scraper_node_targets: ["{{ matrix_docker_network_info.network.IPAM.Config[0].Gateway }}:9100"] - when: "matrix_prometheus_scraper_node_enabled|bool and matrix_prometheus_scraper_node_targets|length == 0" - - - name: Download synapse-v2.rules get_url: url: "{{ matrix_prometheus_scraper_synapse_rules_download_url }}" diff --git a/roles/matrix-prometheus/tasks/setup_uninstall.yml b/roles/matrix-prometheus/tasks/setup_uninstall.yml index 0a4a8cb6..dd46a222 100644 --- a/roles/matrix-prometheus/tasks/setup_uninstall.yml +++ b/roles/matrix-prometheus/tasks/setup_uninstall.yml @@ -23,9 +23,3 @@ service: daemon_reload: yes when: "matrix_prometheus_service_stat.stat.exists|bool" - -- name: Ensure matrix-prometheus Docker image doesn't exist - docker_image: - name: "{{ matrix_prometheus_docker_image }}" - state: absent - when: "not matrix_prometheus_enabled|bool" diff --git a/roles/matrix-redis/defaults/main.yml b/roles/matrix-redis/defaults/main.yml index 74728d87..e33e7493 100644 --- a/roles/matrix-redis/defaults/main.yml +++ b/roles/matrix-redis/defaults/main.yml @@ -5,7 +5,8 @@ matrix_redis_connection_password: "" matrix_redis_base_path: "{{ matrix_base_data_path }}/redis" matrix_redis_data_path: "{{ matrix_redis_base_path }}/data" -matrix_redis_docker_image_v6: "docker.io/redis:6.0.10-alpine" +matrix_redis_version: 6.0.10-alpine +matrix_redis_docker_image_v6: "{{ matrix_container_global_registry_prefix }}redis:{{ matrix_redis_version }}" matrix_redis_docker_image_latest: "{{ matrix_redis_docker_image_v6 }}" matrix_redis_docker_image_to_use: '{{ matrix_redis_docker_image_latest }}' diff --git a/roles/matrix-registration/defaults/main.yml b/roles/matrix-registration/defaults/main.yml index 065e0c48..e03891b2 100644 --- a/roles/matrix-registration/defaults/main.yml +++ b/roles/matrix-registration/defaults/main.yml @@ -15,7 +15,7 @@ matrix_registration_docker_src_files_path: "{{ matrix_registration_base_path }}/ matrix_registration_version: "v0.7.2" 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_name_prefix: "{{ 'localhost/' if matrix_registration_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_registration_docker_image_force_pull: "{{ matrix_registration_docker_image.endswith(':latest') }}" # A list of extra arguments to pass to the container diff --git a/roles/matrix-registration/tasks/init.yml b/roles/matrix-registration/tasks/init.yml index 158ad605..b58ba659 100644 --- a/roles/matrix-registration/tasks/init.yml +++ b/roles/matrix-registration/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_registration_container_image_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-registration.service'] }}" when: matrix_registration_enabled|bool diff --git a/roles/matrix-registration/tasks/setup_install.yml b/roles/matrix-registration/tasks/setup_install.yml index 2b806fe0..0d7da9ce 100644 --- a/roles/matrix-registration/tasks/setup_install.yml +++ b/roles/matrix-registration/tasks/setup_install.yml @@ -66,7 +66,8 @@ docker_image: name: "{{ matrix_registration_docker_image }}" source: build - force_source: "{{ matrix_registration_git_pull_results.changed }}" + force_source: "{{ matrix_registration_git_pull_results.changed 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_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_registration_docker_src_files_path }}" diff --git a/roles/matrix-sygnal/defaults/main.yml b/roles/matrix-sygnal/defaults/main.yml new file mode 100644 index 00000000..476ac2ad --- /dev/null +++ b/roles/matrix-sygnal/defaults/main.yml @@ -0,0 +1,95 @@ +# Sygnal is a reference Push Gateway for Matrix. +# To make use of it for delivering push notificatins, you'll need to develop/build your own Matrix app. +# Learn more here: https://github.com/matrix-org/sygnal +matrix_sygnal_enabled: false + +matrix_sygnal_base_path: "{{ matrix_base_data_path }}/sygnal" +matrix_sygnal_config_path: "{{ matrix_sygnal_base_path }}/config" +matrix_sygnal_data_path: "{{ matrix_sygnal_base_path }}/data" + +matrix_sygnal_version: v0.9.0 +matrix_sygnal_docker_image: "{{ matrix_container_global_registry_prefix }}matrixdotorg/sygnal:{{ matrix_sygnal_version }}" +matrix_sygnal_docker_image_force_pull: "{{ matrix_sygnal_docker_image.endswith(':latest') }}" + +# List of systemd services that matrix-sygnal.service depends on. +matrix_sygnal_systemd_required_services_list: ['docker.service'] + +# List of systemd services that matrix-sygnal.service wants +matrix_sygnal_systemd_wanted_services_list: [] + +# Controls whether the matrix-sygnal container exposes its HTTP port (tcp/6000 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:6000"), or empty string to not expose. +matrix_sygnal_container_http_host_bind_port: '' + +# A list of extra arguments to pass to the container +matrix_sygnal_container_extra_arguments: [] + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_sygnal_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_sygnal_postgres_*` variables +matrix_sygnal_database_engine: 'sqlite' + +matrix_sygnal_sqlite_database_path_local: "{{ matrix_sygnal_data_path }}/sygnal.db" +matrix_sygnal_sqlite_database_path_in_container: "/data/sygnal.db" + +matrix_sygnal_database_username: 'matrix_sygnal' +matrix_sygnal_database_password: 'some-password' +matrix_sygnal_database_hostname: 'matrix-postgres' +matrix_sygnal_database_port: 5432 +matrix_sygnal_database_name: 'matrix_sygnal' + +matrix_sygnal_database_connection_string: 'postgres://{{ matrix_sygnal_database_username }}:{{ matrix_sygnal_database_password }}@{{ matrix_sygnal_database_hostname }}:{{ matrix_sygnal_database_port }}/{{ matrix_sygnal_database_name }}' + +# A map (dictionary) of apps instances that this server works with. +# +# Example configuration: +# +# matrix_sygnal_apps: +# com.example.myapp.ios: +# type: apns +# # .. more configuration .. +# com.example.myapp.android: +# type: gcm +# api_key: your_api_key_for_gcm +# # .. more configuration .. +# +# The APNS configuration needs to reference some certificate files. +# One can put these in the `matrix_sygnal_data_path` directory (`/matrix/sygnal/data`), mounted to `/data` in the container. +# The `matrix_sygnal_apps` paths need to use the in-container path (`/data`). +# To install these files via the playbook, one can use the `matrix-aux` role. +# Examples and more details are available in `docs/configuring-playbook-sygnal.md`. +matrix_sygnal_apps: [] + +matrix_sygnal_metrics_prometheus_enabled: false + +# Default Sygnal configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_sygnal_configuration_extension_yaml`) +# or completely replace this variable with your own template. +matrix_sygnal_configuration_yaml: "{{ lookup('template', 'templates/sygnal.yaml.j2') }}" + +matrix_sygnal_configuration_extension_yaml: | + # Your custom YAML configuration for Sygnal goes here. + # This configuration extends the default starting configuration (`matrix_sygnal_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_sygnal_configuration_yaml`. + # + # Example configuration extension follows: + # metrics: + # opentracing: + # enabled: true + +matrix_sygnal_configuration_extension: "{{ matrix_sygnal_configuration_extension_yaml|from_yaml if matrix_sygnal_configuration_extension_yaml|from_yaml is mapping else {} }}" + +# Holds the final sygnal configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_sygnal_configuration_yaml`. +matrix_sygnal_configuration: "{{ matrix_sygnal_configuration_yaml|from_yaml|combine(matrix_sygnal_configuration_extension, recursive=True) }}" diff --git a/roles/matrix-sygnal/tasks/init.yml b/roles/matrix-sygnal/tasks/init.yml new file mode 100644 index 00000000..559a3681 --- /dev/null +++ b/roles/matrix-sygnal/tasks/init.yml @@ -0,0 +1,3 @@ +- set_fact: + matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-sygnal.service'] }}" + when: matrix_sygnal_enabled|bool diff --git a/roles/matrix-sygnal/tasks/main.yml b/roles/matrix-sygnal/tasks/main.yml new file mode 100644 index 00000000..c00862a4 --- /dev/null +++ b/roles/matrix-sygnal/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 + tags: + - setup-all + - setup-sygnal + +- import_tasks: "{{ role_path }}/tasks/setup_install.yml" + when: run_setup|bool and matrix_sygnal_enabled|bool + tags: + - setup-all + - setup-sygnal + +- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + when: run_setup|bool and not matrix_sygnal_enabled|bool + tags: + - setup-all + - setup-sygnal diff --git a/roles/matrix-sygnal/tasks/setup_install.yml b/roles/matrix-sygnal/tasks/setup_install.yml new file mode 100644 index 00000000..afac61c4 --- /dev/null +++ b/roles/matrix-sygnal/tasks/setup_install.yml @@ -0,0 +1,73 @@ +--- + +- set_fact: + matrix_sygnal_requires_restart: false + +- block: + - name: Check if an SQLite database already exists + stat: + path: "{{ matrix_sygnal_sqlite_database_path_local }}" + register: matrix_sygnal_sqlite_database_path_local_stat_result + + - block: + - set_fact: + matrix_postgres_db_migration_request: + src: "{{ matrix_sygnal_sqlite_database_path_local }}" + dst: "{{ matrix_sygnal_database_connection_string }}" + caller: "{{ role_path|basename }}" + engine_variable_name: 'matrix_sygnal_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-sygnal.service'] + pgloader_options: ['--with "quote identifiers"'] + + - import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml" + + - set_fact: + matrix_sygnal_requires_restart: true + when: "matrix_sygnal_sqlite_database_path_local_stat_result.stat.exists|bool" + when: "matrix_sygnal_database_engine == 'postgres'" + +- name: Ensure Sygnal image is pulled + docker_image: + name: "{{ matrix_sygnal_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_sygnal_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_sygnal_docker_image_force_pull }}" + +- name: Ensure Sygnal paths exists + file: + path: "{{ item }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - "{{ matrix_sygnal_base_path }}" + - "{{ matrix_sygnal_config_path }}" + - "{{ matrix_sygnal_data_path }}" + +- name: Ensure Sygnal config installed + copy: + content: "{{ matrix_sygnal_configuration|to_nice_yaml }}" + dest: "{{ matrix_sygnal_config_path }}/sygnal.yaml" + mode: 0640 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + +- name: Ensure matrix-sygnal.service installed + template: + src: "{{ role_path }}/templates/systemd/matrix-sygnal.service.j2" + dest: "{{ matrix_systemd_path }}/matrix-sygnal.service" + mode: 0644 + register: matrix_sygnal_systemd_service_result + +- name: Ensure systemd reloaded after matrix-sygnal.service installation + service: + daemon_reload: yes + when: "matrix_sygnal_systemd_service_result.changed|bool" + +- name: Ensure matrix-sygnal.service restarted, if necessary + service: + name: "matrix-sygnal.service" + state: restarted + when: "matrix_sygnal_requires_restart|bool" diff --git a/roles/matrix-sygnal/tasks/setup_uninstall.yml b/roles/matrix-sygnal/tasks/setup_uninstall.yml new file mode 100644 index 00000000..dc50078c --- /dev/null +++ b/roles/matrix-sygnal/tasks/setup_uninstall.yml @@ -0,0 +1,35 @@ +--- + +- name: Check existence of matrix-sygnal service + stat: + path: "{{ matrix_systemd_path }}/matrix-sygnal.service" + register: matrix_sygnal_service_stat + +- name: Ensure matrix-sygnal is stopped + service: + name: matrix-sygnal + state: stopped + daemon_reload: yes + register: stopping_result + when: "matrix_sygnal_service_stat.stat.exists|bool" + +- name: Ensure matrix-sygnal.service doesn't exist + file: + path: "{{ matrix_systemd_path }}/matrix-sygnal.service" + state: absent + when: "matrix_sygnal_service_stat.stat.exists|bool" + +- name: Ensure systemd reloaded after matrix-sygnal.service removal + service: + daemon_reload: yes + when: "matrix_sygnal_service_stat.stat.exists|bool" + +- name: Ensure Sygnal base directory doesn't exist + file: + path: "{{ matrix_sygnal_base_path }}" + state: absent + +- name: Ensure Sygnal Docker image doesn't exist + docker_image: + name: "{{ matrix_sygnal_docker_image }}" + state: absent diff --git a/roles/matrix-sygnal/tasks/validate_config.yml b/roles/matrix-sygnal/tasks/validate_config.yml new file mode 100644 index 00000000..efd64104 --- /dev/null +++ b/roles/matrix-sygnal/tasks/validate_config.yml @@ -0,0 +1,13 @@ +- name: Fail if no Sygnal apps defined + fail: + msg: >- + Enabling Sygnal requires that you specify at least one app in `matrix_sygnal_apps` + when: "matrix_sygnal_enabled and matrix_sygnal_apps|length == 0" + +- name: Fail if running on a non-supported architecture + fail: + msg: >- + Sygnal can only be used on the amd64 architecture for now. + Only amd64 container images are pushed for the `docker.io/matrixdotorg/sygnal` container image. + Either use a different image (by redefining `matrix_sygnal_docker_image`) or consider contributing self-building support to this role. + when: "matrix_sygnal_enabled and matrix_architecture != 'amd64' and matrix_sygnal_docker_image.startswith('docker.io/matrixdotorg/sygnal')" diff --git a/roles/matrix-sygnal/templates/sygnal.yaml.j2 b/roles/matrix-sygnal/templates/sygnal.yaml.j2 new file mode 100644 index 00000000..bb8c521d --- /dev/null +++ b/roles/matrix-sygnal/templates/sygnal.yaml.j2 @@ -0,0 +1,288 @@ +## +# This is a configuration for Sygnal, the reference Push Gateway for Matrix +# See: matrix.org +## + +# The 'database' setting defines the database that sygnal uses to store all of +# its data. +# +# 'name' gives the database engine to use: either 'sqlite3' (for SQLite) or +# 'psycopg2' (for PostgreSQL). +# +# 'args' gives options which are passed through to the database engine, +# except for options starting 'cp_', which are used to configure the Twisted +# connection pool. For a reference to valid arguments, see: +# * for sqlite: https://docs.python.org/3/library/sqlite3.html#sqlite3.connect +# * for postgres: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS +# * for the connection pool: https://twistedmatrix.com/documents/current/api/twisted.enterprise.adbapi.ConnectionPool.html#__init__ +# +# +# Example SQLite configuration: +# +#database: +# name: sqlite3 +# args: +# dbfile: /path/to/database.db +# +# +# Example Postgres configuration: +# +#database: +# name: psycopg2 +# args: +# host: localhost +# database: sygnal +# user: sygnal +# password: pass +# cp_min: 1 +# cp_max: 5 +# +{% if matrix_sygnal_database_engine == 'sqlite' %} +database: + name: sqlite3 + args: + dbfile: {{ matrix_sygnal_sqlite_database_path_in_container|to_json }} +{% else %} +database: + name: psycopg2 + args: + host: {{ matrix_sygnal_database_hostname|to_json }} + database: {{ matrix_sygnal_database_name|to_json }} + user: {{ matrix_sygnal_database_username|to_json }} + password: {{ matrix_sygnal_database_password|to_json }} + cp_min: 1 + cp_max: 5 +{% endif %} + +## Logging # +# +log: + # Specify a Python logging 'dictConfig', as described at: + # https://docs.python.org/3.7/library/logging.config.html#logging.config.dictConfig + # + setup: + version: 1 + formatters: + normal: + format: "%(asctime)s [%(process)d] %(levelname)-5s %(name)s %(message)s" + handlers: + # This handler prints to Standard Error + # + stderr: + class: "logging.StreamHandler" + formatter: "normal" + stream: "ext://sys.stderr" + + # This handler prints to Standard Output. + # + stdout: + class: "logging.StreamHandler" + formatter: "normal" + stream: "ext://sys.stdout" + + # This handler demonstrates logging to a text file on the filesystem. + # You can use logrotate(8) to perform log rotation. + # + #file: + # class: "logging.handlers.WatchedFileHandler" + # formatter: "normal" + # filename: "./sygnal.log" + loggers: + # sygnal.access contains the access logging lines. + # Comment out this section if you don't want to give access logging + # any special treatment. + # + sygnal.access: + propagate: false + handlers: ["stdout"] + level: "INFO" + + # sygnal contains log lines from Sygnal itself. + # You can comment out this section to fall back to the root logger. + # + sygnal: + propagate: false + handlers: ["stderr"] + + root: + # Specify the handler(s) to send log messages to. + handlers: ["stderr"] + level: "INFO" + + disable_existing_loggers: false + + + access: + # Specify whether or not to trust the IP address in the `X-Forwarded-For` + # header. In general, you want to enable this if and only if you are using a + # reverse proxy which is configured to emit it. + # + x_forwarded_for: true + +## HTTP Server (Matrix Push Gateway API) # +# +http: + # Specify a list of interface addresses to bind to. + # + # This example listens on the IPv4 loopback device: + #bind_addresses: ['127.0.0.1'] + # This example listens on all IPv4 interfaces: + #bind_addresses: ['0.0.0.0'] + # This example listens on all IPv4 and IPv6 interfaces: + #bind_addresses: ['0.0.0.0', '::'] + bind_addresses: ['::'] + + # Specify the port number to listen on. + # + port: 6000 + +## Proxying for outgoing connections # +# +# Specify the URL of a proxy to use for outgoing traffic +# (e.g. to Apple & Google) if desired. +# Currently only HTTP proxies with CONNECT capability are supported. +# +# If you do not specify a value, the `HTTPS_PROXY` environment variable will +# be used if present. Otherwise, no proxy will be used. +# +# Default is unspecified. +# +#proxy: 'http://user:secret@prox:8080' + +## Metrics # +# +metrics: + ## Prometheus # + # + prometheus: + # Specify whether or not to enable Prometheus. + # + enabled: false + + # Specify an address for the Prometheus HTTP Server to listen on. + # + address: '0.0.0.0' + + # Specify a port for the Prometheus HTTP Server to listen on. + # + port: 8000 + + ## OpenTracing # + # + opentracing: + # Specify whether or not to enable OpenTracing. + # + enabled: false + + # Specify an implementation of OpenTracing to use. Currently only 'jaeger' + # is supported. + # + implementation: jaeger + + # Specify the service name to be reported to the tracer. + # + service_name: sygnal + + # Specify configuration values to pass to jaeger_client. + # + jaeger: + sampler: + type: 'const' + param: 1 +# local_agent: +# reporting_host: '127.0.0.1' +# reporting_port: + logging: true + + ## Sentry # + # + sentry: + # Specify whether or not to enable Sentry. + # + enabled: false + + # Specify your Sentry DSN if you enable Sentry + # + #dsn: "https://@sentry.example.org/" + +## Pushkins/Apps # +# +# Add a section for every push application here. +# Specify the pushkey for the application and also the type. +# For the type, you may specify a fully-qualified Python classname if desired. +# +#apps: + # This is an example APNs push configuration + # + #com.example.myapp.ios: + # type: apns + # + # # Authentication + # # + # # Two methods of authentication to APNs are currently supported. + # # + # # You can authenticate using a key: + # keyfile: my_key.p8 + # key_id: MY_KEY_ID + # team_id: MY_TEAM_ID + # topic: MY_TOPIC + # + # # Or, a certificate can be used instead: + # certfile: com.example.myApp_prod_APNS.pem + # + # # This is the maximum number of in-flight requests *for this pushkin* + # # before additional notifications will be failed. + # # (This is a robustness measure to prevent one pushkin stacking up with + # # queued requests and saturating the inbound connection queue of a load + # # balancer or reverse proxy). + # # Defaults to 512 if unset. + # # + # #inflight_request_limit: 512 + # + # # Specifies whether to use the production or sandbox APNs server. Note that + # # sandbox tokens should only be used with the sandbox server and vice versa. + # # + # # Valid options are: + # # * production + # # * sandbox + # # + # # The default is 'production'. Uncomment to use the sandbox instance. + # #platform: sandbox + + # This is an example GCM/FCM push configuration. + # + #com.example.myapp.android: + # type: gcm + # api_key: your_api_key_for_gcm + # + # # This is the maximum number of connections to GCM servers at any one time + # # the default is 20. + # #max_connections: 20 + # + # # This is the maximum number of in-flight requests *for this pushkin* + # # before additional notifications will be failed. + # # (This is a robustness measure to prevent one pushkin stacking up with + # # queued requests and saturating the inbound connection queue of a load + # # balancer or reverse proxy). + # # Defaults to 512 if unset. + # # + # #inflight_request_limit: 512 + # + # # This allows you to specify additional options to send to Firebase. + # # + # # Of particular interest, admins who wish to support iOS apps using Firebase + # # probably wish to set content_available, and may need to set mutable_content. + # # (content_available allows your iOS app to be woken up by data messages, + # # and mutable_content allows your notification to be modified by a + # # Notification Service app extension). + # # + # # See https://firebase.google.com/docs/cloud-messaging/http-server-ref + # # for the exhaustive list of valid options. + # # + # # Do not specify `data`, `priority`, `to` or `registration_ids` as they may + # # be overwritten or lead to an invalid request. + # # + # #fcm_options: + # # content_available: true + # # mutable_content: true +apps: {{ matrix_sygnal_apps|to_json }} diff --git a/roles/matrix-sygnal/templates/systemd/matrix-sygnal.service.j2 b/roles/matrix-sygnal/templates/systemd/matrix-sygnal.service.j2 new file mode 100644 index 00000000..019ab40c --- /dev/null +++ b/roles/matrix-sygnal/templates/systemd/matrix-sygnal.service.j2 @@ -0,0 +1,42 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix Sygnal +{% for service in matrix_sygnal_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_sygnal_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ matrix_systemd_unit_home_path }}" +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-sygnal 2>/dev/null' +ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-sygnal 2>/dev/null' + +ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-sygnal \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --env=SYGNAL_CONF=/config/sygnal.yaml \ + --network={{ matrix_docker_network }} \ + {% if matrix_sygnal_container_http_host_bind_port %} + -p {{ matrix_sygnal_container_http_host_bind_port }}:6000 \ + {% endif %} + --mount type=bind,src={{ matrix_sygnal_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_sygnal_data_path }},dst=/data \ + {% for arg in matrix_sygnal_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_sygnal_docker_image }} + +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-sygnal 2>/dev/null' +ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-sygnal 2>/dev/null' +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-sygnal + +[Install] +WantedBy=multi-user.target diff --git a/roles/matrix-synapse-admin/defaults/main.yml b/roles/matrix-synapse-admin/defaults/main.yml index ce0ccd39..dc4cc770 100644 --- a/roles/matrix-synapse-admin/defaults/main.yml +++ b/roles/matrix-synapse-admin/defaults/main.yml @@ -8,8 +8,9 @@ matrix_synapse_admin_container_self_build_repo: "https://github.com/Awesome-Tech matrix_synapse_admin_docker_src_files_path: "{{ matrix_base_data_path }}/synapse-admin/docker-src" -matrix_synapse_admin_docker_image: "{{ matrix_synapse_admin_docker_image_name_prefix }}awesometechnologies/synapse-admin:0.7.0" -matrix_synapse_admin_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_admin_container_self_build else 'docker.io/' }}" +matrix_synapse_admin_version: latest +matrix_synapse_admin_docker_image: "{{ matrix_synapse_admin_docker_image_name_prefix }}awesometechnologies/synapse-admin:{{ matrix_synapse_admin_version }}" +matrix_synapse_admin_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_admin_container_self_build else matrix_container_global_registry_prefix }}" 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/init.yml b/roles/matrix-synapse-admin/tasks/init.yml index 36bdb611..7898dec9 100644 --- a/roles/matrix-synapse-admin/tasks/init.yml +++ b/roles/matrix-synapse-admin/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_synapse_admin_container_self_build" + - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-synapse-admin.service'] }}" when: matrix_synapse_admin_enabled|bool diff --git a/roles/matrix-synapse-admin/tasks/setup.yml b/roles/matrix-synapse-admin/tasks/setup.yml index a96ec10f..002ff68d 100644 --- a/roles/matrix-synapse-admin/tasks/setup.yml +++ b/roles/matrix-synapse-admin/tasks/setup.yml @@ -24,7 +24,8 @@ docker_image: name: "{{ matrix_synapse_admin_docker_image }}" source: build - force_source: "{{ matrix_synapse_admin_git_pull_results.changed }}" + force_source: "{{ matrix_synapse_admin_git_pull_results.changed 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_synapse_admin_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_synapse_admin_docker_src_files_path }}" diff --git a/roles/matrix-synapse/defaults/main.yml b/roles/matrix-synapse/defaults/main.yml index 5da48c08..d966665f 100644 --- a/roles/matrix-synapse/defaults/main.yml +++ b/roles/matrix-synapse/defaults/main.yml @@ -7,7 +7,7 @@ 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: "{{ 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/' }}" +matrix_synapse_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_container_image_self_build else matrix_container_global_registry_prefix }}" # 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. @@ -15,7 +15,9 @@ matrix_synapse_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_cont # amd64 gets released first. # arm32 relies on self-building, so the same version can be built immediately. # arm64 users need to wait for a prebuilt image to become available. -matrix_synapse_docker_image_tag: "{{ 'v1.27.0' if matrix_architecture in ['arm32', 'amd64'] else 'v1.26.0' }}" +matrix_synapse_version: v1.34.0 +matrix_synapse_version_arm64: v1.34.0 +matrix_synapse_docker_image_tag: "{{ matrix_synapse_version if matrix_architecture in ['arm32', 'amd64'] else matrix_synapse_version_arm64 }}" matrix_synapse_docker_image_force_pull: "{{ matrix_synapse_docker_image.endswith(':latest') }}" matrix_synapse_base_path: "{{ matrix_base_data_path }}/synapse" @@ -168,7 +170,7 @@ matrix_synapse_report_stats: false # Controls whether the Matrix server will track presence status (online, offline, unavailable) for users. # If users participate in large rooms with many other servers, # disabling this will decrease server load significantly. -matrix_synapse_use_presence: true +matrix_synapse_presence_enabled: true # Controls whether accessing the server's public rooms directory can be done without authentication. # For private servers, you most likely wish to require authentication, @@ -179,6 +181,26 @@ matrix_synapse_allow_public_rooms_without_auth: false # For private servers, you most likely wish to forbid it. matrix_synapse_allow_public_rooms_over_federation: false +# Whether to require authentication to retrieve profile data (avatars, +# display names) of other users through the client API. Defaults to +# 'false'. Note that profile data is also available via the federation +# API, so this setting is of limited value if federation is enabled on +# the server. +matrix_synapse_require_auth_for_profile_requests: false + +# Set to true to require a user to share a room with another user in order +# to retrieve their profile information. Only checked on Client-Server +# requests. Profile requests from other servers should be checked by the +# requesting server. Defaults to 'false'. +matrix_synapse_limit_profile_requests_to_users_who_share_rooms: false + +# Set to false to prevent a user's profile data from being retrieved and +# displayed in a room until they have joined it. By default, a user's +# profile data is included in an invite event, regardless of the values +# of the above two settings, and whether or not the users share a server. +# Defaults to 'true'. +matrix_synapse_include_profile_data_on_invite: true + # Controls whether people with access to the homeserver can register by themselves. matrix_synapse_enable_registration: false @@ -432,6 +454,7 @@ matrix_synapse_sentry_dsn: "" # Postgres database information matrix_synapse_database_host: "matrix-postgres" +matrix_synapse_database_port: 5432 matrix_synapse_database_user: "synapse" matrix_synapse_database_password: "" matrix_synapse_database_database: "synapse" @@ -479,7 +502,7 @@ matrix_synapse_ext_password_provider_ldap_filter: "" # See: https://github.com/t2bot/synapse-simple-antispam matrix_synapse_ext_spam_checker_synapse_simple_antispam_enabled: false matrix_synapse_ext_spam_checker_synapse_simple_antispam_git_repository_url: "https://github.com/t2bot/synapse-simple-antispam" -matrix_synapse_ext_spam_checker_synapse_simple_antispam_git_version: "f058d9ce2c7d4195ae461dcdd02df11a2d06a36b" +matrix_synapse_ext_spam_checker_synapse_simple_antispam_git_version: "923ca5c85b08f157181721abbae50dd89c31e4b5" matrix_synapse_ext_spam_checker_synapse_simple_antispam_config_blocked_homeservers: [] matrix_s3_media_store_enabled: false diff --git a/roles/matrix-synapse/tasks/init.yml b/roles/matrix-synapse/tasks/init.yml index 04b8d2b8..16790664 100644 --- a/roles/matrix-synapse/tasks/init.yml +++ b/roles/matrix-synapse/tasks/init.yml @@ -1,3 +1,10 @@ +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1070 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/1ab507349c752042d26def3e95884f6df8886b74#commitcomment-51108407 +- name: Fail if trying to self-build on Ansible < 2.8 + fail: + msg: "To self-build the Element image, you should use Ansible 2.8 or higher. See docs/ansible.md" + when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_synapse_container_image_self_build" + # Unless `matrix_synapse_workers_enabled_list` is explicitly defined, # we'll generate it dynamically. - import_tasks: "{{ role_path }}/tasks/synapse/workers/init.yml" @@ -17,10 +24,3 @@ - set_fact: matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-goofys.service'] }}" when: matrix_s3_media_store_enabled|bool - -# ansible lower than 2.8, does not support docker_image build parameters -# for self buildig it is explicitly needed, so we rather fail here -- name: Fail if running on Ansible lower than 2.8 and trying self building - fail: - msg: "To self build Synapse image, you should usa ansible 2.8 or higher. E.g. pip contains such packages." - when: "ansible_version.major == 2 and ansible_version.minor < 8 and matrix_synapse_container_image_self_build" diff --git a/roles/matrix-synapse/tasks/rust-synapse-compress-state/main.yml b/roles/matrix-synapse/tasks/rust-synapse-compress-state/main.yml index 4ce02bc4..eef46cb3 100644 --- a/roles/matrix-synapse/tasks/rust-synapse-compress-state/main.yml +++ b/roles/matrix-synapse/tasks/rust-synapse-compress-state/main.yml @@ -10,7 +10,7 @@ - name: Set matrix_synapse_rust_synapse_compress_state_find_rooms_command_wait_time, if not provided set_fact: - matrix_synapse_rust_synapse_compress_state_find_rooms_command_wait_time: 15 + matrix_synapse_rust_synapse_compress_state_find_rooms_command_wait_time: 180 when: "matrix_synapse_rust_synapse_compress_state_find_rooms_command_wait_time|default('') == ''" - name: Set matrix_synapse_rust_synapse_compress_state_compress_room_time, if not provided diff --git a/roles/matrix-synapse/tasks/synapse/setup_install.yml b/roles/matrix-synapse/tasks/synapse/setup_install.yml index f1abcbcc..d4a7268f 100644 --- a/roles/matrix-synapse/tasks/synapse/setup_install.yml +++ b/roles/matrix-synapse/tasks/synapse/setup_install.yml @@ -31,7 +31,8 @@ docker_image: name: "{{ matrix_synapse_docker_image }}" source: build - force_source: "{{ matrix_synapse_git_pull_results.changed }}" + force_source: "{{ matrix_synapse_git_pull_results.changed 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_synapse_git_pull_results.changed }}" build: dockerfile: docker/Dockerfile path: "{{ matrix_synapse_docker_src_files_path }}" diff --git a/roles/matrix-synapse/tasks/validate_config.yml b/roles/matrix-synapse/tasks/validate_config.yml index f7631111..6dcb50ce 100644 --- a/roles/matrix-synapse/tasks/validate_config.yml +++ b/roles/matrix-synapse/tasks/validate_config.yml @@ -47,6 +47,7 @@ - {'old': 'matrix_synapse_container_expose_metrics_port', 'new': ''} - {'old': 'matrix_synapse_cache_factor', 'new': 'matrix_synapse_caches_global_factor'} - {'old': 'matrix_synapse_trusted_third_party_id_servers', 'new': ''} + - {'old': 'matrix_synapse_use_presence', 'new': 'matrix_synapse_presence_enabled'} - name: (Deprecation) Catch and report renamed settings in matrix_synapse_configuration_extension_yaml fail: diff --git a/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 b/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 index 99169b8a..22f5f1ea 100644 --- a/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 +++ b/roles/matrix-synapse/templates/synapse/homeserver.yaml.j2 @@ -58,24 +58,50 @@ public_baseurl: https://{{ matrix_server_fqn_matrix }}/ # #soft_file_limit: 0 -# Set to false to disable presence tracking on this homeserver. +# Presence tracking allows users to see the state (e.g online/offline) +# of other local and remote users. # -use_presence: {{ matrix_synapse_use_presence|to_json }} +presence: + # Uncomment to disable presence tracking on this homeserver. This option + # replaces the previous top-level 'use_presence' option. + # + enabled: {{ matrix_synapse_presence_enabled|to_json }} + + # Presence routers are third-party modules that can specify additional logic + # to where presence updates from users are routed. + # + presence_router: + # The custom module's class. Uncomment to use a custom presence router module. + # + #module: "my_custom_router.PresenceRouter" + + # Configuration options of the custom module. Refer to your module's + # documentation for available options. + # + #config: + # example_option: 'something' # Whether to require authentication to retrieve profile data (avatars, # display names) of other users through the client API. Defaults to # 'false'. Note that profile data is also available via the federation -# API, so this setting is of limited value if federation is enabled on -# the server. +# API, unless allow_profile_lookup_over_federation is set to false. # -#require_auth_for_profile_requests: true +require_auth_for_profile_requests: {{ matrix_synapse_require_auth_for_profile_requests|to_json }} # Uncomment to require a user to share a room with another user in order # to retrieve their profile information. Only checked on Client-Server # requests. Profile requests from other servers should be checked by the # requesting server. Defaults to 'false'. # -#limit_profile_requests_to_users_who_share_rooms: true +limit_profile_requests_to_users_who_share_rooms: {{ matrix_synapse_limit_profile_requests_to_users_who_share_rooms|to_json }} + +# Uncomment to prevent a user's profile data from being retrieved and +# displayed in a room until they have joined it. By default, a user's +# profile data is included in an invite event, regardless of the values +# of the above two settings, and whether or not the users share a server. +# Defaults to 'true'. +# +include_profile_data_on_invite: {{ matrix_synapse_include_profile_data_on_invite|to_json }} # If set to 'true', removes the need for authentication to access the server's # public rooms directory through the client API, meaning that anyone can @@ -102,6 +128,16 @@ default_room_version: {{ matrix_synapse_default_room_version|to_json }} # #gc_thresholds: [700, 10, 10] +# The minimum time in seconds between each GC for a generation, regardless of +# the GC thresholds. This ensures that we don't do GC too frequently. +# +# A value of `[1s, 10s, 30s]` indicates that a second must pass between consecutive +# generation 0 GCs, etc. +# +# Defaults to `[1s, 10s, 30s]`. +# +#gc_min_interval: [0.5s, 30s, 1m] + # Set the limit on the returned events in the timeline in the get # and sync operations. The default value is 100. -1 means no upper limit. # @@ -141,6 +177,7 @@ default_room_version: {{ matrix_synapse_default_room_version|to_json }} # - '100.64.0.0/10' # - '192.0.0.0/24' # - '169.254.0.0/16' +# - '192.88.99.0/24' # - '198.18.0.0/15' # - '192.0.2.0/24' # - '198.51.100.0/24' @@ -149,6 +186,9 @@ default_room_version: {{ matrix_synapse_default_room_version|to_json }} # - '::1/128' # - 'fe80::/10' # - 'fc00::/7' +# - '2001:db8::/32' +# - 'ff00::/8' +# - 'fec0::/10' # List of IP address CIDR ranges that should be allowed for federation, # identity servers, push servers, and for checking key validity for @@ -721,6 +761,18 @@ federation_domain_whitelist: {{ matrix_synapse_federation_domain_whitelist|to_js # - matrix.org # - example.com +# Uncomment to disable profile lookup over federation. By default, the +# Federation API allows other homeservers to obtain profile data of any user +# on this homeserver. Defaults to 'true'. +# +#allow_profile_lookup_over_federation: false + +# Uncomment to disable device display name lookup over federation. By default, the +# Federation API allows other homeservers to obtain device display names of any user +# on this homeserver. Defaults to 'true'. +# +#allow_device_name_lookup_over_federation: false + ## Caching ## @@ -777,6 +829,7 @@ database: password: {{ matrix_synapse_database_password|string|to_json }} database: "{{ matrix_synapse_database_database }}" host: "{{ matrix_synapse_database_host }}" + port: {{ matrix_synapse_database_port }} cp_min: 5 cp_max: 10 @@ -852,10 +905,10 @@ rc_admin_redaction: {{ matrix_synapse_rc_admin_redaction|to_json }} #rc_joins: # local: # per_second: 0.1 -# burst_count: 3 +# burst_count: 10 # remote: # per_second: 0.01 -# burst_count: 3 +# burst_count: 10 rc_joins: {{ matrix_synapse_rc_joins|to_json }} # #rc_3pid_validation: @@ -993,6 +1046,7 @@ url_preview_ip_range_blacklist: - '100.64.0.0/10' - '192.0.0.0/24' - '169.254.0.0/16' + - '192.88.99.0/24' - '198.18.0.0/15' - '192.0.2.0/24' - '198.51.100.0/24' @@ -1001,6 +1055,9 @@ url_preview_ip_range_blacklist: - '::1/128' - 'fe80::/10' - 'fc00::/7' + - '2001:db8::/32' + - 'ff00::/8' + - 'fec0::/10' # List of IP address CIDR ranges that the URL preview spider is allowed # to access even if they are specified in url_preview_ip_range_blacklist. @@ -1138,69 +1195,6 @@ turn_allow_guests: {{ matrix_synapse_turn_allow_guests|to_json }} # enable_registration: {{ matrix_synapse_enable_registration|to_json }} -# Optional account validity configuration. This allows for accounts to be denied -# any request after a given period. -# -# Once this feature is enabled, Synapse will look for registered users without an -# expiration date at startup and will add one to every account it found using the -# current settings at that time. -# This means that, if a validity period is set, and Synapse is restarted (it will -# then derive an expiration date from the current validity period), and some time -# after that the validity period changes and Synapse is restarted, the users' -# expiration dates won't be updated unless their account is manually renewed. This -# date will be randomly selected within a range [now + period - d ; now + period], -# where d is equal to 10% of the validity period. -# -account_validity: - # The account validity feature is disabled by default. Uncomment the - # following line to enable it. - # - #enabled: true - - # The period after which an account is valid after its registration. When - # renewing the account, its validity period will be extended by this amount - # of time. This parameter is required when using the account validity - # feature. - # - #period: 6w - - # The amount of time before an account's expiry date at which Synapse will - # send an email to the account's email address with a renewal link. By - # default, no such emails are sent. - # - # If you enable this setting, you will also need to fill out the 'email' and - # 'public_baseurl' configuration sections. - # - #renew_at: 1w - - # The subject of the email sent out with the renewal link. '%(app)s' can be - # used as a placeholder for the 'app_name' parameter from the 'email' - # section. - # - # Note that the placeholder must be written '%(app)s', including the - # trailing 's'. - # - # If this is not set, a default value is used. - # - #renew_email_subject: "Renew your %(app)s account" - - # Directory in which Synapse will try to find templates for the HTML files to - # serve to the user when trying to renew an account. If not set, default - # templates from within the Synapse package will be used. - # - #template_dir: "res/templates" - - # File within 'template_dir' giving the HTML to be displayed to the user after - # they successfully renewed their account. If not set, default text is used. - # - #account_renewed_html_path: "account_renewed.html" - - # File within 'template_dir' giving the HTML to be displayed when the user - # tries to renew an account with an invalid renewal token. If not set, - # default text is used. - # - #invalid_token_html_path: "invalid_token.html" - # Time that a user's session remains valid for, after they log in. # # Note that this is not currently compatible with guest logins. @@ -1231,9 +1225,9 @@ registrations_require_3pid: {{ matrix_synapse_registrations_require_3pid|to_json # #allowed_local_3pids: # - medium: email -# pattern: '.*@matrix\.org' +# pattern: '^[^@]+@matrix\.org$' # - medium: email -# pattern: '.*@vector\.im' +# pattern: '^[^@]+@vector\.im$' # - medium: msisdn # pattern: '\+44' {% if matrix_synapse_allowed_local_3pids|length > 0 %} @@ -1327,6 +1321,8 @@ account_threepid_delegates: # By default, any room aliases included in this list will be created # as a publicly joinable room when the first user registers for the # homeserver. This behaviour can be customised with the settings below. +# If the room already exists, make certain it is a publicly joinable +# room. The join rule of the room must be set to 'public'. # #auto_join_rooms: # - "#example:example.com" @@ -1403,13 +1399,97 @@ autocreate_auto_join_rooms: {{ matrix_synapse_autocreate_auto_join_rooms|to_json #auto_join_rooms_for_guests: false +## Account Validity ## + +# Optional account validity configuration. This allows for accounts to be denied +# any request after a given period. +# +# Once this feature is enabled, Synapse will look for registered users without an +# expiration date at startup and will add one to every account it found using the +# current settings at that time. +# This means that, if a validity period is set, and Synapse is restarted (it will +# then derive an expiration date from the current validity period), and some time +# after that the validity period changes and Synapse is restarted, the users' +# expiration dates won't be updated unless their account is manually renewed. This +# date will be randomly selected within a range [now + period - d ; now + period], +# where d is equal to 10% of the validity period. +# +account_validity: + # The account validity feature is disabled by default. Uncomment the + # following line to enable it. + # + #enabled: true + + # The period after which an account is valid after its registration. When + # renewing the account, its validity period will be extended by this amount + # of time. This parameter is required when using the account validity + # feature. + # + #period: 6w + + # The amount of time before an account's expiry date at which Synapse will + # send an email to the account's email address with a renewal link. By + # default, no such emails are sent. + # + # If you enable this setting, you will also need to fill out the 'email' and + # 'public_baseurl' configuration sections. + # + #renew_at: 1w + + # The subject of the email sent out with the renewal link. '%(app)s' can be + # used as a placeholder for the 'app_name' parameter from the 'email' + # section. + # + # Note that the placeholder must be written '%(app)s', including the + # trailing 's'. + # + # If this is not set, a default value is used. + # + #renew_email_subject: "Renew your %(app)s account" + + # Directory in which Synapse will try to find templates for the HTML files to + # serve to the user when trying to renew an account. If not set, default + # templates from within the Synapse package will be used. + # + # The currently available templates are: + # + # * account_renewed.html: Displayed to the user after they have successfully + # renewed their account. + # + # * account_previously_renewed.html: Displayed to the user if they attempt to + # renew their account with a token that is valid, but that has already + # been used. In this case the account is not renewed again. + # + # * invalid_token.html: Displayed to the user when they try to renew an account + # with an unknown or invalid renewal token. + # + # See https://github.com/matrix-org/synapse/tree/master/synapse/res/templates for + # default template contents. + # + # The file name of some of these templates can be configured below for legacy + # reasons. + # + #template_dir: "res/templates" + + # A custom file name for the 'account_renewed.html' template. + # + # If not set, the file is assumed to be named "account_renewed.html". + # + #account_renewed_html_path: "account_renewed.html" + + # A custom file name for the 'invalid_token.html' template. + # + # If not set, the file is assumed to be named "invalid_token.html". + # + #invalid_token_html_path: "invalid_token.html" + + ## Metrics ### # Enable collection and rendering of performance metrics # enable_metrics: {{ matrix_synapse_metrics_enabled|to_json }} - # Enable sentry integration # NOTE: While attempts are made to ensure that the logs don't contain # any sensitive information, this cannot be guaranteed. By enabling @@ -1444,14 +1524,32 @@ report_stats: {{ matrix_synapse_report_stats|to_json }} ## API Configuration ## -# A list of event types that will be included in the room_invite_state +# Controls for the state that is shared with users who receive an invite +# to a room # -#room_invite_state_types: -# - "m.room.join_rules" -# - "m.room.canonical_alias" -# - "m.room.avatar" -# - "m.room.encryption" -# - "m.room.name" +room_prejoin_state: + # By default, the following state event types are shared with users who + # receive invites to the room: + # + # - m.room.join_rules + # - m.room.canonical_alias + # - m.room.avatar + # - m.room.encryption + # - m.room.name + # - m.room.create + # + # Uncomment the following to disable these defaults (so that only the event + # types listed in 'additional_event_types' are shared). Defaults to 'false'. + # + #disable_default_event_types: true + + # Additional state event types to share with users when they are invited + # to a room. + # + # By default, this list is empty (so only the default event types are shared). + # + #additional_event_types: + # - org.example.custom.event.type # A list of application service config files to use @@ -1749,14 +1847,21 @@ saml2_config: # Note that, if this is changed, users authenticating via that provider # will no longer be recognised as the same user! # +# (Use "oidc" here if you are migrating from an old "oidc_config" +# configuration.) +# # idp_name: A user-facing name for this identity provider, which is used to # offer the user a choice of login mechanisms. # # idp_icon: An optional icon for this identity provider, which is presented -# by identity picker pages. If given, must be an MXC URI of the format -# mxc:///. (An easy way to obtain such an MXC URI -# is to upload an image to an (unencrypted) room and then copy the "url" -# from the source of the event.) +# by clients and Synapse's own IdP picker page. If given, must be an +# MXC URI of the format mxc:///. (An easy way to +# obtain such an MXC URI is to upload an image to an (unencrypted) room +# and then copy the "url" from the source of the event.) +# +# idp_brand: An optional brand for this identity provider, allowing clients +# to style the login flow according to the identity provider in question. +# See the spec for possible options here. # # discover: set to 'false' to disable the use of the OIDC discovery mechanism # to discover endpoints. Defaults to true. @@ -1766,7 +1871,26 @@ saml2_config: # # client_id: Required. oauth2 client id to use. # -# client_secret: Required. oauth2 client secret to use. +# client_secret: oauth2 client secret to use. May be omitted if +# client_secret_jwt_key is given, or if client_auth_method is 'none'. +# +# client_secret_jwt_key: Alternative to client_secret: details of a key used +# to create a JSON Web Token to be used as an OAuth2 client secret. If +# given, must be a dictionary with the following properties: +# +# key: a pem-encoded signing key. Must be a suitable key for the +# algorithm specified. Required unless 'key_file' is given. +# +# key_file: the path to file containing a pem-encoded signing key file. +# Required unless 'key' is given. +# +# jwt_header: a dictionary giving properties to include in the JWT +# header. Must include the key 'alg', giving the algorithm used to +# sign the JWT, such as "ES256", using the JWA identifiers in +# RFC7518. +# +# jwt_payload: an optional dictionary giving properties to include in +# the JWT payload. Normally this should include an 'iss' key. # # client_auth_method: auth method to use when exchanging the token. Valid # values are 'client_secret_basic' (default), 'client_secret_post' and @@ -1807,7 +1931,7 @@ saml2_config: # sub-properties: # # module: The class name of a custom mapping module. Default is -# 'synapse.handlers.oidc_handler.JinjaOidcMappingProvider'. +# 'synapse.handlers.oidc.JinjaOidcMappingProvider'. # See https://github.com/matrix-org/synapse/blob/master/docs/sso_mapping_providers.md#openid-mapping-providers # for information on implementing a custom mapping provider. # @@ -1841,6 +1965,24 @@ saml2_config: # which is set to the claims returned by the UserInfo Endpoint and/or # in the ID Token. # +# It is possible to configure Synapse to only allow logins if certain attributes +# match particular values in the OIDC userinfo. The requirements can be listed under +# `attribute_requirements` as shown below. All of the listed attributes must +# match for the login to be permitted. Additional attributes can be added to +# userinfo by expanding the `scopes` section of the OIDC config to retrieve +# additional information from the OIDC provider. +# +# If the OIDC claim is a list, then the attribute must match any value in the list. +# Otherwise, it must exactly match the value of the claim. Using the example +# below, the `family_name` claim MUST be "Stephensson", but the `groups` +# claim MUST contain "admin". +# +# attribute_requirements: +# - attribute: family_name +# value: "Stephensson" +# - attribute: groups +# value: "admin" +# # See https://github.com/matrix-org/synapse/blob/master/docs/openid.md # for information on how to configure these options. # @@ -1869,37 +2011,12 @@ oidc_providers: # user_mapping_provider: # config: # subject_claim: "id" - # localpart_template: "{ user.login }" - # display_name_template: "{ user.name }" - # email_template: "{ user.email }" - - # For use with Keycloak - # - #- idp_id: keycloak - # idp_name: Keycloak - # issuer: "https://127.0.0.1:8443/auth/realms/my_realm_name" - # client_id: "synapse" - # client_secret: "copy secret generated in Keycloak UI" - # scopes: ["openid", "profile"] - - # For use with Github - # - #- idp_id: github - # idp_name: Github - # idp_brand: org.matrix.github - # discover: false - # issuer: "https://github.com/" - # client_id: "your-client-id" # TO BE FILLED - # client_secret: "your-client-secret" # TO BE FILLED - # authorization_endpoint: "https://github.com/login/oauth/authorize" - # token_endpoint: "https://github.com/login/oauth/access_token" - # userinfo_endpoint: "https://api.github.com/user" - # scopes: ["read:user"] - # user_mapping_provider: - # config: - # subject_claim: "id" - # localpart_template: "{ user.login }" - # display_name_template: "{ user.name }" + # localpart_template: "{% raw %}{{ user.login }}{% endraw %}" + # display_name_template: "{% raw %}{{ user.name }}{% endraw %}" + # email_template: "{% raw %}{{ user.email }}{% endraw %}" + # attribute_requirements: + # - attribute: userGroup + # value: "synapseUsers" # Enable Central Authentication Service (CAS) for registration and login. @@ -2227,11 +2344,11 @@ password_config: #require_uppercase: true ui_auth: - # The number of milliseconds to allow a user-interactive authentication - # session to be active. + # The amount of time to allow a user-interactive authentication session + # to be active. # # This defaults to 0, meaning the user is queried for their credentials - # before every action, but this can be overridden to alow a single + # before every action, but this can be overridden to allow a single # validation to be re-used. This weakens the protections afforded by # the user-interactive authentication process, by allowing for multiple # (and potentially different) operations to use the same validation session. @@ -2239,7 +2356,7 @@ ui_auth: # Uncomment below to allow for credential validation to last for 15 # seconds. # - #session_timeout: 15000 + #session_timeout: "15s" {% if matrix_synapse_email_enabled %} @@ -2568,19 +2685,35 @@ enable_group_creation: {{ matrix_synapse_enable_group_creation|to_json }} # User Directory configuration # -# 'enabled' defines whether users can search the user directory. If -# false then empty responses are returned to all queries. Defaults to -# true. -# -# 'search_all_users' defines whether to search all users visible to your HS -# when searching the user directory, rather than limiting to users visible -# in public rooms. Defaults to false. If you set it True, you'll have to -# rebuild the user_directory search indexes, see -# https://github.com/matrix-org/synapse/blob/master/docs/user_directory.md -# -#user_directory: -# enabled: true -# search_all_users: false +user_directory: + # Defines whether users can search the user directory. If false then + # empty responses are returned to all queries. Defaults to true. + # + # Uncomment to disable the user directory. + # + #enabled: false + + # Defines whether to search all users visible to your HS when searching + # the user directory, rather than limiting to users visible in public + # rooms. Defaults to false. + # + # If you set it true, you'll have to rebuild the user_directory search + # indexes, see: + # https://github.com/matrix-org/synapse/blob/master/docs/user_directory.md + # + # Uncomment to return search results containing all known users, even if that + # user does not share a room with the requester. + # + #search_all_users: true + + # Defines whether to prefer local users in search query results. + # If True, local users are more likely to appear above remote users + # when searching the user directory. Defaults to false. + # + # Uncomment to prefer local over remote users in user directory search + # results. + # + #prefer_local_users: true # User Consent configuration @@ -2635,19 +2768,20 @@ enable_group_creation: {{ matrix_synapse_enable_group_creation|to_json }} -# Local statistics collection. Used in populating the room directory. -# -# 'bucket_size' controls how large each statistics timeslice is. It can -# be defined in a human readable short form -- e.g. "1d", "1y". +# Settings for local room and user statistics collection. See +# docs/room_and_user_statistics.md. # -# 'retention' controls how long historical statistics will be kept for. -# It can be defined in a human readable short form -- e.g. "1d", "1y". -# -# -#stats: -# enabled: true -# bucket_size: 1d -# retention: 1y +stats: + # Uncomment the following to disable room and user statistics. Note that doing + # so may cause certain features (such as the room directory) not to work + # correctly. + # + #enabled: false + + # The size of each timeslice in the room_stats_historical and + # user_stats_historical tables, as a time period. Defaults to "1d". + # + #bucket_size: 1h # Server Notices room configuration diff --git a/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 b/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 index 0f5e7be2..6c90c9a3 100644 --- a/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 +++ b/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 @@ -17,11 +17,17 @@ ExecStartPre={{ matrix_host_command_sleep }} 5 ExecStart={{ matrix_host_command_docker }} run --rm --name {{ matrix_synapse_worker_container_name }} \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + -e UID={{ matrix_user_uid }} \ + -e GID={{ matrix_user_gid }} \ --cap-drop=ALL \ - --entrypoint=python \ --read-only \ --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_synapse_tmp_directory_size_mb }}m \ --network={{ matrix_docker_network }} \ + {% if matrix_synapse_worker_details.port != 0 %} + --health-cmd 'curl -fSs http://localhost:{{ matrix_synapse_worker_details.port }}/health || exit 1' \ + {% else %} + --no-healthcheck \ + {% endif %} {% if matrix_synapse_workers_enabled and matrix_synapse_workers_container_host_bind_address %} {% if matrix_synapse_worker_details.port != 0 %} -p {{ '' if matrix_synapse_workers_container_host_bind_address == '*' else (matrix_synapse_workers_container_host_bind_address + ':') }}{{ matrix_synapse_worker_details.port }}:{{ matrix_synapse_worker_details.port }} \ @@ -39,7 +45,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name {{ matrix_synapse_wor {{ arg }} \ {% endfor %} {{ matrix_synapse_docker_image }} \ - -m synapse.app.{{ matrix_synapse_worker_details.type }} -c /data/homeserver.yaml -c /data/{{ matrix_synapse_worker_config_file_name }} + run -m synapse.app.{{ matrix_synapse_worker_details.type }} -c /data/homeserver.yaml -c /data/{{ matrix_synapse_worker_config_file_name }} ExecStop=-{{ matrix_host_command_docker }} kill {{ matrix_synapse_worker_container_name }} 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 5f69e315..2fbaac7b 100644 --- a/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 +++ b/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 @@ -33,8 +33,9 @@ ExecStartPre={{ matrix_host_command_sleep }} 3 ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-synapse \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --env=UID={{ matrix_user_uid }} \ + --env=GID={{ matrix_user_gid }} \ --cap-drop=ALL \ - --entrypoint=python \ --read-only \ --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_synapse_tmp_directory_size_mb }}m \ --network={{ matrix_docker_network }} \ @@ -62,7 +63,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-synapse \ {{ arg }} \ {% endfor %} {{ matrix_synapse_docker_image }} \ - -m synapse.app.homeserver -c /data/homeserver.yaml + run -m synapse.app.homeserver -c /data/homeserver.yaml ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-synapse 2>/dev/null' ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-synapse 2>/dev/null' diff --git a/roles/matrix-synapse/vars/main.yml b/roles/matrix-synapse/vars/main.yml index 9c6d8ce4..5839aa81 100644 --- a/roles/matrix-synapse/vars/main.yml +++ b/roles/matrix-synapse/vars/main.yml @@ -6,7 +6,6 @@ matrix_synapse_federation_api_url_endpoint_public: "https://{{ matrix_server_fqn # Tells whether this role had executed or not. Toggled to `true` during runtime. matrix_synapse_role_executed: false -matrix_synapse_media_store_parent_path: "{{ matrix_synapse_media_store_path|dirname }}" matrix_synapse_media_store_directory_name: "{{ matrix_synapse_media_store_path|basename }}" # A Synapse generic worker can handle both federation and client-server API endpoints. diff --git a/roles/matrix-synapse/vars/workers.yml b/roles/matrix-synapse/vars/workers.yml index 3adfd9c3..c989fb5b 100644 --- a/roles/matrix-synapse/vars/workers.yml +++ b/roles/matrix-synapse/vars/workers.yml @@ -55,9 +55,6 @@ matrix_synapse_workers_generic_worker_endpoints: # Registration/login requests - ^/_matrix/client/(api/v1|r0|unstable)/login$ - ^/_matrix/client/(r0|unstable)/register$ - # FIXME: possible bug with SSO and multiple generic workers - # see https://github.com/matrix-org/synapse/issues/7530 - # ^/_matrix/client/(r0|unstable)/auth/.*/fallback/web$ # Event sending requests - ^/_matrix/client/(api/v1|r0|unstable)/rooms/.*/redact @@ -107,7 +104,8 @@ matrix_synapse_workers_generic_worker_endpoints: # Ensure that all SSO logins go to a single process. # For multiple workers not handling the SSO endpoints properly, see - # [#7530](https://github.com/matrix-org/synapse/issues/7530). + # [#7530](https://github.com/matrix-org/synapse/issues/7530) and + # [#9427](https://github.com/matrix-org/synapse/issues/9427). # Note that a HTTP listener with `client` and `federation` resources must be # configured in the `worker_listeners` option in the worker config. @@ -203,7 +201,15 @@ matrix_synapse_workers_generic_worker_endpoints: # REST endpoints itself, but you should set `start_pushers: False` in the # shared configuration file to stop the main synapse sending push notifications. - # Note this worker cannot be load-balanced: only one instance should be active. + # To run multiple instances at once the `pusher_instances` option should list all + # pusher instances by their worker name, e.g.: + + # ```yaml + # pusher_instances: + # - pusher_worker1 + # - pusher_worker2 + # ``` + # ] # appservice worker (no API endpoints) [ diff --git a/setup.yml b/setup.yml index d9f25ecf..9e3cd625 100755 --- a/setup.yml +++ b/setup.yml @@ -7,6 +7,7 @@ - roles/matrix-synapse/vars/workers.yml roles: + - matrix-awx - matrix-base - matrix-dynamic-dns - matrix-mailer @@ -31,7 +32,10 @@ - matrix-bridge-mx-puppet-twitter - matrix-bridge-mx-puppet-instagram - matrix-bridge-sms + - matrix-bridge-heisenbridge - matrix-bot-matrix-reminder-bot + - matrix-bot-go-neb + - matrix-bot-mjolnir - matrix-synapse - matrix-synapse-admin - matrix-prometheus-node-exporter @@ -39,12 +43,16 @@ - matrix-grafana - matrix-registration - matrix-client-element + - matrix-client-hydrogen - matrix-jitsi - matrix-ma1sd - matrix-dimension - matrix-etherpad - matrix-email2matrix + - matrix-sygnal - matrix-nginx-proxy - matrix-coturn - matrix-aux + - matrix-postgres-backup - matrix-common-after +