diff --git a/defaults/main.yml b/meet/defaults/main.yml similarity index 72% rename from defaults/main.yml rename to meet/defaults/main.yml index b957236..a1edb52 100644 --- a/defaults/main.yml +++ b/meet/defaults/main.yml @@ -1,16 +1,19 @@ --- - jitsi_meet_packages: - - jitsi-meet + - jicofo - jitsi-meet-prosody - jitsi-meet-web - jitsi-meet-web-config - - jitsi-videobridge2 jitsi_meet_server_name: "meet.example.com" jitsi_meet_server_name_aliases: [] -jitsi_meet_videobridge_port: 5347 +## single server vs scalable setup +jitsi_meet_single_instance: True +jitsi_meet_videobridge_instances: + - name: 'default-id' + ip: 127.0.0.1 + jitsi_meet_jicofo_user: focus jitsi_meet_jicofo_port: 5347 @@ -24,6 +27,8 @@ jitsi_meet_cert_choice: "Generate a new self-signed certificate (You will later jitsi_meet_config_default_language: "de" jitsi_meet_config_disable_third_party_requests: "true" jitsi_meet_config_disable_audio_levels: "false" +jitsi_meet_config_enable_no_audio_detection: "true" +jitsi_meet_config_enable_noisy_mic_detection: "true" jitsi_meet_config_disable_aec: "false" # disable acoustic echo cancellation jitsi_meet_config_disable_agc: "false" # disable automatic gain control jitsi_meet_config_disable_ap: "false" # disable all audio processing @@ -37,18 +42,21 @@ jitsi_meet_config_require_display_name: "false" jitsi_meet_config_resolution: 720 jitsi_meet_config_constraints: video: + frameRate: + max: 20 + min: 5 height: ideal: "{{ jitsi_meet_config_resolution }}" max: 720 min: 240 jitsi_meet_config_start_audio_only: "false" +jitsi_meet_config_start_audio_muted: 10 # every participant after the Nth will start audio muted +jitsi_meet_config_start_video_muted: 10 # every participant after the Nth will start video muted jitsi_meet_config_stun_servers: - meet-jit-si-turnrelay.jitsi.net:443 # Jitsi Meet global variables -# Jitsi Meet global variables - jitsi_meet_title: Jitsi Meet jitsi_meet_description: Join a WebRTC video conference powered by the Jitsi Videobridge @@ -69,7 +77,19 @@ jitsi_meet_interface_mobile_download_link_android: https://play.google.com/store jitsi_meet_interface_mobile_download_link_f_droid: https://f-droid.org/en/packages/org.jitsi.meet/ jitsi_meet_interface_mobile_download_link_ios: https://itunes.apple.com/us/app/jitsi-meet/id1165103905 jitsi_meet_interface_native_app_name: Jitsi Meet +jitsi_meet_interface_connection_indicator_disabled: "false" +jitsi_meet_interface_disable_dominant_speaker_indicator: "false" +jitsi_meet_interface_disable_focus_indicator: "false" +jitsi_meet_interface_disable_join_leave_notifications: "false" jitsi_meet_interface_disable_video_background: "false" +jitsi_meet_interface_set_filmstrip_enabled: "true" +jitsi_meet_interface_toolbar_buttons: [ + 'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen', + 'fodeviceselection', 'hangup', 'profile', 'chat', 'recording', + 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand', + 'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts', + 'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'security' +] # Jitsi Meet variables for title.html @@ -78,62 +98,28 @@ jitsi_meet_title_favicon: images/favicon.ico?v=1 jitsi_meet_debsums_ignore_custom_assets: false +# Jibri +jitsi_meet_jibri_enabled: False +jitsi_meet_jibri_password: "CHANGEME6" +jitsi_meet_recorder_password: "CHANGEME7" + +# Jigasi SIP Dial-In +jitsi_meet_jigasi_enabled: False + +# Octo +jitsi_meet_octo_enabled: False +jitsi_meet_octo_selection_strategy: "RegionBasedBridgeSelectionStrategy" ## Logging jitsi_meet_logrotate_retained_days: 7 jitsi_meet_loglevel: "WARNING" -jitsi_meet_videobridge_loglevel: "{{ jitsi_meet_loglevel }}" jitsi_meet_jicofo_loglevel: "{{ jitsi_meet_loglevel }}" -jitsi_meet_jicofo_logging_properties: | - handlers= java.util.logging.ConsoleHandler - #handlers= java.util.logging.ConsoleHandler, com.agafua.syslog.SyslogHandler - - java.util.logging.ConsoleHandler.level = {{ jitsi_meet_jicofo_loglevel }} - java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter - - net.java.sip.communicator.util.ScLogFormatter.programname=JVB - - .level= {{ jitsi_meet_jicofo_loglevel }} - - org.jitsi.videobridge.xmpp.ComponentImpl.level=FINE - - # All of the INFO level logs from MediaStreamImpl are unnecessary in the context of jitsi-videobridge. - org.jitsi.impl.neomedia.MediaStreamImpl.level=WARNING - - # Syslog(uncomment handler to use) - com.agafua.syslog.SyslogHandler.transport = udp - com.agafua.syslog.SyslogHandler.facility = local0 - com.agafua.syslog.SyslogHandler.port = 514 - com.agafua.syslog.SyslogHandler.hostname = localhost - com.agafua.syslog.SyslogHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter - com.agafua.syslog.SyslogHandler.escapeNewlines = false - - # to disable double timestamps in syslog uncomment next line - #net.java.sip.communicator.util.ScLogFormatter.disableTimestamp=true - - # time series logging - java.util.logging.SimpleFormatter.format= %5$s%n - java.util.logging.FileHandler.level = ALL - java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter - java.util.logging.FileHandler.pattern = /tmp/jvb-series.log - java.util.logging.FileHandler.limit = 200000000 - java.util.logging.FileHandler.count = 1 - java.util.logging.FileHandler.append = false - - timeseries.level=OFF - timeseries.org.jitsi.videobridge.cc.vp8.level=ALL - timeseries.useParentHandlers = false - timeseries.handlers = java.util.logging.FileHandler jitsi_meet_nginx_base_config: True # Disable nginx access log per default jitsi_meet_nginx_access_log: "off" -jitsi_meet_nginx_error_log: /var/log/nginx/error.log - -jitsi_meet_jibri_enabled: False -jitsi_meet_jibri_password: "CHANGEME6" -jitsi_meet_recorder_password: "CHANGEME7" +jitsi_meet_nginx_error_log: "/var/log/nginx/{{ jitsi_meet_server_name }}.error.log" jitsi_meet_nginx_ssl_preset: "intermediate" jitsi_meet_nginx_ssl_presets: diff --git a/files/dhparam b/meet/files/dhparam similarity index 100% rename from files/dhparam rename to meet/files/dhparam diff --git a/handlers/main.yml b/meet/handlers/main.yml similarity index 100% rename from handlers/main.yml rename to meet/handlers/main.yml diff --git a/meet/meta/main.yml b/meet/meta/main.yml new file mode 100644 index 0000000..e740962 --- /dev/null +++ b/meet/meta/main.yml @@ -0,0 +1,10 @@ +--- +galaxy_info: + role_name: meet +dependencies: + - role: systemli.apt_repositories + vars: + apt_repositories: + - preset: jitsi + name: download_jitsi_org + packages: "{{ jitsi_meet_packages }}" diff --git a/molecule/default/converge.yml b/meet/molecule/default/converge.yml similarity index 100% rename from molecule/default/converge.yml rename to meet/molecule/default/converge.yml diff --git a/molecule/default/molecule.yml b/meet/molecule/default/molecule.yml similarity index 100% rename from molecule/default/molecule.yml rename to meet/molecule/default/molecule.yml diff --git a/molecule/default/requirements.yml b/meet/molecule/default/requirements.yml similarity index 100% rename from molecule/default/requirements.yml rename to meet/molecule/default/requirements.yml diff --git a/molecule/default/roles/ansible-role-jitsi-meet b/meet/molecule/default/roles/ansible-role-jitsi-meet similarity index 100% rename from molecule/default/roles/ansible-role-jitsi-meet rename to meet/molecule/default/roles/ansible-role-jitsi-meet diff --git a/molecule/docker/INSTALL.rst b/meet/molecule/docker/INSTALL.rst similarity index 100% rename from molecule/docker/INSTALL.rst rename to meet/molecule/docker/INSTALL.rst diff --git a/molecule/docker/molecule.yml b/meet/molecule/docker/molecule.yml similarity index 100% rename from molecule/docker/molecule.yml rename to meet/molecule/docker/molecule.yml diff --git a/tasks/jitsi-meet.yml b/meet/tasks/jitsi-meet.yml similarity index 66% rename from tasks/jitsi-meet.yml rename to meet/tasks/jitsi-meet.yml index 3672aca..d1b2b34 100644 --- a/tasks/jitsi-meet.yml +++ b/meet/tasks/jitsi-meet.yml @@ -7,10 +7,6 @@ value: "{{ item.value }}" vtype: "{{ item.vtype }}" loop: - - name: jitsi-videobridge2 - question: jitsi-videobridge/jvb-hostname - value: "{{ jitsi_meet_server_name }}" - vtype: string - name: jitsi-meet-web-config question: jitsi-meet/cert-choice value: "{{ jitsi_meet_cert_choice }}" @@ -27,6 +23,18 @@ question: jitsi-meet-prosody/turn-secret value: "{{ jitsi_meet_turn_secret }}" vtype: string + - name: jitsi-meet-prosody + question: jitsi-videobridge/jvb-hostname + value: "{{ jitsi_meet_server_name }}" + vtype: string + - name: jitsi-videobridge2 + question: jitsi-videobridge/jvb-hostname + value: "{{ jitsi_meet_server_name }}" + vtype: string + - name: jitsi-meet + question: jitsi-meet/jvb-serve + value: "{{ jitsi_meet_single_instance | to_json }}" + vtype: boolean - name: Install jitsi-meet apt: @@ -35,15 +43,6 @@ state: present update_cache: yes -- name: Copy videobridge sip-communicator.properties - template: - src: videobridge/sip-communicator.properties.j2 - dest: /etc/jitsi/videobridge/sip-communicator.properties - owner: jvb - group: jitsi - mode: 0640 - notify: restart jitsi-videobridge2 - - name: Copy jicofo config template: src: jicofo/config.j2 @@ -60,46 +59,22 @@ owner: jicofo group: jitsi notify: restart jicofo - when: jitsi_meet_jibri_enabled -- name: Copy Jicofo log.properties - copy: - content: "{{ jitsi_meet_jicofo_logging_properties }}" +- name: Copy Jicofo logging.properties + template: + src: jicofo/logging.properties.j2 dest: /etc/jitsi/jicofo/logging.properties owner: jicofo group: jitsi mode: 0640 notify: restart jicofo -- name: Copy jitsi-videobridge2 config - template: - src: videobridge/config.j2 - dest: /etc/jitsi/videobridge/config - owner: jvb - group: jitsi - mode: 0640 - notify: restart jitsi-videobridge2 - -- name: Copy jitsi-videobridge2 log.properties - template: - src: videobridge/logging.properties.j2 - dest: /etc/jitsi/videobridge/logging.properties - owner: jvb - group: jitsi - mode: 0640 - notify: restart jitsi-videobridge2 - - name: Copy jitsi meet config template: mode: 0644 src: meet-config.js.j2 dest: "/etc/jitsi/meet/{{ jitsi_meet_server_name }}-config.js" -- name: Enable jitsi-videobridge2 - service: - name: jitsi-videobridge2 - enabled: yes - - name: Enable jicofo service: name: jicofo diff --git a/tasks/main.yml b/meet/tasks/main.yml similarity index 79% rename from tasks/main.yml rename to meet/tasks/main.yml index 642bbbd..cd1db30 100644 --- a/tasks/main.yml +++ b/meet/tasks/main.yml @@ -8,11 +8,7 @@ - jitsi_meet_videobridge_password - jitsi_meet_jicofo_secret - jitsi_meet_jicofo_password - when: jitsi_meet_base_secret is defined - -- name: Derive videobridge nickname - set_fact: - jitsi_meet_videobridge_muc_nickname: "{{ (jitsi_meet_base_secret | string + 'jvb_muc_nick') | to_uuid }}" + - jitsi_meet_jigasi_secret when: jitsi_meet_base_secret is defined - import_tasks: jitsi-meet.yml diff --git a/tasks/nginx.yml b/meet/tasks/nginx.yml similarity index 100% rename from tasks/nginx.yml rename to meet/tasks/nginx.yml diff --git a/tasks/prosody.yml b/meet/tasks/prosody.yml similarity index 100% rename from tasks/prosody.yml rename to meet/tasks/prosody.yml diff --git a/tasks/ui_customization.yml b/meet/tasks/ui_customization.yml similarity index 100% rename from tasks/ui_customization.yml rename to meet/tasks/ui_customization.yml diff --git a/templates/interface_config.js.j2 b/meet/templates/interface_config.js.j2 similarity index 93% rename from templates/interface_config.js.j2 rename to meet/templates/interface_config.js.j2 index 0ad350d..8efdce8 100644 --- a/templates/interface_config.js.j2 +++ b/meet/templates/interface_config.js.j2 @@ -42,7 +42,7 @@ var interfaceConfig = { * * @type {boolean} */ - CONNECTION_INDICATOR_DISABLED: false, + CONNECTION_INDICATOR_DISABLED: {{ jitsi_meet_interface_connection_indicator_disabled }}, DEFAULT_BACKGROUND: '{{ jitsi_meet_interface_default_background }}', DEFAULT_LOCAL_DISPLAY_NAME: '{{ jitsi_meet_interface_default_local_display_name }}', @@ -50,14 +50,14 @@ var interfaceConfig = { DEFAULT_REMOTE_DISPLAY_NAME: '{{ jitsi_meet_interface_default_remote_display_name }}', DEFAULT_WELCOME_PAGE_LOGO_URL: '{{ jitsi_meet_interface_default_welcome_page_logo_url }}', - DISABLE_DOMINANT_SPEAKER_INDICATOR: false, + DISABLE_DOMINANT_SPEAKER_INDICATOR: {{ jitsi_meet_interface_disable_dominant_speaker_indicator }}, - DISABLE_FOCUS_INDICATOR: false, + DISABLE_FOCUS_INDICATOR: {{ jitsi_meet_interface_disable_focus_indicator }}, /** * If true, notifications regarding joining/leaving are no longer displayed. */ - DISABLE_JOIN_LEAVE_NOTIFICATIONS: false, + DISABLE_JOIN_LEAVE_NOTIFICATIONS: {{ jitsi_meet_interface_disable_join_leave_notifications }}, /** * If true, presence status: busy, calling, connected etc. is not displayed. @@ -201,13 +201,7 @@ var interfaceConfig = { * - it's impossible to control the placement of buttons * - 'desktop' controls the "Share your screen" button */ - TOOLBAR_BUTTONS: [ - 'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen', - 'fodeviceselection', 'hangup', 'profile', 'chat', 'recording', - 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand', - 'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts', - 'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'security' - ], + TOOLBAR_BUTTONS: {{ jitsi_meet_interface_toolbar_buttons | to_nice_json }}, TOOLBAR_TIMEOUT: 4000, @@ -215,6 +209,8 @@ var interfaceConfig = { // are not supported and should show the unsupported browser page. UNSUPPORTED_BROWSERS: [], + SET_FILMSTRIP_ENABLED: {{ jitsi_meet_interface_set_filmstrip_enabled }}, + /** * Whether to show thumbnails in filmstrip as a column instead of as a row. */ diff --git a/templates/jicofo/config.j2 b/meet/templates/jicofo/config.j2 similarity index 74% rename from templates/jicofo/config.j2 rename to meet/templates/jicofo/config.j2 index ab5a5c2..59e65e7 100644 --- a/templates/jicofo/config.j2 +++ b/meet/templates/jicofo/config.j2 @@ -24,4 +24,9 @@ JICOFO_AUTH_PASSWORD={{ jitsi_meet_jicofo_password }} JICOFO_OPTS="" # adds java system props that are passed to jicofo (default are for home and logging config file) -JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=jicofo -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi -Djava.util.logging.config.file=/etc/jitsi/jicofo/logging.properties" +JAVA_SYS_PROPS=" \ + -Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi \ + -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=jicofo \ + -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi \ + -Djava.util.logging.config.file=/etc/jitsi/jicofo/logging.properties \ +" diff --git a/meet/templates/jicofo/logging.properties.j2 b/meet/templates/jicofo/logging.properties.j2 new file mode 100644 index 0000000..f149386 --- /dev/null +++ b/meet/templates/jicofo/logging.properties.j2 @@ -0,0 +1,50 @@ +handlers= java.util.logging.ConsoleHandler + +# Handlers with XMPP debug enabled: +#handlers= java.util.logging.ConsoleHandler, org.jitsi.impl.protocol.xmpp.log.XmppPacketsFileHandler + +# Handlers with syslog enabled: +#handlers= java.util.logging.ConsoleHandler, com.agafua.syslog.SyslogHandler + +java.util.logging.ConsoleHandler.level = {{ jitsi_meet_jicofo_loglevel }} +java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter +java.util.logging.ConsoleHandler.filter = org.jitsi.impl.protocol.xmpp.log.ExcludeXmppPackets + +net.java.sip.communicator.util.ScLogFormatter.programname=Jicofo +.level= {{ jitsi_meet_jicofo_loglevel }} + +# To enable XMPP packets logging add XmppPacketsFileHandler to the handlers property +org.jitsi.impl.protocol.xmpp.log.PacketDebugger.level=ALL +org.jitsi.impl.protocol.xmpp.log.XmppPacketsFileHandler.pattern=/var/log/jitsi/jicofo-xmpp.log +org.jitsi.impl.protocol.xmpp.log.XmppPacketsFileHandler.append=true +org.jitsi.impl.protocol.xmpp.log.XmppPacketsFileHandler.limit=200000000 +org.jitsi.impl.protocol.xmpp.log.XmppPacketsFileHandler.count=3 + +# Syslog (uncomment handler to use) +com.agafua.syslog.SyslogHandler.transport = udp +com.agafua.syslog.SyslogHandler.facility = local0 +com.agafua.syslog.SyslogHandler.port = 514 +com.agafua.syslog.SyslogHandler.hostname = localhost +com.agafua.syslog.SyslogHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter +com.agafua.syslog.SyslogHandler.escapeNewlines = false +com.agafua.syslog.SyslogHandler.filter = org.jitsi.impl.protocol.xmpp.log.ExcludeXmppPackets + +# to disable double timestamps in syslog uncomment next line +#net.java.sip.communicator.util.ScLogFormatter.disableTimestamp=true + +# time series logging +java.util.logging.SimpleFormatter.format= %5$s%n +java.util.logging.FileHandler.level = ALL +java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.FileHandler.pattern = /tmp/jvb-series.log +java.util.logging.FileHandler.limit = 200000000 +java.util.logging.FileHandler.count = 1 +java.util.logging.FileHandler.append = false + +timeseries.level=OFF +timeseries.org.jitsi.videobridge.cc.vp8.level=ALL +timeseries.useParentHandlers = false +timeseries.handlers = java.util.logging.FileHandler + +# uncomment to see how Jicofo talks to the JVB +#org.jitsi.impl.protocol.xmpp.colibri.level=ALL diff --git a/meet/templates/jicofo/sip-communicator.properties.j2 b/meet/templates/jicofo/sip-communicator.properties.j2 new file mode 100644 index 0000000..a87fd5d --- /dev/null +++ b/meet/templates/jicofo/sip-communicator.properties.j2 @@ -0,0 +1,10 @@ +org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.auth.{{ jitsi_meet_server_name }} +{% if jitsi_meet_jibri_enabled == true -%} +org.jitsi.jicofo.jibri.BREWERY=JibriBrewery@internal.auth.{{ jitsi_meet_server_name }} +org.jitsi.jicofo.jibri.PENDING_TIMEOUT=90 +{% endif -%} + +{% if jitsi_meet_octo_enabled -%} +org.jitsi.jicofo.BridgeSelector.BRIDGE_SELECTION_STRATEGY={{ jitsi_meet_octo_selection_strategy }} +org.jitsi.jicofo.SHORT_ID=1 +{% endif -%} diff --git a/templates/logrotate.d/jicofo.j2 b/meet/templates/logrotate.d/jicofo.j2 similarity index 100% rename from templates/logrotate.d/jicofo.j2 rename to meet/templates/logrotate.d/jicofo.j2 diff --git a/templates/logrotate.d/nginx.j2 b/meet/templates/logrotate.d/nginx.j2 similarity index 100% rename from templates/logrotate.d/nginx.j2 rename to meet/templates/logrotate.d/nginx.j2 diff --git a/templates/logrotate.d/prosody.j2 b/meet/templates/logrotate.d/prosody.j2 similarity index 100% rename from templates/logrotate.d/prosody.j2 rename to meet/templates/logrotate.d/prosody.j2 diff --git a/templates/meet-config.js.j2 b/meet/templates/meet-config.js.j2 similarity index 94% rename from templates/meet-config.js.j2 rename to meet/templates/meet-config.js.j2 index 5168794..7ebbb6e 100644 --- a/templates/meet-config.js.j2 +++ b/meet/templates/meet-config.js.j2 @@ -44,6 +44,11 @@ var config = { // testing: { +{% if jitsi_meet_octo_enabled %} + octo: { + probability: 1 + }, +{% endif %} // P2P test mode disables automatic switching to P2P when there are 2 // participants in the conference. p2pTestMode: false @@ -77,20 +82,20 @@ var config = { // Enabling this will run the lib-jitsi-meet no audio detection module which // will notify the user if the current selected microphone has no audio // input and will suggest another valid device if one is present. - enableNoAudioDetection: true, + enableNoAudioDetection: {{ jitsi_meet_config_enable_no_audio_detection }}, // Enabling this will run the lib-jitsi-meet noise detection module which will // notify the user if there is noise, other than voice, coming from the current // selected microphone. The purpose it to let the user know that the input could // be potentially unpleasant for other meeting participants. - enableNoisyMicDetection: true, + enableNoisyMicDetection: {{ jitsi_meet_config_enable_noisy_mic_detection }}, // Start the conference in audio only mode (no video is being received nor // sent). startAudioOnly: {{ jitsi_meet_config_start_audio_only }}, // Every participant after the Nth will start audio muted. - // startAudioMuted: 10, + startAudioMuted: {{ jitsi_meet_config_start_audio_muted }}, // Start calls with audio muted. Unlike the option above, this one is only // applied locally. FIXME: having these 2 options is confusing. @@ -121,7 +126,7 @@ var config = { enableLayerSuspension: {{ jitsi_meet_config_layer_suspension }}, // Every participant after the Nth will start video muted. - // startVideoMuted: 10, + startVideoMuted: {{ jitsi_meet_config_start_video_muted }}, // Start calls with video muted. Unlike the option above, this one is only // applied locally. FIXME: having these 2 options is confusing. @@ -205,6 +210,22 @@ var config = { // Default value for the channel "last N" attribute. -1 for unlimited. channelLastN: {{ jitsi_meet_config_last_n }}, + // Provides a way to use different "last N" values based on the number of participants in the conference. + // The keys in an Object represent number of participants and the values are "last N" to be used when number of + // participants gets to or above the number. + // + // For the given example mapping, "last N" will be set to 20 as long as there are at least 5, but less than + // 29 participants in the call and it will be lowered to 15 when the 30th participant joins. The 'channelLastN' + // will be used as default until the first threshold is reached. + // + // lastNLimits: { + // 5: 20, + // 30: 15, + // 50: 10, + // 70: 5, + // 90: 2 + // }, + // Disables or enables RTX (RFC 4588) (defaults to false). // disableRtx: false, @@ -383,8 +404,8 @@ var config = { // the user region as seen by the server. deploymentInfo: { // shard: "shard1", - // region: "europe", - // userRegion: "asia" + region: "{{ jitsi_meet_octo_region }}", + userRegion: "{{ jitsi_meet_octo_region }}" }, // Decides whether the start/stop recording audio notifications should play on record. diff --git a/templates/nginx/nginx.conf.j2 b/meet/templates/nginx/nginx.conf.j2 similarity index 100% rename from templates/nginx/nginx.conf.j2 rename to meet/templates/nginx/nginx.conf.j2 diff --git a/templates/nginx/sites-available/vhost.conf.j2 b/meet/templates/nginx/sites-available/vhost.conf.j2 similarity index 69% rename from templates/nginx/sites-available/vhost.conf.j2 rename to meet/templates/nginx/sites-available/vhost.conf.j2 index 4cd1ab6..0d67e9f 100644 --- a/templates/nginx/sites-available/vhost.conf.j2 +++ b/meet/templates/nginx/sites-available/vhost.conf.j2 @@ -10,10 +10,42 @@ server { {% if jitsi_meet_nginx_listen_https_enabled %} location / { - return 301 https://$host$request_uri; + return 301 https://{{ jitsi_meet_server_name }}$request_uri; } } +{% if jitsi_meet_server_name_aliases | length > 0 -%} +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + + server_name {{ jitsi_meet_server_name_aliases | join(' ') }}; + + ssl_protocols {{ jitsi_meet_nginx_ssl_protocols }}; + ssl_prefer_server_ciphers {{ jitsi_meet_nginx_ssl_prefer_server_ciphers }}; + {% if not jitsi_meet_nginx_ssl_ciphers == "" %} + ssl_ciphers "{{ jitsi_meet_nginx_ssl_ciphers }}"; + {% endif %} + + {% if not jitsi_meet_nginx_ssl_preset == "modern" %} + ssl_dhparam {{ jitsi_meet_nginx_ssl_dhparam }}; + {% endif %} + + ssl_certificate {{ jitsi_meet_ssl_cert_path }}; + ssl_certificate_key {{ jitsi_meet_ssl_key_path }}; + ssl_session_timeout 1d; + ssl_session_cache shared:MozSSL:10m; # about 40000 sessions + ssl_session_tickets off; + + ssl_stapling on; + ssl_stapling_verify on; + + add_header Strict-Transport-Security "max-age=31536000"; + + return 301 https://{{ jitsi_meet_server_name }}$request_uri; +} +{% endif %} + server { listen 443 ssl http2; listen [::]:443 ssl http2; @@ -40,7 +72,10 @@ server { add_header Strict-Transport-Security "max-age=31536000"; {% endif %} - server_name {{ jitsi_meet_server_name }} {{ jitsi_meet_server_name_aliases | join(' ') }}; + server_name {{ jitsi_meet_server_name }}; + + access_log {{ jitsi_meet_nginx_access_log }}; + error_log {{ jitsi_meet_nginx_error_log }}; root /usr/share/jitsi-meet; @@ -91,14 +126,16 @@ server { tcp_nodelay on; } - # colibri (JVB) websockets for jvb1 - location ~ ^/colibri-ws/default-id/(.*) { - proxy_pass http://127.0.0.1:9090/colibri-ws/default-id/$1$is_args$args; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - tcp_nodelay on; + # colibri (JVB) websockets +{% for videobridge in jitsi_meet_videobridge_instances -%} + location ~ ^/colibri-ws/{{ videobridge.name }}/(.*) { + proxy_pass http://{{ videobridge.ip }}:9090/colibri-ws/{{ videobridge.name }}/$1$is_args$args; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + tcp_nodelay on; } +{% endfor -%} location ~ ^/([^/?&:'"]+)$ { try_files $uri @root_path; diff --git a/templates/prosody/conf.avail/virtualhost.cfg.lua.j2 b/meet/templates/prosody/conf.avail/virtualhost.cfg.lua.j2 similarity index 89% rename from templates/prosody/conf.avail/virtualhost.cfg.lua.j2 rename to meet/templates/prosody/conf.avail/virtualhost.cfg.lua.j2 index 952a7bd..088052c 100644 --- a/templates/prosody/conf.avail/virtualhost.cfg.lua.j2 +++ b/meet/templates/prosody/conf.avail/virtualhost.cfg.lua.j2 @@ -15,6 +15,7 @@ turncredentials = { cross_domain_bosh = false; consider_bosh_secure = true; +https_ports = { } -- https is proxied through nginx VirtualHost "{{ jitsi_meet_server_name }}" -- enabled = false -- Remove this line to enable this host @@ -65,7 +66,7 @@ Component "internal.auth.{{ jitsi_meet_server_name }}" "muc" modules_enabled = { "ping"; } - admins = { "focus@auth.{{ jitsi_meet_server_name }}", "jvb@auth.{{ jitsi_meet_server_name }}" } + admins = { "focus@auth.{{ jitsi_meet_server_name }}", "jvb@auth.{{ jitsi_meet_server_name }}"{% if jitsi_meet_jigasi_enabled %}, "jigasi@auth.{{ jitsi_meet_server_name }}"{% endif %} } muc_room_locking = false muc_room_default_public_jids = true muc_room_cache_size = 1000 @@ -75,7 +76,7 @@ VirtualHost "auth.{{ jitsi_meet_server_name }}" key = "/etc/prosody/certs/auth.{{ jitsi_meet_server_name }}.key"; certificate = "/etc/prosody/certs/auth.{{ jitsi_meet_server_name }}.crt"; } - authentication = "internal_plain" + authentication = "internal_hashed" Component "focus.{{ jitsi_meet_server_name }}" component_secret = "{{ jitsi_meet_jicofo_secret }}" @@ -89,12 +90,17 @@ Component "conferenceduration.{{ jitsi_meet_server_name }}" "conference_duration Component "jitsi-videobridge.{{ jitsi_meet_server_name }}" component_secret = "{{ jitsi_meet_videobridge_secret }}" -{% if jitsi_meet_jibri_enabled %} +{% if jitsi_meet_jigasi_enabled -%} +Component "callcontrol.{{ jitsi_meet_server_name }}" + component_secret = "{{ jitsi_meet_jigasi_secret }}" +{% endif %} + +{% if jitsi_meet_jibri_enabled -%} VirtualHost "recorder.{{ jitsi_meet_server_name }}" modules_enabled = { "ping"; } - authentication = "internal_plain" + authentication = "internal_hashed" {% endif %} Component "lobby.{{ jitsi_meet_server_name }}" "muc" diff --git a/templates/prosody/prosody.cfg.lua.j2 b/meet/templates/prosody/prosody.cfg.lua.j2 similarity index 99% rename from templates/prosody/prosody.cfg.lua.j2 rename to meet/templates/prosody/prosody.cfg.lua.j2 index 00f6832..54a1c00 100644 --- a/templates/prosody/prosody.cfg.lua.j2 +++ b/meet/templates/prosody/prosody.cfg.lua.j2 @@ -23,6 +23,8 @@ -- Example: admins = { "user1@example.com", "user2@example.net" } admins = { } +network_backend = "epoll" + -- Enable use of libevent for better performance under high load -- For more information see: https://prosody.im/doc/libevent --use_libevent = true diff --git a/templates/title.html.j2 b/meet/templates/title.html.j2 similarity index 100% rename from templates/title.html.j2 rename to meet/templates/title.html.j2 diff --git a/meta/main.yml b/meta/main.yml index 55c3161..e2877ee 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,9 +1,9 @@ --- galaxy_info: role_name: jitsi_meet - author: systemli + author: technischerpunkt description: Install and maintain jitsi-meet. Contains tests for Molecule. - company: systemli.org + company: technischer.org license: GPLv3 min_ansible_version: 2.2 galaxy_tags: @@ -17,9 +17,5 @@ galaxy_info: notifications: webhooks: https://galaxy.ansible.com/api/v1/notifications/ dependencies: - - role: systemli.apt_repositories - vars: - apt_repositories: - - preset: jitsi - name: download_jitsi_org - packages: "{{ jitsi_meet_packages }}" + - role: jitsi_meet/meet + - role: jitsi_meet/videobridge diff --git a/templates/jicofo/sip-communicator.properties.j2 b/templates/jicofo/sip-communicator.properties.j2 deleted file mode 100644 index d716b1a..0000000 --- a/templates/jicofo/sip-communicator.properties.j2 +++ /dev/null @@ -1,3 +0,0 @@ -org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.auth.{{ jitsi_meet_server_name }} -org.jitsi.jicofo.jibri.BREWERY=JibriBrewery@internal.auth.{{ jitsi_meet_server_name }} -org.jitsi.jicofo.jibri.PENDING_TIMEOUT=90 \ No newline at end of file diff --git a/videobridge/defaults/main.yml b/videobridge/defaults/main.yml new file mode 100644 index 0000000..55664b5 --- /dev/null +++ b/videobridge/defaults/main.yml @@ -0,0 +1,34 @@ +--- +# Global +jitsi_meet_server_name: "meet.example.com" +jitsi_meet_config_stun_servers: + - stun:meet-jit-si-turnrelay.jitsi.net:443 +jitsi_meet_jicofo_user: focus + +# Videobridge +jitsi_meet_videobridge_port: 5347 + +## single server vs scalable setup +jitsi_meet_single_instance: True +jitsi_meet_videobridge_prosody_server_ip: "localhost" +jitsi_meet_videobridge_muc_nickname: "{{ jitsi_meet_single_instance | ternary('jvb1', inventory_hostname) }}" +_jitsi_meet_apt_repositories_pin_packages: + - jicofo + - jitsi-meet-prosody + - jitsi-meet-web + - jitsi-meet-web-config +jitsi_meet_apt_repositories_pin_packages: "{{ ['jitsi-videobridge2'] + (jitsi_meet_single_instance | ternary(_jitsi_meet_apt_repositories_pin_packages, [])) }}" + +# Octo +jitsi_meet_octo_enabled: False +jitsi_meet_octo_private_ip: "{{ ansible_default_ipv4.address }}" +jitsi_meet_octo_public_ip: "{{ ansible_default_ipv4.address }}" +jitsi_meet_octo_region: region1 + +## The packet rate (pps) at which we'll consider the bridge overloaded +jitsi_meet_videobridge_load_threshold: 50000 +## The packet rate (pps) at which we'll consider the bridge 'underloaded' enough to start recovery +jitsi_meet_videobridge_recovery_threshold: 40000 + +## Logging +jitsi_meet_videobridge_loglevel: "WARNING" diff --git a/videobridge/handlers/main.yml b/videobridge/handlers/main.yml new file mode 100644 index 0000000..9964ec6 --- /dev/null +++ b/videobridge/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart jitsi-videobridge2 + service: + name: jitsi-videobridge2 + state: restarted diff --git a/videobridge/meta/main.yml b/videobridge/meta/main.yml new file mode 100644 index 0000000..bcdaf18 --- /dev/null +++ b/videobridge/meta/main.yml @@ -0,0 +1,10 @@ +--- +galaxy_info: + role_name: videobridge +dependencies: + - role: systemli.apt_repositories + vars: + apt_repositories: + - preset: jitsi + name: download_jitsi_org + packages: "{{ jitsi_meet_apt_repositories_pin_packages }}" diff --git a/videobridge/tasks/main.yml b/videobridge/tasks/main.yml new file mode 100644 index 0000000..ae1ebc1 --- /dev/null +++ b/videobridge/tasks/main.yml @@ -0,0 +1,64 @@ +--- +- name: Derive individual secrets from base secret + set_fact: + "{{ item }}": "{{ (item + jitsi_meet_base_secret | string) | hash('sha1') }}" + loop: + - jitsi_meet_videobridge_secret + - jitsi_meet_videobridge_password + when: jitsi_meet_base_secret is defined + +- name: Set debconf options for jitsi-videobridge + debconf: + name: "{{ item.name }}" + question: "{{ item.question }}" + value: "{{ item.value }}" + vtype: "{{ item.vtype }}" + loop: + - name: jitsi-videobridge2 + question: jitsi-videobridge/jvb-hostname + value: "{{ jitsi_meet_server_name }}" + vtype: string + +- name: Install jitsi-videobridge + apt: + pkg: jitsi-videobridge2 + install_recommends: no + state: present + update_cache: yes + +- name: Copy videobridge sip-communicator.properties + template: + src: videobridge/sip-communicator.properties.j2 + dest: /etc/jitsi/videobridge/sip-communicator.properties + owner: jvb + group: jitsi + mode: 0640 + notify: restart jitsi-videobridge2 + +- name: Copy jitsi-videobridge2 config + template: + src: videobridge/{{ item }}.j2 + dest: /etc/jitsi/videobridge/{{ item }} + owner: jvb + group: jitsi + mode: 0640 + with_items: + - config + - jvb.conf + notify: restart jitsi-videobridge2 + +- name: Copy jitsi-videobridge2 log.properties + template: + src: videobridge/logging.properties.j2 + dest: /etc/jitsi/videobridge/logging.properties + owner: jvb + group: jitsi + mode: 0640 + notify: restart jitsi-videobridge2 + +- name: Enable jitsi-videobridge2 + service: + name: jitsi-videobridge2 + enabled: yes + +- meta: flush_handlers diff --git a/templates/videobridge/config.j2 b/videobridge/templates/videobridge/config.j2 similarity index 66% rename from templates/videobridge/config.j2 rename to videobridge/templates/videobridge/config.j2 index 39739b0..706583a 100644 --- a/templates/videobridge/config.j2 +++ b/videobridge/templates/videobridge/config.j2 @@ -16,4 +16,9 @@ JVB_SECRET={{ jitsi_meet_videobridge_secret }} JVB_OPTS="--apis=rest,xmpp" # adds java system props that are passed to jvb (default are for home and logging config file) -JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=videobridge -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi -Djava.util.logging.config.file=/etc/jitsi/videobridge/logging.properties" +JAVA_SYS_PROPS=" \ + -Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi \ + -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=videobridge \ + -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi \ + -Djava.util.logging.config.file=/etc/jitsi/videobridge/logging.properties \ +" diff --git a/videobridge/templates/videobridge/jvb.conf.j2 b/videobridge/templates/videobridge/jvb.conf.j2 new file mode 100644 index 0000000..b5f7eb5 --- /dev/null +++ b/videobridge/templates/videobridge/jvb.conf.j2 @@ -0,0 +1,24 @@ +videobridge { + http-servers { + public { + port = 9090 + } + } + websockets { + enabled = true + domain = "{{ jitsi_meet_server_name }}:443" + tls = true + server-id = {{ ansible_hostname }} + } + load-management { + load-measurements { + packet-rate { + # The packet rate at which we'll consider the bridge overloaded + load-threshold = {{ jitsi_meet_videobridge_load_threshold }} + # The packet rate at which we'll consider the bridge 'underloaded' enough + # to start recovery + recovery-threshold = {{ jitsi_meet_videobridge_recovery_threshold }} + } + } + } +} diff --git a/templates/videobridge/logging.properties.j2 b/videobridge/templates/videobridge/logging.properties.j2 similarity index 100% rename from templates/videobridge/logging.properties.j2 rename to videobridge/templates/videobridge/logging.properties.j2 diff --git a/templates/videobridge/sip-communicator.properties.j2 b/videobridge/templates/videobridge/sip-communicator.properties.j2 similarity index 54% rename from templates/videobridge/sip-communicator.properties.j2 rename to videobridge/templates/videobridge/sip-communicator.properties.j2 index 410eaad..e772473 100644 --- a/templates/videobridge/sip-communicator.properties.j2 +++ b/videobridge/templates/videobridge/sip-communicator.properties.j2 @@ -4,11 +4,23 @@ org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES={{ jitsi_meet_config_stun org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS="{{ jitsi_meet_nat_local_ip }}" org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS="{{ jitsi_meet_nat_public_ip }}" {% endif %} +org.jitsi.videobridge.AUTHORIZED_SOURCE_REGEXP=jvbbrewery@internal.auth.{{ jitsi_meet_server_name }}/{{ jitsi_meet_jicofo_user }}.*$ org.jitsi.videobridge.ENABLE_STATISTICS=true org.jitsi.videobridge.STATISTICS_TRANSPORT=muc,colibri -org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=localhost +org.jitsi.videobridge.xmpp.user.shard.HOSTNAME={{ jitsi_meet_videobridge_prosody_server_ip }} org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.{{ jitsi_meet_server_name }} org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb org.jitsi.videobridge.xmpp.user.shard.PASSWORD={{ jitsi_meet_videobridge_password }} org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.{{ jitsi_meet_server_name }} org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME={{ jitsi_meet_videobridge_muc_nickname }} +org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=true + +{% if jitsi_meet_octo_enabled -%} +# the address to bind to locally +org.jitsi.videobridge.octo.BIND_ADDRESS={{ jitsi_meet_octo_private_ip }} +# the address to advertise (in case BIND_ADDRESS is not accessible) +org.jitsi.videobridge.octo.PUBLIC_ADDRESS={{ jitsi_meet_octo_public_ip }} +# the port to bind to +org.jitsi.videobridge.octo.BIND_PORT=4096 +org.jitsi.videobridge.REGION={{ jitsi_meet_octo_region }} +{% endif -%}