Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Element Call, Livekit Server and JWT Service integrations for Element Call functionality #3562

Draft
wants to merge 110 commits into
base: master
Choose a base branch
from

Conversation

wjbeckett
Copy link

This Pull Request adds support for deploying Element Call, JWT Service, and Livekit Server as part of the Matrix stack. The changes introduce new roles and corresponding tasks, systemd services, configuration files, and updates to existing configurations to support these new components.

Summary of Changes:

  1. New Roles Added:

    • Element Call: Handles the setup, configuration, and deployment of the Element Call container.
    • JWT Service: Deploys the JWT Service for managing Livekit authentication.
    • Livekit Server: Configures and runs the Livekit server for video conferencing.
  2. Key Additions:

    • Systemd Services: Added systemd files for each service to manage the Docker containers for Element Call, JWT Service, and Livekit.
    • Configuration Updates:
      • Updated homeserver.yaml to include listener settings for Element Call.
      • Modified the well-known client JSON to support the RTC FOCI needed for Element Call and Livekit.
      • Updated the Element Web config.json to include configuration settings for using Element Call.
      • Added well-known configuration for Element X to point to Element Call.
  3. Traefik Configuration:

    • Added appropriate Traefik labels for Element Call, JWT Service, and Livekit Server containers to ensure that requests are correctly proxied to the appropriate service.
    • Created separate labels files for each service for better organization and maintainability.
  4. Tasks and Templates:

    • Refactored common tasks into reusable components where possible.
    • Added validation tasks to ensure all required configurations are present before deployment.
    • Created and updated necessary templates (config.json, element.json, livekit.yaml.j2, etc.) to provide the correct settings for each service.

Testing Performed:

  • Each role was tested independently, and the full deployment was validated to ensure that:
    • Containers start successfully with the correct configurations.
    • Systemd services are set up and managed properly.
    • Element Call integrates seamlessly with the Matrix ecosystem, allowing users to initiate video calls through Element.
    • Traefik correctly routes requests for each service based on defined hostnames.

Documentation:

  • Updated documentation in the docs directory to include setup and configuration details for:
    • Element Call: Including required DNS changes and settings for the well-known client.
    • JWT Service and Livekit Server: Configuration steps, default variables, and examples of customization.

Limitations:

  • Standalone Element Call: While Element Call works within the Element apps, the standalone call.DOMAIN website for ad-hoc calls will not function correctly until the Matrix Authentication Service (MAS) is implemented. This is due to the requirement of an OIDC header from MAS, which is currently not in place.

Checklist:

  • Roles for Element Call, JWT Service, and Livekit Server created and tested.
  • Systemd files for service management added.
  • Traefik labels set correctly for each container.
  • Configuration files updated or created as required.
  • Documentation updated with detailed setup instructions.
  • Group Vars and Setup Playbook modified to accommodate new roles.
  • Testing performed to ensure no regression and correctness of new additions.

Notes for Reviewers:

  • The changes involve significant updates to the configuration and introduction of multiple new roles. Please verify that all group variables and systemd services have been defined as required.
  • Special attention should be given to the well-known client configuration and the integration of Traefik labels to ensure that requests are correctly proxied.
  • Please note the current limitation regarding the standalone Element Call website until MAS integration is complete.

@torrybr
Copy link

torrybr commented Oct 2, 2024

Huge PR! Thanks for taking the time to do this!

@wjbeckett
Copy link
Author

My pleasure.
Hopefully it's enough to get it working.

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett
I tried applying your patch and got errors in the group_vars/matrix-servers file . Am I doing something wrong?

ubuntu@o1:~/matrix-docker-ansible-deploy$ wget https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3562.patch
--2024-10-03 02:15:23--  https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3562.patch
Resolving github.com (github.com)... 140.82.113.3
Connecting to github.com (github.com)|140.82.113.3|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://patch-diff.githubusercontent.com/raw/spantaleev/matrix-docker-ansible-deploy/pull/3562.patch [following]
--2024-10-03 02:15:23--  https://patch-diff.githubusercontent.com/raw/spantaleev/matrix-docker-ansible-deploy/pull/3562.patch
Resolving patch-diff.githubusercontent.com (patch-diff.githubusercontent.com)... 140.82.114.4
Connecting to patch-diff.githubusercontent.com (patch-diff.githubusercontent.com)|140.82.114.4|:443... connected.
HTTP request sent, awaiting response... 200 OK
Cookie coming from patch-diff.githubusercontent.com attempted to set domain to github.com
Length: unspecified [text/plain]
Saving to: ‘3562.patch’

3562.patch                                             [ <=>                                                                                                             ] 372.11K  --.-KB/s    in 0.008s  

2024-10-03 02:15:23 (45.9 MB/s) - ‘3562.patch’ saved [381041]

ubuntu@o1:~/matrix-docker-ansible-deploy$ git am < 3562.patch
Applying: Feat: Added element call setup and configuration.
error: patch failed: group_vars/matrix_servers:5690
error: group_vars/matrix_servers: patch does not apply
Patch failed at 0001 Feat: Added element call setup and configuration.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
ubuntu@o1:~/matrix-docker-ansible-deploy$ git am --abort

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett
This seemed to work with some whitespace warnings

ubuntu@o1:~/matrix-docker-ansible-deploy$ git am -C1 < 3562.patch
Applying: Feat: Added element call setup and configuration.
Context reduced to (2/0) to apply fragment at 5735
Applying: added doc for setting up element call.
Applying: fixed matrix_redis for migration
Applying: Update main.yml
Applying: Fixed assertion block to remove jinja2 delimiters
Applying: Fixed regex for checking the hostname.
.git/rebase-apply/patch:18: trailing whitespace.
    
warning: 1 line adds whitespace errors.
Applying: Added matrix_server_name to the defaults
Applying: Changed matrix_base_domain to matrix_domain
Applying: Removed additional label loop
Applying: Added debug task to test labels configuration
Applying: Adding another debug task for testing the labels file.
Applying: Update main.yml
Applying: Restructure install.yml to follow other roles more closely
Applying: Updated with new structure.
Applying: Updated to support new structure
Applying: Simplified the validation step.
Applying: Update env.j2 to support the new configuration
Applying: Update config.json.j2
Applying: Update livekit.yaml.j2
Applying: Update redis.conf.j2
Applying: Update labels.j2
Applying: Migrating to systemd for container management
Applying: Create matrix-livekit.service.j2
Applying: Create matrix-redis.service.j2
Applying: Update install.yml
Applying: Update matrix_servers
Applying: Update main.yml
Applying: Update labels.j2
Applying: Update main.yml
Applying: Create matrix-jwt-service.service.j2
Applying: Update main.yml
Applying: Update install.yml
Applying: Create well_known_element.json.j2
Applying: Added well-known element directory
Applying: Update main.yml
Applying: Migrated from matrix_redis to redis_
Applying: Update validate_config.yml
Applying: Update install.yml
Applying: Update matrix-redis.service.j2
Applying: Remove serve command from matrix-element-call.service.j2
Applying: Added missing labels for sfu and jwt
Applying: Created element-call-labels to separate the labels for each container
Applying: Created livekit-labels.j2
Applying: Create jwt-service-labels.j2
Applying: Updated label file
Applying: Updated label file
Applying: Updated livekit labels
Applying: Added tasks for moving the new labels files into place
Applying: Update matrix-element-call.service.j2
Applying: Rename element-call-labels.j2 to element-call-labels.j2-new
Applying: Update and rename labels.j2 to element-call-labels.j2
Applying: Corrected element call labels file name
Applying: Update matrix_servers
Applying: Handle empty labels correctly.
Applying: Update element-call-labels.j2
Applying: Update matrix_servers
Applying: Added hostname label
Applying: Added hostnames for livekit and jwt labels
.git/rebase-apply/patch:15: trailing whitespace.
# jwt configuration 
warning: 1 line adds whitespace errors.
Applying: Update livekit-labels.j2
Applying: Update jwt-service-labels.j2
Applying: Update element-call-labels.j2-new
Applying: Update matrix-element-call.service.j2
Applying: Added element-call systemd services to the service manager.
Applying: Added serve command back in.
Applying: Update env.j2
Applying: Update main.yml
Applying: Update env.j2
Applying: Removed env file
Applying: Removed serve function
Applying: Fix: Restructured Element call configuration files.
Applying: fix: changed matrix server name to matrix domain in element-call config.
Applying: fix: removed duplicate keys.
Applying: fix: Type in the element-call main.yml
Applying: fix: added missing labels to main.
Applying: fix: removed the read-only tag from the element-call systemd file.
Applying: fixed traefik router issues.
Applying: testing traefik labels again.
Applying: fixing labels again.
Applying: separated livekit and jwt to separate roles
.git/rebase-apply/patch:104: trailing whitespace.
matrix_livekit_server_path_prefix: "/" 
.git/rebase-apply/patch:674: trailing whitespace.
# jwt configuration 
warning: 2 lines add whitespace errors.
Applying: removed duplicate tasks.
Applying: hard coded redis port.
Applying: fixed config file placement.
Applying: fixed livekit service name
Applying: cleaned up old services again
Applying: renamed the livekit role and added livekit-server and jwt-service roles to the setup file.
Applying: typo in livekit-server validate.
Applying: resolved missing key.
Applying: Fixed typo in livekit server hostname
Applying: fixed type in livekit image
Applying: removed redis images in favor of the inbuilt keyDB
Applying: changed jwt-service port label.
Applying: updated jwt hostname.
Applying: stopping the recursive loop
Applying: adjusted jwt service ports for traefik
Applying: added element-call config.json to systemd file
Applying: updated jwt bind port
Applying: testing livekit configuration
Applying: updated headers for each of the call services.
Applying: removed additinoal headers
Applying: removed headers.
Applying: added header flags back in.
Applying: updated docs, broke the well-known and element client modifications out to separate tasks.
.git/rebase-apply/patch:134: trailing whitespace.
    
.git/rebase-apply/patch:108: new blank line at EOF.
+
warning: 2 lines add whitespace errors.
Applying: fixed error with element client update task
.git/rebase-apply/patch:23: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
Applying: updated documentation or the new roles.
.git/rebase-apply/patch:106: trailing whitespace.
Once installed, and in conjunction with Element Call and JWT Service, Livekit will become the WebRTC backend for all Element client calls. 
warning: 1 line adds whitespace errors.
ubuntu@o1:~/matrix-docker-ansible-deploy$ 

@wjbeckett
Copy link
Author

@saket424 Thanks for that. I've just pushed another commit to remove the trailing whitespaces from my files. Hopefully that fixes that up.

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett
Still not out of the woods. The patch does not yet apply cleanly

I get the following error when I try to start
ansible-playbook -i inventory/hosts setup.yml --tags=install-all,ensure-matrix-users-created,start
ASK [custom/matrix-element-call : Ensure matrix-element-call Docker labels file is in place] **************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible.errors.AnsibleUndefinedVariable: {{ devture_traefik_entrypoint_primary }}: 'devture_traefik_entrypoint_primary' is undefined
fatal: [matrix.example.com]: FAILED! => changed=false
msg: 'AnsibleUndefinedVariable: {{ devture_traefik_entrypoint_primary }}: ''devture_traefik_entrypoint_primary'' is undefined'

PLAY RECAP *************************************************************************************************************************************************************************************************
matrix.example.com : ok=159 changed=3 unreachable=0 failed=1 skipped=310 rescued=0 ignored=0

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett

This seemed to fix the undefineds

ubuntu@o1:~/matrix-docker-ansible-deploy$ git diff group_vars/matrix_servers
diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers
index b55e2623..d5c2ab8d 100755
--- a/group_vars/matrix_servers
+++ b/group_vars/matrix_servers
@@ -5767,8 +5767,8 @@ matrix_element_call_container_additional_networks: "{{ [matrix_playbook_reverse_
 # Traefik Configuration for Element Call
 matrix_element_call_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] }}"
 matrix_element_call_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}"
-matrix_element_call_container_labels_traefik_entrypoints: "{{ devture_traefik_entrypoint_primary }}"
-matrix_element_call_container_labels_traefik_tls_certResolver: "{{ devture_traefik_certResolver_primary }}"
+matrix_element_call_container_labels_traefik_entrypoints: "{{ traefik_entrypoint_primary }}"
+matrix_element_call_container_labels_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}"
 
 ########################################################################
 #                                                                      #
@@ -5799,8 +5799,8 @@ matrix_livekit_server_container_additional_networks: "{{ [matrix_playbook_revers
 # Traefik Configuration for Livekit
 matrix_livekit_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] }}"
 matrix_livekit_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}"
-matrix_livekit_server_container_labels_traefik_entrypoints: "{{ devture_traefik_entrypoint_primary }}"
-matrix_livekit_server_container_labels_traefik_tls_certResolver: "{{ devture_traefik_certResolver_primary }}"
+matrix_livekit_server_container_labels_traefik_entrypoints: "{{ traefik_entrypoint_primary }}"
+matrix_livekit_server_container_labels_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}"
 
 # LiveKit Service Configuration
 matrix_livekit_server_livekit_dev_key: "{{ matrix_livekit_server_dev_key }}"  # LiveKit dev key
@@ -5836,8 +5836,8 @@ matrix_jwt_service_container_additional_networks: "{{ [matrix_playbook_reverse_p
 # Traefik Configuration for JWT Service
 matrix_jwt_service_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] }}"
 matrix_jwt_service_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}"
-matrix_jwt_service_container_labels_traefik_entrypoints: "{{ devture_traefik_entrypoint_primary }}"
-matrix_jwt_service_container_labels_traefik_tls_certResolver: "{{ devture_traefik_certResolver_primary }}"
+matrix_jwt_service_container_labels_traefik_entrypoints: "{{ traefik_entrypoint_primary }}"
+matrix_jwt_service_container_labels_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}"
 
 # JWT Service Configuration
 matrix_jwt_service_url: "https://sfu-jwt.{{ matrix_domain }}"  # Default JWT service URL; adjust as needed
ubuntu@o1:~/matrix-docker-ansible-deploy$ 

@wjbeckett
Copy link
Author

wjbeckett commented Oct 3, 2024

@saket424 ah!
So this has just unfortunately co-incided with the change in traefik!

I had not updated my dev environment with that patch.

I'll fix that now.

@wjbeckett
Copy link
Author

@saket424 Updated pushed that should resolve that error.

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett
The docs/configuring-playbook-element-call.md has a typo
Instead of matrix_element_call_livekit_dev_key it ought to be matrix_livekit_server_dev_key

@wjbeckett
Copy link
Author

@wjbeckett The docs/configuring-playbook-element-call.md has a typo Instead of matrix_element_call_livekit_dev_key it ought to be matrix_livekit_server_dev_key

@saket424. Good catch. Updated :-)

@wjbeckett wjbeckett marked this pull request as draft October 3, 2024 05:49
@wjbeckett
Copy link
Author

wjbeckett commented Oct 3, 2024

Converting to draft until I can figure out the Matrix Authentication Service integration piece as this is now needed before this can work correctly.

JWT service is working as intended, however the call can't connect until it can lookup a user.
Failed to look up user info: HTTP 404 : 404 page not found

@spantaleev
Copy link
Owner

Thanks for doing all this work! 🙇

I haven't reviewed this in detail yet, but:

  1. Why is Matrix Authentication Service required for Element Call to function? Perhaps it only supports authentication via Matrix Authentication Service?
  2. As LiveKit is a generally-useful service (that is not specific to Matrix), it should be extracted out of this playbook's embedded roles. Let's think about having it as a separate role in the mother-of-all-self-hosting organization and possibly as a standalone service in mash-playbook.

@wjbeckett
Copy link
Author

Thanks for doing all this work! 🙇

My pleasure @spantaleev. This is my first big PR in any open source project so I'm just happy to helping out however I can.

I haven't reviewed this in detail yet, but:

  1. Why is Matrix Authentication Service required for Element Call to function? Perhaps it only supports authentication via Matrix Authentication Service?

The JWT broker that manages the integration between livekit and element call is configured to use oidc headers to lookup users. Element-HQ have made it a requirement that MAS is in place for this to be functional.

The MAS integration was going to be my next task to try and bring to this playbook.

  1. As LiveKit is a generally-useful service (that is not specific to Matrix), it should be extracted out of this playbook's embedded roles. Let's think about having it as a separate role in the mother-of-all-self-hosting organization and possibly as a standalone service in mash-playbook.

That's probably a good idea. I'm not across how the two playbooks integrate, but I'm happy to move the livekit over to the mash playbook.

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett The docs/configuring-playbook-element-call.md has a typo Instead of matrix_element_call_livekit_dev_key it ought to be matrix_livekit_server_dev_key

Can you update the doc to indicate how to generate a live kit dev_key ? I naively thought it was a random string .

https://docs.livekit.io/home/server/generating-tokens/

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett
configuring-playbook-livekit-server.md and configuring-playbook-element-call.md documentation only makes reference to matrix_livekit_server_dev_key but not the associated matrix_livekit_server_jwt_secret

@saket424
Copy link

saket424 commented Oct 3, 2024

@wjbeckett

In this file https://github.com/livekit/livekit/blob/master/config-sample.yaml

API dev_key and jwt_secret as specified as key1 and key2 respectively. Do you agree that template format roles/custom/matrix-livekit-server/templates/livekit.yaml.j2 needs to be modified to match the sample?

# API key / secret pairs.
# Keys are used for JWT authentication, server APIs would require a keypair in order to generate access tokens
# and make calls to the server
keys:
  key1: secret1
  key2: secret2

@saket424
Copy link

saket424 commented Oct 4, 2024

@wjbeckett

The correct syntax for the keypair in roles/custom/matrix-livekit-server/templates/livekit.yaml.j2 is

cat roles/custom/matrix-livekit-server/templates/livekit.yaml.j2
port: 7880
bind_addresses:
  - "0.0.0.0"
rtc:
  tcp_port: 7881
  port_range_start: 50100
  port_range_end: 50200
  use_external_ip: true

turn:
  enabled: false
  domain: localhost
  cert_file: ""
  key_file: ""
  tls_port: 5349
  udp_port: 443
  external_tls: true

keys:
  {{ matrix_livekit_server_dev_key }}: {{ matrix_livekit_server_jwt_secret }}

@wjbeckett
Copy link
Author

https://docs.livekit.io/home/server/generating-tokens/

@wjbeckett

The correct syntax for the keypair in roles/custom/matrix-livekit-server/templates/livekit.yaml.j2 is

that's correct, however we aren't talking to livekit directly. The JWT service is the one that does the token generation between Matrix and Livekit.
https://github.com/element-hq/lk-jwt-service

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants