diff --git a/README.md b/README.md index 1cb8d1c..69d5202 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,10 @@ Jitsi Meet is a libre software (Apache) WebRTC JavaScript app that uses Jitsi Vi 2. **Jitsi** requires you create additionals domains in your DNS and in your YunoHost * auth.jitsi.domain.tld * conference.jitsi.domain.tld - * jitsi-videobridge.jitsi.domain.tld + * coturn.jitsi.domain.tld * focus.jitsi.domain.tld -3. **Jitsi** requires the ports TCP/4443 and UDP/10000 to be forwarded to your YunoHost (The same way you forwarded 80 (HTTP), 443 (HTTPS), etc... https://yunohost.org/#/isp_box_config) + * jitsi-videobridge.jitsi.domain.tld +3. **Jitsi** requires the ports TCP/5349 UDP/5349 TCP/5350 UDP/5350 TCP/4443 and UDP/10000 to be forwarded to your YunoHost (The same way you forwarded 80 (HTTP), 443 (HTTPS), etc... https://yunohost.org/#/isp_box_config) ## Screenshots diff --git a/conf/config.js b/conf/config.js index 349a852..c99d852 100644 --- a/conf/config.js +++ b/conf/config.js @@ -1,12 +1,530 @@ +/* eslint-disable no-unused-vars, no-var */ + var config = { + // Connection + // + hosts: { + // XMPP domain. domain: '__DOMAIN__', + + // When using authentication, domain for guest users. + // anonymousdomain: 'guest.example.com', + + // Domain for authenticated users. Defaults to . + // authdomain: 'jitsi-meet.example.com', + + // Jirecon recording component domain. + // jirecon: 'jirecon.jitsi-meet.example.com', + + // Call control component (Jigasi). + // call_control: 'callcontrol.jitsi-meet.example.com', + + // Focus component domain. Defaults to focus.. + focus: 'focus.__DOMAIN__', + + // XMPP MUC domain. FIXME: use XEP-0030 to discover it. muc: 'conference.__DOMAIN__', - bridge: 'jitsi-videobridge.__DOMAIN__', - focus: 'focus.__DOMAIN__' + + bridge: 'jitsi-videobridge.__DOMAIN__' }, + + // BOSH URL. FIXME: use XEP-0156 to discover it. + bosh: '//__DOMAIN__/http-bind', + + // Websocket URL + websocket: 'wss://__DOMAIN__/xmpp-websocket', + + // 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.jitsi-meet.example.com', + + + // 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 the auto-play behavior of *all* newly created video element. + // This is useful when the client runs on a host with limited resources. + // noAutoPlayVideo: 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, + // audioLevelsInterval: 200, + + // 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, + + // 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, + + // 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, + + // 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://jitsi-meet.example.com/static/oauth.html' + // redirectURI: + // 'https://jitsi-meet.example.com/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, + + // Enables automatic turning on captions when recording is started + // autoCaptionOnRecord: 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, - bosh: '//__DOMAIN__/http-bind', // FIXME: use xep-0156 for that - //chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension - //minChromeExtVersion: '0.1' // Required version of Chrome extension -}; \ No newline at end of file + + // 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, + + // Enabling the close page will ignore the welcome page redirection when + // a call is hangup. + // enableClosePage: false, + + // Enabling pre join page will add an additional step before starting the meeting, + // where the user can configure its devices and choose the way he + // joins audio (by phone/or web). + // prejoinPageEnabled: 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, + + // The interval at which PeerConnection.getStats() is called. Defaults to 10000 + // pcStatsInterval: 10000, + + // To enable sending statistics to callstats.io you must provide the + // Application ID and Secret. + // callStatsID: '', + // callStatsSecret: '', + + // enables sending participants display name to callstats + // enableDisplayNameInStats: false, + + // enables sending participants email if available to callstats and other analytics + // enableEmailInStats: 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: true, + + // 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:coturn.__DOMAIN__:__PORT_COTURN_TLS__' }, + { urls: 'stun:coturn.__DOMAIN__:__PORT_COTURN_ALT_TLS__' } + // { 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" + }, + + // Information for the chrome extension banner + // chromeExtensionBanner: { + // // The chrome extension to be installed address + // url: 'https://chrome.google.com/webstore/detail/jitsi-meetings/kglhbbefdnlheedjiejgomgmfplipfeb', + + // // Extensions info which allows checking if they are installed or not + // chromeExtensionsInfo: [ + // { + // id: 'kglhbbefdnlheedjiejgomgmfplipfeb', + // path: 'jitsi-logo-48x48.png' + // } + // ] + // }, + + // 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, + + // Deployment specific URLs. + // deploymentUrls: { + // // If specified a 'Help' button will be displayed in the overflow menu with a link to the specified URL for + // // user documentation. + // userDocumentationURL: 'https://docs.example.com/video-meetings.html', + // // If specified a 'Download our apps' button will be displayed in the overflow menu with a link + // // to the specified URL for an app download page. + // downloadAppsUrl: 'https://docs.example.com/our-apps.html' + // }, + + // 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 + */ + + + // Allow all above example options to include a trailing comma and + // prevent fear when commenting out the last value. + makeJsonParserHappy: 'even if last key had a trailing comma' + + // no configuration value should follow this line. +}; + +/* eslint-enable no-unused-vars, no-var */ diff --git a/conf/coturn.conf b/conf/coturn.conf new file mode 100644 index 0000000..a1d6dc2 --- /dev/null +++ b/conf/coturn.conf @@ -0,0 +1,13 @@ +# jitsi-meet coturn config. Do not modify this line +lt-cred-mech +use-auth-secret +static-auth-secret=__COTURN_PWD__ +realm=__DOMAIN__ +cert=/etc/yunohost/certs/__DOMAIN__/crt.pem +pkey=/etc/yunohost/certs/__DOMAIN__/key.pem + +no-tcp +tls-listening-port=__PORT_COTURN_TLS__ +alt-tls-listening-port=__PORT_COTURN_ALT_TLS__ +external-ip=__PUBLIC_IPV4____PRIVATE_IPV4__ +external-ip=__PUBLIC_IPV6__ diff --git a/conf/default_coturn b/conf/default_coturn new file mode 100644 index 0000000..fc87269 --- /dev/null +++ b/conf/default_coturn @@ -0,0 +1,5 @@ +# +# Uncomment it if you want to have the turnserver running as +# an automatic system service daemon +# +TURNSERVER_ENABLED=1 diff --git a/conf/jitsi-coturn.service b/conf/jitsi-coturn.service new file mode 100644 index 0000000..781a45c --- /dev/null +++ b/conf/jitsi-coturn.service @@ -0,0 +1,17 @@ +[Unit] +Description=coturn +Documentation=man:coturn(1) man:turnadmin(1) man:turnserver(1) +After=syslog.target network.target + +[Service] +User=turnserver +Group=turnserver +Type=forking +RuntimeDirectory=__APP__-coturn +ExecStart=/usr/bin/turnserver -o -c __FINALPATH__/coturn.conf +ExecStartPost=/bin/sleep 2 +Restart=on-failure +PrivateTmp=yes + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/conf/jitsi-jicofo.service b/conf/jitsi-jicofo.service index 8c2d59a..4198746 100644 --- a/conf/jitsi-jicofo.service +++ b/conf/jitsi-jicofo.service @@ -7,7 +7,7 @@ Type=simple User=__APP__ Group=__APP__ WorkingDirectory=__FINALPATH__/jitsi-jicofo/ -ExecStart=__FINALPATH__/jitsi-jicofo/jicofo.sh --host=localhost --domain=__DOMAIN__ --secret=__FOCUS_SECRET__ --user_domain=auth.__DOMAIN__ --user_name=__FOCUS_USER__ --user_password=__FOCUS_PASSWORD__ & >> /var/log/__APP__/__APP__-jitsi-jicofo.log 2>&1 +ExecStart=__FINALPATH__/jitsi-jicofo/jicofo.sh --host=localhost --domain=__DOMAIN__ --secret=__FOCUS_SECRET__ --user_domain=auth.__DOMAIN__ --user_name=__FOCUS_USER__ --user_password=__FOCUS_PASSWORD__ [Install] WantedBy=multi-user.target diff --git a/conf/jitsi-jicofo.src b/conf/jitsi-jicofo.src index 0f55222..372a01c 100644 --- a/conf/jitsi-jicofo.src +++ b/conf/jitsi-jicofo.src @@ -1,5 +1,5 @@ -SOURCE_URL=https://github.com/jitsi/jicofo/archive/517.tar.gz -SOURCE_SUM=5239a8a4c8519a9362cabf151a1bb34138ba5083d652bc2c44a397484d6ffe08 +SOURCE_URL=https://github.com/jitsi/jicofo/archive/539.tar.gz +SOURCE_SUM=117b15b871118186512a15c1ca3f42615db680d7155a1876f2ef3a7028cb4616 SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=tar.gz SOURCE_IN_SUBDIR=true diff --git a/conf/jitsi-videobridge.service b/conf/jitsi-videobridge.service index 07bbd1d..a6a3149 100644 --- a/conf/jitsi-videobridge.service +++ b/conf/jitsi-videobridge.service @@ -7,7 +7,7 @@ Type=simple User=__APP__ Group=__APP__ WorkingDirectory=__FINALPATH__/jitsi-videobridge/ -ExecStart=__FINALPATH__/jitsi-videobridge/jvb.sh --host=127.0.0.1 --domain=__DOMAIN__ --port=__PORT_COMPONENT__ --secret=__VIDEOBRIDGE_SECRET__ > /var/log/jvb.log 2>&1 +ExecStart=__FINALPATH__/jitsi-videobridge/jvb.sh --host=127.0.0.1 --domain=__DOMAIN__ --port=__PORT_COMPONENT__ --secret=__VIDEOBRIDGE_SECRET__ [Install] WantedBy=multi-user.target diff --git a/conf/jitsi-videobridge.src b/conf/jitsi-videobridge.src index 32d85cd..eb6c434 100644 --- a/conf/jitsi-videobridge.src +++ b/conf/jitsi-videobridge.src @@ -1,5 +1,5 @@ -SOURCE_URL=https://download.jitsi.org/jitsi-videobridge/linux/jitsi-videobridge-linux-x64-1130.zip -SOURCE_SUM=792db05e61e36d8811e7b132581b95b1022a8bf5689189e6206bc05888b54ec4 +SOURCE_URL=https://download.jitsi.org/jitsi-videobridge/linux/jitsi-videobridge-linux-x64-1132.zip +SOURCE_SUM=2157d3872747ddae2360f47588327dbd4ed48e93a5b7f21cfccdd67341516077 SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=zip SOURCE_IN_SUBDIR=true diff --git a/conf/metronome.cfg.lua b/conf/metronome.cfg.lua index cbb3291..fa41ef3 100644 --- a/conf/metronome.cfg.lua +++ b/conf/metronome.cfg.lua @@ -83,6 +83,7 @@ modules_enabled = { "adhoc"; "websocket"; "http_altconnect"; + "turncredentials"; } -- These modules are auto-loaded, but should you want @@ -178,7 +179,10 @@ VirtualHost "__DOMAIN__" key = "/etc/yunohost/certs/__DOMAIN__/key.pem"; certificate = "/etc/yunohost/certs/__DOMAIN__/crt.pem"; } - + modules_enabled = { + "bosh"; + "pubsub"; + } c2s_require_encryption = false VirtualHost "auth.__DOMAIN__" @@ -223,3 +227,11 @@ Component "jitsi-videobridge.__DOMAIN__" component_secret = "__VIDEOBRIDGE_SECRET__" Component "focus.__DOMAIN__" component_secret = "__FOCUS_SECRET__" + +------ COTURN configuration ------ +turncredentials_secret = "__CORTURN_PWD__"; +turncredentials = { + { type = "turns", host = "coturn.__DOMAIN__", port = "__PORT_COTURN_TLS__", transport = "tcp" }, + { type = "turns", host = "coturn.__DOMAIN__", port = "__PORT_COTURN_ALT_TLS__", transport = "tcp" } +}; + diff --git a/conf/mod_turncredentials.lua b/conf/mod_turncredentials.lua new file mode 100644 index 0000000..98fdaa0 --- /dev/null +++ b/conf/mod_turncredentials.lua @@ -0,0 +1,76 @@ +-- XEP-0215 implementation for time-limited turn credentials +-- Copyright (C) 2012-2014 Philipp Hancke +-- This file is MIT/X11 licensed. + +--turncredentials_secret = "keepthissecret"; +--turncredentials = { +-- { type = "stun", host = "8.8.8.8" }, +-- { type = "turn", host = "8.8.8.8", port = 3478 }, +-- { type = "turn", host = "8.8.8.8", port = 80, transport = "tcp" } +--} +-- for stun servers, host is required, port defaults to 3478 +-- for turn servers, host is required, port defaults to tcp, +-- transport defaults to udp +-- hosts can be a list of server names / ips for random +-- choice loadbalancing + +local st = require "util.stanza"; +local hmac_sha1 = require "util.hashes".hmac_sha1; +local base64 = require "util.encodings".base64; +local os_time = os.time; +local secret = module:get_option_string("turncredentials_secret"); +local ttl = module:get_option_number("turncredentials_ttl", 86400); +local hosts = module:get_option("turncredentials") or {}; +if not (secret) then + module:log("error", "turncredentials not configured"); + return; +end + +function random(arr) + local index = math.random(1, #arr); + return arr[index]; +end + + +module:hook_global("config-reloaded", function() + module:log("debug", "config-reloaded") + secret = module:get_option_string("turncredentials_secret"); + ttl = module:get_option_number("turncredentials_ttl", 86400); + hosts = module:get_option("turncredentials") or {}; +end); + +module:hook("iq-get/host/urn:xmpp:extdisco:1:services", function(event) + local origin, stanza = event.origin, event.stanza; + if origin.type ~= "c2s" then + return; + end + local now = os_time() + ttl; + local userpart = tostring(now); + local nonce = base64.encode(hmac_sha1(secret, tostring(userpart), false)); + local reply = st.reply(stanza):tag("services", {xmlns = "urn:xmpp:extdisco:1"}) + for idx, item in pairs(hosts) do + if item.type == "stun" or item.type == "stuns" then + -- stun items need host and port (defaults to 3478) + reply:tag("service", item):up(); + elseif item.type == "turn" or item.type == "turns" then + local turn = {} + -- turn items need host, port (defaults to 3478), + -- transport (defaults to udp) + -- username, password, ttl + turn.type = item.type; + turn.port = item.port; + turn.transport = item.transport; + turn.username = userpart; + turn.password = nonce; + turn.ttl = ttl; + if item.hosts then + turn.host = random(item.hosts) + else + turn.host = item.host + end + reply:tag("service", turn):up(); + end + end + origin.send(reply); + return true; +end); diff --git a/conf/nginx.conf b/conf/nginx.conf index 35c4a49..e33206f 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -38,3 +38,10 @@ location __PATH__/xmpp-websocket { proxy_set_header Host $host; tcp_nodelay on; } + +# external_api.js must be accessible from the root of the +# installation for the electron version of Jitsi Meet to work +# https://github.com/jitsi/jitsi-meet-electron +location /external_api.js { + alias __FINALPATH__/jitsi-meet/libs/external_api.min.js; +} diff --git a/conf/sip-communicator.properties b/conf/sip-communicator.properties index 24cf4ef..49a7107 100644 --- a/conf/sip-communicator.properties +++ b/conf/sip-communicator.properties @@ -1,2 +1,7 @@ org.jitsi.impl.neomedia.transform.srtp.SRTPCryptoContext.checkReplay=false +# The videobridge uses 443 by default with 4443 as a fallback, but since we're already +# running nginx on 443 in this example doc, we specify 4443 manually to avoid a race condition org.jitsi.videobridge.TCP_HARVESTER_PORT=__PORT__ +org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=__PRIVATE_IPV4__ +org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=__PUBLIC_IPV4__ + diff --git a/scripts/_common.sh b/scripts/_common.sh index 48cf5d6..ef2cef3 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -5,7 +5,7 @@ #================================================= # dependencies used by the app -pkg_dependencies="openjdk-8-jdk|openjdk-11-jdk openjdk-8-jre|openjdk-11-jre maven" +pkg_dependencies="openjdk-8-jdk|openjdk-11-jdk openjdk-8-jre|openjdk-11-jre maven coturn" #================================================= # PERSONAL HELPERS diff --git a/scripts/backup b/scripts/backup index 032aea5..64062e8 100644 --- a/scripts/backup +++ b/scripts/backup @@ -38,8 +38,9 @@ domain=$(ynh_app_setting_get --app=$app --key=domain) #================================================= ynh_print_info --message="Stopping a systemd service..." -ynh_systemd_action --service_name=$app-videobridge --action="stop" --log_path="/var/log/$app/$app-videobridge.log" -ynh_systemd_action --service_name=$app-jicofo --action="stop" --log_path="/var/log/$app/$app-jicofo.log" +ynh_systemd_action --service_name=$app-videobridge --action="stop" --log_path="systemd" --line_match="Stopped $app-videobridge" +ynh_systemd_action --service_name=$app-jicofo --action="stop" --log_path="systemd" --line_match="Stopped $app-jicofo" +ynh_systemd_action --service_name=$app-coturn --action="stop" --log_path="systemd" --line_match="Stopped coturn" #================================================= # BACKUP THE APP MAIN DIR @@ -57,6 +58,13 @@ ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # SPECIFIC BACKUP +#================================================= +# BACKUP COTURN +#================================================= +ynh_print_info --message="Backing up coturn..." + +ynh_backup --src_path="/etc/default/$app-coturn" + #================================================= # BACKUP METRONOME #================================================= @@ -68,6 +76,8 @@ ynh_backup --src_path="/usr/share/yunohost/templates/jitsi/auth.$domain.cfg.lua" ynh_backup --src_path="/usr/share/yunohost/templates/jitsi/conference.$domain.cfg.lua" ynh_backup --src_path="/usr/share/yunohost/templates/jitsi/jitsi-videobridge.$domain.cfg.lua" ynh_backup --src_path="/usr/share/yunohost/templates/jitsi/focus.$domain.cfg.lua" +ynh_backup --src_path="/usr/share/yunohost/templates/jitsi/coturn.$domain.cfg.lua" + # Backup Metronome Hook ynh_backup --src_path="/usr/share/yunohost/hooks/conf_regen/50-metronome_$app" @@ -76,6 +86,7 @@ ynh_backup --src_path="/usr/share/yunohost/hooks/conf_regen/50-metronome_$app" ynh_backup --src_path="/usr/lib/metronome/modules/mod_carbons.lua" ynh_backup --src_path="/usr/lib/metronome/modules/mod_http_altconnect.lua" ynh_backup --src_path="/usr/lib/metronome/modules/mod_smacks.lua" +ynh_backup --src_path="/usr/lib/metronome/modules/mod_turncredentials.lua" #================================================= # SPECIFIC BACKUP @@ -93,14 +104,16 @@ ynh_print_info --message="Backing up systemd configuration..." ynh_backup --src_path="/etc/systemd/system/$app-videobridge.service" ynh_backup --src_path="/etc/systemd/system/$app-jicofo.service" +ynh_backup --src_path="/etc/systemd/system/$app-coturn.service" #================================================= # START SYSTEMD SERVICE #================================================= ynh_print_info --message="Starting a systemd service..." -ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="/var/log/$app/$app-videobridge.log" -ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="/var/log/$app/$app-jicofo.log" +ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="systemd" --line_match="Started $app-videobridge" +ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="systemd" --line_match="Started $app-jicofo" +ynh_systemd_action --service_name=$app-coturn --action="start" --log_path="systemd" --line_match="Started coturn" #================================================= # END OF SCRIPT diff --git a/scripts/install b/scripts/install index 1c9d80b..faa5388 100644 --- a/scripts/install +++ b/scripts/install @@ -39,6 +39,8 @@ focus_secret=$(ynh_string_random --length=8) focus_user="svc${app}focus" +coturn_pwd=$(ynh_string_random --length=30) + #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= @@ -61,6 +63,7 @@ ynh_app_setting_set --app=$app --key=focus_password --value=$focus_password ynh_app_setting_set --app=$app --key=videobridge_secret --value=$videobridge_secret ynh_app_setting_set --app=$app --key=focus_secret --value=$focus_secret ynh_app_setting_set --app=$app --key=focus_user --value=$focus_user +ynh_app_setting_set --app=$app --key=coturn_pwd --value=$coturn_pwd #================================================= # STANDARD MODIFICATIONS @@ -83,10 +86,20 @@ ynh_app_setting_set --app=$app --key=port_videobridge --value=$port_videobridge # Find an available port port_component=$(ynh_find_port --port=5347) -# Open this port -ynh_exec_warn_less yunohost firewall allow --no-upnp TCP $port_component ynh_app_setting_set --app=$app --key=port_component --value=$port_component +# Find an available port +port_coturn_tls=$(ynh_find_port --port=5349) +# Open this port +ynh_exec_warn_less yunohost firewall allow TCP $port_coturn_tls +ynh_app_setting_set --app=$app --key=port_coturn_tls --value=$port_coturn_tls + +# Find an available port +port_coturn_alt_tls=$(ynh_find_port --port=$((port_coturn_tls+1))) +# Open this port +ynh_exec_warn_less yunohost firewall allow TCP $port_coturn_alt_tls +ynh_app_setting_set --app=$app --key=port_coturn_alt_tls --value=$port_coturn_alt_tls + #================================================= # INSTALL DEPENDENCIES #================================================= @@ -125,6 +138,52 @@ ynh_system_user_create --username=$app --home_dir=$final_path #================================================= # SPECIFIC SETUP +#================================================= +# CONFIGURE COTURN +#================================================= +ynh_print_info --message="Configuring coturn..." + +cp ../conf/default_coturn /etc/default/$app-coturn + +coturn_config="$final_path/coturn.conf" + +cp ../conf/coturn.conf "$coturn_config" + +ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$coturn_config" +ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$coturn_config" +ynh_replace_string --match_string="__PORT_COTURN_TLS__" --replace_string="$port_coturn_tls" --target_file="$coturn_config" +ynh_replace_string --match_string="__PORT_COTURN_ALT_TLS__" --replace_string="$port_coturn_alt_tls" --target_file="$coturn_config" +ynh_replace_string --match_string="__COTURN_PWD__" --replace_string="$coturn_pwd" --target_file="$coturn_config" + +# Get public and private IP and set as external IP for coturn +# note : '|| true' is used to ignore the errors if we can't get the public ipv4 or ipv6 +public_ipv4="$(curl ip.yunohost.org)" || true +public_ip6="$(curl ipv6.yunohost.org)" || true +private_ipv4="$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')" || true + +if [ -n "$public_ipv4" ] && ynh_validate_ip4 --ip_address="$public_ipv4" +then + ynh_replace_string --match_string='__PUBLIC_IPV4__' --replace_string="$public_ipv4" --target_file="$coturn_config" +else + ynh_replace_string --match_string='__PUBLIC_IPV4__,' --replace_string="" --target_file="$coturn_config" +fi + +if [ -n "$public_ip6" ] && ynh_validate_ip6 --ip_address="$public_ip6" +then + ynh_replace_string --match_string='__PUBLIC_IPV6__' --replace_string="$public_ip6" --target_file="$coturn_config" +else + ynh_replace_string --match_string=',__PUBLIC_IPV6__' --replace_string="" --target_file="$coturn_config" +fi + +if [ -n "$private_ipv4" ] && ynh_validate_ip4 --ip_address="$private_ipv4" +then + ynh_replace_string --match_string='__PRIVATE_IPV4__' --replace_string="/$private_ipv4" --target_file="$coturn_config" +else + ynh_replace_string --match_string='__PRIVATE_IPV4__,' --replace_string="" --target_file="$coturn_config" +fi + +ynh_store_file_checksum --file="$coturn_config" + #================================================= # CONFIGURE METRONOME #================================================= @@ -137,6 +196,7 @@ if [ ${PACKAGE_CHECK_EXEC:-0} -eq 1 ]; then yunohost domain add conference.$domain yunohost domain add jitsi-videobridge.$domain yunohost domain add focus.$domain + yunohost domain add coturn.$domain fi # Create focus user @@ -151,11 +211,15 @@ ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_fil ynh_replace_string --match_string="__VIDEOBRIDGE_SECRET__" --replace_string="$videobridge_secret" --target_file="$metronome_conf" ynh_replace_string --match_string="__FOCUS_SECRET__" --replace_string="$focus_secret" --target_file="$metronome_conf" ynh_replace_string --match_string="__PORT_COMPONENT__" --replace_string="$port_component" --target_file="$metronome_conf" +ynh_replace_string --match_string="__CORTURN_PWD__" --replace_string="$coturn_pwd" --target_file="$metronome_conf" +ynh_replace_string --match_string="__PORT_COTURN_TLS__" --replace_string="$port_coturn_tls" --target_file="$metronome_conf" +ynh_replace_string --match_string="__PORT_COTURN_ALT_TLS__" --replace_string="$port_coturn_alt_tls" --target_file="$metronome_conf" touch "/usr/share/yunohost/templates/jitsi/auth.$domain.cfg.lua" touch "/usr/share/yunohost/templates/jitsi/conference.$domain.cfg.lua" touch "/usr/share/yunohost/templates/jitsi/jitsi-videobridge.$domain.cfg.lua" touch "/usr/share/yunohost/templates/jitsi/focus.$domain.cfg.lua" +touch "/usr/share/yunohost/templates/jitsi/coturn.$domain.cfg.lua" # Add Metronome hook cp -R ../conf/metronome_regen_conf.hook /usr/share/yunohost/hooks/conf_regen/50-metronome_$app @@ -165,6 +229,7 @@ yunohost tools regen-conf metronome cp ../conf/mod_carbons.lua /usr/lib/metronome/modules/mod_carbons.lua cp ../conf/mod_http_altconnect.lua /usr/lib/metronome/modules/mod_http_altconnect.lua cp ../conf/mod_smacks.lua /usr/lib/metronome/modules/mod_smacks.lua +cp ../conf/mod_turncredentials.lua /usr/lib/metronome/modules/mod_turncredentials.lua ynh_systemd_action --service_name=metronome --action=restart @@ -176,6 +241,8 @@ ynh_print_info --message="Building Jitsi-Videobridge..." mkdir -p "$final_path/.sip-communicator" cp ../conf/sip-communicator.properties "$final_path/.sip-communicator/sip-communicator.properties" ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$final_path/.sip-communicator/sip-communicator.properties" +ynh_replace_string --match_string="__PUBLIC_IPV4__" --replace_string="$public_ipv4" --target_file="$final_path/.sip-communicator/sip-communicator.properties" +ynh_replace_string --match_string="__PRIVATE_IPV4__" --replace_string="$private_ipv4" --target_file="$final_path/.sip-communicator/sip-communicator.properties" chown -R $app: $final_path #================================================= @@ -187,9 +254,9 @@ pushd "$final_path/jitsi-jicofo-build" mvn package -DskipTests -Dassembly.skipAssembly=false popd -unzip $final_path/jitsi-jicofo-build/target/jicofo-linux-x64-1.1-SNAPSHOT.zip -d $final_path +unzip $final_path/jitsi-jicofo-build/target/jicofo-1.1-SNAPSHOT-archive.zip -d $final_path -mv $final_path/jicofo-linux-x64-1.1-SNAPSHOT/ $final_path/jitsi-jicofo/ +mv $final_path/jicofo-1.1-SNAPSHOT/ $final_path/jitsi-jicofo/ ynh_secure_remove --file="$final_path/jitsi-jicofo-build" @@ -209,6 +276,8 @@ ynh_secure_remove --file="$final_path/jitsi-meet_temp" config="$final_path/jitsi-meet/config.js" cp ../conf/config.js "$config" ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$config" +ynh_replace_string --match_string="__PORT_COTURN_TLS__" --replace_string="$port_coturn_tls" --target_file="$config" +ynh_replace_string --match_string="__PORT_COTURN_ALT_TLS__" --replace_string="$port_coturn_alt_tls" --target_file="$config" #================================================= # SETUP SYSTEMD @@ -227,6 +296,8 @@ ynh_replace_string --match_string="__FOCUS_USER__" --replace_string="$focus_user ynh_replace_string --match_string="__FOCUS_PASSWORD__" --replace_string="$focus_password" --target_file="../conf/jitsi-jicofo.service" ynh_add_systemd_config --service=$app-jicofo --template="jitsi-jicofo.service" +ynh_add_systemd_config --service=$app-coturn --template="jitsi-coturn.service" + #================================================= # STORE THE CONFIG FILE CHECKSUM #================================================= @@ -258,8 +329,9 @@ ynh_use_logrotate #================================================= ynh_print_info --message="Integrating service in YunoHost..." -yunohost service add $app-videobridge --description "$app jitsi-videobridge for jitsi" --log "/var/log/$app/$app-videobridge.log" -yunohost service add $app-jicofo --description "$app jitsi-jicofo for jitsi" --log "/var/log/$app/$app-jicofo.log" +yunohost service add $app-videobridge --description "$app jitsi-videobridge for jitsi" --log_type "systemd" +yunohost service add $app-jicofo --description "$app jitsi-jicofo for jitsi" --log_type "systemd" +yunohost service add $app-coturn --description "$app jitsi-coturn for jitsi" --log_type "systemd" #================================================= # START SYSTEMD SERVICE @@ -267,8 +339,9 @@ yunohost service add $app-jicofo --description "$app jitsi-jicofo for jitsi" --l ynh_print_info --message="Starting a systemd service..." # Start a systemd service -ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="/var/log/$app/$app-videobridge.log" -ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="/var/log/$app/$app-jicofo.log" +ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="systemd" --line_match="Started $app-videobridge" +ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="systemd" --line_match="Started $app-jicofo" +ynh_systemd_action --service_name=$app-coturn --action="start" --log_path="systemd" --line_match="Started coturn" #================================================= # SETUP SSOWAT diff --git a/scripts/remove b/scripts/remove index 45dead7..fd7d8d7 100644 --- a/scripts/remove +++ b/scripts/remove @@ -43,6 +43,12 @@ then yunohost service remove $app-jicofo fi +if ynh_exec_warn_less yunohost service status $app-coturn >/dev/null +then + ynh_print_info --message="Removing $app-coturn service..." + yunohost service remove $app-coturn +fi + #================================================= # STOP AND REMOVE SERVICE #================================================= @@ -51,6 +57,7 @@ ynh_print_info --message="Stopping and removing the systemd service..." # Remove the dedicated systemd config ynh_remove_systemd_config --service=$app-videobridge ynh_remove_systemd_config --service=$app-jicofo +ynh_remove_systemd_config --service=$app-coturn #================================================= # REMOVE DEPENDENCIES @@ -111,6 +118,13 @@ fi #================================================= # SPECIFIC REMOVE +#================================================= +# REMOVE COTURN CONFIGURATION +#================================================= +ynh_print_info --message="Removing courn configuration..." + +ynh_secure_remove --file="/etc/default/$app-coturn" + #================================================= # RECONFIGURE METRONOME #================================================= @@ -120,6 +134,7 @@ ynh_print_info --message="Reconfiguring Metronome..." ynh_secure_remove --file="/usr/lib/metronome/modules/mod_carbons.lua" ynh_secure_remove --file="/usr/lib/metronome/modules/mod_http_altconnect.lua" ynh_secure_remove --file="/usr/lib/metronome/modules/mod_smacks.lua" +ynh_secure_remove --file="/usr/lib/metronome/modules/mod_turncredentials.lua" ynh_systemd_action --service_name=metronome --action=restart @@ -148,15 +163,9 @@ if [ ${PACKAGE_CHECK_EXEC:-0} -eq 1 ]; then yunohost domain remove conference.$domain yunohost domain remove jitsi-videobridge.$domain yunohost domain remove focus.$domain + yunohost domain remove coturn.$domain fi -#================================================= -# REMOVE THE LOG FILES -#================================================= - -# Remove the log files -ynh_secure_remove --file="/var/log/$app" - #================================================= # GENERIC FINALIZATION #================================================= diff --git a/scripts/restore b/scripts/restore index 8a1a456..387a197 100644 --- a/scripts/restore +++ b/scripts/restore @@ -38,6 +38,8 @@ focus_password=$(ynh_app_setting_get --app=$app --key=focus_password) port=$(ynh_app_setting_get --app=$app --key=port) port_videobridge=$(ynh_app_setting_get --app=$app --key=port_videobridge) port_component=$(ynh_app_setting_get --app=$app --key=port_component) +port_coturn_tls=$(ynh_app_setting_get --app=$app --key=port_coturn_tls) +port_coturn_alt_tls=$(ynh_app_setting_get --app=$app --key=port_coturn_alt_tls) #================================================= # CHECK IF THE APP CAN BE RESTORED @@ -101,7 +103,15 @@ ynh_print_info --message="Configuring firewall..." # Open this port ynh_exec_warn_less yunohost firewall allow --no-upnp TCP $port ynh_exec_warn_less yunohost firewall allow --no-upnp UDP $port_videobridge -ynh_exec_warn_less yunohost firewall allow --no-upnp TCP $port_component +ynh_exec_warn_less yunohost firewall allow --no-upnp TCP $port_coturn_tls +ynh_exec_warn_less yunohost firewall allow --no-upnp TCP $port_coturn_alt_tls + +#================================================= +# CONFIGURE COTURN +#================================================= +ynh_print_info --message="Configuring coturn..." + +ynh_restore_file --origin_path="/etc/default/$app-coturn" #================================================= # CONFIGURE METRONOME @@ -126,6 +136,7 @@ ynh_restore_file --origin_path="/usr/share/yunohost/templates/jitsi/auth.$domain ynh_restore_file --origin_path="/usr/share/yunohost/templates/jitsi/conference.$domain.cfg.lua" ynh_restore_file --origin_path="/usr/share/yunohost/templates/jitsi/jitsi-videobridge.$domain.cfg.lua" ynh_restore_file --origin_path="/usr/share/yunohost/templates/jitsi/focus.$domain.cfg.lua" +ynh_restore_file --origin_path="/usr/share/yunohost/templates/jitsi/coturn.$domain.cfg.lua" # Restore Metronome Hook ynh_restore_file --origin_path="/usr/share/yunohost/hooks/conf_regen/50-metronome_$app" @@ -135,6 +146,7 @@ yunohost tools regen-conf metronome ynh_restore_file --origin_path="/usr/lib/metronome/modules/mod_carbons.lua" ynh_restore_file --origin_path="/usr/lib/metronome/modules/mod_http_altconnect.lua" ynh_restore_file --origin_path="/usr/lib/metronome/modules/mod_smacks.lua" +ynh_restore_file --origin_path="/usr/lib/metronome/modules/mod_turncredentials.lua" ynh_systemd_action --service_name=metronome --action=restart @@ -147,22 +159,27 @@ ynh_restore_file --origin_path="/etc/systemd/system/$app-videobridge.service" systemctl enable $app-videobridge.service ynh_restore_file --origin_path="/etc/systemd/system/$app-jicofo.service" systemctl enable $app-jicofo.service +ynh_restore_file --origin_path="/etc/systemd/system/$app-coturn.service" +systemctl enable $app-coturn.service #================================================= # INTEGRATE SERVICE IN YUNOHOST #================================================= ynh_print_info --message="Integrating service in YunoHost..." -yunohost service add $app-videobridge --log "/var/log/$app/$app-videobridge.log" -yunohost service add $app-jicofo --log "/var/log/$app/$app-jicofo.log" +yunohost service add $app-videobridge --log_type "systemd" +yunohost service add $app-jicofo --log_type "systemd" +yunohost service add $app-coturn --log_type "systemd" #================================================= # START SYSTEMD SERVICE #================================================= ynh_print_info --message="Starting a systemd service..." -ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="/var/log/$app/$app-videobridge.log" -ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="/var/log/$app/$app-jicofo.log" +ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="systemd" --line_match="Started $app-videobridge" +ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="systemd" --line_match="Started $app-jicofo" +ynh_systemd_action --service_name=$app-coturn --action="start" --log_path="systemd" --line_match="Started coturn" + #================================================= # RESTORE THE LOGROTATE CONFIGURATION diff --git a/scripts/upgrade b/scripts/upgrade index d39c65a..60423a2 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -24,6 +24,9 @@ videobridge_secret=$(ynh_app_setting_get --app=$app --key=videobridge_secret) focus_secret=$(ynh_app_setting_get --app=$app --key=focus_secret) port=$(ynh_app_setting_get --app=$app --key=port) port_component=$(ynh_app_setting_get --app=$app --key=port_component) +port_coturn_tls=$(ynh_app_setting_get --app=$app --key=port_coturn_tls) +port_coturn_alt_tls=$(ynh_app_setting_get --app=$app --key=port_coturn_alt_tls) +coturn_pwd=$(ynh_app_setting_get --app=$app --key=coturn_pwd) focus_user=$(ynh_app_setting_get --app=$app --key=focus_user) focus_password=$(ynh_app_setting_get --app=$app --key=focus_password) @@ -56,11 +59,15 @@ if ynh_version_gt "1.0.3387~ynh2" "${current_version}" ; then ynh_replace_string --match_string="__VIDEOBRIDGE_SECRET__" --replace_string="$videobridge_secret" --target_file="$metronome_conf" ynh_replace_string --match_string="__FOCUS_SECRET__" --replace_string="$focus_secret" --target_file="$metronome_conf" ynh_replace_string --match_string="__PORT_COMPONENT__" --replace_string="$port_component" --target_file="$metronome_conf" + ynh_replace_string --match_string="__CORTURN_PWD__" --replace_string="$coturn_pwd" --target_file="$metronome_conf" + ynh_replace_string --match_string="__PORT_COTURN_TLS__" --replace_string="$port_coturn_tls" --target_file="$metronome_conf" + ynh_replace_string --match_string="__PORT_COTURN_ALT_TLS__" --replace_string="$port_coturn_alt_tls" --target_file="$metronome_conf" touch "/usr/share/yunohost/templates/jitsi/auth.$domain.cfg.lua" touch "/usr/share/yunohost/templates/jitsi/conference.$domain.cfg.lua" touch "/usr/share/yunohost/templates/jitsi/jitsi-videobridge.$domain.cfg.lua" touch "/usr/share/yunohost/templates/jitsi/focus.$domain.cfg.lua" + touch "/usr/share/yunohost/templates/jitsi/coturn.$domain.cfg.lua" # Add Metronome hook cp -R ../conf/metronome_regen_conf.hook /usr/share/yunohost/hooks/conf_regen/50-metronome_$app @@ -89,8 +96,9 @@ ynh_abort_if_errors #================================================= ynh_print_info --message="Stopping a systemd service..." -ynh_systemd_action --service_name=$app-videobridge --action="stop" --log_path="/var/log/$app/$app-videobridge.log" -ynh_systemd_action --service_name=$app-jicofo --action="stop" --log_path="/var/log/$app/$app-jicofo.log" +ynh_systemd_action --service_name=$app-videobridge --action="stop" --log_path="systemd" --line_match="Stopped $app-videobridge" +ynh_systemd_action --service_name=$app-jicofo --action="stop" --log_path="systemd" --line_match="Stopped $app-jicofo" +ynh_systemd_action --service_name=$app-coturn --action="stop" --log_path="systemd" --line_match="Stopped coturn" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE @@ -133,6 +141,44 @@ ynh_system_user_create --username=$app --home_dir=$final_path #================================================= # SPECIFIC UPGRADE +#================================================= +# CONFIGURE COTURN +#================================================= +ynh_print_info --message="Configuring coturn..." + +cp -f ../conf/default_coturn /etc/default/$app-coturn + +coturn_config="$final_path/coturn.conf" + +cp -f ../conf/coturn.conf "$coturn_config" + +ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$coturn_config" +ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$coturn_config" +ynh_replace_string --match_string="__PORT_COTURN_TLS__" --replace_string="$port_coturn_tls" --target_file="$coturn_config" +ynh_replace_string --match_string="__PORT_COTURN_ALT_TLS__" --replace_string="$port_coturn_alt_tls" --target_file="$coturn_config" +ynh_replace_string --match_string="__COTURN_PWD__" --replace_string="$coturn_pwd" --target_file="$coturn_config" + +# Get public IP and set as external IP for coturn +# note : '|| true' is used to ignore the errors if we can't get the public ipv4 or ipv6 +public_ipv4="$(curl ip.yunohost.org)" || true +public_ip6="$(curl ipv6.yunohost.org)" || true + +if [ -n "$public_ipv4" ] && ynh_validate_ip4 --ip_address="$public_ipv4" +then + ynh_replace_string --match_string='__IPV4__' --replace_string="$public_ipv4" --target_file="$coturn_config" +else + ynh_replace_string --match_string='__IPV4__,' --replace_string="" --target_file="$coturn_config" +fi + +if [ -n "$public_ip6" ] && ynh_validate_ip6 --ip_address="$public_ip6" +then + ynh_replace_string --match_string='__IPV6__' --replace_string="$public_ip6" --target_file="$coturn_config" +else + ynh_replace_string --match_string=',__IPV6__' --replace_string="" --target_file="$coturn_config" +fi + +ynh_store_file_checksum --file="$coturn_config" + #================================================= # BUILD JITSI-VIDEOBRIDGE #================================================= @@ -157,11 +203,11 @@ then mvn package -DskipTests -Dassembly.skipAssembly=false popd - unzip $final_path/jitsi-jicofo-build/target/jicofo-linux-x64-1.1-SNAPSHOT.zip -d $final_path + unzip $final_path/jitsi-jicofo-build/target/jicofo-1.1-SNAPSHOT-archive.zip -d $final_path ynh_secure_remove --file="$final_path/jitsi-jicofo" - mv $final_path/jicofo-linux-x64-1.1-SNAPSHOT/ $final_path/jitsi-jicofo/ + mv $final_path/jicofo-1.1-SNAPSHOT/ $final_path/jitsi-jicofo/ ynh_secure_remove --file="$final_path/jitsi-jicofo-build" fi @@ -218,6 +264,8 @@ ynh_replace_string --match_string="__FOCUS_USER__" --replace_string="$focus_user ynh_replace_string --match_string="__FOCUS_PASSWORD__" --replace_string="$focus_password" --target_file="../conf/jitsi-jicofo.service" ynh_add_systemd_config --service=$app-jicofo --template="jitsi-jicofo.service" +ynh_add_systemd_config --service=$app-coturn --template="jitsi-coturn.service" + #================================================= # GENERIC FINALIZATION #================================================= @@ -241,8 +289,9 @@ ynh_app_setting_set --app=$app --key=unprotected_uris --value="/" #================================================= ynh_print_info --message="Starting a systemd service..." -ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="/var/log/$app/$app-videobridge.log" -ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="/var/log/$app/$app-jicofo.log" +ynh_systemd_action --service_name=$app-videobridge --action="start" --log_path="systemd" --line_match="Started $app-videobridge" +ynh_systemd_action --service_name=$app-jicofo --action="start" --log_path="systemd" --line_match="Started $app-jicofo" +ynh_systemd_action --service_name=$app-coturn --action="start" --log_path="systemd" --line_match="Started coturn" #================================================= # RELOAD NGINX