From 8b093dacd52646399698ce7ea3a1924bd39c54ab Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Fri, 20 Mar 2020 16:30:31 -0700 Subject: [PATCH] Add meetpad server Depends-On: https://review.opendev.org/714189 Change-Id: I5863aaa805a18f9085ee01c3205b0f9ad602922d --- .zuul.yaml | 30 ++ inventory/groups.yaml | 3 + playbooks/group_vars/meetpad.yaml | 6 + .../host_vars/meetpad01.opendev.org.yaml | 4 + playbooks/roles/jitsi-meet/README.rst | 2 + playbooks/roles/jitsi-meet/files/config.js | 483 ++++++++++++++++++ .../jitsi-meet/files/jitsi-meet-docker/.env | 295 +++++++++++ .../jitsi-meet-docker/docker-compose.yaml | 143 ++++++ playbooks/roles/jitsi-meet/tasks/main.yaml | 30 ++ .../handlers/main.yaml | 3 + .../handlers/restart_jitsi_meet.yaml | 37 ++ playbooks/service-meetpad.yaml | 5 + run_all.sh | 4 + testinfra/test_meetpad.py | 21 + 14 files changed, 1066 insertions(+) create mode 100644 playbooks/group_vars/meetpad.yaml create mode 100644 playbooks/host_vars/meetpad01.opendev.org.yaml create mode 100644 playbooks/roles/jitsi-meet/README.rst create mode 100644 playbooks/roles/jitsi-meet/files/config.js create mode 100644 playbooks/roles/jitsi-meet/files/jitsi-meet-docker/.env create mode 100644 playbooks/roles/jitsi-meet/files/jitsi-meet-docker/docker-compose.yaml create mode 100644 playbooks/roles/jitsi-meet/tasks/main.yaml create mode 100644 playbooks/roles/letsencrypt-create-certs/handlers/restart_jitsi_meet.yaml create mode 100644 playbooks/service-meetpad.yaml create mode 100644 testinfra/test_meetpad.py diff --git a/.zuul.yaml b/.zuul.yaml index 9f1a008795..1afb6abf6f 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -1061,6 +1061,34 @@ # to run this job as well. - docker/haproxy-statsd/.* +- job: + name: system-config-run-meetpad + parent: system-config-run + description: | + Run the playbook for jitsi-meet. + dependencies: opendev-buildset-registry + nodeset: + nodes: + - name: bridge.openstack.org + label: ubuntu-bionic + - name: meetpad01.opendev.org + label: ubuntu-bionic + vars: + run_playbooks: + - playbooks/service-letsencrypt.yaml + - playbooks/service-meetpad.yaml + host-vars: + meetpad01.opendev.org: + host_copy_output: + '/var/jitsi-meet': logs + files: + - playbooks/bridge.yaml + - playbooks/group_vars/meetpad.yaml + - ^playbooks/host_vars/meetpad\d+.opendev.org.yaml + - playbooks/roles/letsencrypt-create-certs/handlers/restart_jitsi_meet.yaml + - playbooks/roles/jitsi-meet/ + - testinfra/test_meetpad.py + - job: name: system-config-run-zuul-preview parent: system-config-run @@ -1392,6 +1420,7 @@ - system-config-run-eavesdrop - system-config-run-lists - system-config-run-nodepool + - system-config-run-meetpad - system-config-run-mirror-x86 - system-config-run-mirror-update - system-config-run-static @@ -1441,6 +1470,7 @@ - system-config-run-eavesdrop - system-config-run-lists - system-config-run-nodepool + - system-config-run-meetpad - system-config-run-mirror-x86 - system-config-run-mirror-update - system-config-run-static diff --git a/inventory/groups.yaml b/inventory/groups.yaml index 7cc06dc986..25fc5164ba 100644 --- a/inventory/groups.yaml +++ b/inventory/groups.yaml @@ -69,6 +69,7 @@ groups: - gitea[0-9]*.opendev.org - graphite01.opendev.org - insecure-ci-registry[0-9]*.opendev.org + - meetpad[0-9]*.opendev.org - mirror[0-9]*.opendev.org - nb[0-9]*.opendev.org - review-dev[0-9]*.open*.org @@ -83,6 +84,8 @@ groups: mailman: - lists*.katacontainers.io - lists*.open*.org + meetpad: + - meetpad[0-9]*.opendev.org mirror: - mirror[0-9]*.openstack.org mirror_opendev: diff --git a/playbooks/group_vars/meetpad.yaml b/playbooks/group_vars/meetpad.yaml new file mode 100644 index 0000000000..e3398eb03b --- /dev/null +++ b/playbooks/group_vars/meetpad.yaml @@ -0,0 +1,6 @@ +iptables_extra_public_tcp_ports: + - 80 + - 443 + - 4443 +iptables_extra_public_udp_ports: + - 10000 diff --git a/playbooks/host_vars/meetpad01.opendev.org.yaml b/playbooks/host_vars/meetpad01.opendev.org.yaml new file mode 100644 index 0000000000..82fc801113 --- /dev/null +++ b/playbooks/host_vars/meetpad01.opendev.org.yaml @@ -0,0 +1,4 @@ +letsencrypt_certs: + meetpad01-main: + - meetpad01.opendev.org + - meetpad.opendev.org diff --git a/playbooks/roles/jitsi-meet/README.rst b/playbooks/roles/jitsi-meet/README.rst new file mode 100644 index 0000000000..5163fb64b1 --- /dev/null +++ b/playbooks/roles/jitsi-meet/README.rst @@ -0,0 +1,2 @@ +Install, configure, and run jitsi-meet. + diff --git a/playbooks/roles/jitsi-meet/files/config.js b/playbooks/roles/jitsi-meet/files/config.js new file mode 100644 index 0000000000..b64c5a10e4 --- /dev/null +++ b/playbooks/roles/jitsi-meet/files/config.js @@ -0,0 +1,483 @@ +/* eslint-disable no-unused-vars, no-var */ + +var config = { + // Configuration + // + + // Alternative location for the configuration. + // configLocation: './config.json', + + // Custom function which given the URL path should return a room name. + // getroomnode: function (path) { return 'someprefixpossiblybasedonpath'; }, + + + // Connection + // + + hosts: { + // XMPP domain. + domain: 'localhost.localdomain', + + // When using authentication, domain for guest users. + // anonymousdomain: 'guest.example.com', + + // Domain for authenticated users. Defaults to . + // authdomain: 'localhost.localdomain', + + // Jirecon recording component domain. + // jirecon: 'jirecon.localhost.localdomain', + + // Call control component (Jigasi). + // call_control: 'callcontrol.localhost.localdomain', + + // Focus component domain. Defaults to focus.. + // focus: 'focus.localhost.localdomain', + + // XMPP MUC domain. FIXME: use XEP-0030 to discover it. + muc: 'muc.localhost.localdomain', + }, + + // BOSH URL. FIXME: use XEP-0156 to discover it. + bosh: '/http-bind', + + // The name of client node advertised in XEP-0115 'c' stanza + clientNode: 'http://jitsi.org/jitsimeet', + + // The real JID of focus participant - can be overridden here + focusUserJid: 'focus@auth.localhost.localdomain', + + + // Testing / experimental features. + // + + testing: { + // Enables experimental simulcast support on Firefox. + enableFirefoxSimulcast: false, + + // P2P test mode disables automatic switching to P2P when there are 2 + // participants in the conference. + p2pTestMode: false + + // Enables the test specific features consumed by jitsi-meet-torture + // testMode: false + }, + + // Disables ICE/UDP by filtering out local and remote UDP candidates in + // signalling. + // webrtcIceUdpDisable: false, + + // Disables ICE/TCP by filtering out local and remote TCP candidates in + // signalling. + // webrtcIceTcpDisable: false, + + + // Media + // + + // Audio + + // Disable measuring of audio levels. + // disableAudioLevels: false, + + // Start the conference in audio only mode (no video is being received nor + // sent). + // startAudioOnly: false, + + // Every participant after the Nth will start audio muted. + // startAudioMuted: 10, + + // Start calls with audio muted. Unlike the option above, this one is only + // applied locally. FIXME: having these 2 options is confusing. + // startWithAudioMuted: false, + + // Enabling it (with #params) will disable local audio output of remote + // participants and to enable it back a reload is needed. + // startSilent: false + + // Video + + // Sets the preferred resolution (height) for local video. Defaults to 720. + // resolution: 720, + + // w3c spec-compliant video constraints to use for video capture. Currently + // used by browsers that return true from lib-jitsi-meet's + // util#browser#usesNewGumFlow. The constraints are independency from + // this config's resolution value. Defaults to requesting an ideal aspect + // ratio of 16:9 with an ideal resolution of 720. + // constraints: { + // video: { + // aspectRatio: 16 / 9, + // height: { + // ideal: 720, + // max: 720, + // min: 240 + // } + // } + // }, + + // Enable / disable simulcast support. + // disableSimulcast: false, + + // Enable / disable layer suspension. If enabled, endpoints whose HD + // layers are not in use will be suspended (no longer sent) until they + // are requested again. + // enableLayerSuspension: false, + + // Suspend sending video if bandwidth estimation is too low. This may cause + // problems with audio playback. Disabled until these are fixed. + disableSuspendVideo: true, + + // Every participant after the Nth will start video muted. + // startVideoMuted: 10, + + // Start calls with video muted. Unlike the option above, this one is only + // applied locally. FIXME: having these 2 options is confusing. + // startWithVideoMuted: false, + + // If set to true, prefer to use the H.264 video codec (if supported). + // Note that it's not recommended to do this because simulcast is not + // supported when using H.264. For 1-to-1 calls this setting is enabled by + // default and can be toggled in the p2p section. + // preferH264: true, + + // If set to true, disable H.264 video codec by stripping it out of the + // SDP. + // disableH264: false, + + // Desktop sharing + + // The ID of the jidesha extension for Chrome. + desktopSharingChromeExtId: null, + + // Whether desktop sharing should be disabled on Chrome. + // desktopSharingChromeDisabled: false, + + // The media sources to use when using screen sharing with the Chrome + // extension. + desktopSharingChromeSources: [ 'screen', 'window', 'tab' ], + + // Required version of Chrome extension + desktopSharingChromeMinExtVersion: '0.1', + + // Whether desktop sharing should be disabled on Firefox. + // desktopSharingFirefoxDisabled: false, + + // Optional desktop sharing frame rate options. Default value: min:5, max:5. + // desktopSharingFrameRate: { + // min: 5, + // max: 5 + // }, + + // Try to start calls with screen-sharing instead of camera video. + // startScreenSharing: false, + + // Recording + + // Whether to enable file recording or not. + // fileRecordingsEnabled: false, + // Enable the dropbox integration. + // dropbox: { + // appKey: '' // Specify your app key here. + // // A URL to redirect the user to, after authenticating + // // by default uses: + // // 'https://localhost.localdomain/static/oauth.html' + // redirectURI: + // 'https://localhost.localdomain/subfolder/static/oauth.html' + // }, + // When integrations like dropbox are enabled only that will be shown, + // by enabling fileRecordingsServiceEnabled, we show both the integrations + // and the generic recording service (its configuration and storage type + // depends on jibri configuration) + // fileRecordingsServiceEnabled: false, + // Whether to show the possibility to share file recording with other people + // (e.g. meeting participants), based on the actual implementation + // on the backend. + // fileRecordingsServiceSharingEnabled: false, + + // Whether to enable live streaming or not. + // liveStreamingEnabled: false, + + // Transcription (in interface_config, + // subtitles and buttons can be configured) + // transcribingEnabled: false, + + // Misc + + // Default value for the channel "last N" attribute. -1 for unlimited. + channelLastN: -1, + + // Disables or enables RTX (RFC 4588) (defaults to false). + // disableRtx: false, + + // Disables or enables TCC (the default is in Jicofo and set to true) + // (draft-holmer-rmcat-transport-wide-cc-extensions-01). This setting + // affects congestion control, it practically enables send-side bandwidth + // estimations. + // enableTcc: true, + + // Disables or enables REMB (the default is in Jicofo and set to false) + // (draft-alvestrand-rmcat-remb-03). This setting affects congestion + // control, it practically enables recv-side bandwidth estimations. When + // both TCC and REMB are enabled, TCC takes precedence. When both are + // disabled, then bandwidth estimations are disabled. + // enableRemb: false, + + // Defines the minimum number of participants to start a call (the default + // is set in Jicofo and set to 2). + // minParticipants: 2, + + // Use XEP-0215 to fetch STUN and TURN servers. + // useStunTurn: true, + + // Enable IPv6 support. + // useIPv6: true, + + // Enables / disables a data communication channel with the Videobridge. + // Values can be 'datachannel', 'websocket', true (treat it as + // 'datachannel'), undefined (treat it as 'datachannel') and false (don't + // open any channel). + // openBridgeChannel: true, + + + // UI + // + + // Use display name as XMPP nickname. + // useNicks: false, + + // Require users to always specify a display name. + // requireDisplayName: true, + + // Whether to use a welcome page or not. In case it's false a random room + // will be joined when no room is specified. + enableWelcomePage: true, + etherpad_base: 'https://etherpad.openstack.org/p/', + useRoomAsSharedDocumentName: true, + + // Enabling the close page will ignore the welcome page redirection when + // a call is hangup. + // enableClosePage: false, + + // Disable hiding of remote thumbnails when in a 1-on-1 conference call. + // disable1On1Mode: false, + + // Default language for the user interface. + // defaultLanguage: 'en', + + // If true all users without a token will be considered guests and all users + // with token will be considered non-guests. Only guests will be allowed to + // edit their profile. + enableUserRolesBasedOnToken: false, + + // Whether or not some features are checked based on token. + // enableFeaturesBasedOnToken: false, + + // Enable lock room for all moderators, even when userRolesBasedOnToken is enabled and participants are guests. + // lockRoomGuestEnabled: false, + + // When enabled the password used for locking a room is restricted to up to the number of digits specified + // roomPasswordNumberOfDigits: 10, + // default: roomPasswordNumberOfDigits: false, + + // Message to show the users. Example: 'The service will be down for + // maintenance at 01:00 AM GMT, + // noticeMessage: '', + + // Enables calendar integration, depends on googleApiApplicationClientID + // and microsoftApiApplicationClientID + // enableCalendarIntegration: false, + + // Stats + // + + // Whether to enable stats collection or not in the TraceablePeerConnection. + // This can be useful for debugging purposes (post-processing/analysis of + // the webrtc stats) as it is done in the jitsi-meet-torture bandwidth + // estimation tests. + // gatherStats: false, + + // To enable sending statistics to callstats.io you must provide the + // Application ID and Secret. + // callStatsID: '', + // callStatsSecret: '', + + // enables callstatsUsername to be reported as statsId and used + // by callstats as repoted remote id + // enableStatsID: false + + // enables sending participants display name to callstats + // enableDisplayNameInStats: false + + + // Privacy + // + + // If third party requests are disabled, no other server will be contacted. + // This means avatars will be locally generated and callstats integration + // will not function. + // disableThirdPartyRequests: false, + + + // Peer-To-Peer mode: used (if enabled) when there are just 2 participants. + // + + p2p: { + // Enables peer to peer mode. When enabled the system will try to + // establish a direct connection when there are exactly 2 participants + // in the room. If that succeeds the conference will stop sending data + // through the JVB and use the peer to peer connection instead. When a + // 3rd participant joins the conference will be moved back to the JVB + // connection. + enabled: false, + + // Use XEP-0215 to fetch STUN and TURN servers. + // useStunTurn: true, + + // The STUN servers that will be used in the peer to peer connections + stunServers: [ + { urls: 'stun:stun.l.google.com:19302' }, + { urls: 'stun:stun1.l.google.com:19302' }, + { urls: 'stun:stun2.l.google.com:19302' } + ], + + // Sets the ICE transport policy for the p2p connection. At the time + // of this writing the list of possible values are 'all' and 'relay', + // but that is subject to change in the future. The enum is defined in + // the WebRTC standard: + // https://www.w3.org/TR/webrtc/#rtcicetransportpolicy-enum. + // If not set, the effective value is 'all'. + // iceTransportPolicy: 'all', + + // If set to true, it will prefer to use H.264 for P2P calls (if H.264 + // is supported). + preferH264: true + + // If set to true, disable H.264 video codec by stripping it out of the + // SDP. + // disableH264: false, + + // How long we're going to wait, before going back to P2P after the 3rd + // participant has left the conference (to filter out page reload). + // backToP2PDelay: 5 + }, + + analytics: { + // The Google Analytics Tracking ID: + // googleAnalyticsTrackingId: 'your-tracking-id-UA-123456-1' + + // The Amplitude APP Key: + // amplitudeAPPKey: '' + + // Array of script URLs to load as lib-jitsi-meet "analytics handlers". + // scriptURLs: [ + // "libs/analytics-ga.min.js", // google-analytics + // "https://example.com/my-custom-analytics.js" + // ], + }, + + // Information about the jitsi-meet instance we are connecting to, including + // the user region as seen by the server. + deploymentInfo: { + // shard: "shard1", + // region: "europe", + // userRegion: "asia" + } + + // Local Recording + // + + // localRecording: { + // Enables local recording. + // Additionally, 'localrecording' (all lowercase) needs to be added to + // TOOLBAR_BUTTONS in interface_config.js for the Local Recording + // button to show up on the toolbar. + // + // enabled: true, + // + + // The recording format, can be one of 'ogg', 'flac' or 'wav'. + // format: 'flac' + // + + // } + + // Options related to end-to-end (participant to participant) ping. + // e2eping: { + // // The interval in milliseconds at which pings will be sent. + // // Defaults to 10000, set to <= 0 to disable. + // pingInterval: 10000, + // + // // The interval in milliseconds at which analytics events + // // with the measured RTT will be sent. Defaults to 60000, set + // // to <= 0 to disable. + // analyticsInterval: 60000, + // } + + // If set, will attempt to use the provided video input device label when + // triggering a screenshare, instead of proceeding through the normal flow + // for obtaining a desktop stream. + // NOTE: This option is experimental and is currently intended for internal + // use only. + // _desktopSharingSourceDevice: 'sample-id-or-label' + + // If true, any checks to handoff to another application will be prevented + // and instead the app will continue to display in the current browser. + // disableDeepLinking: false + + // A property to disable the right click context menu for localVideo + // the menu has option to flip the locally seen video for local presentations + // disableLocalVideoFlip: false + + // List of undocumented settings used in jitsi-meet + /** + _immediateReloadThreshold + autoRecord + autoRecordToken + debug + debugAudioLevels + deploymentInfo + dialInConfCodeUrl + dialInNumbersUrl + dialOutAuthUrl + dialOutCodesUrl + disableRemoteControl + displayJids + etherpad_base + externalConnectUrl + firefox_fake_device + googleApiApplicationClientID + iAmRecorder + iAmSipGateway + microsoftApiApplicationClientID + peopleSearchQueryTypes + peopleSearchUrl + requireDisplayName + tokenAuthUrl + */ + + // List of undocumented settings used in lib-jitsi-meet + /** + _peerConnStatusOutOfLastNTimeout + _peerConnStatusRtcMuteTimeout + abTesting + avgRtpStatsN + callStatsConfIDNamespace + callStatsCustomScriptUrl + desktopSharingSources + disableAEC + disableAGC + disableAP + disableHPF + disableNS + enableLipSync + enableTalkWhileMuted + forceJVB121Ratio + hiddenDomain + ignoreStartMuted + nick + startBitrate + */ + +}; + +/* eslint-enable no-unused-vars, no-var */ diff --git a/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/.env b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/.env new file mode 100644 index 0000000000..86f00e5372 --- /dev/null +++ b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/.env @@ -0,0 +1,295 @@ +# Based on https://github.com/jitsi/docker-jitsi-meet/blob/df404476160526d8512fb23b606965b98f7f25f3/env.example +# Licensed under the ASL v2. + +# Customized for OpenDev: + +# Directory where all configuration will be stored. +CONFIG=/var/jitsi-meet + +# System time zone. +TZ=Etc/UTC + +# Public URL for the web service. +PUBLIC_URL="https://meetpad.opendev.org" + +# Set etherpad-lite URL (uncomment to enable). +ETHERPAD_URL_BASE=https://etherpad.openstack.org/p/ + +# +# Basic configuration options +# + +# IP address of the Docker host. See the "Running on a LAN environment" section +# in the README. +#DOCKER_HOST_ADDRESS=192.168.1.1 + +# +# Let's Encrypt configuration +# + +# Enable Let's Encrypt certificate generation. +#ENABLE_LETSENCRYPT=1 + +# Domain for which to generate the certificate. +#LETSENCRYPT_DOMAIN=meet.example.com + +# E-Mail for receiving important account notifications (mandatory). +#LETSENCRYPT_EMAIL=alice@atlanta.net + + +# +# Basic Jigasi configuration options (needed for SIP gateway support) +# + +# SIP URI for incoming / outgoing calls. +#JIGASI_SIP_URI=test@sip2sip.info + +# Password for the specified SIP account as a clear text +#JIGASI_SIP_PASSWORD=passw0rd + +# SIP server (use the SIP account domain if in doubt). +#JIGASI_SIP_SERVER=sip2sip.info + +# SIP server port +#JIGASI_SIP_PORT=5060 + +# SIP server transport +#JIGASI_SIP_TRANSPORT=UDP + +# +# Authentication configuration (see README for details) +# + +# Enable authentication. +#ENABLE_AUTH=1 + +# Enable guest access. +#ENABLE_GUESTS=1 + +# Select authentication type: internal, jwt or ldap +#AUTH_TYPE=internal + +# JWT auuthentication +# + +# Application identifier. +#JWT_APP_ID=my_jitsi_app_id + +# Application secret known only to your token. +#JWT_APP_SECRET=my_jitsi_app_secret + +# (Optional) Set asap_accepted_issuers as a comma separated list. +#JWT_ACCEPTED_ISSUERS=my_web_client,my_app_client + +# (Optional) Set asap_accepted_audiences as a comma separated list. +#JWT_ACCEPTED_AUDIENCES=my_server1,my_server2 + + +# LDAP authentication (for more information see the Cyrus SASL saslauthd.conf man page) +# + +# LDAP url for connection. +#LDAP_URL=ldaps://ldap.domain.com/ + +# LDAP base DN. Can be empty +#LDAP_BASE=DC=example,DC=domain,DC=com + +# LDAP user DN. Do not specify this parameter for the anonymous bind. +#LDAP_BINDDN=CN=binduser,OU=users,DC=example,DC=domain,DC=com + +# LDAP user password. Do not specify this parameter for the anonymous bind. +#LDAP_BINDPW=LdapUserPassw0rd + +# LDAP filter. Tokens example: +# %1-9 - if the input key is user@mail.domain.com, then %1 is com, %2 is domain and %3 is mail. +# %s - %s is replaced by the complete service string. +# %r - %r is replaced by the complete realm string. +#LDAP_FILTER=(sAMAccountName=%u) + +# LDAP authentication method +#LDAP_AUTH_METHOD=bind + +# LDAP version +#LDAP_VERSION=3 + +# LDAP TLS using +#LDAP_USE_TLS=1 + +# List of SSL/TLS ciphers to allow. +#LDAP_TLS_CIPHERS=SECURE256:SECURE128:!AES-128-CBC:!ARCFOUR-128:!CAMELLIA-128-CBC:!3DES-CBC:!CAMELLIA-128-CBC + +# Require and verify server certificate +#LDAP_TLS_CHECK_PEER=1 + +# Path to CA cert file. Used when server sertificate verify is enabled. +#LDAP_TLS_CACERT_FILE=/etc/ssl/certs/ca-certificates.crt + +# Path to CA certs directory. Used when server sertificate verify is enabled. +#LDAP_TLS_CACERT_DIR=/etc/ssl/certs + +# Wether to use starttls, implies LDAPv3 and requires ldap:// instead of ldaps:// +# LDAP_START_TLS=1 + + +# +# Advanced configuration options (you generally don't need to change these) +# + +# Internal XMPP domain. +XMPP_DOMAIN=localhost + +# Internal XMPP server +XMPP_SERVER=localhost + +# Internal XMPP server URL +XMPP_BOSH_URL_BASE=http://localhost:5280 + +# Internal XMPP domain for authenticated services. +XMPP_AUTH_DOMAIN=auth.localhost + +# XMPP domain for the MUC. +XMPP_MUC_DOMAIN=muc.localhost + +# XMPP domain for the internal MUC used for jibri, jigasi and jvb pools. +XMPP_INTERNAL_MUC_DOMAIN=internal-muc.localhost + +# XMPP domain for unauthenticated users. +XMPP_GUEST_DOMAIN=guest.localhost + +# Custom Prosody modules for XMPP_DOMAIN (comma separated) +XMPP_MODULES= + +# Custom Prosody modules for MUC component (comma separated) +XMPP_MUC_MODULES= + +# Custom Prosody modules for internal MUC component (comma separated) +XMPP_INTERNAL_MUC_MODULES= + +# MUC for the JVB pool. +JVB_BREWERY_MUC=jvbbrewery + +# XMPP user for JVB client connections. +JVB_AUTH_USER=jvb + +# XMPP password for JVB client connections. +JVB_AUTH_PASSWORD=passw0rd + +# STUN servers used to discover the server's public IP. +JVB_STUN_SERVERS=stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302 + +# Media port for the Jitsi Videobridge +JVB_PORT=10000 + +# TCP Fallback for Jitsi Videobridge for when UDP isn't available +JVB_TCP_HARVESTER_DISABLED=true +JVB_TCP_PORT=4443 + +# A comma separated list of APIs to enable when the JVB is started. The default is none. +# See https://github.com/jitsi/jitsi-videobridge/blob/master/doc/rest.md for more information +#JVB_ENABLE_APIS=rest,colibri + +# XMPP component password for Jicofo. +JICOFO_COMPONENT_SECRET=s3cr37 + +# XMPP user for Jicofo client connections. NOTE: this option doesn't currently work due to a bug. +JICOFO_AUTH_USER=focus + +# XMPP password for Jicofo client connections. +JICOFO_AUTH_PASSWORD=passw0rd + +# Base URL of Jicofo's reservation REST API +#JICOFO_RESERVATION_REST_BASE_URL=http://reservation.example.com + +# XMPP user for Jigasi MUC client connections. +JIGASI_XMPP_USER=jigasi + +# XMPP password for Jigasi MUC client connections. +JIGASI_XMPP_PASSWORD=passw0rd + +# MUC name for the Jigasi pool. +JIGASI_BREWERY_MUC=jigasibrewery + +# Minimum port for media used by Jigasi. +JIGASI_PORT_MIN=20000 + +# Maximum port for media used by Jigasi. +JIGASI_PORT_MAX=20050 + +# Enable SDES srtp +#JIGASI_ENABLE_SDES_SRTP=1 + +# Keepalive method +#JIGASI_SIP_KEEP_ALIVE_METHOD=OPTIONS + +# Health-check extension +#JIGASI_HEALTH_CHECK_SIP_URI=keepalive + +# Health-check interval +#JIGASI_HEALTH_CHECK_INTERVAL=300000 +# +# Enable Jigasi transcription. +#ENABLE_TRANSCRIPTIONS=1 + +# Jigasi will recordord an audio when transcriber is on. Default false. +#JIGASI_TRANSCRIBER_RECORD_AUDIO=true + +# Jigasi will send transcribed text to the chat when transcriber is on. Default false. +#JIGASI_TRANSCRIBER_SEND_TXT=true + +# Jigasi post to the chat an url with transcription file. Default false. +#JIGASI_TRANSCRIBER_ADVERTISE_URL=true + +# Credentials for connect to Cloud Google API from Jigasi. Path located inside the container. +# Please read https://cloud.google.com/text-to-speech/docs/quickstart-protocol +# section "Before you begin" from 1 to 5 paragraph. Copy the key on +# the docker host to ${CONFIG}/jigasi/key.json and to enable this setting: +#GOOGLE_APPLICATION_CREDENTIALS=/config/key.json + +# Enable recording +#ENABLE_RECORDING=1 + +# XMPP domain for the jibri recorder +XMPP_RECORDER_DOMAIN=recorder.localhost + +# XMPP recorder user for Jibri client connections. +JIBRI_RECORDER_USER=recorder + +# XMPP recorder password for Jibri client connections. +JIBRI_RECORDER_PASSWORD=passw0rd + +# Directory for recordings inside Jibri container. +JIBRI_RECORDING_DIR=/config/recordings + +# The finalizing script. Will run after recording is complete. +JIBRI_FINALIZE_RECORDING_SCRIPT_PATH=/config/finalize.sh + +# XMPP user for Jibri client connections. +JIBRI_XMPP_USER=jibri + +# XMPP password for Jibri client connections. +JIBRI_XMPP_PASSWORD=passw0rd + +# MUC name for the Jibri pool. +JIBRI_BREWERY_MUC=jibribrewery + +# MUC connection timeout +JIBRI_PENDING_TIMEOUT=90 + +# When jibri gets a request to start a service for a room, the room +# jid will look like: roomName@optional.prefixes.subdomain.xmpp_domain +# We'll build the url for the call by transforming that into: +# https://xmpp_domain/subdomain/roomName +# So if there are any prefixes in the jid (like jitsi meet, which +# has its participants join a muc at conference.xmpp_domain) then +# list that prefix here so it can be stripped out to generate +# the call url correctly. +JIBRI_STRIP_DOMAIN_JID=muc + +# Directory for logs inside Jibri container. +JIBRI_LOGS_DIR=/config/logs + +# Disable HTTPS. This can be useful if TLS connections are going to be handled outside of this setup. +#DISABLE_HTTPS=1 + +# Redirects HTTP traffic to HTTPS. Only works with the standard HTTPS port (443). +#ENABLE_HTTP_REDIRECT=1 diff --git a/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/docker-compose.yaml b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/docker-compose.yaml new file mode 100644 index 0000000000..f2cdc32358 --- /dev/null +++ b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/docker-compose.yaml @@ -0,0 +1,143 @@ +# Based on https://github.com/jitsi/docker-jitsi-meet/blob/df404476160526d8512fb23b606965b98f7f25f3/docker-compose.yml +# Licensed under the ASL v2. + +version: '2' + +services: + # Frontend + web: + image: docker.io/jitsi/web + network_mode: host + volumes: + - ${CONFIG}/web:/config + - ${CONFIG}/web/letsencrypt:/etc/letsencrypt + - ${CONFIG}/transcripts:/usr/share/jitsi-meet/transcripts + environment: + - ENABLE_AUTH + - ENABLE_GUESTS + - ENABLE_LETSENCRYPT + - ENABLE_HTTP_REDIRECT + - ENABLE_TRANSCRIPTIONS + - DISABLE_HTTPS + - JICOFO_AUTH_USER + - LETSENCRYPT_DOMAIN + - LETSENCRYPT_EMAIL + - PUBLIC_URL + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_BOSH_URL_BASE + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_RECORDER_DOMAIN + - ETHERPAD_URL_BASE + - TZ + - JIBRI_BREWERY_MUC + - JIBRI_PENDING_TIMEOUT + - JIBRI_XMPP_USER + - JIBRI_XMPP_PASSWORD + - JIBRI_RECORDER_USER + - JIBRI_RECORDER_PASSWORD + - ENABLE_RECORDING + + # XMPP server + prosody: + image: docker.io/jitsi/prosody + network_mode: host + volumes: + - ${CONFIG}/prosody:/config + environment: + - AUTH_TYPE + - ENABLE_AUTH + - ENABLE_GUESTS + - GLOBAL_MODULES + - GLOBAL_CONFIG + - LDAP_URL + - LDAP_BASE + - LDAP_BINDDN + - LDAP_BINDPW + - LDAP_FILTER + - LDAP_AUTH_METHOD + - LDAP_VERSION + - LDAP_USE_TLS + - LDAP_TLS_CIPHERS + - LDAP_TLS_CHECK_PEER + - LDAP_TLS_CACERT_FILE + - LDAP_TLS_CACERT_DIR + - LDAP_START_TLS + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_MODULES + - XMPP_MUC_MODULES + - XMPP_INTERNAL_MUC_MODULES + - XMPP_RECORDER_DOMAIN + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JIGASI_XMPP_USER + - JIGASI_XMPP_PASSWORD + - JIBRI_XMPP_USER + - JIBRI_XMPP_PASSWORD + - JIBRI_RECORDER_USER + - JIBRI_RECORDER_PASSWORD + - JWT_APP_ID + - JWT_APP_SECRET + - JWT_ACCEPTED_ISSUERS + - JWT_ACCEPTED_AUDIENCES + - JWT_ASAP_KEYSERVER + - JWT_ALLOW_EMPTY + - JWT_AUTH_TYPE + - JWT_TOKEN_AUTH_MODULE + - LOG_LEVEL + - TZ + + # Focus component + jicofo: + image: docker.io/jitsi/jicofo + network_mode: host + volumes: + - ${CONFIG}/jicofo:/config + environment: + - ENABLE_AUTH + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_SERVER + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JICOFO_RESERVATION_REST_BASE_URL + - JVB_BREWERY_MUC + - JIGASI_BREWERY_MUC + - JIBRI_BREWERY_MUC + - JIBRI_PENDING_TIMEOUT + - TZ + depends_on: + - prosody + + # Video bridge + jvb: + image: docker.io/jitsi/jvb + network_mode: host + volumes: + - ${CONFIG}/jvb:/config + environment: + - DOCKER_HOST_ADDRESS + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_SERVER + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JVB_BREWERY_MUC + - JVB_PORT + - JVB_TCP_HARVESTER_DISABLED + - JVB_TCP_PORT + - JVB_STUN_SERVERS + - JVB_ENABLE_APIS + - TZ + depends_on: + - prosody diff --git a/playbooks/roles/jitsi-meet/tasks/main.yaml b/playbooks/roles/jitsi-meet/tasks/main.yaml new file mode 100644 index 0000000000..29416a2a0e --- /dev/null +++ b/playbooks/roles/jitsi-meet/tasks/main.yaml @@ -0,0 +1,30 @@ +- name: Synchronize docker-compose directory + synchronize: + src: jitsi-meet-docker/ + dest: /etc/jitsi-meet-docker/ +- name: Ensure jitsi-meet volume directories exist + file: + state: directory + path: "/var/jitsi-meet/{{ item }}" + loop: + - web +- name: Write web config + copy: + src: config.js + dest: /var/jitsi-meet/web/config.js +- name: Install docker-compose + package: + name: + - docker-compose + state: present +- name: Run docker-compose pull + shell: + cmd: docker-compose pull + chdir: /etc/jitsi-meet-docker/ +- name: Run docker-compose up + shell: + cmd: docker-compose up -d + chdir: /etc/jitsi-meet-docker/ +- name: Run docker prune to cleanup unneeded images + shell: + cmd: docker image prune -f diff --git a/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml b/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml index a5c7b522db..c84e847705 100644 --- a/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml +++ b/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml @@ -34,6 +34,9 @@ - name: letsencrypt updated insecure-ci-registry01-main include_tasks: roles/letsencrypt-create-certs/handlers/restart_zuul_registry.yaml +- name: letsencrypt updated meetpad01-main + include_tasks: roles/letsencrypt-create-certs/handlers/restart_jitsi_meet.yaml + # Static - name: letsencrypt updated static01-opendev-org-main include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml diff --git a/playbooks/roles/letsencrypt-create-certs/handlers/restart_jitsi_meet.yaml b/playbooks/roles/letsencrypt-create-certs/handlers/restart_jitsi_meet.yaml new file mode 100644 index 0000000000..04f260e641 --- /dev/null +++ b/playbooks/roles/letsencrypt-create-certs/handlers/restart_jitsi_meet.yaml @@ -0,0 +1,37 @@ +- name: Ensure cert directory exists + file: + state: directory + path: /var/jitsi-meet/web/keys + owner: root + group: root + +- name: Put key in place + copy: + remote_src: yes + src: /etc/letsencrypt-certs/{{ inventory_hostname }}/{{ inventory_hostname }}.key + dest: /var/jitsi-meet/web/keys/cert.key + owner: root + group: root + mode: '0644' + +- name: Put cert in place + copy: + remote_src: yes + src: /etc/letsencrypt-certs/{{ inventory_hostname }}/fullchain.cer + dest: /var/jitsi-meet/web/keys/cert.crt + owner: root + group: root + mode: '0644' + +- name: Check for running nginx + command: pgrep -f nginx + ignore_errors: yes + register: nginx_pids + +- name: Restart nginx if running + when: nginx_pids.rc == 0 + block: + - name: Restart nginx + shell: + cmd: docker-compose restart web + chdir: /etc/jitsi-meet-docker/ diff --git a/playbooks/service-meetpad.yaml b/playbooks/service-meetpad.yaml new file mode 100644 index 0000000000..e98e801669 --- /dev/null +++ b/playbooks/service-meetpad.yaml @@ -0,0 +1,5 @@ +- hosts: "meetpad:!disabled" + name: "Configure meetpad" + roles: + - install-docker + - jitsi-meet diff --git a/run_all.sh b/run_all.sh index bfd12404de..9e726efd80 100755 --- a/run_all.sh +++ b/run_all.sh @@ -109,6 +109,10 @@ start_timer timeout -k 2m 30m ansible-playbook -f 50 ${ANSIBLE_PLAYBOOKS}/service-nodepool.yaml send_timer nodepool +start_timer +timeout -k 2m 30m ansible-playbook -f 50 ${ANSIBLE_PLAYBOOKS}/service-meetpad.yaml +send_timer meetpad + start_timer timeout -k 2m 30m ansible-playbook -f 50 ${ANSIBLE_PLAYBOOKS}/service-mirror-update.yaml send_timer mirror-update diff --git a/testinfra/test_meetpad.py b/testinfra/test_meetpad.py new file mode 100644 index 0000000000..d95636ca9c --- /dev/null +++ b/testinfra/test_meetpad.py @@ -0,0 +1,21 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +testinfra_hosts = ['meetpad01.opendev.org'] + + +def test_jitsi_meet_listening(host): + registry = host.socket("tcp://0.0.0.0:443") + assert registry.is_listening