sync with previous repo

This commit is contained in:
Michael Collins
2021-08-13 16:05:57 +08:00
parent 83a90f1cd1
commit 98e6cd685d
641 changed files with 43857 additions and 55 deletions

View File

@ -0,0 +1,72 @@
---
# matrix-aux is a role that manages auxiliary files and directories on your Matrix server.
#
# Certain components (like matrix-synapse, etc.) may sometimes require additional templates (email templates, privacy policies, etc.).
# This role allows such files to be managed by the playbook.
#
# Note that files and directories created via this role are not automatically made available for containers to use.
# If you use this role to put files in a directory that's already mounted into a container,
# you can access the files without additional work.
# Otherwise, you'd need to mount the file/directory to the container that needs it.
# Roles usually provide a `matrix_*_additional_volumes` or `matrix_*_container_extra_arguments` variable
# that you can use to mount an additional volume.
# The default permission mode when creating directories using `matrix_aux_directory_definitions`
matrix_aux_directory_default_mode: '0750'
# Holds a list of directories to create on the server.
#
# By default, directories are:
# - created with permissions as specified in `matrix_aux_directory_default_mode`
# - owned by the `matrix_user_username` user and `matrix_user_groupname` group (usually `matrix:matrix`)
#
# Example:
#
# matrix_aux_directory_definitions:
# - dest: /matrix/aux
#
# - dest: /matrix/another
# mode: '0700'
# owner: 'some-user'
# group: 'some-group'
matrix_aux_directory_definitions: []
# The default permission mode when creating directories using `matrix_aux_directory_definitions`
matrix_aux_file_default_mode: '0640'
# Holds a list of files to create on the server.
#
# By default, files are:
# - created with permissions as specified in `matrix_aux_file_default_mode`
# - owned by the `matrix_user_username` user and `matrix_user_groupname` group (usually `matrix:matrix`)
#
# You can define the file content inline (in your `vars.yml` file) or as an external file (see the example below).
# Defining the content inline in `vars.yml` has the benefit of not splitting your configuration into multiple files,
# but rather keeping everything inside `vars.yml` (which also gets backed up on the server in `/matrix/vars.yml`).
#
# Note: parent paths for files must exist.
# If you've defined a file with a destination of `/matrix/some/path/file.txt`,
# then you likely need to add `/matrix/some/path` to `matrix_aux_directory_definitions` as well.
# You don't need to do this for directories that the playbook already creates for you.
#
# Example:
#
# matrix_aux_file_definitions:
# - dest: "{{ matrix_synapse_config_dir_path }}/something.html"
# content: |
# <!doctype html>
# <html><body>Something</body></html>
#
# - dest: /matrix/aux/some-other-file.txt
# content: "Something"
# mode: '0600'
# owner: 'some-user'
# group: 'some-group'
#
# - dest: /matrix/aux/yet-another-file.txt
# content: "{{ lookup('template', '/path/to/file.txt.j2') }}"
# mode: '0600'
# owner: 'some-user'
# group: 'some-group'
matrix_aux_file_definitions: []

View File

@ -0,0 +1,5 @@
- import_tasks: "{{ role_path }}/tasks/setup.yml"
when: run_stop|bool
tags:
- setup-all
- setup-aux-files

View File

@ -0,0 +1,19 @@
---
- name: Ensure AUX directories are created
file:
dest: "{{ item.dest }}"
state: directory
owner: "{{ item.owner|default(matrix_user_username) }}"
group: "{{ item.group|default(matrix_user_groupname) }}"
mode: "{{ item.mode|default(matrix_aux_directory_default_mode) }}"
with_items: "{{ matrix_aux_directory_definitions }}"
- name: Ensure AUX files are created
copy:
dest: "{{ item.dest }}"
content: "{{ item.content }}"
owner: "{{ item.owner|default(matrix_user_username) }}"
group: "{{ item.group|default(matrix_user_groupname) }}"
mode: "{{ item.mode|default(matrix_aux_file_default_mode) }}"
with_items: "{{ matrix_aux_file_definitions }}"

View File

@ -0,0 +1 @@
matrix_awx_enabled: true

View File

@ -0,0 +1,28 @@
import sys
import requests
import json
janitor_token = sys.argv[1]
synapse_container_ip = sys.argv[2]
# collect total amount of rooms
rooms_raw_url = 'http://' + synapse_container_ip + ':8008/_synapse/admin/v1/rooms'
rooms_raw_header = {'Authorization': 'Bearer ' + janitor_token}
rooms_raw = requests.get(rooms_raw_url, headers=rooms_raw_header)
rooms_raw_python = json.loads(rooms_raw.text)
total_rooms = rooms_raw_python["total_rooms"]
# build complete room list file
room_list_file = open("/tmp/room_list_complete.json", "w")
for i in range(0, total_rooms, 100):
rooms_inc_url = 'http://' + synapse_container_ip + ':8008/_synapse/admin/v1/rooms?from=' + str(i)
rooms_inc = requests.get(rooms_inc_url, headers=rooms_raw_header)
room_list_file.write(rooms_inc.text)
room_list_file.close()
print(total_rooms)

View File

@ -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"
}
]
}

View File

@ -0,0 +1,18 @@
{
"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"
}
]
}

View File

@ -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"
}
]
}

View File

@ -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"
}
]
}

View File

@ -0,0 +1,66 @@
{
"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"
}
]
}

View File

@ -0,0 +1,18 @@
{
"name": "Configure Element Subdomain",
"description": "Configure Element clients subdomain location. (Eg: 'element' for element.example.org)",
"spec": [
{
"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"
}
]
}

View File

@ -0,0 +1,19 @@
{
"name": "Configure Email Relay",
"description": "Enable MailGun relay to increase verification email reliability.",
"spec": [
{
"question_name": "Enable Email Relay",
"question_description": "Enables the MailGun email relay server, enabling this will increase the reliability of your email verification.",
"required": false,
"min": null,
"max": null,
"default": "{{ matrix_mailer_relay_use | string | lower }}",
"choices": "true\nfalse",
"new_question": true,
"variable": "matrix_mailer_relay_use",
"type": "multiplechoice"
}
]
}

View File

@ -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"
}
]
}

View File

@ -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"
}
]
}

View File

@ -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": "ext_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"
}
]
}

View File

@ -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"
}
]
}

View File

@ -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"
}
]
}

View File

@ -0,0 +1,99 @@
- 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: 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: Run initial backup of /matrix/ and snapshot the database simultaneously
command: "{{ item }}"
with_items:
- borgmatic -c /root/.config/borgmatic/config_1.yaml
- /bin/sh /usr/local/bin/awx-export-service.sh 1 0
register: _create_instances
async: 3600 # Maximum runtime in seconds.
poll: 0 # Fire and continue (never poll)
when: matrix_awx_backup_enabled|bool
- name: Wait for both of these jobs to finish
async_status:
jid: "{{ item.ansible_job_id }}"
register: _jobs
until: _jobs.finished
delay: 5 # Check every 5 seconds.
retries: 720 # Retry for a full hour.
with_items: "{{ _create_instances.results }}"
when: matrix_awx_backup_enabled|bool
- name: Perform borg backup of postgres dump
command: borgmatic -c /root/.config/borgmatic/config_2.yaml
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

View File

@ -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 }}"

View File

@ -0,0 +1,31 @@
#
# Create user and define if they are admin
#
# /usr/local/bin/matrix-synapse-register-user <your_username> <your_password> <admin access: 0 or 1>
#
- 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

View File

@ -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: 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: matrix
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: matrix
password: "{{ sftp_password | password_hash('sha512') }}"
update_password: always
when: sftp_password|length > 0
- name: Ensure group "sftp" exists
group:
name: sftp
state: present
- name: adding existing user 'sftp' to group matrix
user:
name: sftp
groups: sftp
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: '0770'
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: Remove any existing Subsystem lines
lineinfile:
path: /etc/ssh/sshd_config
state: absent
regexp: '^Subsystem'
- name: Set SSH Subsystem State
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

View File

@ -0,0 +1,33 @@
- name: Run export of /matrix/ and snapshot the database simultaneously
command: "{{ item }}"
with_items:
- /bin/sh /usr/local/bin/awx-export-service.sh 1 0
- /bin/sh /usr/local/bin/awx-export-service.sh 0 1
register: _create_instances
async: 3600 # Maximum runtime in seconds.
poll: 0 # Fire and continue (never poll)
- name: Wait for both of these jobs to finish
async_status:
jid: "{{ item.ansible_job_id }}"
register: _jobs
until: _jobs.finished
delay: 5 # Check every 5 seconds.
retries: 720 # Retry for a full hour.
with_items: "{{ _create_instances.results }}"
- name: Schedule deletion of the export in 24 hours
at:
command: rm /chroot/export/matrix*
count: 1
units: days
unique: yes
- 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

View File

@ -0,0 +1,7 @@
- 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

View File

@ -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

View File

@ -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'

189
roles/matrix-awx/tasks/main.yml Executable file
View File

@ -0,0 +1,189 @@
# 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
# Perform a export of the server
- include_tasks:
file: "export_server.yml"
apply:
tags: export-server
when: run_setup|bool and matrix_awx_enabled|bool
tags:
- export-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 Mailer configuration
- include_tasks:
file: "set_variables_mailer.yml"
apply:
tags: setup-mailer
when: run_setup|bool and matrix_awx_enabled|bool
tags:
- setup-mailer
# Additional playbook to set the variable file during Element configuration
- include_tasks:
file: "set_variables_element_subdomain.yml"
apply:
tags: setup-client-element-subdomain
when: run_setup|bool and matrix_awx_enabled|bool
tags:
- setup-client-element-subdomain
# 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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,317 @@
- 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 before shrink size of Synapse database
shell: du -sh /matrix/postgres/data
register: db_size_before_stat
when: (purge_mode.find("Perform final shrink") != -1)
no_log: True
- name: Collect the internal IP of the matrix-synapse container
shell: "/usr/bin/docker inspect --format '{''{range.NetworkSettings.Networks}''}{''{.IPAddress}''}{''{end}''}' matrix-synapse"
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
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'
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
register: janitors_token
no_log: True
- name: Copy build_room_list.py script to target machine
copy:
src: ./roles/matrix-awx/scripts/matrix_build_room_list.py
dest: /usr/local/bin/matrix_build_room_list.py
owner: matrix
group: matrix
mode: '0755'
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- name: Run build_room_list.py script
shell: |
runuser -u matrix -- python3 /usr/local/bin/matrix_build_room_list.py {{ janitors_token.stdout[1:-1] }} {{ synapse_container_ip.stdout }}
register: rooms_total
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- name: Fetch complete room list from target machine
fetch:
src: /tmp/room_list_complete.json
dest: "/tmp/{{ subscription_id }}_room_list_complete.json"
flat: yes
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- name: Remove complete room list from target machine
file:
path: /tmp/room_list_complete.json
state: absent
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- 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_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- 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_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- 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_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- 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_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- name: Collect epoche time from date
delegate_to: 127.0.0.1
shell: |
date -d '{{ purge_date }}' +"%s"
when: (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
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_mode.find("Number of users [slower]") != -1
- 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_mode.find("Number of users [slower]") != -1
- 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_mode.find("Number of users [slower]") != -1
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_mode.find("Number of users [slower]") != -1
- 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_mode.find("Number of events [slower]") != -1
- name: Count number of rooms with more then N events
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_mode.find("Number of events [slower]") != -1
- 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_mode.find("Number of events [slower]") != -1
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_mode.find("Number of events [slower]") != -1
- 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: Adjust 'Deploy/Update a Server' job template
delegate_to: 127.0.0.1
awx.awx.tower_job_template:
name: "{{ matrix_domain }} - 0 - Deploy/Update a Server"
description: "Creates a new matrix service with Spantaleev's playbooks"
extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}"
job_type: run
job_tags: "rust-synapse-compress-state"
inventory: "{{ member_id }}"
project: "{{ member_id }} - Matrix Docker Ansible Deploy"
playbook: setup.yml
credential: "{{ member_id }} - AWX SSH Key"
state: present
verbosity: 1
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1) or (purge_mode.find("Skip purging rooms [faster]") != -1)
- 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"
wait: yes
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1) or (purge_mode.find("Skip purging rooms [faster]") != -1)
- name: Revert 'Deploy/Update a Server' job template
delegate_to: 127.0.0.1
awx.awx.tower_job_template:
name: "{{ matrix_domain }} - 0 - Deploy/Update a Server"
description: "Creates a new matrix service with Spantaleev's playbooks"
extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}"
job_type: run
job_tags: "setup-all,start"
inventory: "{{ member_id }}"
project: "{{ member_id }} - Matrix Docker Ansible Deploy"
playbook: setup.yml
credential: "{{ member_id }} - AWX SSH Key"
state: present
verbosity: 1
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1) or (purge_mode.find("Skip purging rooms [faster]") != -1)
- name: Ensure matrix-synapse is stopped
service:
name: matrix-synapse
state: stopped
daemon_reload: yes
when: (purge_mode.find("Perform final shrink") != -1)
- 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'
when: (purge_mode.find("Perform final shrink") != -1)
- name: Ensure matrix-synapse is started
service:
name: matrix-synapse
state: started
daemon_reload: yes
when: (purge_mode.find("Perform final shrink") != -1)
- name: Adjust 'Deploy/Update a Server' job template
delegate_to: 127.0.0.1
awx.awx.tower_job_template:
name: "{{ matrix_domain }} - 0 - Deploy/Update a Server"
description: "Creates a new matrix service with Spantaleev's playbooks"
extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}"
job_type: run
job_tags: "run-postgres-vacuum,start"
inventory: "{{ member_id }}"
project: "{{ member_id }} - Matrix Docker Ansible Deploy"
playbook: setup.yml
credential: "{{ member_id }} - AWX SSH Key"
state: present
verbosity: 1
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes
when: (purge_mode.find("Perform final shrink") != -1)
- 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"
wait: yes
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes
when: (purge_mode.find("Perform final shrink") != -1)
- name: Revert 'Deploy/Update a Server' job template
delegate_to: 127.0.0.1
awx.awx.tower_job_template:
name: "{{ matrix_domain }} - 0 - Deploy/Update a Server"
description: "Creates a new matrix service with Spantaleev's playbooks"
extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}"
job_type: run
job_tags: "setup-all,start"
inventory: "{{ member_id }}"
project: "{{ member_id }} - Matrix Docker Ansible Deploy"
playbook: setup.yml
credential: "{{ member_id }} - AWX SSH Key"
state: present
verbosity: 1
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes
when: (purge_mode.find("Perform final shrink") != -1)
- name: Cleanup room_list files
delegate_to: 127.0.0.1
shell: |
rm /tmp/{{ subscription_id }}_room_list*
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
ignore_errors: yes
- name: Collect after shrink size of Synapse database
shell: du -sh /matrix/postgres/data
register: db_size_after_stat
when: (purge_mode.find("Perform final shrink") != -1)
no_log: True
- name: Print total number of rooms processed
debug:
msg: '{{ rooms_total.stdout }}'
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- name: Print the number of rooms purged with no local users
debug:
msg: '{{ rooms_no_local_total.stdout }}'
when: (purge_mode.find("No local users [recommended]") != -1) or (purge_mode.find("Number of users [slower]") != -1) or (purge_mode.find("Number of events [slower]") != -1)
- name: Print the number of rooms purged with more then N users
debug:
msg: '{{ rooms_join_members_total.stdout }}'
when: purge_mode.find("Number of users") != -1
- name: Print the number of rooms purged with more then N events
debug:
msg: '{{ rooms_state_events_total.stdout }}'
when: purge_mode.find("Number of events") != -1
- name: Print before purge size of Synapse database
debug:
msg: "{{ db_size_before_stat.stdout.split('\n') }}"
when: (db_size_before_stat is defined) and (purge_mode.find("Perform final shrink") != -1)
- name: Print after purge size of Synapse database
debug:
msg: "{{ db_size_after_stat.stdout.split('\n') }}"
when: (db_size_after_stat is defined) and (purge_mode.find("Perform final shrink") != -1)
- 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

View File

@ -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

View File

@ -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

View File

@ -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 }}000'
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

View File

@ -0,0 +1,99 @@
- 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 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 -XPOST -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: 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

View File

@ -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 }}000'
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

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,69 @@
- 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 }}'
- 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

View File

@ -0,0 +1,49 @@
- 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_server_fqn_element': "{{ element_subdomain }}.{{ matrix_domain }}"
- name: Save new 'Configure Element Subdomain' survey.json to the AWX tower, template
delegate_to: 127.0.0.1
template:
src: 'roles/matrix-awx/surveys/configure_element_subdomain.json.j2'
dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_element_subdomain.json'
- name: Copy new 'Configure Element Subdomain' survey.json to target machine
copy:
src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_element_subdomain.json'
dest: '/matrix/awx/configure_element_subdomain.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 Subdomain' job template
delegate_to: 127.0.0.1
awx.awx.tower_job_template:
name: "{{ matrix_domain }} - 1 - Configure Element Subdomain"
description: "Configure Element clients subdomain location. (Eg: 'element' for element.example.org)"
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-client-element-subdomain"
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_subdomain.json') }}"
state: present
verbosity: 1
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes

View File

@ -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

View File

@ -0,0 +1,109 @@
- 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: 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/Update ma1sd configuration extension variables
delegate_to: 127.0.0.1
blockinfile:
path: '{{ awx_cached_matrix_vars }}'
marker: "# {mark} ma1sd ANSIBLE MANAGED BLOCK"
insertafter: '# Start ma1sd Extension'
block: '{{ ext_matrix_ma1sd_configuration_extension_yaml }}'
- 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 }}'
no_log: True
- 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

View File

@ -0,0 +1,50 @@
- name: Record Mailer 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: '# Email Settings Start'
with_dict:
'matrix_mailer_relay_use': '{{ matrix_mailer_relay_use }}'
- name: Save new 'Configure Email Relay' survey.json to the AWX tower, template
delegate_to: 127.0.0.1
template:
src: 'roles/matrix-awx/surveys/configure_email_relay.json.j2'
dest: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_email_relay.json'
- name: Copy new 'Configure Email Relay' survey.json to target machine
copy:
src: '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/configure_email_relay.json'
dest: '/matrix/awx/configure_email_relay.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 Email Relay' job template
delegate_to: 127.0.0.1
awx.awx.tower_job_template:
name: "{{ matrix_domain }} - 1 - Configure Email Relay"
description: "Enable MailGun relay to increase verification email reliability."
extra_vars: "{{ lookup('file', '/var/lib/awx/projects/clients/{{ member_id }}/{{ subscription_id }}/extra_vars.json') }}"
job_type: run
job_tags: "start,setup-mailer"
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_email_relay.json') }}"
become_enabled: yes
state: present
verbosity: 1
tower_host: "https://{{ tower_host }}"
tower_oauthtoken: "{{ tower_token.stdout }}"
validate_certs: yes

View File

@ -0,0 +1,229 @@
- name: Limit max upload size to 200MB part 1
set_fact:
matrix_synapse_max_upload_size_mb: "200"
when: matrix_synapse_max_upload_size_mb_raw|int >= 200
- name: Limit max upload size to 200MB 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 < 200
- 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': '{{ ext_matrix_synapse_registration_shared_secret }}'
when: ext_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: 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: 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 }}'
'ext_enable_registration_captcha': '{{ ext_enable_registration_captcha }}'
'ext_recaptcha_public_key': '"{{ ext_recaptcha_public_key }}"'
'ext_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

View File

@ -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

View File

@ -0,0 +1,158 @@
# The bare domain name which represents your Matrix identity.
# Matrix user ids for your server will be of the form (`@user:<matrix-domain>`).
#
# Note: this playbook does not touch the server referenced here.
# Installation happens on another server ("matrix.<matrix-domain>", see `matrix_server_fqn_matrix`).
#
# Example value: example.com
matrix_domain: ~
# This is where your data lives and what we set up.
# This and the Element FQN (see below) are expected to be on the same server.
matrix_server_fqn_matrix: "matrix.{{ matrix_domain }}"
# This is where you access federation API.
matrix_server_fqn_matrix_federation: '{{ matrix_server_fqn_matrix }}'
# This is where you access the Element web UI from (if enabled via matrix_client_element_enabled; enabled by default).
# 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.
# Recognized values by us are 'amd64', 'arm32' and 'arm64'.
# Not all architectures support all services, so your experience (on non-amd64) may vary.
# See docs/alternative-architectures.md
matrix_architecture: amd64
# The architecture for Debian packages.
# See: https://wiki.debian.org/SupportedArchitectures
# We just remap from our `matrix_architecture` values to what Debian and possibly other distros call things.
matrix_debian_arch: "{{ 'armhf' if matrix_architecture == 'arm32' else matrix_architecture }}"
matrix_user_username: "matrix"
matrix_user_groupname: "matrix"
# By default, the playbook creates the user (`matrix_user_username`)
# and group (`matrix_user_groupname`) with a random id.
# To use a specific user/group id, override these variables.
matrix_user_uid: ~
matrix_user_gid: ~
matrix_base_data_path: "/matrix"
matrix_base_data_path_mode: "750"
matrix_static_files_base_path: "{{ matrix_base_data_path }}/static-files"
matrix_systemd_path: "/etc/systemd/system"
# Specifies the path to use for the `HOME` environment variable for systemd unit files.
# Docker 20.10 complains with `WARNING: Error loading config file: .dockercfg: $HOME is not defined`
# if `$HOME` is not defined, so we define something to make it happy.
matrix_systemd_unit_home_path: /root
# This is now unused. We keep it so that cleanup tasks can use it.
# To be removed in the future.
matrix_cron_path: "/etc/cron.d"
matrix_local_bin_path: "/usr/local/bin"
matrix_host_command_docker: "/usr/bin/env docker"
matrix_host_command_sleep: "/usr/bin/env sleep"
matrix_host_command_chown: "/usr/bin/env chown"
matrix_host_command_fusermount: "/usr/bin/env fusermount"
matrix_host_command_openssl: "/usr/bin/env openssl"
matrix_host_command_systemctl: "/usr/bin/env systemctl"
matrix_host_command_sh: "/usr/bin/env sh"
matrix_ntpd_package: "{{ 'systemd-timesyncd' if ansible_distribution == 'CentOS' and ansible_distribution_major_version > '7' else 'ntp' }}"
matrix_ntpd_service: "{{ 'systemd-timesyncd' if ansible_distribution == 'CentOS' and ansible_distribution_major_version > '7' else ('ntpd' if ansible_os_family == 'RedHat' or ansible_distribution == 'Archlinux' else 'ntp') }}"
matrix_homeserver_url: "https://{{ matrix_server_fqn_matrix }}"
# Specifies where the homeserver is on the container network.
# Where this is depends on whether there's a reverse-proxy in front of it, etc.
# This likely gets overriden elsewhere.
matrix_homeserver_container_url: "http://matrix-synapse:8008"
matrix_identity_server_url: ~
matrix_integration_manager_rest_url: ~
matrix_integration_manager_ui_url: ~
# The domain name where a Jitsi server is self-hosted.
# If set, `/.well-known/matrix/client` will suggest Element clients to use that Jitsi server.
# See: https://github.com/vector-im/element-web/blob/develop/docs/jitsi.md#configuring-element-to-use-your-self-hosted-jitsi-server
matrix_client_element_jitsi_preferredDomain: ''
# Controls whether Element should use End-to-End Encryption by default.
# Setting this to false will update `/.well-known/matrix/client` and tell Element clients to avoid E2EE.
# See: https://github.com/vector-im/element-web/blob/develop/docs/e2ee.md
matrix_client_element_e2ee_default: true
# Controls whether Element should require a secure backup set up before Element can be used.
# Setting this to true will update `/.well-known/matrix/client` and tell Element require a secure backup.
# See: https://github.com/vector-im/element-web/blob/develop/docs/e2ee.md
matrix_client_element_e2ee_secure_backup_required: false
# Controls which backup methods from ["key", "passphrase"] should be used, both is the default.
# Setting this to other then empty will update `/.well-known/matrix/client` and tell Element which method to use
# See: https://github.com/vector-im/element-web/blob/develop/docs/e2ee.md
matrix_client_element_e2ee_secure_backup_setup_methods: []
# The Docker network that all services would be put into
matrix_docker_network: "matrix"
# Controls whether we'll preserve the vars.yml file on the Matrix server.
# If you have a differently organized inventory, you may wish to disable this feature,
# or to repoint `matrix_vars_yml_snapshotting_src` to the file you'd like to preserve.
matrix_vars_yml_snapshotting_enabled: true
matrix_vars_yml_snapshotting_src: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}/vars.yml"
# Controls whether a `/.well-known/matrix/server` file is generated and used at all.
#
# If you wish to rely on DNS SRV records only, you can disable this.
# Using DNS SRV records implies that you'll be handling Matrix Federation API traffic (tcp/8448)
# using certificates for the base domain (`matrix_domain`) and not for the
# matrix domain (`matrix_server_fqn_matrix`).
matrix_well_known_matrix_server_enabled: true
# Controls whether Docker is automatically installed.
# If you change this to false you must install and update Docker manually. You also need to install the docker (https://pypi.org/project/docker/) Python package.
matrix_docker_installation_enabled: true
# Controls the Docker package that is installed.
# Possible values are "docker-ce" (default) and "docker.io" (Debian).
matrix_docker_package_name: docker-ce
# Variables to Control which parts of our roles run.
run_postgres_import: true
run_postgres_upgrade: true
run_postgres_import_sqlite_db: true
run_postgres_vacuum: true
run_synapse_register_user: true
run_synapse_update_user_password: true
run_synapse_import_media_store: true
run_synapse_rust_synapse_compress_state: true
run_setup: true
run_self_check: true
run_start: true
run_stop: true

View File

@ -0,0 +1,62 @@
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-stable-debuginfo]
name=Docker CE Stable - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/stable
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-stable-source]
name=Docker CE Stable - Sources
baseurl=https://download.docker.com/linux/centos/$releasever/source/stable
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-test]
name=Docker CE Test - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-test-debuginfo]
name=Docker CE Test - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-test-source]
name=Docker CE Test - Sources
baseurl=https://download.docker.com/linux/centos/$releasever/source/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-nightly]
name=Docker CE Nightly - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-nightly-debuginfo]
name=Docker CE Nightly - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-nightly-source]
name=Docker CE Nightly - Sources
baseurl=https://download.docker.com/linux/centos/$releasever/source/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

View File

@ -0,0 +1,9 @@
---
- name: Get rid of old files and directories
file:
path: "{{ item }}"
state: absent
with_items:
- "{{ matrix_base_data_path }}/environment-variables"
- "{{ matrix_base_data_path }}/scratchpad"

View File

@ -0,0 +1,34 @@
- import_tasks: "{{ role_path }}/tasks/sanity_check.yml"
tags:
- always
- import_tasks: "{{ role_path }}/tasks/clean_up_old_files.yml"
when: run_setup|bool
tags:
- setup-all
- import_tasks: "{{ role_path }}/tasks/server_base/setup.yml"
when: run_setup|bool
tags:
- setup-all
# This needs to always run, because it populates `matrix_user_uid` and `matrix_user_gid`,
# which are required by many other roles.
- import_tasks: "{{ role_path }}/tasks/setup_matrix_user.yml"
when: run_setup|bool
tags:
- always
- setup-system-user
- import_tasks: "{{ role_path }}/tasks/setup_matrix_base.yml"
when: run_setup|bool
tags:
- setup-all
- import_tasks: "{{ role_path }}/tasks/setup_well_known.yml"
when: run_setup|bool
tags:
- setup-all
- setup-ma1sd
- setup-synapse
- setup-nginx-proxy

View File

@ -0,0 +1,61 @@
---
# We generally support Ansible 2.7.1 and above.
- name: Fail if running on Ansible < 2.7.1
fail:
msg: "You are running on Ansible {{ ansible_version.string }}, which is not supported. See our guide about Ansible: https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/ansible.md"
when:
- "(ansible_version.major < 2) or (ansible_version.major == 2 and ansible_version.minor < 7) or (ansible_version.major == 2 and ansible_version.minor == 7 and ansible_version.revision < 1)"
# Though we do not support Ansible 2.9.6 which is buggy
- name: Fail if running on Ansible 2.9.6 on Ubuntu
fail:
msg: "You are running on Ansible {{ ansible_version.string }}, which is not supported. See our guide about Ansible: https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/ansible.md"
when:
- ansible_distribution == 'Ubuntu'
- "ansible_version.major == 2 and ansible_version.minor == 9 and ansible_version.revision == 6"
- name: (Deprecation) Catch and report renamed settings
fail:
msg: >-
Your configuration contains a variable, which now has a different name.
Please change your configuration to rename the variable (`{{ item.old }}` -> `{{ item.new }}`).
when: "item.old in vars"
with_items:
- {'old': 'host_specific_hostname_identity', 'new': 'matrix_domain'}
- {'old': 'hostname_identity', 'new': 'matrix_domain'}
- {'old': 'hostname_matrix', 'new': 'matrix_server_fqn_matrix'}
- {'old': 'hostname_riot', 'new': 'matrix_server_fqn_element'}
- {'old': 'matrix_server_fqn_riot', 'new': 'matrix_server_fqn_element'}
- name: Fail if required variables are undefined
fail:
msg: "The `{{ item }}` variable must be defined and have a non-null value"
with_items:
- matrix_domain
- matrix_server_fqn_matrix
- matrix_server_fqn_element
when: "item not in vars or vars[item] is none"
- name: Fail if uppercase domain used
fail:
msg: "Detected that you're using an uppercase domain name - `{{ item }}`. This will cause trouble. Please use all-lowercase!"
with_items:
- "{{ matrix_domain }}"
- "{{ matrix_server_fqn_matrix }}"
- "{{ matrix_server_fqn_element }}"
when: "item != item|lower"
- name: Fail if using python2 on Archlinux
fail:
msg: "Detected that you're using python2 when installing onto Archlinux. Archlinux by default only supports python3."
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")

View File

@ -0,0 +1,43 @@
---
- include_tasks: "{{ role_path }}/tasks/server_base/setup_centos.yml"
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version < '8'
- include_tasks: "{{ role_path }}/tasks/server_base/setup_centos8.yml"
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version > '7'
- block:
# ansible_lsb is only available if lsb-release is installed.
- name: Ensure lsb-release installed
apt:
name:
- lsb-release
state: present
update_cache: yes
register: lsb_release_installation_result
- name: Reread ansible_lsb facts if lsb-release got installed
setup: filter=ansible_lsb*
when: lsb_release_installation_result.changed
- include_tasks: "{{ role_path }}/tasks/server_base/setup_debian.yml"
when: (ansible_os_family == 'Debian') and (ansible_lsb.id != 'Raspbian')
- include_tasks: "{{ role_path }}/tasks/server_base/setup_raspbian.yml"
when: (ansible_os_family == 'Debian') and (ansible_lsb.id == 'Raspbian')
when: ansible_os_family == 'Debian'
- include_tasks: "{{ role_path }}/tasks/server_base/setup_archlinux.yml"
when: ansible_distribution == 'Archlinux'
- name: Ensure Docker is started and autoruns
service:
name: docker
state: started
enabled: yes
- name: "Ensure {{ matrix_ntpd_service }} is started and autoruns"
service:
name: "{{ matrix_ntpd_service }}"
state: started
enabled: yes

View File

@ -0,0 +1,19 @@
---
- name: Install host dependencies
pacman:
name:
- python-docker
- "{{ matrix_ntpd_package }}"
# TODO This needs to be verified. Which version do we need?
- fuse3
- python-dnspython
state: latest
update_cache: yes
- name: Ensure Docker is installed
pacman:
name:
- docker
state: latest
when: matrix_docker_installation_enabled|bool

View File

@ -0,0 +1,34 @@
---
- name: Ensure Docker repository is enabled
template:
src: "{{ role_path }}/files/yum.repos.d/{{ item }}"
dest: "/etc/yum.repos.d/{{ item }}"
owner: "root"
group: "root"
mode: 0644
with_items:
- docker-ce.repo
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce'
- name: Ensure Docker's RPM key is trusted
rpm_key:
state: present
key: https://download.docker.com/linux/centos/gpg
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce'
- name: Ensure yum packages are installed
yum:
name:
- "{{ matrix_ntpd_package }}"
- fuse
state: latest
update_cache: yes
- name: Ensure Docker is installed
yum:
name:
- "{{ matrix_docker_package_name }}"
- docker-python
state: latest
when: matrix_docker_installation_enabled|bool

View File

@ -0,0 +1,47 @@
---
- name: Ensure Docker repository is enabled
template:
src: "{{ role_path }}/files/yum.repos.d/{{ item }}"
dest: "/etc/yum.repos.d/{{ item }}"
owner: "root"
group: "root"
mode: 0644
with_items:
- docker-ce.repo
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce'
- name: Ensure Docker's RPM key is trusted
rpm_key:
state: present
key: https://download.docker.com/linux/centos/gpg
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce'
- name: Ensure EPEL is installed
yum:
name:
- epel-release
state: latest
update_cache: yes
- name: Ensure yum packages are installed
yum:
name:
- "{{ matrix_ntpd_package }}"
- fuse
state: latest
update_cache: yes
- name: Ensure Docker is installed
yum:
name:
- "{{ matrix_docker_package_name }}"
- python3-pip
state: latest
when: matrix_docker_installation_enabled|bool
- name: Ensure Docker-Py is installed
pip:
name: docker-py
state: latest
when: matrix_docker_installation_enabled|bool

View File

@ -0,0 +1,49 @@
---
- name: Ensure APT usage dependencies are installed
apt:
name:
- apt-transport-https
- ca-certificates
- gnupg
state: present
update_cache: yes
- name: Ensure Docker's APT key is trusted
apt_key:
url: "https://download.docker.com/linux/{{ ansible_distribution|lower }}/gpg"
id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
state: present
register: add_repository_key
ignore_errors: true
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce'
- name: Ensure Docker repository is enabled
apt_repository:
repo: "deb [arch={{ matrix_debian_arch }}] https://download.docker.com/linux/{{ ansible_distribution|lower }} {{ ansible_distribution_release }} stable"
state: present
update_cache: yes
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce' and not ansible_distribution_release == 'bullseye'
- name: Ensure Docker repository is enabled (using Debian Buster on Debian Bullseye, for which there is no Docker yet)
apt_repository:
repo: "deb [arch={{ matrix_debian_arch }}] https://download.docker.com/linux/{{ ansible_distribution|lower }} buster stable"
state: present
update_cache: yes
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce' and ansible_distribution_release == 'bullseye'
- name: Ensure APT packages are installed
apt:
name:
- "{{ matrix_ntpd_package }}"
- fuse
state: latest
update_cache: yes
- name: Ensure Docker is installed
apt:
name:
- "{{ matrix_docker_package_name }}"
- "python{{'3' if ansible_python.version.major == 3 else ''}}-docker"
state: latest
when: matrix_docker_installation_enabled|bool

View File

@ -0,0 +1,42 @@
---
- name: Ensure APT usage dependencies are installed
apt:
name:
- apt-transport-https
- ca-certificates
- gnupg
state: present
update_cache: yes
- name: Ensure Docker's APT key is trusted
apt_key:
url: https://download.docker.com/linux/raspbian/gpg
id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
state: present
register: add_repository_key
ignore_errors: true
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce'
- name: Ensure Docker repository is enabled
apt_repository:
repo: "deb [arch={{ matrix_debian_arch }}] https://download.docker.com/linux/raspbian {{ ansible_distribution_release }} stable"
state: present
update_cache: yes
when: matrix_docker_installation_enabled|bool and matrix_docker_package_name == 'docker-ce'
- name: Ensure APT packages are installed
apt:
name:
- "{{ matrix_ntpd_package }}"
- fuse
state: latest
update_cache: yes
- name: Ensure Docker is installed
apt:
name:
- "{{ matrix_docker_package_name }}"
- "python{{'3' if ansible_python.version.major == 3 else ''}}-docker"
state: latest
when: matrix_docker_installation_enabled|bool

View File

@ -0,0 +1,31 @@
---
- name: Ensure Matrix base path exists
file:
path: "{{ item }}"
state: directory
mode: "{{ matrix_base_data_path_mode }}"
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- "{{ matrix_base_data_path }}"
- name: Preserve vars.yml on the server for easily restoring if it gets lost later on
copy:
src: "{{ matrix_vars_yml_snapshotting_src }}"
dest: "{{ matrix_base_data_path }}/vars.yml"
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
mode: '0660'
when: "matrix_vars_yml_snapshotting_enabled|bool"
- name: Ensure Matrix network is created in Docker
docker_network:
name: "{{ matrix_docker_network }}"
driver: bridge
- name: Ensure matrix-remove-all script created
template:
src: "{{ role_path }}/templates/usr-local-bin/matrix-remove-all.j2"
dest: "{{ matrix_local_bin_path }}/matrix-remove-all"
mode: 0750

View File

@ -0,0 +1,27 @@
---
- name: Ensure Matrix group is created
group:
name: "{{ matrix_user_groupname }}"
gid: "{{ omit if matrix_user_gid is none else matrix_user_gid }}"
state: present
register: matrix_group
- name: Set Matrix Group GID Variable
set_fact:
matrix_user_gid: "{{ matrix_group.gid }}"
- name: Ensure Matrix user is created
user:
name: "{{ matrix_user_username }}"
uid: "{{ omit if matrix_user_uid is none else matrix_user_uid }}"
state: present
group: "{{ matrix_user_groupname }}"
home: "{{ matrix_base_data_path }}"
create_home: no
system: yes
register: matrix_user
- name: Set Matrix Group UID Variable
set_fact:
matrix_user_uid: "{{ matrix_user.uid }}"

View File

@ -0,0 +1,36 @@
# We need others to be able to read these directories too,
# so that matrix-nginx-proxy's nginx user can access the files.
#
# For running with another webserver, we recommend being part of the `matrix` group.
- name: Ensure Matrix static-files path exists
file:
path: "{{ item }}"
state: directory
mode: 0755
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- "{{ matrix_static_files_base_path }}/.well-known/matrix"
- name: Ensure Matrix /.well-known/matrix/client file configured
template:
src: "{{ role_path }}/templates/static-files/well-known/matrix-client.j2"
dest: "{{ matrix_static_files_base_path }}/.well-known/matrix/client"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
- name: Ensure Matrix /.well-known/matrix/server file configured
template:
src: "{{ role_path }}/templates/static-files/well-known/matrix-server.j2"
dest: "{{ matrix_static_files_base_path }}/.well-known/matrix/server"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
when: matrix_well_known_matrix_server_enabled|bool
- name: Ensure Matrix /.well-known/matrix/server file deleted
file:
path: "{{ matrix_static_files_base_path }}/.well-known/matrix/server"
state: absent
when: "not matrix_well_known_matrix_server_enabled|bool"

View File

@ -0,0 +1,38 @@
#jinja2: lstrip_blocks: "True"
{
"m.homeserver": {
"base_url": "{{ matrix_homeserver_url }}"
}
{% if matrix_identity_server_url %},
"m.identity_server": {
"base_url": "{{ matrix_identity_server_url }}"
}
{% endif %}
{% if matrix_integration_manager_rest_url and matrix_integration_manager_ui_url %},
"m.integrations": {
"managers": [
{
"api_url": "{{ matrix_integration_manager_rest_url }}",
"ui_url": "{{ matrix_integration_manager_ui_url }}"
}
]
}
{% endif %}
{% if matrix_client_element_jitsi_preferredDomain %},
"io.element.jitsi": {
"preferredDomain": {{ matrix_client_element_jitsi_preferredDomain|to_json }}
},
"im.vector.riot.jitsi": {
"preferredDomain": {{ matrix_client_element_jitsi_preferredDomain|to_json }}
}
{% endif %}
,
"io.element.e2ee": {
"default": {{ matrix_client_element_e2ee_default|to_json }},
"secure_backup_required": {{ matrix_client_element_e2ee_secure_backup_required|to_json }},
"secure_backup_setup_methods": {{ matrix_client_element_e2ee_secure_backup_setup_methods|to_json }}
},
"im.vector.riot.e2ee": {
"default": {{ matrix_client_element_e2ee_default|to_json }}
}
}

View File

@ -0,0 +1,4 @@
#jinja2: lstrip_blocks: "True"
{
"m.server": "{{ matrix_server_fqn_matrix_federation }}:{{ matrix_federation_public_port }}"
}

View File

@ -0,0 +1,36 @@
#jinja2: lstrip_blocks: "True"
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "This script must be executed as root! Aborting."
exit 1
fi
echo "WARNING! You are about to remove everything the playbook installs for {{ matrix_server_fqn_matrix }}: matrix, docker images,..."
echo -n "If you're sure you want to do this, type: 'Yes, I really want to remove everything!'"
read sure
if [ "$sure" != "Yes, I really want to remove everything!" ]; then
echo "Good thing I asked, exiting"
exit 0
else
echo "Stop and remove matrix services"
for s in $(find {{ matrix_systemd_path }}/ -type f -name "matrix-*" -printf "%f\n"); do
systemctl disable --now $s
rm -f {{ matrix_systemd_path }}/$s
done
systemctl daemon-reload
echo "Remove matrix scripts"
find {{ matrix_local_bin_path }}/ -name "matrix-*" -delete
echo "Remove unused Docker images and resources"
docker system prune -af
echo "Remove Docker matrix network (should be gone already, but ..)"
docker network rm {{ matrix_docker_network }}
echo "Remove {{ matrix_base_data_path }} directory"
rm -fr "{{ matrix_base_data_path }}"
exit 0
fi

View File

@ -0,0 +1,3 @@
# This will contain a list of enabled services that the playbook is managing.
# Each component is expected to append its service name to this list.
matrix_systemd_services_list: []

View File

@ -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 "<ip>:<port>" or "<port>" 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/<base64 encoded service ID>`
# # 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\"}} <font color='red'><b>[FIRING - CRITICAL]</b></font> {{ else if eq $severity \"warning\"}} <font color='orange'><b>[FIRING - WARNING]</b></font> {{ else }} <b>[FIRING - {{ $severity }}]</b> {{ end }} {{ else }} <font color='green'><b>[RESOLVED]</b></font> {{ end }} {{ index .Labels \"alertname\"}} : {{ index .Annotations \"description\"}} <a href=\"{{ .GeneratorURL }}\">source</a><br/>{{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) }}"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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 }}

View File

@ -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

View File

@ -0,0 +1,97 @@
# matrix-reminder-bot is a bot for one-off and recurring reminders
# See: https://github.com/anoadragon453/matrix-reminder-bot
matrix_bot_matrix_reminder_bot_enabled: true
matrix_bot_matrix_reminder_bot_container_self_build: false
matrix_bot_matrix_reminder_bot_docker_repo: "https://github.com/anoadragon453/matrix-reminder-bot.git"
matrix_bot_matrix_reminder_bot_docker_src_files_path: "{{ matrix_base_data_path }}/matrix-reminder-bot/docker-src"
matrix_bot_matrix_reminder_bot_version: release-v0.2.1
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"
matrix_bot_matrix_reminder_bot_config_path: "{{ matrix_bot_matrix_reminder_bot_base_path }}/config"
matrix_bot_matrix_reminder_bot_data_path: "{{ matrix_bot_matrix_reminder_bot_base_path }}/data"
matrix_bot_matrix_reminder_bot_data_store_path: "{{ matrix_bot_matrix_reminder_bot_data_path }}/store"
# A list of extra arguments to pass to the container
matrix_bot_matrix_reminder_bot_container_extra_arguments: []
# List of systemd services that matrix-bot-matrix-reminder-bot.service depends on
matrix_bot_matrix_reminder_bot_systemd_required_services_list: ['docker.service']
# List of systemd services that matrix-bot-matrix-reminder-bot.service wants
matrix_bot_matrix_reminder_bot_systemd_wanted_services_list: []
# Database-related configuration fields.
#
# To use SQLite, stick to these defaults.
#
# To use Postgres:
# - change the engine (`matrix_bot_matrix_reminder_bot_database_engine: 'postgres'`)
# - adjust your database credentials via the `matrix_bot_matrix_reminder_bot_database_*` variables
matrix_bot_matrix_reminder_bot_database_engine: 'sqlite'
matrix_bot_matrix_reminder_bot_sqlite_database_path_local: "{{ matrix_bot_matrix_reminder_bot_data_path }}/bot.db"
matrix_bot_matrix_reminder_bot_sqlite_database_path_in_container: "/data/bot.db"
matrix_bot_matrix_reminder_bot_database_username: 'matrix_reminder_bot'
matrix_bot_matrix_reminder_bot_database_password: 'some-password'
matrix_bot_matrix_reminder_bot_database_hostname: 'matrix-postgres'
matrix_bot_matrix_reminder_bot_database_port: 5432
matrix_bot_matrix_reminder_bot_database_name: 'matrix_reminder_bot'
matrix_bot_matrix_reminder_bot_database_connection_string: 'postgres://{{ matrix_bot_matrix_reminder_bot_database_username }}:{{ matrix_bot_matrix_reminder_bot_database_password }}@{{ matrix_bot_matrix_reminder_bot_database_hostname }}:{{ matrix_bot_matrix_reminder_bot_database_port }}/{{ matrix_bot_matrix_reminder_bot_database_name }}'
matrix_bot_matrix_reminder_bot_storage_database: "{{
{
'sqlite': ('sqlite://' + matrix_bot_matrix_reminder_bot_sqlite_database_path_in_container),
'postgres': matrix_bot_matrix_reminder_bot_database_connection_string,
}[matrix_bot_matrix_reminder_bot_database_engine]
}}"
# The bot's username. This user needs to be created manually beforehand.
# Also see `matrix_bot_matrix_reminder_bot_user_password`.
matrix_bot_matrix_reminder_bot_matrix_user_id_localpart: "bot.matrix-reminder-bot"
matrix_bot_matrix_reminder_bot_matrix_user_id: '@{{ matrix_bot_matrix_reminder_bot_matrix_user_id_localpart }}:{{ matrix_domain }}'
# The password that the bot uses to authenticate.
matrix_bot_matrix_reminder_bot_matrix_user_password: ''
matrix_bot_matrix_reminder_bot_matrix_homeserver_url: "{{ matrix_homeserver_container_url }}"
# The timezone to use when creating reminders.
# Examples: 'Europe/London', 'Etc/UTC'
matrix_bot_matrix_reminder_bot_reminders_timezone: ''
# 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_matrix_reminder_bot_configuration_extension_yaml`)
# or completely replace this variable with your own template.
matrix_bot_matrix_reminder_bot_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}"
matrix_bot_matrix_reminder_bot_configuration_extension_yaml: |
# Your custom YAML configuration goes here.
# This configuration extends the default starting configuration (`matrix_bot_matrix_reminder_bot_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_matrix_reminder_bot_configuration_yaml`.
#
# Example configuration extension follows:
#
# matrix:
# device_name: My-Reminder-Bot
matrix_bot_matrix_reminder_bot_configuration_extension: "{{ matrix_bot_matrix_reminder_bot_configuration_extension_yaml|from_yaml if matrix_bot_matrix_reminder_bot_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_matrix_reminder_bot_configuration_yaml`.
matrix_bot_matrix_reminder_bot_configuration: "{{ matrix_bot_matrix_reminder_bot_configuration_yaml|from_yaml|combine(matrix_bot_matrix_reminder_bot_configuration_extension, recursive=True) }}"

View File

@ -0,0 +1,3 @@
- set_fact:
matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-bot-matrix-reminder-bot.service'] }}"
when: matrix_bot_matrix_reminder_bot_enabled|bool

View File

@ -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_matrix_reminder_bot_enabled|bool"
tags:
- setup-all
- setup-bot-matrix-reminder-bot
- import_tasks: "{{ role_path }}/tasks/setup_install.yml"
when: "run_setup|bool and matrix_bot_matrix_reminder_bot_enabled|bool"
tags:
- setup-all
- setup-bot-matrix-reminder-bot
- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
when: "run_setup|bool and not matrix_bot_matrix_reminder_bot_enabled|bool"
tags:
- setup-all
- setup-bot-matrix-reminder-bot

View File

@ -0,0 +1,95 @@
---
- set_fact:
matrix_bot_matrix_reminder_bot_requires_restart: false
- block:
- name: Check if an SQLite database already exists
stat:
path: "{{ matrix_bot_matrix_reminder_bot_sqlite_database_path_local }}"
register: matrix_bot_matrix_reminder_bot_sqlite_database_path_local_stat_result
- block:
- set_fact:
matrix_postgres_db_migration_request:
src: "{{ matrix_bot_matrix_reminder_bot_sqlite_database_path_local }}"
dst: "{{ matrix_bot_matrix_reminder_bot_database_connection_string }}"
caller: "{{ role_path|basename }}"
engine_variable_name: 'matrix_bot_matrix_reminder_bot_database_engine'
engine_old: 'sqlite'
systemd_services_to_stop: ['matrix-bot-matrix-reminder-bot.service']
- import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml"
- set_fact:
matrix_bot_matrix_reminder_bot_requires_restart: true
when: "matrix_bot_matrix_reminder_bot_sqlite_database_path_local_stat_result.stat.exists|bool"
when: "matrix_bot_matrix_reminder_bot_database_engine == 'postgres'"
- name: Ensure matrix-reminder-bot paths exist
file:
path: "{{ item.path }}"
state: directory
mode: 0750
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- { path: "{{ matrix_bot_matrix_reminder_bot_config_path }}", when: true }
- { path: "{{ matrix_bot_matrix_reminder_bot_data_path }}", when: true }
- { path: "{{ matrix_bot_matrix_reminder_bot_data_store_path }}", when: true }
- { path: "{{ matrix_bot_matrix_reminder_bot_docker_src_files_path }}", when: true}
when: "item.when|bool"
- name: Ensure matrix-reminder-bot image is pulled
docker_image:
name: "{{ matrix_bot_matrix_reminder_bot_docker_image }}"
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"
force_source: "{{ matrix_bot_matrix_reminder_bot_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}"
force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_matrix_reminder_bot_docker_image_force_pull }}"
when: "not matrix_bot_matrix_reminder_bot_container_self_build|bool"
- name: Ensure matrix-reminder-bot repository is present on self-build
git:
repo: "{{ matrix_bot_matrix_reminder_bot_docker_repo }}"
dest: "{{ matrix_bot_matrix_reminder_bot_docker_src_files_path }}"
force: "yes"
register: matrix_bot_matrix_reminder_bot_git_pull_results
when: "matrix_bot_matrix_reminder_bot_container_self_build|bool"
- name: Ensure matrix-reminder-bot image is built
docker_image:
name: "{{ matrix_bot_matrix_reminder_bot_docker_image }}"
source: build
force_source: "{{ matrix_bot_matrix_reminder_bot_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: docker/Dockerfile
path: "{{ matrix_bot_matrix_reminder_bot_docker_src_files_path }}"
pull: yes
when: "matrix_bot_matrix_reminder_bot_container_self_build|bool"
- name: Ensure matrix-reminder-bot config installed
copy:
content: "{{ matrix_bot_matrix_reminder_bot_configuration|to_nice_yaml }}"
dest: "{{ matrix_bot_matrix_reminder_bot_config_path }}/config.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
- name: Ensure matrix-bot-matrix-reminder-bot.service installed
template:
src: "{{ role_path }}/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2"
dest: "{{ matrix_systemd_path }}/matrix-bot-matrix-reminder-bot.service"
mode: 0644
register: matrix_bot_matrix_reminder_bot_systemd_service_result
- name: Ensure systemd reloaded after matrix-bot-matrix-reminder-bot.service installation
service:
daemon_reload: yes
when: "matrix_bot_matrix_reminder_bot_systemd_service_result.changed|bool"
- name: Ensure matrix-bot-matrix-reminder-bot.service restarted, if necessary
service:
name: "matrix-bot-matrix-reminder-bot.service"
state: restarted
when: "matrix_bot_matrix_reminder_bot_requires_restart|bool"

View File

@ -0,0 +1,35 @@
---
- name: Check existence of matrix-matrix-reminder-bot service
stat:
path: "{{ matrix_systemd_path }}/matrix-bot-matrix-reminder-bot.service"
register: matrix_bot_matrix_reminder_bot_service_stat
- name: Ensure matrix-matrix-reminder-bot is stopped
service:
name: matrix-bot-matrix-reminder-bot
state: stopped
daemon_reload: yes
register: stopping_result
when: "matrix_bot_matrix_reminder_bot_service_stat.stat.exists|bool"
- name: Ensure matrix-bot-matrix-reminder-bot.service doesn't exist
file:
path: "{{ matrix_systemd_path }}/matrix-bot-matrix-reminder-bot.service"
state: absent
when: "matrix_bot_matrix_reminder_bot_service_stat.stat.exists|bool"
- name: Ensure systemd reloaded after matrix-bot-matrix-reminder-bot.service removal
service:
daemon_reload: yes
when: "matrix_bot_matrix_reminder_bot_service_stat.stat.exists|bool"
- name: Ensure Matrix matrix-reminder-bot paths don't exist
file:
path: "{{ matrix_bot_matrix_reminder_bot_base_path }}"
state: absent
- name: Ensure matrix-reminder-bot Docker image doesn't exist
docker_image:
name: "{{ matrix_bot_matrix_reminder_bot_docker_image }}"
state: absent

View File

@ -0,0 +1,10 @@
---
- name: Fail if required settings not defined
fail:
msg: >-
You need to define a required configuration setting (`{{ item }}`).
when: "vars[item] == ''"
with_items:
- "matrix_bot_matrix_reminder_bot_matrix_user_password"
- "matrix_bot_matrix_reminder_bot_reminders_timezone"

View File

@ -0,0 +1,50 @@
# The string to prefix bot commands with
command_prefix: "!"
# Options for connecting to the bot's Matrix account
matrix:
# The Matrix User ID of the bot account
user_id: {{ matrix_bot_matrix_reminder_bot_matrix_user_id|to_json }}
# Matrix account password
user_password: {{ matrix_bot_matrix_reminder_bot_matrix_user_password|to_json }}
# The public URL at which the homeserver's Client-Server API can be accessed
homeserver_url: {{ matrix_bot_matrix_reminder_bot_matrix_homeserver_url }}
# The device ID that is a **non pre-existing** device
# If this device ID already exists, messages will be dropped silently in
# encrypted rooms
device_id: REMINDER
# What to name the logged in device
device_name: Reminder Bot
storage:
# The database connection string
# For SQLite3, this would look like:
# database: "sqlite://bot.db"
# For Postgres, this would look like:
# database: "postgres://username:password@localhost/dbname?sslmode=disable"
#database: "postgres://matrix-reminder-bot:remindme@localhost/matrix-reminder-bot?sslmode=disable"
database: {{ matrix_bot_matrix_reminder_bot_storage_database|to_json }}
# The path to a directory for internal bot storage
# containing encryption keys, sync tokens, etc.
store_path: "/data/store"
reminders:
# Uncomment to set a default timezone that will be used when creating reminders.
# If not set, UTC will be used
timezone: {{ matrix_bot_matrix_reminder_bot_reminders_timezone }}
# Logging setup
logging:
# Logging level
# Allowed levels are 'INFO', 'WARNING', 'ERROR', 'DEBUG' where DEBUG is most verbose
level: INFO
# Configure logging to a file
file_logging:
# Whether logging to a file is enabled
enabled: false
# The path to the file to log to. May be relative or absolute
filepath: /data/bot.log
# Configure logging to the console (stdout/stderr)
console_logging:
# Whether console logging is enabled
enabled: true

View File

@ -0,0 +1,42 @@
#jinja2: lstrip_blocks: "True"
[Unit]
Description=Matrix reminder bot
{% for service in matrix_bot_matrix_reminder_bot_systemd_required_services_list %}
Requires={{ service }}
After={{ service }}
{% endfor %}
{% for service in matrix_bot_matrix_reminder_bot_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-matrix-reminder-bot 2>/dev/null'
ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-bot-matrix-reminder-bot 2>/dev/null'
ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-bot-matrix-reminder-bot \
--log-driver=none \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--cap-drop=ALL \
--read-only \
--network={{ matrix_docker_network }} \
-e 'TZ={{ matrix_bot_matrix_reminder_bot_reminders_timezone }}' \
--mount type=bind,src={{ matrix_bot_matrix_reminder_bot_config_path }},dst=/config,ro \
--mount type=bind,src={{ matrix_bot_matrix_reminder_bot_data_path }},dst=/data \
--entrypoint=/bin/sh \
{% for arg in matrix_bot_matrix_reminder_bot_container_extra_arguments %}
{{ arg }} \
{% endfor %}
{{ matrix_bot_matrix_reminder_bot_docker_image }} \
-c "matrix-reminder-bot /config/config.yaml"
ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-bot-matrix-reminder-bot 2>/dev/null'
ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-bot-matrix-reminder-bot 2>/dev/null'
Restart=always
RestartSec=30
SyslogIdentifier=matrix-bot-matrix-reminder-bot
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,60 @@
# A moderation tool for Matrix
# See: https://github.com/matrix-org/mjolnir
matrix_bot_mjolnir_enabled: true
matrix_bot_mjolnir_version: "v0.1.18"
matrix_bot_mjolnir_container_image_self_build: false
matrix_bot_mjolnir_container_image_self_build_repo: "https://github.com/matrix-org/mjolnir.git"
matrix_bot_mjolnir_docker_image: "{{ matrix_bot_mjolnir_docker_image_name_prefix }}matrixdotorg/mjolnir:{{ matrix_bot_mjolnir_version }}"
matrix_bot_mjolnir_docker_image_name_prefix: "{{ 'localhost/' if matrix_bot_mjolnir_container_image_self_build else matrix_container_global_registry_prefix }}"
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"
matrix_bot_mjolnir_docker_src_files_path: "{{ matrix_bot_mjolnir_base_path }}/docker-src"
# 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) }}"

View File

@ -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 Mjolnir 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_bot_mjolnir_container_image_self_build and matrix_bot_mjolnir_enabled"
- set_fact:
matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-bot-mjolnir.service'] }}"
when: matrix_bot_mjolnir_enabled|bool

View File

@ -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

View File

@ -0,0 +1,72 @@
---
- 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 }
- { path: "{{ matrix_bot_mjolnir_docker_src_files_path }}", when: "{{ matrix_bot_mjolnir_container_image_self_build }}" }
when: "item.when|bool"
- name: Ensure mjolnir Docker 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 }}"
when: "not matrix_bot_mjolnir_container_image_self_build|bool"
- name: Ensure mjolnir repository is present on self-build
git:
repo: "{{ matrix_bot_mjolnir_container_image_self_build_repo }}"
dest: "{{ matrix_bot_mjolnir_docker_src_files_path }}"
version: "{{ matrix_bot_mjolnir_docker_image.split(':')[1] }}"
force: "yes"
register: matrix_bot_mjolnir_git_pull_results
when: "matrix_bot_mjolnir_container_image_self_build|bool"
- name: Ensure mjolnir Docker image is built
docker_image:
name: "{{ matrix_bot_mjolnir_docker_image }}"
source: build
force_source: "{{ matrix_bot_mjolnir_git_pull_results.changed }}"
build:
dockerfile: Dockerfile
path: "{{ matrix_bot_mjolnir_docker_src_files_path }}"
pull: yes
when: "matrix_bot_mjolnir_container_image_self_build|bool"
- 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"

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,110 @@
# matrix-appservice-discord is a Matrix <-> Discord bridge
# See: https://github.com/Half-Shot/matrix-appservice-discord
matrix_appservice_discord_enabled: true
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"
matrix_appservice_discord_config_path: "{{ matrix_base_data_path }}/appservice-discord/config"
matrix_appservice_discord_data_path: "{{ matrix_base_data_path }}/appservice-discord/data"
# Get your own keys at https://discordapp.com/developers/applications/me/create
matrix_appservice_discord_client_id: ''
matrix_appservice_discord_bot_token: ''
matrix_appservice_discord_appservice_token: ''
matrix_appservice_discord_homeserver_token: ''
matrix_appservice_discord_homeserver_domain: "{{ matrix_domain }}"
# Controls whether the matrix-appservice-discord container exposes its HTTP port (tcp/9005 in the container).
#
# Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:9005"), or empty string to not expose.
matrix_appservice_discord_container_http_host_bind_port: ''
# A list of extra arguments to pass to the container
matrix_appservice_discord_container_extra_arguments: []
# List of systemd services that matrix-appservice-discord.service depends on.
matrix_appservice_discord_systemd_required_services_list: ['docker.service']
# List of systemd services that matrix-appservice-discord.service wants
matrix_appservice_discord_systemd_wanted_services_list: []
matrix_appservice_discord_appservice_url: 'http://matrix-appservice-discord:9005'
matrix_appservice_discord_bridge_domain: "{{ matrix_domain }}"
# As of right now, the homeserver URL must be a public URL. See below.
matrix_appservice_discord_bridge_homeserverUrl: "{{ matrix_homeserver_url }}"
matrix_appservice_discord_bridge_disablePresence: false
matrix_appservice_discord_bridge_enableSelfServiceBridging: false
# Database-related configuration fields.
#
# To use SQLite, stick to these defaults.
#
# To use Postgres:
# - change the engine (`matrix_appservice_discord_database_engine: 'postgres'`)
# - adjust your database credentials via the `matrix_appservice_discord_postgres_*` variables
matrix_appservice_discord_database_engine: 'sqlite'
matrix_appservice_discord_sqlite_database_path_local: "{{ matrix_appservice_discord_data_path }}/discord.db"
matrix_appservice_discord_sqlite_database_path_in_container: "/data/discord.db"
matrix_appservice_discord_database_username: 'matrix_appservice_discord'
matrix_appservice_discord_database_password: 'some-password'
matrix_appservice_discord_database_hostname: 'matrix-postgres'
matrix_appservice_discord_database_port: 5432
matrix_appservice_discord_database_name: 'matrix_appservice_discord'
# These 2 variables are what actually ends up in the bridge configuration.
# It's best if you don't change them directly, but rather redefine the sub-variables that constitute them.
matrix_appservice_discord_database_filename: "{{ matrix_appservice_discord_sqlite_database_path_in_container }}"
matrix_appservice_discord_database_connString: 'postgresql://{{ matrix_appservice_discord_database_username }}:{{ matrix_appservice_discord_database_password }}@{{ matrix_appservice_discord_database_hostname }}:{{ matrix_appservice_discord_database_port }}/{{ matrix_appservice_discord_database_name }}'
# Tells whether the bot should make use of "Privileged Gateway Intents".
#
# Enabling this means that you need to enable it for the bot (Discord application) as well,
# by triggering all Intent checkboxes on a page like this: `https://discord.com/developers/applications/694448564151123988/bot`
#
# Learn more: https://gist.github.com/advaith1/e69bcc1cdd6d0087322734451f15aa2f
matrix_appservice_discord_auth_usePrivilegedIntents: false
matrix_appservice_discord_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}"
matrix_appservice_discord_configuration_extension_yaml: |
# Your custom YAML configuration goes here.
# This configuration extends the default starting configuration (`matrix_appservice_discord_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_appservice_discord_configuration_yaml`.
matrix_appservice_discord_configuration_extension: "{{ matrix_appservice_discord_configuration_extension_yaml|from_yaml if matrix_appservice_discord_configuration_extension_yaml|from_yaml is mapping else {} }}"
matrix_appservice_discord_configuration: "{{ matrix_appservice_discord_configuration_yaml|from_yaml|combine(matrix_appservice_discord_configuration_extension, recursive=True) }}"
matrix_appservice_discord_registration_yaml: |
#jinja2: lstrip_blocks: "True"
id: appservice-discord
as_token: "{{ matrix_appservice_discord_appservice_token }}"
hs_token: "{{ matrix_appservice_discord_homeserver_token }}"
namespaces:
users:
- exclusive: true
regex: '@_discord_.*:{{ matrix_appservice_discord_homeserver_domain|regex_escape }}'
aliases:
- exclusive: true
regex: '#_discord_.*:{{ matrix_appservice_discord_homeserver_domain|regex_escape }}'
url: {{ matrix_appservice_discord_appservice_url }}
sender_localpart: _discord_bot
rate_limited: false
protocols:
- discord
matrix_appservice_discord_registration: "{{ matrix_appservice_discord_registration_yaml|from_yaml }}"

View File

@ -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-appservice-discord role needs to execute before the matrix-synapse role.
when: "matrix_appservice_discord_enabled and matrix_synapse_role_executed|default(False)"
- set_fact:
matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-appservice-discord.service'] }}"
when: matrix_appservice_discord_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_appservice_discord_config_path }}/registration.yaml,dst=/matrix-appservice-discord-registration.yaml,ro"]
matrix_synapse_app_service_config_files: >
{{ matrix_synapse_app_service_config_files|default([]) }}
+
{{ ["/matrix-appservice-discord-registration.yaml"] }}
when: matrix_appservice_discord_enabled|bool

View File

@ -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_appservice_discord_enabled|bool"
tags:
- setup-all
- setup-appservice-discord
- import_tasks: "{{ role_path }}/tasks/setup_install.yml"
when: "run_setup|bool and matrix_appservice_discord_enabled|bool"
tags:
- setup-all
- setup-appservice-discord
- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
when: "run_setup|bool and not matrix_appservice_discord_enabled|bool"
tags:
- setup-all
- setup-appservice-discord

View File

@ -0,0 +1,114 @@
---
- set_fact:
matrix_appservice_discord_requires_restart: false
- block:
- name: Check if an SQLite database already exists
stat:
path: "{{ matrix_appservice_discord_sqlite_database_path_local }}"
register: matrix_appservice_discord_sqlite_database_path_local_stat_result
- block:
- set_fact:
matrix_postgres_db_migration_request:
src: "{{ matrix_appservice_discord_sqlite_database_path_local }}"
dst: "{{ matrix_appservice_discord_database_connString }}"
caller: "{{ role_path|basename }}"
engine_variable_name: 'matrix_appservice_discord_database_engine'
engine_old: 'sqlite'
systemd_services_to_stop: ['matrix-appservice-discord.service']
- import_tasks: "{{ role_path }}/../matrix-postgres/tasks/util/migrate_db_to_postgres.yml"
- set_fact:
matrix_appservice_discord_requires_restart: true
when: "matrix_appservice_discord_sqlite_database_path_local_stat_result.stat.exists|bool"
when: "matrix_appservice_discord_database_engine == 'postgres'"
- name: Ensure Appservice Discord image is pulled
docker_image:
name: "{{ matrix_appservice_discord_docker_image }}"
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"
force_source: "{{ matrix_appservice_discord_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}"
force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_discord_docker_image_force_pull }}"
- name: Ensure AppService Discord paths exist
file:
path: "{{ item }}"
state: directory
mode: 0750
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- "{{ matrix_appservice_discord_base_path }}"
- "{{ matrix_appservice_discord_config_path }}"
- "{{ matrix_appservice_discord_data_path }}"
- name: Check if an old database file already exists
stat:
path: "{{ matrix_appservice_discord_base_path }}/discord.db"
register: matrix_appservice_discord_stat_db
- name: (Data relocation) Ensure matrix-appservice-discord.service is stopped
service:
name: matrix-appservice-discord
state: stopped
daemon_reload: yes
failed_when: false
when: "matrix_appservice_discord_stat_db.stat.exists"
- name: (Data relocation) Move AppService Discord discord.db file to ./data directory
command: "mv {{ matrix_appservice_discord_base_path }}/{{ item }} {{ matrix_appservice_discord_data_path }}/{{ item }}"
with_items:
- discord.db
- user-store.db
- room-store.db
when: "matrix_appservice_discord_stat_db.stat.exists"
- name: Ensure AppService Discord config.yaml installed
copy:
content: "{{ matrix_appservice_discord_configuration|to_nice_yaml }}"
dest: "{{ matrix_appservice_discord_config_path }}/config.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
- name: Ensure AppService Discord registration.yaml installed
copy:
content: "{{ matrix_appservice_discord_registration|to_nice_yaml }}"
dest: "{{ matrix_appservice_discord_config_path }}/registration.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
# If `matrix_appservice_discord_client_id` hasn't changed, the same invite link would be generated.
# We intentionally suppress Ansible changes.
- name: Generate AppService Discord invite link
shell: >-
{{ matrix_host_command_docker }} run --rm --name matrix-appservice-discord-link-gen
--user={{ matrix_user_uid }}:{{ matrix_user_gid }}
--cap-drop=ALL
--mount type=bind,src={{ matrix_appservice_discord_config_path }},dst=/cfg
-w /cfg
{{ matrix_appservice_discord_docker_image }}
/bin/sh -c "node /build/tools/addbot.js > /cfg/invite_link"
changed_when: false
- name: Ensure matrix-appservice-discord.service installed
template:
src: "{{ role_path }}/templates/systemd/matrix-appservice-discord.service.j2"
dest: "{{ matrix_systemd_path }}/matrix-appservice-discord.service"
mode: 0644
register: matrix_appservice_discord_systemd_service_result
- name: Ensure systemd reloaded after matrix-appservice-discord.service installation
service:
daemon_reload: yes
when: "matrix_appservice_discord_systemd_service_result.changed"
- name: Ensure matrix-appservice-discord.service restarted, if necessary
service:
name: "matrix-appservice-discord.service"
state: restarted
when: "matrix_appservice_discord_requires_restart|bool"

View File

@ -0,0 +1,24 @@
---
- name: Check existence of matrix-appservice-discord service
stat:
path: "{{ matrix_systemd_path }}/matrix-appservice-discord.service"
register: matrix_appservice_discord_service_stat
- name: Ensure matrix-appservice-discord is stopped
service:
name: matrix-appservice-discord
state: stopped
daemon_reload: yes
when: "matrix_appservice_discord_service_stat.stat.exists"
- name: Ensure matrix-appservice-discord.service doesn't exist
file:
path: "{{ matrix_systemd_path }}/matrix-appservice-discord.service"
state: absent
when: "matrix_appservice_discord_service_stat.stat.exists"
- name: Ensure systemd reloaded after matrix-appservice-discord.service removal
service:
daemon_reload: yes
when: "matrix_appservice_discord_service_stat.stat.exists"

View File

@ -0,0 +1,26 @@
---
- name: Fail if required settings not defined
fail:
msg: >-
You need to define a required configuration setting (`{{ item }}`).
when: "vars[item] == ''"
with_items:
- "matrix_appservice_discord_client_id"
- "matrix_appservice_discord_bot_token"
- "matrix_appservice_discord_appservice_token"
- "matrix_appservice_discord_homeserver_token"
- "matrix_appservice_discord_homeserver_domain"
- name: (Deprecation) Catch and report renamed appservice-discord variables
fail:
msg: >-
Your configuration contains a variable, which now has a different name.
Please change your configuration to rename the variable (`{{ item.old }}` -> `{{ item.new }}`).
when: "item.old in vars"
with_items:
- {'old': 'matrix_appservice_discord_container_expose_client_server_api_port', 'new': '<superseded by matrix_appservice_discord_container_http_host_bind_port>'}
- name: Require a valid database engine
fail: msg="`matrix_appservice_discord_database_engine` needs to be either 'sqlite' or 'postgres'"
when: "matrix_appservice_discord_database_engine not in ['sqlite', 'postgres']"

View File

@ -0,0 +1,103 @@
#jinja2: lstrip_blocks: "True"
bridge:
# Domain part of the bridge, e.g. matrix.org
domain: {{ matrix_appservice_discord_bridge_domain|to_json }}
# This should be your publically facing URL because Discord may use it to
# fetch media from the media store.
homeserverUrl: {{ matrix_appservice_discord_bridge_homeserverUrl|to_json }}
# Interval at which to process users in the 'presence queue'. If you have
# 5 users, one user will be processed every 500 milliseconds according to the
# value below. This has a minimum value of 250.
# WARNING: This has a high chance of spamming the homeserver with presence
# updates since it will send one each time somebody changes state or is online.
presenceInterval: 500
# Disable setting presence for 'ghost users' which means Discord users on Matrix
# will not be shown as away or online.
disablePresence: {{ matrix_appservice_discord_bridge_disablePresence|to_json }}
# Disable sending typing notifications when somebody on Discord types.
disableTypingNotifications: false
# Disable deleting messages on Discord if a message is redacted on Matrix.
disableDeletionForwarding: false
# Enable users to bridge rooms using !discord commands. See
# https://t2bot.io/discord for instructions.
enableSelfServiceBridging: {{ matrix_appservice_discord_bridge_enableSelfServiceBridging|to_json }}
# Disable sending of read receipts for Matrix events which have been
# successfully bridged to Discord.
disableReadReceipts: false
# Disable Join Leave echos from matrix
disableJoinLeaveNotifications: false
# Disable Invite echos from matrix
disableInviteNotifications: false
# Auto-determine the language of code blocks (this can be CPU-intensive)
determineCodeLanguage: false
# Authentication configuration for the discord bot.
auth:
clientID: {{ matrix_appservice_discord_client_id|string|to_json }}
botToken: {{ matrix_appservice_discord_bot_token|to_json }}
# You must enable "Privileged Gateway Intents" in your bot settings on discord.com (e.g. https://discord.com/developers/applications/12345/bot)
# for this to work
usePrivilegedIntents: {{ matrix_appservice_discord_auth_usePrivilegedIntents|to_json }}
logging:
# What level should the logger output to the console at.
console: "warn" #silly, verbose, info, http, warn, error, silent
lineDateFormat: "MMM-D HH:mm:ss.SSS" # This is in moment.js format
# files:
# - file: "debug.log"
# disable:
# - "PresenceHandler" # Will not capture presence logging
# - file: "warn.log" # Will capture warnings
# level: "warn"
# - file: "botlogs.log" # Will capture logs from DiscordBot
# level: "info"
# enable:
# - "DiscordBot"
database:
# You may either use SQLite or Postgresql for the bridge database, which contains
# important mappings for events and user puppeting configurations.
# Use the filename option for SQLite, or connString for Postgresql.
# If you are migrating, see https://github.com/Half-Shot/matrix-appservice-discord/blob/master/docs/howto.md#migrate-to-postgres-from-sqlite
# WARNING: You will almost certainly be fine with sqlite unless your bridge
# is in heavy demand and you suffer from IO slowness.
{% if matrix_appservice_discord_database_engine == 'sqlite' %}
filename: {{ matrix_appservice_discord_database_filename|to_json }}
{% else %}
connString: {{ matrix_appservice_discord_database_connString|to_json }}
{% endif %}
room:
# Set the default visibility of alias rooms, defaults to "public".
# One of: "public", "private"
defaultVisibility: "public"
channel:
# Pattern of the name given to bridged rooms.
# Can use :guild for the guild name and :name for the channel name.
namePattern: "[Discord] :guild :name"
# Changes made to rooms when a channel is deleted.
deleteOptions:
# Prefix the room name with a string.
#namePrefix: "[Deleted]"
# Prefix the room topic with a string.
#topicPrefix: "This room has been deleted"
# Disable people from talking in the room by raising the event PL to 50
disableMessaging: false
# Remove the discord alias from the room.
unsetRoomAlias: true
# Remove the room from the directory.
unlistFromDirectory: true
# Set the room to be unavaliable for joining without an invite.
setInviteOnly: true
# Make all the discord users leave the room.
ghostsLeave: true
limits:
# Delay in milliseconds between discord users joining a room.
roomGhostJoinDelay: 6000
# Lock timeout in milliseconds before sending messages to discord to avoid
# echos. Default is rather high as the lock will most likely time out
# before anyways.
# echos = (Copies of a sent message may arrive from discord before we've
# fininished handling it, causing us to echo it back to the room)
discordSendDelay: 1500
ghosts:
# Pattern for the ghosts nick, available is :nick, :username, :tag and :id
nickPattern: ":nick"
# Pattern for the ghosts username, available is :username, :tag and :id
usernamePattern: ":username#:tag"

View File

@ -0,0 +1,45 @@
#jinja2: lstrip_blocks: "True"
[Unit]
Description=Matrix Appservice Discord bridge
{% for service in matrix_appservice_discord_systemd_required_services_list %}
Requires={{ service }}
After={{ service }}
{% endfor %}
{% for service in matrix_appservice_discord_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-appservice-discord 2>/dev/null'
ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-appservice-discord 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-appservice-discord \
--log-driver=none \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--cap-drop=ALL \
--network={{ matrix_docker_network }} \
{% if matrix_appservice_discord_container_http_host_bind_port %}
-p {{ matrix_appservice_discord_container_http_host_bind_port }}:9005 \
{% endif %}
--mount type=bind,src={{ matrix_appservice_discord_config_path }},dst=/cfg \
--mount type=bind,src={{ matrix_appservice_discord_data_path }},dst=/data \
{% for arg in matrix_appservice_discord_container_extra_arguments %}
{{ arg }} \
{% endfor %}
{{ matrix_appservice_discord_docker_image }} \
node /build/src/discordas.js -p 9005 -c /cfg/config.yaml -f /cfg/registration.yaml
ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-appservice-discord 2>/dev/null'
ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-appservice-discord 2>/dev/null'
Restart=always
RestartSec=30
SyslogIdentifier=matrix-appservice-discord
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,401 @@
# Matrix Appservice IRC is a Matrix <-> IRC bridge
# See: https://github.com/matrix-org/matrix-appservice-irc
matrix_appservice_irc_enabled: true
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_version: release-v0.29.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"
matrix_appservice_irc_config_path: "{{ matrix_appservice_irc_base_path }}/config"
matrix_appservice_irc_data_path: "{{ matrix_appservice_irc_base_path }}/data"
matrix_appservice_irc_homeserver_url: "{{ matrix_homeserver_container_url }}"
matrix_appservice_irc_homeserver_media_url: 'https://{{ matrix_server_fqn_matrix }}'
matrix_appservice_irc_homeserver_domain: '{{ matrix_domain }}'
matrix_appservice_irc_homeserver_enablePresence: true
matrix_appservice_irc_appservice_address: 'http://matrix-appservice-irc:9999'
matrix_appservice_irc_database_engine: nedb
matrix_appservice_irc_database_username: matrix_appservice_irc
matrix_appservice_irc_database_password: ~
matrix_appservice_irc_database_hostname: 'matrix-postgres'
matrix_appservice_irc_database_port: 5432
matrix_appservice_irc_database_name: matrix_appservice_irc
# This is just the Postgres connection string, if Postgres is used.
# Naming clashes with `matrix_appservice_irc_database_connectionString` somewhat.
matrix_appservice_irc_database_connection_string: 'postgresql://{{ matrix_appservice_irc_database_username }}:{{ matrix_appservice_irc_database_password }}@{{ matrix_appservice_irc_database_hostname }}:{{ matrix_appservice_irc_database_port }}/{{ matrix_appservice_irc_database_name }}?sslmode=disable'
# This is what actually goes into `database.connectionString` for the bridge.
matrix_appservice_irc_database_connectionString: "{{
{
'nedb': 'nedb:///data',
'postgres': matrix_appservice_irc_database_connection_string,
}[matrix_appservice_irc_database_engine]
}}"
matrix_appservice_irc_ircService_servers: []
# Example of `matrix_appservice_irc_ircService_servers` with one server (and all its options):
#
# matrix_appservice_irc_ircService_servers:
# # The address of the server to connect to.
# irc.example.com:
# # A human-readable short name. This is used to label IRC status rooms
# # where matrix users control their connections.
# # E.g. 'ExampleNet IRC Bridge status'.
# # It is also used in the Third Party Lookup API as the instance `desc`
# # property, where each server is an instance.
# name: "ExampleNet"
# additionalAddresses: [ "irc2.example.com" ]
# #
# # [DEPRECATED] Use `name`, above, instead.
# # A human-readable description string
# # description: "Example.com IRC network"
# # An ID for uniquely identifying this server amongst other servers being bridged.
# # networkId: "example"
# # URL to an icon used as the network icon whenever this network appear in
# # a network list. (Like in the riot room directory, for instance.)
# # icon: https://example.com/images/hash.png
# # The port to connect to. Optional.
# port: 6697
# # Whether to use SSL or not. Default: false.
# ssl: true
# # Whether or not IRC server is using a self-signed cert or not providing CA Chain
# sslselfsign: false
# # Should the connection attempt to identify via SASL (if a server or user password is given)
# # If false, this will use PASS instead. If SASL fails, we do not fallback to PASS.
# sasl: false
# # Whether to allow expired certs when connecting to the IRC server.
# # Usually this should be off. Default: false.
# allowExpiredCerts: false
# # A specific CA to trust instead of the default CAs. Optional.
# #ca: |
# # -----BEGIN CERTIFICATE-----
# # ...
# # -----END CERTIFICATE-----
# #
# # The connection password to send for all clients as a PASS (or SASL, if enabled above) command. Optional.
# # password: 'pa$$w0rd'
# #
# # Whether or not to send connection/error notices to real Matrix users. Default: true.
# sendConnectionMessages: true
# quitDebounce:
# # Whether parts due to net-splits are debounced for delayMs, to allow
# # time for the netsplit to resolve itself. A netsplit is detected as being
# # a QUIT rate higher than quitsPerSecond. Default: false.
# enabled: false
# # The maximum number of quits per second acceptable above which a netsplit is
# # considered ongoing. Default: 5.
# quitsPerSecond: 5
# # The time window in which to wait before bridging a QUIT to Matrix that occurred during
# # a netsplit. Debouncing is jittered randomly between delayMinMs and delayMaxMs so that the HS
# # is not sent many requests to leave rooms all at once if a netsplit occurs and many
# # people to not rejoin.
# # If the user with the same IRC nick as the one who sent the quit rejoins a channel
# # they are considered back online and the quit is not bridged, so long as the rejoin
# # occurs before the randomly-jittered timeout is not reached.
# # Default: 3600000, = 1h
# delayMinMs: 3600000 # 1h
# # Default: 7200000, = 2h
# delayMaxMs: 7200000 # 2h
# # A map for conversion of IRC user modes to Matrix power levels. This enables bridging
# # of IRC ops to Matrix power levels only, it does not enable the reverse. If a user has
# # been given multiple modes, the one that maps to the highest power level will be used.
# modePowerMap:
# o: 50
# botConfig:
# # Enable the presence of the bot in IRC channels. The bot serves as the entity
# # which maps from IRC -> Matrix. You can disable the bot entirely which
# # means IRC -> Matrix chat will be shared by active "M-Nick" connections
# # in the room. If there are no users in the room (or if there are users
# # but their connections are not on IRC) then nothing will be bridged to
# # Matrix. If you're concerned about the bot being treated as a "logger"
# # entity, then you may want to disable the bot. If you want IRC->Matrix
# # but don't want to have TCP connections to IRC unless a Matrix user speaks
# # (because your client connection limit is low), then you may want to keep
# # the bot enabled. Default: true.
# # NB: If the bot is disabled, you SHOULD have matrix-to-IRC syncing turned
# # on, else there will be no users and no bot in a channel (meaning no
# # messages to Matrix!) until a Matrix user speaks which makes a client
# # join the target IRC channel.
# # NBB: The bridge bot IRC client will still join the target IRC network so
# # it can service bridge-specific queries from the IRC-side e.g. so
# # real IRC clients have a way to change their Matrix display name.
# # See https://github.com/matrix-org/matrix-appservice-irc/issues/55
# enabled: true
# # The nickname to give the AS bot.
# nick: "MatrixBot"
# # The password to give to NickServ or IRC Server for this nick. Optional.
# # password: "helloworld"
# #
# # Join channels even if there are no Matrix users on the other side of
# # the bridge. Set to false to prevent the bot from joining channels which have no
# # real matrix users in them, even if there is a mapping for the channel.
# # Default: true
# joinChannelsIfNoUsers: true
# # Configuration for PMs / private 1:1 communications between users.
# privateMessages:
# # Enable the ability for PMs to be sent to/from IRC/Matrix.
# # Default: true.
# enabled: true
# # Prevent Matrix users from sending PMs to the following IRC nicks.
# # Optional. Default: [].
# # exclude: ["Alice", "Bob"] # NOT YET IMPLEMENTED
# # Should created Matrix PM rooms be federated? If false, only users on the
# # HS attached to this AS will be able to interact with this room.
# # Optional. Default: true.
# federate: true
# # Configuration for mappings not explicitly listed in the 'mappings'
# # section.
# dynamicChannels:
# # Enable the ability for Matrix users to join *any* channel on this IRC
# # network.
# # Default: false.
# enabled: true
# # Should the AS create a room alias for the new Matrix room? The form of
# # the alias can be modified via 'aliasTemplate'. Default: true.
# createAlias: true
# # Should the AS publish the new Matrix room to the public room list so
# # anyone can see it? Default: true.
# published: true
# # What should the join_rule be for the new Matrix room? If 'public',
# # anyone can join the room. If 'invite', only users with an invite can
# # join the room. Note that if an IRC channel has +k or +i set on it,
# # join_rules will be set to 'invite' until these modes are removed.
# # Default: "public".
# joinRule: public
# # This will set the m.room.related_groups state event in newly created rooms
# # with the given groupId. This means flares will show up on IRC users in those rooms.
# # This should be set to the same thing as namespaces.users.group_id in irc_registration.
# # This does not alter existing rooms.
# # Leaving this option empty will not set the event.
# groupId: +myircnetwork:localhost
# # Should created Matrix rooms be federated? If false, only users on the
# # HS attached to this AS will be able to interact with this room.
# # Default: true.
# federate: true
# # The room alias template to apply when creating new aliases. This only
# # applies if createAlias is 'true'. The following variables are exposed:
# # $SERVER => The IRC server address (e.g. "irc.example.com")
# # $CHANNEL => The IRC channel (e.g. "#python")
# # This MUST have $CHANNEL somewhere in it.
# # Default: '#irc_$SERVER_$CHANNEL'
# aliasTemplate: "#irc_$CHANNEL"
# # A list of user IDs which the AS bot will send invites to in response
# # to a !join. Only applies if joinRule is 'invite'. Default: []
# # whitelist:
# # - "@foo:example.com"
# # - "@bar:example.com"
# #
# # Prevent the given list of channels from being mapped under any
# # circumstances.
# # exclude: ["#foo", "#bar"]
# # Configuration for controlling how Matrix and IRC membership lists are
# # synced.
# membershipLists:
# # Enable the syncing of membership lists between IRC and Matrix. This
# # can have a significant effect on performance on startup as the lists are
# # synced. This must be enabled for anything else in this section to take
# # effect. Default: false.
# enabled: false
# # Syncing membership lists at startup can result in hundreds of members to
# # process all at once. This timer drip feeds membership entries at the
# # specified rate. Default: 10000. (10s)
# floodDelayMs: 10000
# global:
# ircToMatrix:
# # Get a snapshot of all real IRC users on a channel (via NAMES) and
# # join their virtual matrix clients to the room.
# initial: false
# # Make virtual matrix clients join and leave rooms as their real IRC
# # counterparts join/part channels. Default: false.
# incremental: false
# matrixToIrc:
# # Get a snapshot of all real Matrix users in the room and join all of
# # them to the mapped IRC channel on startup. Default: false.
# initial: false
# # Make virtual IRC clients join and leave channels as their real Matrix
# # counterparts join/leave rooms. Make sure your 'maxClients' value is
# # high enough! Default: false.
# incremental: false
# # Apply specific rules to Matrix rooms. Only matrix-to-IRC takes effect.
# rooms:
# - room: "!fuasirouddJoxtwfge:localhost"
# matrixToIrc:
# initial: false
# incremental: false
# # Apply specific rules to IRC channels. Only IRC-to-matrix takes effect.
# channels:
# - channel: "#foo"
# ircToMatrix:
# initial: false
# incremental: false
# mappings:
# # 1:many mappings from IRC channels to room IDs on this IRC server.
# # The matrix room must already exist. Your matrix client should expose
# # the room ID in a "settings" page for the room.
# "#thepub":
# roomIds: ["!kieouiJuedJoxtVdaG:localhost"]
# # Channel key/password to use. Optional. If provided, matrix users do
# # not need to know the channel key in order to join the channel.
# # key: "secret"
# # Configuration for virtual matrix users. The following variables are
# # exposed:
# # $NICK => The IRC nick
# # $SERVER => The IRC server address (e.g. "irc.example.com")
# matrixClients:
# # The user ID template to use when creating virtual matrix users. This
# # MUST have $NICK somewhere in it.
# # Optional. Default: "@$SERVER_$NICK".
# # Example: "@irc.example.com_Alice:example.com"
# userTemplate: "@irc_$NICK"
# # The display name to use for created matrix clients. This should have
# # $NICK somewhere in it if it is specified. Can also use $SERVER to
# # insert the IRC domain.
# # Optional. Default: "$NICK (IRC)". Example: "Alice (IRC)"
# displayName: "$NICK (IRC)"
# # Number of tries a client can attempt to join a room before the request
# # is discarded. You can also use -1 to never retry or 0 to never give up.
# # Optional. Default: -1
# joinAttempts: -1
# # Configuration for virtual IRC users. The following variables are exposed:
# # $LOCALPART => The user ID localpart ("alice" in @alice:localhost)
# # $USERID => The user ID
# # $DISPLAY => The display name of this user, with excluded characters
# # (e.g. space) removed. If the user has no display name, this
# # falls back to $LOCALPART.
# ircClients:
# # The template to apply to every IRC client nick. This MUST have either
# # $DISPLAY or $USERID or $LOCALPART somewhere in it.
# # Optional. Default: "M-$DISPLAY". Example: "M-Alice".
# nickTemplate: "$DISPLAY[m]"
# # True to allow virtual IRC clients to change their nick on this server
# # by issuing !nick <server> <nick> commands to the IRC AS bot.
# # This is completely freeform: it will NOT follow the nickTemplate.
# allowNickChanges: true
# # The max number of IRC clients that will connect. If the limit is
# # reached, the client that spoke the longest time ago will be
# # disconnected and replaced.
# # Optional. Default: 30.
# maxClients: 30
# # IPv6 configuration.
# ipv6:
# # Optional. Set to true to force IPv6 for outgoing connections.
# only: false
# # Optional. The IPv6 prefix to use for generating unique addresses for each
# # connected user. If not specified, all users will connect from the same
# # (default) address. This may require additional OS-specific work to allow
# # for the node process to bind to multiple different source addresses
# # e.g IP_FREEBIND on Linux, which requires an LD_PRELOAD with the library
# # https://github.com/matrix-org/freebindfree as Node does not expose setsockopt.
# # prefix: "2001:0db8:85a3::" # modify appropriately
# #
# # The maximum amount of time in seconds that the client can exist
# # without sending another message before being disconnected. Use 0 to
# # not apply an idle timeout. This value is ignored if this IRC server is
# # mirroring matrix membership lists to IRC. Default: 172800 (48 hours)
# idleTimeout: 10800
# # The number of millseconds to wait between consecutive reconnections if a
# # client gets disconnected. Setting to 0 will cause the scheduling to be
# # disabled, i.e. it will be scheduled immediately (with jitter.
# # Otherwise, the scheduling interval will be used such that one client
# # reconnect for this server will be handled every reconnectIntervalMs ms using
# # a FIFO queue.
# # Default: 5000 (5 seconds)
# reconnectIntervalMs: 5000
# # The number of concurrent reconnects if a user has been disconnected unexpectedly
# # (e.g. a netsplit). You should set this to a reasonably high number so that
# # bridges are not waiting an eternity to reconnect all its clients if
# # we see a massive number of disconnect. This is unrelated to the reconnectIntervalMs
# # setting above which is for connecting on restart of the bridge. Set to 0 to
# # immediately try to reconnect all users.
# # Default: 50
# concurrentReconnectLimit: 50
# # The number of lines to allow being sent by the IRC client that has received
# # a large block of text to send from matrix. If the number of lines that would
# # be sent is > lineLimit, the text will instead be uploaded to matrix and the
# # resulting URI is treated as a file. As such, a link will be sent to the IRC
# # side instead of potentially spamming IRC and getting the IRC client kicked.
# # Default: 3.
# lineLimit: 3
# # A list of user modes to set on every IRC client. For example, "RiG" would set
# # +R, +i and +G on every IRC connection when they have successfully connected.
# # User modes vary wildly depending on the IRC network you're connecting to,
# # so check before setting this value. Some modes may not work as intended
# # through the bridge e.g. caller ID as there is no way to /ACCEPT.
# # Default: "" (no user modes)
# # userModes: "R"
# Controls whether the matrix-appservice-discord container exposes its HTTP port (tcp/9999 in the container).
#
# Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:9999"), or empty string to not expose.
matrix_appservice_irc_container_http_host_bind_port: ''
# A list of extra arguments to pass to the container
matrix_appservice_irc_container_extra_arguments: []
# List of systemd services that matrix-appservice-irc.service depends on.
matrix_appservice_irc_systemd_required_services_list: ['docker.service']
# List of systemd services that matrix-appservice-irc.service wants
matrix_appservice_irc_systemd_wanted_services_list: []
matrix_appservice_irc_appservice_token: ''
matrix_appservice_irc_homeserver_token: ''
matrix_appservice_irc_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}"
matrix_appservice_irc_configuration_extension_yaml: |
# Your custom YAML configuration for Appservice IRC servers goes here.
# This configuration extends the default starting configuration (`matrix_appservice_irc_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_appservice_irc_configuration_yaml`.
matrix_appservice_irc_configuration_extension: "{{ matrix_appservice_irc_configuration_extension_yaml|from_yaml if matrix_appservice_irc_configuration_extension_yaml|from_yaml is mapping else {} }}"
matrix_appservice_irc_configuration: "{{ matrix_appservice_irc_configuration_yaml|from_yaml|combine(matrix_appservice_irc_configuration_extension, recursive=True) }}"
# The original registration.yaml file generated by AppService IRC is merged with this config override,
# to produce the final registration.yaml file ultimately used by both the bridge and the homeserver.
#
# We do this to ensure consistency:
# - always having an up-to-date registration.yaml file (synced with the configuration file)
# - always having the same AS/HS token and appservice id in the registration.yaml file
#
# Learn more about this in `setup_install.yml`
matrix_appservice_irc_registration_override_yaml: |
id: appservice-irc
as_token: "{{ matrix_appservice_irc_appservice_token }}"
hs_token: "{{ matrix_appservice_irc_homeserver_token }}"
matrix_appservice_irc_registration_override: "{{ matrix_appservice_irc_registration_override_yaml|from_yaml }}"

View File

@ -0,0 +1,31 @@
# 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 and matrix_appservice_irc_enabled"
# 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-appservice-irc role needs to execute before the matrix-synapse role.
when: "matrix_appservice_irc_enabled|bool and matrix_synapse_role_executed|default(False)"
- set_fact:
matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-appservice-irc.service'] }}"
when: matrix_appservice_irc_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_appservice_irc_config_path }}/registration.yaml,dst=/matrix-appservice-irc-registration.yaml,ro"]
matrix_synapse_app_service_config_files: >
{{ matrix_synapse_app_service_config_files|default([]) }}
+
{{ ["/matrix-appservice-irc-registration.yaml"] }}
when: matrix_appservice_irc_enabled|bool

View File

@ -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_appservice_irc_enabled|bool"
tags:
- setup-all
- setup-appservice-irc
- import_tasks: "{{ role_path }}/tasks/setup_install.yml"
when: "run_setup|bool and matrix_appservice_irc_enabled|bool"
tags:
- setup-all
- setup-appservice-irc
- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
when: "run_setup|bool and not matrix_appservice_irc_enabled|bool"
tags:
- setup-all
- setup-appservice-irc

View File

@ -0,0 +1,70 @@
- name: Fail if Postgres not enabled
fail:
msg: "Postgres via the matrix-postgres role is not enabled (`matrix_postgres_enabled`). Cannot migrate."
when: "not matrix_postgres_enabled|bool"
# Defaults
- name: Set postgres_start_wait_time, if not provided
set_fact:
postgres_start_wait_time: 15
when: "postgres_start_wait_time|default('') == ''"
# Actual import work
- name: Ensure matrix-postgres is started
service:
name: matrix-postgres
state: started
daemon_reload: yes
register: matrix_postgres_service_start_result
- name: Wait a bit, so that Postgres can start
wait_for:
timeout: "{{ postgres_start_wait_time }}"
delegate_to: 127.0.0.1
become: false
when: "matrix_postgres_service_start_result.changed|bool"
- name: Check existence of matrix-appservice-irc service
stat:
path: "{{ matrix_systemd_path }}/matrix-appservice-irc.service"
register: matrix_appservice_irc_service_stat
- name: Ensure matrix-appservice-irc is stopped
service:
name: matrix-appservice-irc
state: stopped
when: "matrix_appservice_irc_service_stat.stat.exists"
- name: Import appservice-irc NeDB database into Postgres
command:
cmd: >-
{{ matrix_host_command_docker }} run
--rm
--user={{ matrix_user_uid }}:{{ matrix_user_gid }}
--cap-drop=ALL
--network={{ matrix_docker_network }}
--mount type=bind,src={{ matrix_appservice_irc_data_path }},dst=/data
--entrypoint=/bin/sh
{{ matrix_appservice_irc_docker_image }}
-c
'/usr/local/bin/node /app/lib/scripts/migrate-db-to-pgres.js --dbdir /data --privateKey /data/passkey.pem --connectionString {{ matrix_appservice_irc_database_connection_string }}'
- name: Archive NeDB database files
command:
cmd: "mv {{ matrix_appservice_irc_data_path }}/{{ item }} {{ matrix_appservice_irc_data_path }}/{{ item }}.backup"
with_items:
- rooms.db
- users.db
- name: Inject result
set_fact:
matrix_playbook_runtime_results: |
{{
matrix_playbook_runtime_results|default([])
+
[
"NOTE: Your appservice-irc database files have been imported into Postgres. The original database files have been moved from `{{ matrix_appservice_irc_data_path }}/*.db` to `{{ matrix_appservice_irc_data_path }}/*.db.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete these files."
]
}}

View File

@ -0,0 +1,194 @@
---
- name: Ensure Appservice IRC paths exist
file:
path: "{{ item.path }}"
state: directory
mode: 0750
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- { path: "{{ matrix_appservice_irc_base_path }}", when: true }
- { path: "{{ matrix_appservice_irc_config_path }}", when: true }
- { path: "{{ matrix_appservice_irc_data_path }}", when: true }
- { path: "{{ matrix_appservice_irc_docker_src_files_path }}", when: "{{ matrix_appservice_irc_container_self_build }}" }
when: item.when|bool
- name: Check if an old passkey file already exists
stat:
path: "{{ matrix_appservice_irc_base_path }}/passkey.pem"
register: matrix_appservice_irc_stat_passkey
- block:
- name: (Data relocation) Ensure matrix-appservice-irc.service is stopped
service:
name: matrix-appservice-irc
state: stopped
daemon_reload: yes
failed_when: false
- name: (Data relocation) Move AppService IRC passkey.pem file to ./data directory
command: "mv {{ matrix_appservice_irc_base_path }}/passkey.pem {{ matrix_appservice_irc_data_path }}/passkey.pem"
- name: (Data relocation) Move AppService IRC database files to ./data directory
command: "mv {{ matrix_appservice_irc_base_path }}/{{ item }} {{ matrix_appservice_irc_data_path }}/{{ item }}"
with_items:
- rooms.db
- users.db
failed_when: false
when: "matrix_appservice_irc_stat_passkey.stat.exists"
- set_fact:
matrix_appservice_irc_requires_restart: false
- block:
- name: Check if a nedb database already exists
stat:
path: "{{ matrix_appservice_irc_data_path }}/users.db"
register: matrix_appservice_irc_nedb_database_path_local_stat_result
- block:
- import_tasks: "{{ role_path }}/tasks/migrate_nedb_to_postgres.yml"
- set_fact:
matrix_appservice_irc_requires_restart: true
when: "matrix_appservice_irc_nedb_database_path_local_stat_result.stat.exists|bool"
when: "matrix_appservice_irc_database_engine == 'postgres'"
- name: Ensure Appservice IRC image is pulled
docker_image:
name: "{{ matrix_appservice_irc_docker_image }}"
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"
force_source: "{{ matrix_appservice_irc_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}"
force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_irc_docker_image_force_pull }}"
when: "matrix_appservice_irc_enabled|bool and not matrix_appservice_irc_container_self_build|bool"
- name: Ensure matrix-appservice-irc repository is present when self-building
git:
repo: "{{ matrix_appservice_irc_docker_repo }}"
dest: "{{ matrix_appservice_irc_docker_src_files_path }}"
force: "yes"
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 built
docker_image:
name: "{{ matrix_appservice_irc_docker_image }}"
source: build
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 }}"
pull: yes
when: "matrix_appservice_irc_enabled|bool and matrix_appservice_irc_container_self_build|bool and matrix_appservice_irc_git_pull_results.changed"
- name: Ensure Matrix Appservice IRC config installed
copy:
content: "{{ matrix_appservice_irc_configuration|to_nice_yaml }}"
dest: "{{ matrix_appservice_irc_config_path }}/config.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
- name: Check if Appservice IRC passkey exists
stat:
path: "{{ matrix_appservice_irc_data_path }}/passkey.pem"
register: irc_passkey_file
- name: Generate Appservice IRC passkey if it doesn't exist
shell: "{{ matrix_host_command_openssl }} genpkey -out {{ matrix_appservice_irc_data_path }}/passkey.pem -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048"
become: true
become_user: "{{ matrix_user_username }}"
when: "not irc_passkey_file.stat.exists"
# In the past, we used to generate the passkey.pem file with root, so permissions may not be okay.
# Fix it.
- name: (Migration) Ensure Appservice IRC passkey permissions are okay
file:
path: "{{ matrix_appservice_irc_data_path }}/passkey.pem"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
# Ideally, we'd like to generate the final registration.yaml file by ourselves.
#
# However, the IRC bridge supports multiple servers, which leads to multiple
# users/aliases/rooms rules in the registration file.
#
# Generating a proper file by ourselves is complicated and may lead to deviation
# from what the bridge is doing.
#
# Instead, we do another hacky thing - asking the bridge to generate a template,
# and then we parse it and fix it up with our own AS/HS token.
# We need to do this, because:
# - we'd like to have an up-to-date registration file
# - we can achieve this by asking the bridge to rebuild it each time
# - however, the bridge insists on regenerating all tokens each time
# - .. which is not friendly for integrating with the homeserver
#
# So we have a hybrid approach. We ask the bridge to always generate
# an up-to-date file, and we fix it up with some static values later on,
# to produce a final registration.yaml file, as we desire.
- name: Generate Appservice IRC registration-template.yaml
shell: >-
{{ matrix_host_command_docker }} run --rm --name matrix-appservice-irc-gen
--user={{ matrix_user_uid }}:{{ matrix_user_gid }}
--cap-drop=ALL
-v {{ matrix_appservice_irc_config_path }}:/config:z
-v {{ matrix_appservice_irc_data_path }}:/data:z
--entrypoint=/bin/bash
{{ matrix_appservice_irc_docker_image }}
-c
'node app.js
-r
-f /config/registration-template.yaml
-u "http://matrix-appservice-irc:9999"
-c /config/config.yaml
-l irc_bot'
changed_when: false
- name: Read Appservice IRC registration-template.yaml
slurp:
src: "{{ matrix_appservice_irc_config_path }}/registration-template.yaml"
register: matrix_appservice_irc_registration_template_slurp
- name: Remove unnecessary Appservice IRC registration-template.yaml
file:
path: "{{ matrix_appservice_irc_config_path }}/registration-template.yaml"
state: absent
changed_when: false
- name: Parse registration-template.yaml
set_fact:
matrix_appservice_irc_registration_template: "{{ matrix_appservice_irc_registration_template_slurp['content'] | b64decode | from_yaml }}"
- name: Combine registration-template.yaml and own registration override config
set_fact:
matrix_appservice_irc_registration: "{{ matrix_appservice_irc_registration_template|combine(matrix_appservice_irc_registration_override, recursive=True) }}"
- name: Ensure Appservice IRC registration.yaml installed
copy:
content: "{{ matrix_appservice_irc_registration|to_nice_yaml }}"
dest: "{{ matrix_appservice_irc_config_path }}/registration.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
- name: Ensure matrix-appservice-irc.service installed
template:
src: "{{ role_path }}/templates/systemd/matrix-appservice-irc.service.j2"
dest: "{{ matrix_systemd_path }}/matrix-appservice-irc.service"
mode: 0644
register: matrix_appservice_irc_systemd_service_result
- name: Ensure systemd reloaded after matrix-appservice-irc.service installation
service:
daemon_reload: yes
when: "matrix_appservice_irc_systemd_service_result.changed"
- name: Ensure matrix-appservice-irc.service restarted, if necessary
service:
name: "matrix-appservice-irc.service"
state: restarted
when: "matrix_appservice_irc_requires_restart|bool"

Some files were not shown because too many files have changed in this diff Show More