Only has an effect if the prometheus exporter is enabled and if it is not empty (default). If at least this many conferences are active on the server, the type will bail out before making any changes. This is useful if you want to avoid service disruptions due to e.g. an SLA. Sponsored by: camilion.eu
309 lines
9.7 KiB
Bash
Executable file
309 lines
9.7 KiB
Bash
Executable file
#!/bin/sh -e
|
|
|
|
os="$(cat "${__global}/explorer/os")"
|
|
case "${os}" in
|
|
devuan|debian)
|
|
;;
|
|
*)
|
|
echo "Your OS '${os}' is currently not supported." > /dev/stderr
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
current_conferences="$(cat "${__object}/explorer/jitsi-status" | grep -E "^jitsi_conferences[[:space:]]" | cut -d ' ' -f 2)"
|
|
|
|
ABORT_CONFERENCE_COUNT="$(cat "${__object}/parameter/abort-conference-count")"
|
|
|
|
if [ -n "${current_conferences}" ] && [ -n "${ABORT_CONFERENCE_COUNT}" ] && \
|
|
[ "${ABORT_CONFERENCE_COUNT}" -le "${current_conferences}" ]; then
|
|
cat <<-EOF
|
|
Early bail out was requested when at least ${ABORT_CONFERENCE_COUNT} conferences are taking place.
|
|
There are currently ${current_conferences} active conferences.
|
|
|
|
Try again at a later time or remove or increase --abort-conference-count
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
JITSI_HOST="${__target_host}"
|
|
if [ -f "${__object}/parameter/jitsi-version" ]; then
|
|
# This has been deprecated and will be removed 'soon'
|
|
JITSI_VERSION="$(cat "${__object}/parameter/jitsi-version")"
|
|
else
|
|
# Note this won't be a parameter anymore, we won't let users stay behind
|
|
JITSI_VERSION="$(cat "${__type}/files/jitsi-version")"
|
|
fi
|
|
TURN_SERVER="$(cat "${__object}/parameter/turn-server")"
|
|
TURN_SECRET="$(cat "${__object}/parameter/turn-secret")"
|
|
|
|
if [ -z "${TURN_SERVER}" ]; then
|
|
TURN_SERVER="${JITSI_HOST}"
|
|
fi
|
|
|
|
# The rest is loosely based on Jitsi's documentation
|
|
# https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart
|
|
|
|
# Setup repositories
|
|
## First the signing keys
|
|
### Remove old signing key
|
|
__apt_key "jitsi_meet_2016" \
|
|
--keyid "66A9 CD05 95D6 AFA2 4729 0D3B EF8B 479E 2DC1 389C" \
|
|
--use-deprecated-apt-key \
|
|
--state "absent"
|
|
### Add new signing key
|
|
require="__apt_key/jitsi_meet_2016" __apt_key jitsi_meet_2021 \
|
|
--source "${__type}/files/apt_2021.gpg" \
|
|
--state "present"
|
|
## Now the repositories (they are a tad weird, so distribution is 'stable/')
|
|
require="__apt_key/jitsi_meet_2021" __apt_source jitsi_meet \
|
|
--uri 'https://download.jitsi.org' \
|
|
--distribution 'stable/' \
|
|
--state present
|
|
## Ensure apt cache is up-to-date
|
|
require="__apt_source/jitsi_meet" __apt_update_index
|
|
|
|
export require="${require} __apt_source/jitsi_meet __apt_update_index"
|
|
|
|
# Pre-feed debconf settings, so Jitsi's installation has a good config
|
|
# shellcheck source=type/__jitsi_meet/files/debconf_settings.sh
|
|
. "${__type}/files/debconf_settings.sh" # This defines DEBCONF_SETTINGS
|
|
__debconf_set_selections jitsi_meet --line "${DEBCONF_SETTINGS}"
|
|
export require="${require} __debconf_set_selections/jitsi_meet"
|
|
|
|
# Install and upgrade packages as needed
|
|
# NOTE: we are doing version pinning again, but it breaks sometimes when
|
|
# the version is not the latest.
|
|
# This happens because dependencies might not be properly resolved.
|
|
# To avoid this, this type must be maintained up to date.
|
|
# If we don't use this, keeping Jitsi's up to date is very difficult.
|
|
__package_apt jitsi-meet --version "${JITSI_VERSION}"
|
|
|
|
# Proceed only after installation/upgrade has finished
|
|
export require="__package_apt/jitsi-meet"
|
|
|
|
# TODO: generalise and move out
|
|
# Prep nginx for acme settings
|
|
|
|
NGINX_ETC="/etc/nginx"
|
|
|
|
#
|
|
# Setup the acme-challenge snippet
|
|
#
|
|
__directory "${NGINX_ETC}/snippets" --state present
|
|
require="__directory${NGINX_ETC}/snippets" __file "${NGINX_ETC}/snippets/acme-challenge.conf" \
|
|
--mode 644 \
|
|
--source - << EOF
|
|
# This file is managed remotely, all changes will be lost
|
|
|
|
# This was heavily inspired by debops.org.
|
|
|
|
# Automatic Certificate Management Environment (ACME) support.
|
|
# https://tools.ietf.org/html/draft-ietf-acme-acme-01
|
|
# https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment
|
|
|
|
|
|
# Return the ACME challenge present in the server public root.
|
|
# If not found, switch to global web server root.
|
|
location ^~ /.well-known/acme-challenge/ {
|
|
default_type "text/plain";
|
|
try_files \$uri @well-known-acme-challenge;
|
|
}
|
|
|
|
# Return the ACME challenge present in the global server public root.
|
|
# If not present, redirect request to a specified domain.
|
|
location @well-known-acme-challenge {
|
|
root /usr/share/jitsi-meet;
|
|
default_type "text/plain";
|
|
try_files \$uri @redirect-acme-challenge;
|
|
}
|
|
|
|
# Redirect the ACME challenge to a different host. If a redirect loop is
|
|
# detected, return 404.
|
|
location @redirect-acme-challenge {
|
|
if (\$arg_redirect) {
|
|
return 404;
|
|
}
|
|
return 307 \$scheme://${ACME_DOMAIN}\$request_uri?redirect=yes;
|
|
}
|
|
|
|
# Return 404 if ACME challenge well known path is accessed directly.
|
|
location = /.well-known/acme-challenge/ {
|
|
return 404;
|
|
}
|
|
EOF
|
|
|
|
__directory "${NGINX_ETC}/sites-available" --state present
|
|
require="__directory${NGINX_ETC}/sites-available" __file "${NGINX_ETC}/sites-available/default" \
|
|
--mode 644 \
|
|
--source - << EOF
|
|
# This file is managed remotely, all changes will be lost
|
|
|
|
server_names_hash_bucket_size 64;
|
|
|
|
types {
|
|
# nginx's default mime.types doesn't include a mapping for wasm
|
|
application/wasm wasm;
|
|
}
|
|
|
|
server {
|
|
|
|
# Listen on IPv4
|
|
listen 80;
|
|
# Note: there is an ipv6only=off flag, but it is Linux-only
|
|
# incidentally, that defaults to "on", which is what causes
|
|
# not having the double listen to listen on IPv6-only
|
|
listen [::]:80;
|
|
|
|
server_name welcome;
|
|
|
|
root /srv/www/sites/welcome/public;
|
|
|
|
include snippets/acme-challenge.conf;
|
|
|
|
location / {
|
|
return 301 https://\$host\$request_uri;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Starting from 2.0.7210, jitsi defines following nginx upstreams
|
|
__directory "${NGINX_ETC}/conf.d" --state present
|
|
require="__directory${NGINX_ETC}/conf.d" __file "${NGINX_ETC}/conf.d/prosody.conf" \
|
|
--mode 644 \
|
|
--source - << EOF
|
|
upstream prosody {
|
|
zone upstreams 64K;
|
|
server 127.0.0.1:5280;
|
|
keepalive 2;
|
|
}
|
|
EOF
|
|
require="__directory${NGINX_ETC}/conf.d" __file "${NGINX_ETC}/conf.d/jvb1.conf" \
|
|
--mode 644 \
|
|
--source - << EOF
|
|
upstream jvb1 {
|
|
zone upstreams 64K;
|
|
server 127.0.0.1:9090;
|
|
keepalive 2;
|
|
}
|
|
EOF
|
|
|
|
if [ -f "${__object}/parameter/secured-domains" ]; then
|
|
SECURED_DOMAINS_STATE='present'
|
|
else
|
|
SECURED_DOMAINS_STATE='absent'
|
|
fi
|
|
|
|
# This is the main host config
|
|
PROSODY_MAIN_CONFIG="YES"
|
|
# Prosody settings for common components (jvb, focus, ...)
|
|
# shellcheck source=type/__jitsi_meet/files/prosody.cfg.lua.sh
|
|
. "${__type}/files/prosody.cfg.lua.sh" # This defines PROSODY_CONFIG
|
|
__file "/etc/prosody/conf.d/00_jitsi_base.cfg.lua" \
|
|
--group prosody \
|
|
--mode 0440 \
|
|
--source - <<EOF
|
|
${PROSODY_CONFIG}
|
|
EOF
|
|
|
|
# Clean up zauth.cfg.lua file, which we don't use now
|
|
__file "/etc/prosody/conf.d/${JITSI_HOST}.zauth.cfg.lua" \
|
|
--state absent
|
|
|
|
export SECURED_DOMAINS_STATE
|
|
export JITSI_HOST
|
|
"${__type}/files/jicofo.conf.sh" | \
|
|
__file /etc/jitsi/jicofo/jicofo.conf --mode 0444 --source '-'
|
|
|
|
# Enable the private colibri REST API end point for better stats
|
|
__file "/etc/jitsi/videobridge/jvb.conf" --mode 0444 --source '-' <<EOFJVB
|
|
videobridge {
|
|
http-servers {
|
|
public {
|
|
port = 9090
|
|
}
|
|
private {
|
|
port = 8080
|
|
}
|
|
}
|
|
websockets {
|
|
enabled = true
|
|
domain = "${JITSI_HOST}:443"
|
|
tls = true
|
|
}
|
|
apis {
|
|
rest {
|
|
enabled = true
|
|
}
|
|
}
|
|
}
|
|
EOFJVB
|
|
|
|
# Enable simple per-domain body customisation
|
|
__file "/usr/share/jitsi-meet/body.html" \
|
|
--mode 0644 \
|
|
--source '-' <<EOF
|
|
<!--#include virtual="body-\${host}.html" -->
|
|
EOF
|
|
|
|
# These two should be changed on new release
|
|
EXPORTER_VERSION="1.2.0"
|
|
EXPORTER_CHECKSUM="sha256:6377ffa7be0c7deb66545616add7245da96f8b7746d6712f41cfa9fe72c935ce"
|
|
EXPORTER_URL="https://github.com/systemli/prometheus-jitsi-meet-exporter/releases/download/${EXPORTER_VERSION}/prometheus-jitsi-meet-exporter_${EXPORTER_VERSION}_linux_amd64.tar.gz"
|
|
if [ -f "${__object}/parameter/disable-prometheus-exporter" ]; then
|
|
EXPORTER_STATE="absent"
|
|
else
|
|
EXPORTER_STATE="present"
|
|
fi
|
|
__evilham_single_binary_service prometheus-jitsi-meet-exporter \
|
|
--state "${EXPORTER_STATE}" \
|
|
--do-not-manage-user \
|
|
--user "nobody" \
|
|
--group "nogroup" \
|
|
--version "${EXPORTER_VERSION}" \
|
|
--checksum "${EXPORTER_CHECKSUM}" \
|
|
--url "${EXPORTER_URL}" \
|
|
--unpack \
|
|
--service-args "-videobridge-url 'http://localhost:8080/colibri/stats' -web.listen-address ':9888'"
|
|
|
|
#
|
|
# Setup interpreter assets if requested
|
|
# See: https://gitlab.com/mfmt/jsi/
|
|
#
|
|
jsi_updated_on="2022-04-21"
|
|
__link "/usr/share/jitsi-meet/interpreters.html" \
|
|
--type symbolic \
|
|
--source "/opt/jsi/static/index.html.sample"
|
|
__directory /opt/jsi --mode 0755
|
|
export require="__directory/opt/jsi"
|
|
__download /opt/jsi/jsi.tar.gz \
|
|
--url 'https://gitlab.com/mfmt/jsi/-/archive/1d2cceaf615ee61c0bba80e5bddc61c5d1018303/jsi-1d2cceaf615ee61c0bba80e5bddc61c5d1018303.tar.gz' \
|
|
--sum "sha256:b020141093daa9937507b098f358d0be994834c3e23866a457fc5140415a0c53"
|
|
export require="__download/opt/jsi/jsi.tar.gz"
|
|
__unpack /opt/jsi/jsi.tar.gz \
|
|
--preserve-archive \
|
|
--tar-strip 1 \
|
|
--destination /opt/jsi/static \
|
|
--onchange "$(cat <<EOF
|
|
# Patch style.css to be served on /i/
|
|
sed -i.tmp -E \
|
|
-e 's!url[(]/img/welcome-background.png[)]!url(/i/img/welcome-background.png)!' \
|
|
/opt/jsi/static/style.css
|
|
# Patch jsi.js to be served on /i/
|
|
# and so it always uses the domain it's served from
|
|
# and so it uses /i/ROOM for the form
|
|
sed -i.tmp -E \
|
|
-e 's!substr[(][0-9]+[)]!substr(3)!' \
|
|
-e 's!config[.]jitsimeet_url!url.host!' \
|
|
-e 's!(window[.]location[.]href)[[:space:]]*=[[:space:]]*"/"!\1 = "/i/"!' \
|
|
/opt/jsi/static/jsi.js
|
|
# Patch the sample index.html, so it loads external_api.js from same host
|
|
# and to easen up on the branding
|
|
# and to enable browser cache
|
|
sed -i.tmp -E \
|
|
-e "s!src=[^>]*(/external_api.js).!src='\1'!" \
|
|
-e "s!<h1>[^<]*</h1>!<h1>Jitsi Meetings with interpreter</h1>!" \
|
|
-e "s!https://meet.mayfirst.org!/!" \
|
|
-e "s!(style.css|jsi.js)([^?])!\1?v=${jsi_updated_on:?}\2!" \
|
|
/opt/jsi/static/index.html.sample
|
|
EOF
|
|
)"
|