diff --git a/bbb_install.yml b/bbb_install.yml
new file mode 100644
index 0000000..40db637
--- /dev/null
+++ b/bbb_install.yml
@@ -0,0 +1,9 @@
+---
+- hosts: "{{ target }}"
+ remote_user: core
+ become: yes
+ roles:
+ - kwoodson.yedit
+ - bbb_install
+
+...
\ No newline at end of file
diff --git a/bootstrapRoot.yml b/bootstrapRoot.yml
index c268e57..d91a951 100644
--- a/bootstrapRoot.yml
+++ b/bootstrapRoot.yml
@@ -1,12 +1,18 @@
---
- hosts: "{{ target }}"
remote_user: root
+ become: yes
roles:
- apt_upgrade
- bs_hostnames
- bs_users
- bs_sshd
+# Falls failed to lock apt for exclusive operation Fehler geworfen wird:
+#sudo rm -rf /var/lib/apt/lists/*
+#sudo apt-get clean
+#sudo apt-get update
+
# sshd schließt den root user von ssh aus, danach läuft das Playbook nicht mehr als root
# Weiter geht's mit bootstrapCore
...
\ No newline at end of file
diff --git a/host_vars/bbb.bfwbb-lernen.de b/host_vars/bbb.bfwbb-lernen.de
new file mode 100644
index 0000000..f707bcc
--- /dev/null
+++ b/host_vars/bbb.bfwbb-lernen.de
@@ -0,0 +1,36 @@
+---
+install_image:
+ path: /root/.oldroot/nfs/install/installimage
+ raid: yes -l 1
+ image: /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar.gz
+ drives: sda,sdb
+
+passwordless_sudo: true
+
+# bobby $6$A7Sw5gku7$0WqY/Z4Ei0axG.mZwDQlFJfK8Rtx6H0eKuP8CW23V5f/5j9sXendknLtXexQfgDzA4Ri55ZqhJnpf05MJV71J0
+# Passwort für root ist bobby, muss hier im Klartext angegeben werden
+password: bobby
+
+# root hat kein keypair, nur ein .ssh Verzeichnis mit hohgeladener authorized_keys Datei
+# ssh_key_root: /root/.ssh/id_rsa.pub
+
+ssh_key_core: /home/core/.ssh/id_rsa.pub
+
+default_presentation: rudiDefault.pdf
+
+
+# BBB-Settings
+
+# bigbluebutton.properties
+defaultWelcomeMessage: defaultWelcomeMessage=Willkommen zu %%CONFNAME%%
+defaultWelcomeMessageFooter: defaultWelcomeMessageFooter=BigBlueButton
+learningDashboardEnabled: learningDashboardEnabled=false
+defaultDialAccessNumber: defaultDialAccessNumber=095129909624
+# defaultDialAccessNumber: defaultDialAccessNumber=613-555-1234
+
+disableRecordingDefault: disableRecordingDefault=false
+webcamsOnlyForModerator: webcamsOnlyForModerator=false
+learningDashboardCleanupDelayInMinutes: learningDashboardCleanupDelayInMinutes=0
+bigbluebutton_web_logoutURL: bigbluebutton.web.logoutURL=https://open-diakonie.de
+
+# settings.yml
\ No newline at end of file
diff --git a/host_vars/bbb.xitq.de b/host_vars/bbb.xitq.de
index 40bdc31..c6ada3a 100644
--- a/host_vars/bbb.xitq.de
+++ b/host_vars/bbb.xitq.de
@@ -7,6 +7,28 @@ install_image:
passwordless_sudo: true
+default_presentation: xitDefault.pdf
+
+
+# BBB-Settings
+
+# bigbluebutton.properties
+defaultWelcomeMessage: defaultWelcomeMessage=Willkommen zu %%CONFNAME%%
+defaultWelcomeMessageFooter: defaultWelcomeMessageFooter=BigBlueButton
+learningDashboardEnabled: learningDashboardEnabled=false
+# defaultDialAccessNumber: defaultDialAccessNumber=095129909624
+defaultDialAccessNumber: defaultDialAccessNumber=613-555-1234
+
+disableRecordingDefault: disableRecordingDefault=false
+webcamsOnlyForModerator: webcamsOnlyForModerator=false
+learningDashboardCleanupDelayInMinutes: learningDashboardCleanupDelayInMinutes=0
+bigbluebutton_web_logoutURL: bigbluebutton.web.logoutURL=https://open-diakonie.de
+
+# settings.yml
+
+
+
+
#install_vm:
# osvariant: ubuntu20.04
# image: /home/core/tmp/ubuntu-22.04.1-live-server-amd64.iso
@@ -29,7 +51,8 @@ password: bobby
# ssh_key_root: /root/.ssh/id_rsa.pub
ssh_key_core: /home/core/.ssh/id_rsa.pub
-vm_name: vhosttst2
+vm_name: vhosttst
+vm_ip: 192.168.122.10
vm_vcpus: 2
vm_ram_mb: 4096
vm_net: default
diff --git a/host_vars/bbb0.sdw.systems b/host_vars/bbb0.sdw.systems
new file mode 100644
index 0000000..940b718
--- /dev/null
+++ b/host_vars/bbb0.sdw.systems
@@ -0,0 +1,36 @@
+---
+install_image:
+ path: /root/.oldroot/nfs/install/installimage
+ raid: yes -l 1
+ image: /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar.gz
+ drives: nvme0n1,nvme1n1
+
+passwordless_sudo: true
+
+# bobby $6$A7Sw5gku7$0WqY/Z4Ei0axG.mZwDQlFJfK8Rtx6H0eKuP8CW23V5f/5j9sXendknLtXexQfgDzA4Ri55ZqhJnpf05MJV71J0
+# Passwort für root ist bobby, muss hier im Klartext angegeben werden
+password: bobby
+
+# root hat kein keypair, nur ein .ssh Verzeichnis mit hohgeladener authorized_keys Datei
+# ssh_key_root: /root/.ssh/id_rsa.pub
+
+ssh_key_core: /home/core/.ssh/id_rsa.pub
+
+default_presentation: blankDefault.pdf
+
+
+# BBB-Settings
+
+# bigbluebutton.properties
+defaultWelcomeMessage: defaultWelcomeMessage=Willkommen zu %%CONFNAME%%
+defaultWelcomeMessageFooter: defaultWelcomeMessageFooter=BigBlueButton
+learningDashboardEnabled: learningDashboardEnabled=false
+# defaultDialAccessNumber: defaultDialAccessNumber=095129909624
+defaultDialAccessNumber: defaultDialAccessNumber=613-555-1234
+
+disableRecordingDefault: disableRecordingDefault=false
+webcamsOnlyForModerator: webcamsOnlyForModerator=false
+learningDashboardCleanupDelayInMinutes: learningDashboardCleanupDelayInMinutes=0
+bigbluebutton_web_logoutURL: bigbluebutton.web.logoutURL=https://www.wikipedia.de/
+
+# settings.yml
\ No newline at end of file
diff --git a/host_vars/bbb1.open-diakonie.de b/host_vars/bbb1.open-diakonie.de
new file mode 100644
index 0000000..8313334
--- /dev/null
+++ b/host_vars/bbb1.open-diakonie.de
@@ -0,0 +1,36 @@
+---
+install_image:
+ path: /root/.oldroot/nfs/install/installimage
+ raid: yes -l 1
+ image: /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar.gz
+ drives: sda,sdb
+
+passwordless_sudo: true
+
+# bobby $6$A7Sw5gku7$0WqY/Z4Ei0axG.mZwDQlFJfK8Rtx6H0eKuP8CW23V5f/5j9sXendknLtXexQfgDzA4Ri55ZqhJnpf05MJV71J0
+# Passwort für root ist bobby, muss hier im Klartext angegeben werden
+password: bobby
+
+# root hat kein keypair, nur ein .ssh Verzeichnis mit hohgeladener authorized_keys Datei
+# ssh_key_root: /root/.ssh/id_rsa.pub
+
+ssh_key_core: /home/core/.ssh/id_rsa.pub
+
+default_presentation: rudiDefault.pdf
+
+
+# BBB-Settings
+
+# bigbluebutton.properties
+defaultWelcomeMessage: defaultWelcomeMessage=Willkommen zu %%CONFNAME%%
+defaultWelcomeMessageFooter: defaultWelcomeMessageFooter=BigBlueButton
+learningDashboardEnabled: learningDashboardEnabled=false
+# defaultDialAccessNumber: defaultDialAccessNumber=095129909624
+defaultDialAccessNumber: defaultDialAccessNumber=613-555-1234
+
+disableRecordingDefault: disableRecordingDefault=false
+webcamsOnlyForModerator: webcamsOnlyForModerator=false
+learningDashboardCleanupDelayInMinutes: learningDashboardCleanupDelayInMinutes=0
+bigbluebutton_web_logoutURL: bigbluebutton.web.logoutURL=https://open-diakonie.de
+
+# settings.yml
\ No newline at end of file
diff --git a/host_vars/bbb2.open-diakonie.de b/host_vars/bbb2.open-diakonie.de
new file mode 100644
index 0000000..3138007
--- /dev/null
+++ b/host_vars/bbb2.open-diakonie.de
@@ -0,0 +1,36 @@
+---
+install_image:
+ path: /root/.oldroot/nfs/install/installimage
+ raid: yes -l 1
+ image: /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar.gz
+ drives: nvme0n1,nvme1n1
+
+passwordless_sudo: true
+
+# bobby $6$A7Sw5gku7$0WqY/Z4Ei0axG.mZwDQlFJfK8Rtx6H0eKuP8CW23V5f/5j9sXendknLtXexQfgDzA4Ri55ZqhJnpf05MJV71J0
+# Passwort für root ist bobby, muss hier im Klartext angegeben werden
+password: bobby
+
+# root hat kein keypair, nur ein .ssh Verzeichnis mit hohgeladener authorized_keys Datei
+# ssh_key_root: /root/.ssh/id_rsa.pub
+
+ssh_key_core: /home/core/.ssh/id_rsa.pub
+
+default_presentation: rudiDefault.pdf
+
+
+# BBB-Settings
+
+# bigbluebutton.properties
+defaultWelcomeMessage: defaultWelcomeMessage=Willkommen zu %%CONFNAME%%
+defaultWelcomeMessageFooter: defaultWelcomeMessageFooter=BigBlueButton
+learningDashboardEnabled: learningDashboardEnabled=false
+# defaultDialAccessNumber: defaultDialAccessNumber=095129909624
+defaultDialAccessNumber: defaultDialAccessNumber=613-555-1234
+
+disableRecordingDefault: disableRecordingDefault=false
+webcamsOnlyForModerator: webcamsOnlyForModerator=false
+learningDashboardCleanupDelayInMinutes: learningDashboardCleanupDelayInMinutes=0
+bigbluebutton_web_logoutURL: bigbluebutton.web.logoutURL=https://open-diakonie.de
+
+# settings.yml
\ No newline at end of file
diff --git a/hosts b/hosts
index 4e77df1..b9b5405 100644
--- a/hosts
+++ b/hosts
@@ -1,2 +1,5 @@
-bbb.xitq.de
-# bbb.xit
+# bbb.xitq.de
+# bbb1.open-diakonie.d#
+# bbb2.open-diakonie.de
+# bbb.bfwbb-lernen.de
+bbb0.sdw.systems
\ No newline at end of file
diff --git a/requirements.yml b/requirements.yml
new file mode 100644
index 0000000..75bf100
--- /dev/null
+++ b/requirements.yml
@@ -0,0 +1,2 @@
+---
+- src: kwoodson.yedit
\ No newline at end of file
diff --git a/roles/bbb_install/files/bbb-install-2.5.sh b/roles/bbb_install/files/bbb-install-2.5.sh
new file mode 100644
index 0000000..b140f86
--- /dev/null
+++ b/roles/bbb_install/files/bbb-install-2.5.sh
@@ -0,0 +1,1115 @@
+#!/bin/bash -e
+
+# Copyright (c) 2022 BigBlueButton Inc.
+#
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see .
+
+# BigBlueButton is an open source conferencing system. For more information see
+# https://www.bigbluebutton.org/.
+#
+# This bbb-install-2.5.sh script automates many of the installation and configuration
+# steps at
+# https://docs.bigbluebutton.org/2.5/install.html
+#
+#
+# Examples
+#
+# Install BigBlueButton 2.5.x with a SSL certificate from Let's Encrypt using hostname bbb.example.com
+# and email address info@example.com and apply a basic firewall
+#
+# wget -qO- https://ubuntu.bigbluebutton.org/bbb-install-2.5.sh | bash -s -- -w -v focal-250 -s bbb.example.com -e info@example.com
+#
+# Same as above but also install the API examples for testing.
+#
+# wget -qO- https://ubuntu.bigbluebutton.org/bbb-install-2.5.sh | bash -s -- -w -a -v focal-250 -s bbb.example.com -e info@example.com
+#
+# Install BigBlueButton with SSL + Greenlight
+#
+# wget -qO- https://ubuntu.bigbluebutton.org/bbb-install-2.5.sh | bash -s -- -w -v focal-250 -s bbb.example.com -e info@example.com -g
+#
+
+usage() {
+ set +x
+ cat 1>&2 < Install given version of BigBlueButton (e.g. 'focal-250') (required)
+
+ -s Configure server with
+ -e Email for Let's Encrypt certbot
+
+ -x Use Let's Encrypt certbot with manual dns challenges
+
+ -a Install BBB API demos
+ -g Install Greenlight
+ -c : Configure with coturn server at using
+
+ -m Create a Symbolic link from /var/bigbluebutton to
+
+ -p [:] Use apt-get proxy at (default port 3142)
+ -r Use alternative apt repository (such as packages-eu.bigbluebutton.org)
+
+ -d Skip SSL certificates request (use provided certificates from mounted volume) in /local/certs/
+ -w Install UFW firewall (recommended)
+
+ -j Allows the installation of BigBlueButton to proceed even if not all requirements [for production use] are met.
+ Note that not all requirements can be ignored. This is useful in development / testing / ci scenarios.
+
+ -i Allows the installation of BigBlueButton to proceed even if Apache webserver is installed.
+
+ -h Print help
+
+OPTIONS (install coturn only):
+
+ -c : Setup a coturn server with and (required)
+ -e Configure email for Let's Encrypt certbot (required)
+
+OPTIONS (install Let's Encrypt certificate only):
+
+ -s Configure server with (required)
+ -e Configure email for Let's Encrypt certbot (required)
+ -l Only install Let's Encrypt certificate (not BigBlueButton)
+ -x Use Let's Encrypt certbot with manual dns challenges (optional)
+
+
+EXAMPLES:
+
+Sample options for setup a BigBlueButton server
+
+ -v focal-250 -s bbb.example.com -e info@example.com
+ -v focal-250 -s bbb.example.com -e info@example.com -g
+ -v focal-250 -s bbb.example.com -e info@example.com -g -c turn.example.com:1234324
+
+Sample options for setup of a coturn server (on a Ubuntu 20.04)
+
+ -c turn.example.com:1234324 -e info@example.com
+
+SUPPORT:
+ Community: https://bigbluebutton.org/support
+ Docs: https://github.com/bigbluebutton/bbb-install
+
+HERE
+}
+
+main() {
+ export DEBIAN_FRONTEND=noninteractive
+ PACKAGE_REPOSITORY=ubuntu.bigbluebutton.org
+ LETS_ENCRYPT_OPTIONS="--webroot --non-interactive"
+ SOURCES_FETCHED=false
+ CR_TMPFILE=$(mktemp /tmp/carriage-return.XXXXXX)
+ echo "\n" > $CR_TMPFILE
+
+ need_x64
+
+ while builtin getopts "hs:r:c:v:e:p:m:lxgadwji" opt "${@}"; do
+
+ case $opt in
+ h)
+ usage
+ exit 0
+ ;;
+
+ s)
+ HOST=$OPTARG
+ if [ "$HOST" == "bbb.example.com" ]; then
+ err "You must specify a valid hostname (not the hostname given in the docs)."
+ fi
+ ;;
+ r)
+ PACKAGE_REPOSITORY=$OPTARG
+ ;;
+ e)
+ EMAIL=$OPTARG
+ if [ "$EMAIL" == "info@example.com" ]; then
+ err "You must specify a valid email address (not the email in the docs)."
+ fi
+ ;;
+ x)
+ LETS_ENCRYPT_OPTIONS="--manual --preferred-challenges dns"
+ ;;
+ c)
+ COTURN=$OPTARG
+ check_coturn "$COTURN"
+ ;;
+ v)
+ VERSION=$OPTARG
+ ;;
+
+ p)
+ PROXY=$OPTARG
+ if [ -n "$PROXY" ]; then
+ if [[ "$PROXY" =~ : ]]; then
+ echo "Acquire::http::Proxy \"http://$PROXY\";" > /etc/apt/apt.conf.d/01proxy
+ else
+ echo "Acquire::http::Proxy \"http://$PROXY:3142\";" > /etc/apt/apt.conf.d/01proxy
+ fi
+ fi
+ ;;
+
+ l)
+ LETS_ENCRYPT_ONLY=true
+ ;;
+ g)
+ GREENLIGHT=true
+ ;;
+ a)
+ API_DEMOS=true
+ ;;
+ m)
+ LINK_PATH=$OPTARG
+ ;;
+ d)
+ PROVIDED_CERTIFICATE=true
+ ;;
+ w)
+ SSH_PORT=$(grep Port /etc/ssh/ssh_config | grep -v \# | sed 's/[^0-9]*//g')
+ if [[ -n "$SSH_PORT" && "$SSH_PORT" != "22" ]]; then
+ err "Detected sshd not listening to standard port 22 -- unable to install default UFW firewall rules. See https://docs.bigbluebutton.org/2.2/customize.html#secure-your-system--restrict-access-to-specific-ports"
+ fi
+ UFW=true
+ ;;
+ j)
+ SKIP_MIN_SERVER_REQUIREMENTS_CHECK=true
+ ;;
+ i)
+ SKIP_APACHE_INSTALLED_CHECK=true
+ ;;
+ :)
+ err "Missing option argument for -$OPTARG"
+ exit 1
+ ;;
+
+ \?)
+ err "Invalid option: -$OPTARG" >&2
+ usage
+ ;;
+ esac
+ done
+
+ if [ -n "$HOST" ]; then
+ check_host "$HOST"
+ fi
+
+ if [ -n "$VERSION" ]; then
+ check_version "$VERSION"
+ fi
+
+ if [ "$SKIP_APACHE_INSTALLED_CHECK" != true ]; then
+ check_apache2
+ fi
+
+ # Check if we're installing coturn (need an e-mail address for Let's Encrypt)
+ if [ -z "$VERSION" ] && [ -n "$COTURN" ]; then
+ if [ -z "$EMAIL" ]; then err "Installing coturn needs an e-mail address for Let's Encrypt"; fi
+ check_ubuntu 20.04
+
+ install_coturn
+ exit 0
+ fi
+
+ if [ -z "$VERSION" ]; then
+ usage
+ exit 0
+ fi
+
+ # We're installing BigBlueButton
+ env
+
+ if [ "$DISTRO" == "focal" ]; then
+ check_ubuntu 20.04
+ TOMCAT_USER=tomcat9
+ fi
+ check_mem
+ check_cpus
+
+ need_pkg software-properties-common # needed for add-apt-repository
+ sudo add-apt-repository universe
+ need_pkg wget curl gpg-agent dirmngr
+
+ # need_pkg xmlstarlet
+ get_IP "$HOST"
+
+ if [ "$DISTRO" == "focal" ]; then
+ need_pkg ca-certificates
+
+ # yq version 3 is provided by ppa:bigbluebutton/support
+ # Uncomment the following to enable yq 4 after bigbluebutton/bigbluebutton#14511 is resolved
+ #need_ppa rmescandon-ubuntu-yq-bionic.list ppa:rmescandon/yq CC86BB64 # Edit yaml files with yq
+
+ #need_ppa libreoffice-ubuntu-ppa-focal.list ppa:libreoffice/ppa 1378B444 # Latest version of libreoffice
+ need_ppa bigbluebutton-ubuntu-support-focal.list ppa:bigbluebutton/support E95B94BC # Needed for libopusenc0
+ if ! apt-key list 5AFA7A83 | grep -q -E "1024|4096"; then # Add Kurento package
+ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83
+ fi
+
+ rm -rf /etc/apt/sources.list.d/kurento.list # Kurento 6.15 now packaged with 2.3
+
+ if grep -q 12 /etc/apt/sources.list.d/nodesource.list ; then # Node 12 might be installed, previously used in BigBlueButton
+ sudo apt-get purge nodejs
+ sudo rm -r /etc/apt/sources.list.d/nodesource.list
+ fi
+ if [ ! -f /etc/apt/sources.list.d/nodesource.list ]; then
+ curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
+ fi
+ if ! apt-cache madison nodejs | grep -q node_16; then
+ err "Did not detect nodejs 16.x candidate for installation"
+ fi
+ if ! apt-key list MongoDB | grep -q 4.4; then
+ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
+ fi
+ echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
+ rm -f /etc/apt/sources.list.d/mongodb-org-4.2.list
+
+ touch /root/.rnd
+ MONGODB=mongodb-org
+ install_docker # needed for bbb-libreoffice-docker
+
+ need_pkg ruby
+
+ BBB_WEB_ETC_CONFIG=/etc/bigbluebutton/bbb-web.properties # Override file for local settings
+
+ need_pkg openjdk-11-jre java-common
+ update-java-alternatives -s java-1.11.0-openjdk-amd64
+ fi
+
+ apt-get update
+ apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" dist-upgrade
+
+ need_pkg nodejs $MONGODB apt-transport-https haveged
+ need_pkg bigbluebutton
+ need_pkg bbb-html5
+
+ if [ -f /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties ]; then
+ SERVLET_DIR=/usr/share/bbb-web
+ TURN_XML=$SERVLET_DIR/WEB-INF/classes/spring/turn-stun-servers.xml
+ fi
+
+ while [ ! -f $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties ]; do sleep 1; echo -n '.'; done
+
+ check_lxc
+ check_nat
+ check_LimitNOFILE
+
+ configure_HTML5
+
+ if [ -n "$API_DEMOS" ]; then
+ need_pkg bbb-demo
+ while [ ! -f /var/lib/$TOMCAT_USER/webapps/demo/bbb_api_conf.jsp ]; do sleep 1; echo -n '.'; done
+ fi
+
+ if [ -n "$LINK_PATH" ]; then
+ ln -s "$LINK_PATH" "/var/bigbluebutton"
+ fi
+
+ if [ -n "$PROVIDED_CERTIFICATE" ] ; then
+ install_ssl
+ elif [ -n "$HOST" ] && [ -n "$EMAIL" ] ; then
+ install_ssl
+ fi
+
+ if [ -n "$GREENLIGHT" ]; then
+ install_greenlight
+ fi
+
+ if [ -n "$COTURN" ]; then
+ configure_coturn
+ fi
+
+ apt-get auto-remove -y
+
+ if systemctl status freeswitch.service | grep -q SETSCHEDULER; then
+ sed -i "s/^CPUSchedulingPolicy=rr/#CPUSchedulingPolicy=rr/g" /lib/systemd/system/freeswitch.service
+ systemctl daemon-reload
+ fi
+
+ systemctl restart systemd-journald
+
+ if [ -n "$UFW" ]; then
+ setup_ufw
+ fi
+
+ if [ -n "$HOST" ]; then
+ bbb-conf --setip "$HOST"
+ else
+ bbb-conf --setip "$IP"
+ fi
+
+ if ! systemctl show-environment | grep LANG= | grep -q UTF-8; then
+ sudo systemctl set-environment LANG=C.UTF-8
+ fi
+
+ bbb-conf --check
+}
+
+say() {
+ echo "bbb-install: $1"
+}
+
+err() {
+ say "$1" >&2
+ exit 1
+}
+
+check_root() {
+ if [ $EUID != 0 ]; then err "You must run this command as root."; fi
+}
+
+check_mem() {
+ if awk '$1~/MemTotal/ {exit !($2<3940000)}' /proc/meminfo; then
+ echo "Your server needs to have (at least) 4G of memory."
+ if [ "$SKIP_MIN_SERVER_REQUIREMENTS_CHECK" != true ]; then
+ exit 1
+ fi
+ fi
+}
+
+check_cpus() {
+ if [ "$(nproc --all)" -lt 4 ]; then
+ echo "Your server needs to have (at least) 4 CPUs (8 recommended for production)."
+ if [ "$SKIP_MIN_SERVER_REQUIREMENTS_CHECK" != true ]; then
+ exit 1
+ fi
+ fi
+}
+
+check_ubuntu(){
+ RELEASE=$(lsb_release -r | sed 's/^[^0-9]*//g')
+ if [ "$RELEASE" != "$1" ]; then err "You must run this command on Ubuntu $1 server."; fi
+}
+
+need_x64() {
+ UNAME=`uname -m`
+ if [ "$UNAME" != "x86_64" ]; then err "You must run this command on a 64-bit server."; fi
+}
+
+wait_443() {
+ echo "Waiting for port 443 to clear "
+ # ss fields 4 and 6 are Local Address and State
+ while ss -ant | awk '{print $4, $6}' | grep TIME_WAIT | grep -q ":443"; do sleep 1; echo -n '.'; done
+ echo
+}
+
+get_IP() {
+ if [ -n "$IP" ]; then return 0; fi
+
+ # Determine local IP
+ if [ -e "/sys/class/net/venet0:0" ]; then
+ # IP detection for OpenVZ environment
+ _dev="venet0:0"
+ else
+ _dev=$(awk '$2 == 00000000 { print $1 }' /proc/net/route | head -1)
+ fi
+ _ips=$(LANG=C ip -4 -br address show dev "$_dev" | awk '{ $1=$2=""; print $0 }')
+ _ips=${_ips/127.0.0.1\/8/}
+ read -r IP _ <<< "$_ips"
+ IP=${IP/\/*} # strip subnet provided by ip address
+ if [ -z "$IP" ]; then
+ read -r IP _ <<< "$(hostname -I)"
+ fi
+
+
+ # Determine external IP
+ if grep -sqi ^ec2 /sys/devices/virtual/dmi/id/product_uuid; then
+ # EC2
+ local external_ip=$(wget -qO- http://169.254.169.254/latest/meta-data/public-ipv4)
+ elif [ -f /var/lib/dhcp/dhclient.eth0.leases ] && grep -q unknown-245 /var/lib/dhcp/dhclient.eth0.leases; then
+ # Azure
+ local external_ip=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text")
+ elif [ -f /run/scw-metadata.cache ]; then
+ # Scaleway
+ local external_ip=$(grep "PUBLIC_IP_ADDRESS" /run/scw-metadata.cache | cut -d '=' -f 2)
+ elif which dmidecode > /dev/null && dmidecode -s bios-vendor | grep -q Google; then
+ # Google Compute Cloud
+ local external_ip=$(wget -O - -q "http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" --header 'Metadata-Flavor: Google')
+ elif [ -n "$1" ]; then
+ # Try and determine the external IP from the given hostname
+ need_pkg dnsutils
+ local external_ip=$(dig +short "$1" @resolver1.opendns.com | grep '^[.0-9]*$' | tail -n1)
+ fi
+
+ # Check if the external IP reaches the internal IP
+ if [ -n "$external_ip" ] && [ "$IP" != "$external_ip" ]; then
+ if which nginx; then
+ systemctl stop nginx
+ fi
+
+ need_pkg netcat-openbsd
+
+ wait_443
+
+ nc -l -p 443 > /dev/null 2>&1 &
+ nc_PID=$!
+ sleep 1
+
+ # Check if we can reach the server through it's external IP address
+ if nc -zvw3 "$external_ip" 443 > /dev/null 2>&1; then
+ INTERNAL_IP=$IP
+ IP=$external_ip
+ echo
+ echo " Detected this server has an internal/external IP address."
+ echo
+ echo " INTERNAL_IP: $INTERNAL_IP"
+ echo " (external) IP: $IP"
+ echo
+ fi
+
+ kill $nc_PID > /dev/null 2>&1;
+
+ if which nginx; then
+ systemctl start nginx
+ fi
+ fi
+
+ if [ -z "$IP" ]; then err "Unable to determine local IP address."; fi
+}
+
+need_pkg() {
+ check_root
+ while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do echo "Sleeping for 1 second because of dpkg lock"; sleep 1; done
+
+ if [ ! "$SOURCES_FETCHED" = true ]; then
+ apt-get update
+ SOURCES_FETCHED=true
+ fi
+
+ if ! dpkg -s ${@:1} >/dev/null 2>&1; then
+ LC_CTYPE=C.UTF-8 apt-get install -yq ${@:1}
+ fi
+ while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do echo "Sleeping for 1 second because of dpkg lock"; sleep 1; done
+}
+
+need_ppa() {
+ need_pkg software-properties-common
+ if [ ! -f "/etc/apt/sources.list.d/$1" ]; then
+ LC_CTYPE=C.UTF-8 add-apt-repository -y "$2"
+ fi
+ if ! apt-key list "$3" | grep -q -E "1024|4096"; then # Let's try it a second time
+ LC_CTYPE=C.UTF-8 add-apt-repository "$2" -y
+ if ! apt-key list "$3" | grep -q -E "1024|4096"; then
+ err "Unable to setup PPA for $2"
+ fi
+ fi
+}
+
+check_version() {
+ if ! echo "$1" | grep -Eq "focal"; then err "This script can only install BigBlueButton 2.5 (or later) and is meant to be run on Ubuntu 20.04 (focal) server."; fi
+ DISTRO=$(echo "$1" | sed 's/-.*//g')
+ if ! wget -qS --spider "https://$PACKAGE_REPOSITORY/$1/dists/bigbluebutton-$DISTRO/Release.gpg" > /dev/null 2>&1; then
+ err "Unable to locate packages for $1 at $PACKAGE_REPOSITORY."
+ fi
+ check_root
+ need_pkg apt-transport-https
+ if ! apt-key list | grep -q "BigBlueButton apt-get"; then
+ wget "https://$PACKAGE_REPOSITORY/repo/bigbluebutton.asc" -O- | apt-key add -
+ fi
+
+ echo "deb https://$PACKAGE_REPOSITORY/$VERSION bigbluebutton-$DISTRO main" > /etc/apt/sources.list.d/bigbluebutton.list
+}
+
+check_host() {
+ if [ -z "$PROVIDED_CERTIFICATE" ] && [ -z "$HOST" ]; then
+ need_pkg dnsutils apt-transport-https
+ DIG_IP=$(dig +short "$1" | grep '^[.0-9]*$' | tail -n1)
+ if [ -z "$DIG_IP" ]; then err "Unable to resolve $1 to an IP address using DNS lookup."; fi
+ get_IP "$1"
+ if [ "$DIG_IP" != "$IP" ]; then err "DNS lookup for $1 resolved to $DIG_IP but didn't match local $IP."; fi
+ fi
+}
+
+check_coturn() {
+ if ! echo "$1" | grep -q ':'; then err "Option for coturn must be :"; fi
+
+ COTURN_HOST=$(echo "$OPTARG" | cut -d':' -f1)
+ COTURN_SECRET=$(echo "$OPTARG" | cut -d':' -f2)
+
+ if [ -z "$COTURN_HOST" ]; then err "-c option must contain "; fi
+ if [ -z "$COTURN_SECRET" ]; then err "-c option must contain "; fi
+
+ if [ "$COTURN_HOST" == "turn.example.com" ]; then
+ err "You must specify a valid hostname (not the example given in the docs)"
+ fi
+ if [ "$COTURN_SECRET" == "1234abcd" ]; then
+ err "You must specify a new password (not the example given in the docs)."
+ fi
+
+ check_host "$COTURN_HOST"
+}
+
+check_apache2() {
+ if dpkg -l | grep -q apache2-bin; then
+ echo "You must uninstall the Apache2 server first"
+ if [ "$SKIP_APACHE_INSTALLED_CHECK" != true ]; then
+ exit 1
+ fi
+ fi
+}
+
+# If running under LXC, then modify the FreeSWITCH systemctl service so it does not use realtime scheduler
+check_lxc() {
+ if grep -qa container=lxc /proc/1/environ; then
+ if grep IOSchedulingClass /lib/systemd/system/freeswitch.service > /dev/null; then
+ cat > /lib/systemd/system/freeswitch.service << HERE
+[Unit]
+Description=freeswitch
+After=syslog.target network.target local-fs.target
+
+[Service]
+Type=forking
+PIDFile=/opt/freeswitch/var/run/freeswitch/freeswitch.pid
+Environment="DAEMON_OPTS=-nonat"
+EnvironmentFile=-/etc/default/freeswitch
+ExecStart=/opt/freeswitch/bin/freeswitch -u freeswitch -g daemon -ncwait \$DAEMON_OPTS
+TimeoutSec=45s
+Restart=always
+WorkingDirectory=/opt/freeswitch
+User=freeswitch
+Group=daemon
+
+LimitCORE=infinity
+LimitNOFILE=100000
+LimitNPROC=60000
+LimitSTACK=250000
+LimitRTPRIO=infinity
+LimitRTTIME=7000000
+#IOSchedulingClass=realtime
+#IOSchedulingPriority=2
+#CPUSchedulingPolicy=rr
+#CPUSchedulingPriority=89
+
+[Install]
+WantedBy=multi-user.target
+HERE
+
+ systemctl daemon-reload
+ fi
+fi
+}
+
+# Check if running externally with internal/external IP addresses
+check_nat() {
+ xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_rtp_ip=")]/@data' --value "external_rtp_ip=$IP" /opt/freeswitch/conf/vars.xml
+ xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_sip_ip=")]/@data' --value "external_sip_ip=$IP" /opt/freeswitch/conf/vars.xml
+
+ if [ -n "$INTERNAL_IP" ]; then
+ xmlstarlet edit --inplace --update '//param[@name="ext-rtp-ip"]/@value' --value "\$\${external_rtp_ip}" /opt/freeswitch/conf/sip_profiles/external.xml
+ xmlstarlet edit --inplace --update '//param[@name="ext-sip-ip"]/@value' --value "\$\${external_sip_ip}" /opt/freeswitch/conf/sip_profiles/external.xml
+
+ sed -i "s/$INTERNAL_IP:/$IP:/g" /usr/share/bigbluebutton/nginx/sip.nginx
+ ip addr add "$IP" dev lo
+
+ # If dummy NIC is not in dummy-nic.service (or the file does not exist), update/create it
+ if ! grep -q "$IP" /lib/systemd/system/dummy-nic.service > /dev/null 2>&1; then
+ if [ -f /lib/systemd/system/dummy-nic.service ]; then
+ DAEMON_RELOAD=true;
+ fi
+
+ cat > /lib/systemd/system/dummy-nic.service << HERE
+[Unit]
+Description=Configure dummy NIC for FreeSWITCH
+Before=freeswitch.service
+After=network.target
+
+[Service]
+ExecStart=/sbin/ip addr add $IP dev lo
+
+[Install]
+WantedBy=multi-user.target
+HERE
+
+ if [ "$DAEMON_RELOAD" == "true" ]; then
+ systemctl daemon-reload
+ systemctl restart dummy-nic
+ else
+ systemctl enable dummy-nic
+ systemctl start dummy-nic
+ fi
+ fi
+ fi
+}
+
+check_LimitNOFILE() {
+ CPU=$(nproc --all)
+
+ if [ "$CPU" -ge 8 ]; then
+ if [ -f /lib/systemd/system/bbb-web.service ]; then
+ # Let's create an override file to increase the number of LimitNOFILE
+ mkdir -p /etc/systemd/system/bbb-web.service.d/
+ cat > /etc/systemd/system/bbb-web.service.d/override.conf << HERE
+[Service]
+LimitNOFILE=8192
+HERE
+ systemctl daemon-reload
+ fi
+ fi
+}
+
+configure_HTML5() {
+ # Use Google's default STUN server
+ if [ -n "$INTERNAL_IP" ]; then
+ sed -i "s/[;]*externalIPv4=.*/externalIPv4=$IP/g" /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini
+ sed -i "s/[;]*iceTcp=.*/iceTcp=0/g" /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini
+ fi
+}
+
+install_greenlight(){
+ install_docker
+
+ docker pull bigbluebutton/greenlight:v2 # Ensure the current version of greenlight is pulled
+
+ # Purge older docker compose
+ if dpkg -l | grep -q docker-compose; then
+ apt-get purge -y docker-compose
+ fi
+
+ if [ ! -x /usr/local/bin/docker-compose ]; then
+ curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
+ chmod +x /usr/local/bin/docker-compose
+ fi
+
+ if [ ! -d ~/greenlight ]; then
+ mkdir -p ~/greenlight
+ fi
+
+ # This will trigger the download of Greenlight docker image (if needed)
+ SECRET_KEY_BASE=$(docker run --rm bigbluebutton/greenlight:v2 bundle exec rake secret)
+
+ if [ ! -f ~/greenlight/.env ]; then
+ docker run --rm bigbluebutton/greenlight:v2 cat ./sample.env > ~/greenlight/.env
+ fi
+
+ BIGBLUEBUTTON_URL=$(cat $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties $CR_TMPFILE $BBB_WEB_ETC_CONFIG | grep -v '#' | sed -n '/^bigbluebutton.web.serverURL/{s/.*=//;p}' | tail -n 1 )/bigbluebutton/
+ BIGBLUEBUTTON_SECRET=$(cat $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties $CR_TMPFILE $BBB_WEB_ETC_CONFIG | grep -v '#' | grep ^securitySalt | tail -n 1 | cut -d= -f2)
+ SAFE_HOSTS=$(cat $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties $CR_TMPFILE $BBB_WEB_ETC_CONFIG | grep -v '#' | sed -n '/^bigbluebutton.web.serverURL/{s/.*=//;p}' | tail -n 1 | sed 's/https\?:\/\///')
+
+ # Update Greenlight configuration file in ~/greenlight/env
+ sed -i "s|SECRET_KEY_BASE=.*|SECRET_KEY_BASE=$SECRET_KEY_BASE|" ~/greenlight/.env
+ sed -i "s|.*BIGBLUEBUTTON_ENDPOINT=.*|BIGBLUEBUTTON_ENDPOINT=$BIGBLUEBUTTON_URL|" ~/greenlight/.env
+ sed -i "s|.*BIGBLUEBUTTON_SECRET=.*|BIGBLUEBUTTON_SECRET=$BIGBLUEBUTTON_SECRET|" ~/greenlight/.env
+ sed -i "s|SAFE_HOSTS=.*|SAFE_HOSTS=$SAFE_HOSTS|" ~/greenlight/.env
+
+ # need_pkg bbb-webhooks
+
+ if [ ! -f /usr/share/bigbluebutton/nginx/greenlight.nginx ]; then
+ docker run --rm bigbluebutton/greenlight:v2 cat ./greenlight.nginx | tee /usr/share/bigbluebutton/nginx/greenlight.nginx
+ cat > /usr/share/bigbluebutton/nginx/greenlight-redirect.nginx << HERE
+location = / {
+ return 307 /b;
+}
+HERE
+ systemctl restart nginx
+ fi
+
+ if ! gem list | grep -q java_properties; then
+ gem install jwt java_properties
+ fi
+
+ if [ ! -f ~/greenlight/docker-compose.yml ]; then
+ docker run --rm bigbluebutton/greenlight:v2 cat ./docker-compose.yml > ~/greenlight/docker-compose.yml
+ fi
+
+ # change the default passwords
+ PGPASSWORD=$(openssl rand -base64 24)
+ sed -i "s,^\([ \t-]*POSTGRES_PASSWORD\)\(=password\),\1=$PGPASSWORD,g" ~/greenlight/docker-compose.yml
+ sed -i "s,^\([ \t]*DB_PASSWORD\)\(=password\),\1=$PGPASSWORD,g" ~/greenlight/.env
+
+ # Remove old containers
+ if docker ps | grep -q greenlight_db_1; then
+ docker rm -f greenlight_db_1
+ fi
+ if docker ps | grep -q greenlight-v2; then
+ docker rm -f greenlight-v2
+ fi
+
+ if ! docker ps | grep -q greenlight; then
+ docker-compose -f ~/greenlight/docker-compose.yml up -d
+ sleep 5
+ fi
+}
+
+
+install_docker() {
+ need_pkg apt-transport-https ca-certificates curl gnupg-agent software-properties-common openssl
+
+ # Install Docker
+ if ! apt-key list | grep -q Docker; then
+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
+ fi
+
+ if ! dpkg -l | grep -q docker-ce; then
+ add-apt-repository \
+ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
+ $(lsb_release -cs) \
+ stable"
+
+ apt-get update
+ need_pkg docker-ce docker-ce-cli containerd.io
+ fi
+ if ! which docker; then err "Docker did not install"; fi
+
+ # Remove Docker Compose
+ if dpkg -l | grep -q docker-compose; then
+ apt-get purge -y docker-compose
+ fi
+}
+
+
+install_ssl() {
+ if ! grep -q "$HOST" /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml; then
+ bbb-conf --setip "$HOST"
+ fi
+
+ mkdir -p /etc/nginx/ssl
+
+ if [ -z "$PROVIDED_CERTIFICATE" ]; then
+ add-apt-repository universe
+ apt-get update
+ need_pkg certbot
+ fi
+
+ if [ ! -f /etc/nginx/ssl/dhp-4096.pem ]; then
+ openssl dhparam -dsaparam -out /etc/nginx/ssl/dhp-4096.pem 4096
+ fi
+
+ if [ ! -f "/etc/letsencrypt/live/$HOST/fullchain.pem" ]; then
+ rm -f /tmp/bigbluebutton.bak
+ if ! grep -q "$HOST" /etc/nginx/sites-available/bigbluebutton; then # make sure we can do the challenge
+ if [ -f /etc/nginx/sites-available/bigbluebutton ]; then
+ cp /etc/nginx/sites-available/bigbluebutton /tmp/bigbluebutton.bak
+ fi
+ cat < /etc/nginx/sites-available/bigbluebutton
+server_tokens off;
+server {
+ listen 80;
+ listen [::]:80;
+ server_name $HOST;
+
+ access_log /var/log/nginx/bigbluebutton.access.log;
+
+ # BigBlueButton landing page.
+ location / {
+ root /var/www/bigbluebutton-default;
+ index index.html index.htm;
+ expires 1m;
+ }
+}
+HERE
+ systemctl restart nginx
+ fi
+
+ if [ -z "$PROVIDED_CERTIFICATE" ]; then
+ if ! certbot --email "$EMAIL" --agree-tos --rsa-key-size 4096 -w /var/www/bigbluebutton-default/ \
+ -d "$HOST" --deploy-hook "systemctl reload nginx" $LETS_ENCRYPT_OPTIONS certonly; then
+ systemctl restart nginx
+ err "Let's Encrypt SSL request for $HOST did not succeed - exiting"
+ fi
+ else
+ # Place your fullchain.pem and privkey.pem files in /local/certs/ and bbb-install-2.5.sh will deal with the rest.
+ mkdir -p "/etc/letsencrypt/live/$HOST/"
+ ln -s /local/certs/fullchain.pem "/etc/letsencrypt/live/$HOST/fullchain.pem"
+ ln -s /local/certs/privkey.pem "/etc/letsencrypt/live/$HOST/privkey.pem"
+ fi
+ fi
+
+ cat < /etc/nginx/sites-available/bigbluebutton
+server_tokens off;
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name $HOST;
+
+ return 301 https://\$server_name\$request_uri; #redirect HTTP to HTTPS
+
+}
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name $HOST;
+
+ ssl_certificate /etc/letsencrypt/live/$HOST/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/$HOST/privkey.pem;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 10m;
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ ssl_dhparam /etc/nginx/ssl/dhp-4096.pem;
+
+ # HSTS (comment out to enable)
+ #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+ access_log /var/log/nginx/bigbluebutton.access.log;
+
+ # BigBlueButton landing page.
+ location / {
+ root /var/www/bigbluebutton-default;
+ index index.html index.htm;
+ expires 1m;
+ }
+
+ # Include specific rules for record and playback
+ include /usr/share/bigbluebutton/nginx/*.nginx;
+ include /etc/bigbluebutton/nginx/*.nginx; # possible overrides
+}
+HERE
+
+ # Configure rest of BigBlueButton Configuration for SSL
+ xmlstarlet edit --inplace --update '//param[@name="wss-binding"]/@value' --value "$IP:7443" /opt/freeswitch/conf/sip_profiles/external.xml
+
+ source /etc/bigbluebutton/bigbluebutton-release
+ if [ -n "$(echo "$BIGBLUEBUTTON_RELEASE" | grep '2.2')" ] && [ "$(echo "$BIGBLUEBUTTON_RELEASE" | cut -d\. -f3)" -lt 29 ]; then
+ sed -i "s/proxy_pass .*/proxy_pass https:\/\/$IP:7443;/g" /usr/share/bigbluebutton/nginx/sip.nginx
+ else
+ # Use nginx as proxy for WSS -> WS (see https://github.com/bigbluebutton/bigbluebutton/issues/9667)
+ yq w -i /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml public.media.sipjsHackViaWs true
+ sed -i "s/proxy_pass .*/proxy_pass http:\/\/$IP:5066;/g" /usr/share/bigbluebutton/nginx/sip.nginx
+ xmlstarlet edit --inplace --update '//param[@name="ws-binding"]/@value' --value "$IP:5066" /opt/freeswitch/conf/sip_profiles/external.xml
+ fi
+
+ sed -i 's/^bigbluebutton.web.serverURL=http:/bigbluebutton.web.serverURL=https:/g' $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties
+ if [ -f $BBB_WEB_ETC_CONFIG ]; then
+ sed -i 's/^bigbluebutton.web.serverURL=http:/bigbluebutton.web.serverURL=https:/g' $BBB_WEB_ETC_CONFIG
+ fi
+
+ yq w -i /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml playback_protocol https
+ chmod 644 /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml
+
+ if [ -f /var/lib/$TOMCAT_USER/webapps/demo/bbb_api_conf.jsp ]; then
+ sed -i 's/String BigBlueButtonURL = "http:/String BigBlueButtonURL = "https:/g' /var/lib/$TOMCAT_USER/webapps/demo/bbb_api_conf.jsp
+ fi
+
+ if [ -f /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml ]; then
+ yq w -i /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml public.note.url "https://$HOST/pad"
+ fi
+
+ # Update Greenlight (if installed) to use SSL
+ if [ -f ~/greenlight/.env ]; then
+ if ! grep ^BIGBLUEBUTTON_ENDPOINT ~/greenlight/.env | grep -q https; then
+ BIGBLUEBUTTON_URL=$(cat $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties $CR_TMPFILE $BBB_WEB_ETC_CONFIG | grep -v '#' | sed -n '/^bigbluebutton.web.serverURL/{s/.*=//;p}' | tail -n 1 )/bigbluebutton/
+ sed -i "s|.*BIGBLUEBUTTON_ENDPOINT=.*|BIGBLUEBUTTON_ENDPOINT=$BIGBLUEBUTTON_URL|" ~/greenlight/.env
+ docker-compose -f ~/greenlight/docker-compose.yml down
+ docker-compose -f ~/greenlight/docker-compose.yml up -d
+ fi
+ fi
+
+ TARGET=/usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml
+ if [ -f $TARGET ]; then
+ if grep -q kurentoIp $TARGET; then
+ # 2.0
+ yq w -i $TARGET kurentoIp "$IP"
+ else
+ # 2.2
+ yq w -i $TARGET kurento[0].ip "$IP"
+ yq w -i $TARGET freeswitch.ip "$IP"
+
+ if [ -n "$(echo "$BIGBLUEBUTTON_RELEASE" | grep '2.2')" ] && [ "$(echo "$BIGBLUEBUTTON_RELEASE" | cut -d\. -f3)" -lt 29 ]; then
+ if [ -n "$INTERNAL_IP" ]; then
+ yq w -i $TARGET freeswitch.sip_ip "$INTERNAL_IP"
+ else
+ yq w -i $TARGET freeswitch.sip_ip "$IP"
+ fi
+ else
+ # Use nginx as proxy for WSS -> WS (see https://github.com/bigbluebutton/bigbluebutton/issues/9667)
+ yq w -i $TARGET freeswitch.sip_ip "$IP"
+ fi
+ fi
+ chown bigbluebutton:bigbluebutton $TARGET
+ chmod 644 $TARGET
+ fi
+
+ mkdir -p /etc/bigbluebutton/bbb-webrtc-sfu
+ TARGET=/etc/bigbluebutton/bbb-webrtc-sfu/production.yml
+ touch $TARGET
+
+ # Configure mediasoup IPs, reference: https://raw.githubusercontent.com/bigbluebutton/bbb-webrtc-sfu/v2.7.2/docs/mediasoup.md
+ # mediasoup IPs: WebRTC
+ yq w -i "$TARGET" mediasoup.webrtc.listenIps[0].ip "0.0.0.0"
+ yq w -i "$TARGET" mediasoup.webrtc.listenIps[0].announcedIp "$IP"
+
+ # mediasoup IPs: plain RTP (internal comms, FS <-> mediasoup)
+ yq w -i "$TARGET" mediasoup.plainRtp.listenIp.ip "0.0.0.0"
+ yq w -i "$TARGET" mediasoup.plainRtp.listenIp.announcedIp "$IP"
+}
+
+configure_coturn() {
+ cat < $TURN_XML
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+HERE
+}
+
+
+install_coturn() {
+ apt-get update
+ apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" dist-upgrade
+
+ need_pkg software-properties-common certbot
+
+ if ! certbot certonly --standalone --non-interactive --preferred-challenges http \
+ -d "$COTURN_HOST" --email "$EMAIL" --agree-tos -n ; then
+ err "Let's Encrypt SSL request for $COTURN_HOST did not succeed - exiting"
+ fi
+
+ need_pkg coturn
+
+ if [ -n "$INTERNAL_IP" ]; then
+ EXTERNAL_IP="external-ip=$IP/$INTERNAL_IP"
+ fi
+
+ cat < /etc/turnserver.conf
+listening-port=3478
+tls-listening-port=443
+
+listening-ip=$IP
+relay-ip=$IP
+$EXTERNAL_IP
+
+min-port=32769
+max-port=65535
+verbose
+
+fingerprint
+lt-cred-mech
+use-auth-secret
+static-auth-secret=$COTURN_SECRET
+realm=$(echo "$COTURN_HOST" | cut -d'.' -f2-)
+
+cert=/etc/turnserver/fullchain.pem
+pkey=/etc/turnserver/privkey.pem
+# From https://ssl-config.mozilla.org/ Intermediate, openssl 1.1.0g, 2020-01
+cipher-list="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
+dh-file=/etc/turnserver/dhp.pem
+
+keep-address-family
+
+no-cli
+no-tlsv1
+no-tlsv1_1
+HERE
+
+ mkdir -p /etc/turnserver
+ if [ ! -f /etc/turnserver/dhp.pem ]; then
+ openssl dhparam -dsaparam -out /etc/turnserver/dhp.pem 2048
+ fi
+
+ mkdir -p /var/log/turnserver
+ chown turnserver:turnserver /var/log/turnserver
+
+ cat < /etc/logrotate.d/coturn
+/var/log/turnserver/*.log
+{
+ rotate 7
+ daily
+ missingok
+ notifempty
+ compress
+ postrotate
+ /bin/systemctl kill -s HUP coturn.service
+ endscript
+}
+HERE
+
+ # Eanble coturn to bind to port 443 with CAP_NET_BIND_SERVICE
+ mkdir -p /etc/systemd/system/coturn.service.d
+ rm -rf /etc/systemd/system/coturn.service.d/ansible.conf # Remove previous file
+ cat > /etc/systemd/system/coturn.service.d/override.conf < /etc/letsencrypt/renewal-hooks/deploy/coturn < /etc/bigbluebutton/bbb-conf/apply-config.sh << HERE
+#!/bin/bash
+
+# Pull in the helper functions for configuring BigBlueButton
+source /etc/bigbluebutton/bbb-conf/apply-lib.sh
+
+enableUFWRules
+HERE
+ chmod +x /etc/bigbluebutton/bbb-conf/apply-config.sh
+ fi
+}
+
+main "$@" || exit 1
+
diff --git a/roles/bbb_install/files/bbb-install-2.7.sh b/roles/bbb_install/files/bbb-install-2.7.sh
new file mode 100644
index 0000000..4d41f1c
--- /dev/null
+++ b/roles/bbb_install/files/bbb-install-2.7.sh
@@ -0,0 +1,1889 @@
+#!/bin/bash -e
+
+# Copyright (c) 2023 BigBlueButton Inc.
+#
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see .
+
+# BigBlueButton is an open source conferencing system. For more information see
+# https://www.bigbluebutton.org/.
+#
+# This bbb-install.sh script automates many of the installation and configuration
+# steps at https://docs.bigbluebutton.org/2.7/administration/install
+#
+#
+# Examples
+#
+# Install BigBlueButton 2.7.x with a SSL certificate from Let's Encrypt using hostname bbb.example.com
+# and email address info@example.com and apply a basic firewall
+#
+# wget -qO- https://raw.githubusercontent.com/bigbluebutton/bbb-install/v2.7.x-release/bbb-install.sh | bash -s -- -w -v focal-270 -s bbb.example.com -e info@example.com
+#
+# Install BigBlueButton with SSL + Greenlight
+#
+# wget -qO- https://raw.githubusercontent.com/bigbluebutton/bbb-install/v2.7.x-release/bbb-install.sh | bash -s -- -w -v focal-270 -s bbb.example.com -e info@example.com -g
+#
+
+usage() {
+ set +x
+ cat 1>&2 < Install given version of BigBlueButton (e.g. 'focal-270') (required)
+
+ -s Configure server with
+ -e Email for Let's Encrypt certbot
+
+ -x Use Let's Encrypt certbot with manual DNS challenges
+
+ -g Install Greenlight version 3
+ -k Install Keycloak version 20
+
+ -t : Install BigBlueButton LTI framework tools and add/update LTI consumer credentials :
+
+ -c : Configure with external coturn server at using (instead of built-in TURN server)
+
+ -m Create a Symbolic link from /var/bigbluebutton to
+
+ -p [:] Use apt-get proxy at (default port 3142)
+ -r Use alternative apt repository (such as packages-eu.bigbluebutton.org)
+
+ -d Skip SSL certificates request (use provided certificates from mounted volume) in /local/certs/
+ -w Install UFW firewall (recommended)
+
+ -j Allows the installation of BigBlueButton to proceed even if not all requirements [for production use] are met.
+ Note that not all requirements can be ignored. This is useful in development / testing / ci scenarios.
+
+ -i Allows the installation of BigBlueButton to proceed even if Apache webserver is installed.
+
+ -h Print help
+
+OPTIONS (install Let's Encrypt certificate only):
+
+ -s Configure server with (required)
+ -e Configure email for Let's Encrypt certbot (required)
+ -l Only install Let's Encrypt certificate (not BigBlueButton)
+ -x Use Let's Encrypt certbot with manual dns challenges (optional)
+
+OPTIONS (install Greenlight only):
+
+ -g Install Greenlight version 3 (required)
+ -k Install Keycloak version 20 (optional)
+
+OPTIONS (install BigBlueButton LTI framework only):
+
+ -t : Install BigBlueButton LTI framework tools and add/update LTI consumer credentials : (required)
+
+VARIABLES (configure Greenlight only):
+ GL_PATH Configure Greenlight relative URL root path (Optional)
+ * Use this when deploying Greenlight behind a reverse proxy on a path other than the default '/' e.g. '/gl'.
+
+
+EXAMPLES:
+
+Sample options for setup a BigBlueButton 2.7 server
+
+ -v focal-270 -s bbb.example.com -e info@example.com
+
+Sample options for setup a BigBlueButton 2.7 server with Greenlight 3 and optionally Keycloak
+
+ -v focal-270 -s bbb.example.com -e info@example.com -g [-k]
+
+Sample options for setup a BigBlueButton 2.7 server with LTI framework while managing LTI consumer credentials MY_KEY:MY_SECRET
+
+ -v focal-270 -s bbb.example.com -e info@example.com -t MY_KEY:MY_SECRET
+
+SUPPORT:
+ Community: https://bigbluebutton.org/support
+ Docs: https://github.com/bigbluebutton/bbb-install
+ https://docs.bigbluebutton.org/administration/install/#minimum-server-requirements
+
+HERE
+}
+
+main() {
+ export DEBIAN_FRONTEND=noninteractive
+ PACKAGE_REPOSITORY=ubuntu.bigbluebutton.org
+ LETS_ENCRYPT_OPTIONS=(--webroot --non-interactive)
+ SOURCES_FETCHED=false
+ GL3_DIR=~/greenlight-v3
+ LTI_DIR=~/bbb-lti
+ NGINX_FILES_DEST=/usr/share/bigbluebutton/nginx
+ CR_TMPFILE=$(mktemp /tmp/carriage-return.XXXXXX)
+ printf '\n' > "$CR_TMPFILE"
+
+ need_x64
+
+ while builtin getopts "hs:r:c:v:e:p:m:t:xgadwjik" opt "${@}"; do
+
+ case $opt in
+ h)
+ usage
+ exit 0
+ ;;
+
+ s)
+ HOST=$OPTARG
+ if [ "$HOST" == "bbb.example.com" ]; then
+ err "You must specify a valid hostname (not the hostname given in the docs)."
+ fi
+ ;;
+ r)
+ PACKAGE_REPOSITORY=$OPTARG
+ ;;
+ e)
+ EMAIL=$OPTARG
+ if [ "$EMAIL" == "info@example.com" ]; then
+ err "You must specify a valid email address (not the email in the docs)."
+ fi
+ ;;
+ x)
+ LETS_ENCRYPT_OPTIONS=(--manual --preferred-challenges dns)
+ ;;
+ c)
+ COTURN=$OPTARG
+ check_coturn "$COTURN"
+ ;;
+ v)
+ VERSION=$OPTARG
+ ;;
+
+ p)
+ PROXY=$OPTARG
+ if [ -n "$PROXY" ]; then
+ if [[ "$PROXY" =~ : ]]; then
+ echo "Acquire::http::Proxy \"http://$PROXY\";" > /etc/apt/apt.conf.d/01proxy
+ else
+ echo "Acquire::http::Proxy \"http://$PROXY:3142\";" > /etc/apt/apt.conf.d/01proxy
+ fi
+ fi
+ ;;
+
+ g)
+ GREENLIGHT=true
+ GL_DEFAULT_PATH=/
+
+ if [ -n "$GL_PATH" ] && [ "$GL_PATH" != "$GL_DEFAULT_PATH" ]; then
+ if [[ ! $GL_PATH =~ ^/.*[^/]$ ]]; then
+ err "\$GL_PATH ENV is set to '$GL_PATH' which is invalid, Greenlight relative URL root path must start but not end with '/'."
+ fi
+ fi
+ ;;
+ k)
+ INSTALL_KC=true
+ ;;
+ t)
+ LTI_CREDS_STR=$OPTARG
+
+ if [ "$LTI_CREDS_STR" == "MY_KEY:MY_SECRET" ]; then
+ err "You must use a valid complex credentials for your LTI setup (not the ones in the example)."
+ fi
+
+ if [[ ! $LTI_CREDS_STR == *:* ]]; then
+ err "You must respect the format : when specifying your LTI credentials."
+ fi
+
+ # Making LTI_CREDS an array, first element is the LTI TC key and the second is the LTI TC secret.
+ IFS=: read -ra LTI_CREDS <<<"${LTI_CREDS_STR}"
+ ;;
+ a)
+ err "Error: bbb-demo (API demos, '-a' option) were deprecated in BigBlueButton 2.6. Please use Greenlight or API MATE"
+ ;;
+ m)
+ LINK_PATH=$OPTARG
+ ;;
+ d)
+ PROVIDED_CERTIFICATE=true
+ ;;
+ w)
+ SSH_PORT=$(grep Port /etc/ssh/ssh_config | grep -v \# | sed 's/[^0-9]*//g')
+ if [[ -n "$SSH_PORT" && "$SSH_PORT" != "22" ]]; then
+ err "Detected sshd not listening to standard port 22 -- unable to install default UFW firewall rules. See https://docs.bigbluebutton.org/2.2/customize.html#secure-your-system--restrict-access-to-specific-ports"
+ fi
+ UFW=true
+ ;;
+ j)
+ SKIP_MIN_SERVER_REQUIREMENTS_CHECK=true
+ ;;
+ i)
+ SKIP_APACHE_INSTALLED_CHECK=true
+ ;;
+ :)
+ err "Missing option argument for -$OPTARG"
+ ;;
+
+ \?)
+ usage_err "Invalid option: -$OPTARG" >&2
+ ;;
+ esac
+ done
+
+ if [ -n "$HOST" ]; then
+ check_host "$HOST"
+ fi
+
+ if [ -n "$VERSION" ]; then
+ check_version "$VERSION"
+ fi
+
+ if [ "$SKIP_APACHE_INSTALLED_CHECK" != true ]; then
+ check_apache2
+ fi
+
+ # Check if we're installing coturn (need an e-mail address for Let's Encrypt)
+ if [ -z "$VERSION" ] && [ -n "$COTURN" ]; then
+ if [ -z "$EMAIL" ]; then err "Installing coturn needs an e-mail address for Let's Encrypt"; fi
+ check_ubuntu 20.04
+
+ install_coturn
+ exit 0
+ fi
+
+ if [ -z "$VERSION" ]; then
+ usage
+ exit 0
+ fi
+
+ if [ -n "$INSTALL_KC" ] && [ -z "$GREENLIGHT" ]; then
+ err "Keycloak cannot be installed without Greenlight."
+ fi
+
+ # We're installing BigBlueButton
+ env
+
+ check_mem
+ check_cpus
+ check_ipv6
+
+ need_pkg software-properties-common # needed for add-apt-repository
+ sudo add-apt-repository universe
+ need_pkg wget curl gpg-agent dirmngr apparmor-utils
+
+ # need_pkg xmlstarlet
+ get_IP "$HOST"
+
+ if [ "$DISTRO" == "focal" ]; then
+ need_pkg ca-certificates
+
+ # yq version 3 is provided by ppa:bigbluebutton/support
+ # Uncomment the following to enable yq 4 after bigbluebutton/bigbluebutton#14511 is resolved
+ #need_ppa rmescandon-ubuntu-yq-bionic.list ppa:rmescandon/yq CC86BB64 # Edit yaml files with yq
+
+ #need_ppa libreoffice-ubuntu-ppa-focal.list ppa:libreoffice/ppa 1378B444 # Latest version of libreoffice
+ need_ppa bigbluebutton-ubuntu-support-focal.list ppa:bigbluebutton/support 2E1B01D0E95B94BC # Needed for libopusenc0
+ need_ppa martin-uni-mainz-ubuntu-coturn-focal.list ppa:martin-uni-mainz/coturn 4B77C2225D3BBDB3 # Coturn
+
+ if ! apt-key list 5AFA7A83 | grep -q -E "1024|4096"; then # Add Kurento package
+ sudo apt-key adv --keyserver https://keyserver.ubuntu.com --recv-keys 5AFA7A83
+ fi
+
+ rm -rf /etc/apt/sources.list.d/kurento.list # Kurento 6.15 now packaged with 2.3
+
+ if [ -f /etc/apt/sources.list.d/nodesource.list ] && grep -q 16 /etc/apt/sources.list.d/nodesource.list; then
+ # Node 16 might be installed, previously used in BigBlueButton
+ # Remove the repository config. This will cause the repository to get
+ # re-added using the current nodejs version, and nodejs will be upgraded.
+ sudo rm -r /etc/apt/sources.list.d/nodesource.list
+ fi
+ if [ ! -f /etc/apt/sources.list.d/nodesource.list ]; then
+ sudo mkdir -p /etc/apt/keyrings
+ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
+ NODE_MAJOR=18
+ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
+ fi
+ if ! apt-key list MongoDB | grep -q 4.4; then
+ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
+ fi
+ echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
+ rm -f /etc/apt/sources.list.d/mongodb-org-4.2.list
+
+ touch /root/.rnd
+ MONGODB=mongodb-org
+ install_docker # needed for bbb-libreoffice-docker
+ need_pkg ruby
+
+ BBB_WEB_ETC_CONFIG=/etc/bigbluebutton/bbb-web.properties # Override file for local settings
+
+ need_pkg openjdk-17-jre
+ update-java-alternatives -s java-1.17.0-openjdk-amd64
+
+ # Remove old bbb-demo if installed from a previous 2.5 setup
+ if dpkg -s bbb-demo > /dev/null 2>&1; then
+ apt purge -y bbb-demo tomcat9
+ rm -rf /var/lib/tomcat9
+ fi
+ fi
+
+ apt-get update
+ apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" dist-upgrade
+
+ need_pkg nodejs "$MONGODB" apt-transport-https haveged
+ need_pkg bigbluebutton
+ need_pkg bbb-html5
+
+ if [ -f /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties ]; then
+ SERVLET_DIR=/usr/share/bbb-web
+ fi
+
+ while [ ! -f "$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties" ]; do sleep 1; echo -n '.'; done
+
+ check_cap_sys_nice
+ check_nat
+ check_LimitNOFILE
+
+ configure_HTML5
+
+ if [ -n "$LINK_PATH" ]; then
+ ln -s "$LINK_PATH" "/var/bigbluebutton"
+ fi
+
+ if [ -n "$PROVIDED_CERTIFICATE" ] ; then
+ install_ssl
+ elif [ -n "$HOST" ] && [ -n "$EMAIL" ] ; then
+ install_ssl
+ fi
+
+ if [ -n "$COTURN" ]; then
+ configure_coturn
+
+ if systemctl is-active --quiet haproxy.service; then
+ systemctl disable --now haproxy.service
+ fi
+ else
+ install_coturn
+ install_haproxy
+ systemctl enable --now haproxy.service # In case we had previously disabled (see above)
+
+ # The turn server will always try to connect to the BBB server's public IP address,
+ # so if NAT is in use, add an iptables rule to adjust the destination IP address
+ # of UDP packets sent from the turn server to FreeSWITCH.
+ if [ -n "$INTERNAL_IP" ]; then
+ need_pkg iptables-persistent
+ iptables -t nat -A OUTPUT -p udp -s "$INTERNAL_IP" -d "$IP" -j DNAT --to-destination "$INTERNAL_IP"
+ netfilter-persistent save
+ fi
+ fi
+
+ apt-get auto-remove -y
+
+ systemctl restart systemd-journald
+
+ if [ -n "$UFW" ]; then
+ setup_ufw
+ fi
+
+ if [ -n "$HOST" ]; then
+ bbb-conf --setip "$HOST"
+ else
+ bbb-conf --setip "$IP"
+ fi
+
+ if ! systemctl show-environment | grep LANG= | grep -q UTF-8; then
+ sudo systemctl set-environment LANG=C.UTF-8
+ fi
+
+ # BBB ecosystem apps:
+ if [[ ${#LTI_CREDS[*]} -eq 2 ]]; then
+ install_lti
+ fi
+
+ if [ -n "$GREENLIGHT" ]; then
+ install_greenlight_v3
+ fi
+
+ bbb-conf --check
+}
+
+say() {
+ echo "bbb-install: $1"
+}
+
+err() {
+ say "$1" >&2
+ exit 1
+}
+
+usage_err() {
+ say "$1" >&2
+ usage
+ exit 1
+}
+
+check_root() {
+ if [ $EUID != 0 ]; then err "You must run this command as root."; fi
+}
+
+check_mem() {
+ if awk '$1~/MemTotal/ {exit !($2<3940000)}' /proc/meminfo; then
+ echo "Your server needs to have (at least) 4G of memory."
+ if [ "$SKIP_MIN_SERVER_REQUIREMENTS_CHECK" != true ]; then
+ exit 1
+ fi
+ fi
+}
+
+check_ipv6() {
+ if [ ! -f /proc/net/if_inet6 ]; then
+ echo "Your server does not support IPV6"
+ if [ "$SKIP_MIN_SERVER_REQUIREMENTS_CHECK" != true ]; then
+ exit 1
+ fi
+ fi
+}
+
+check_cpus() {
+ if [ "$(nproc --all)" -lt 4 ]; then
+ echo "Your server needs to have (at least) 4 CPUs (8 recommended for production)."
+ if [ "$SKIP_MIN_SERVER_REQUIREMENTS_CHECK" != true ]; then
+ exit 1
+ fi
+ fi
+}
+
+check_ubuntu(){
+ RELEASE=$(lsb_release -r | sed 's/^[^0-9]*//g')
+ if [ "$RELEASE" != "$1" ]; then err "You must run this command on Ubuntu $1 server."; fi
+}
+
+need_x64() {
+ UNAME=$(uname -m)
+ if [ "$UNAME" != "x86_64" ]; then err "You must run this command on a 64-bit server."; fi
+}
+
+wait_443() {
+ echo "Waiting for port 443 to clear "
+ # ss fields 4 and 6 are Local Address and State
+ while ss -ant | awk '{print $4, $6}' | grep TIME_WAIT | grep -q ":443"; do sleep 1; echo -n '.'; done
+ echo
+}
+
+get_IP() {
+ if [ -n "$IP" ]; then return 0; fi
+
+ # Determine local IP
+ if [ -e "/sys/class/net/venet0:0" ]; then
+ # IP detection for OpenVZ environment
+ _dev="venet0:0"
+ else
+ _dev=$(awk '$2 == 00000000 { print $1 }' /proc/net/route | head -1)
+ fi
+ _ips=$(LANG=C ip -4 -br address show dev "$_dev" | awk '{ $1=$2=""; print $0 }')
+ _ips=${_ips/127.0.0.1\/8/}
+ read -r IP _ <<< "$_ips"
+ IP=${IP/\/*} # strip subnet provided by ip address
+ if [ -z "$IP" ]; then
+ read -r IP _ <<< "$(hostname -I)"
+ fi
+
+
+ local external_ip
+ # Determine external IP
+ if grep -sqi ^ec2 /sys/devices/virtual/dmi/id/product_uuid; then
+ # EC2
+ external_ip=$(wget -qO- http://169.254.169.254/latest/meta-data/public-ipv4)
+ elif [ -f /var/lib/dhcp/dhclient.eth0.leases ] && grep -q unknown-245 /var/lib/dhcp/dhclient.eth0.leases; then
+ # Azure
+ external_ip=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text")
+ elif [ -f /run/scw-metadata.cache ]; then
+ # Scaleway
+ external_ip=$(grep "PUBLIC_IP_ADDRESS" /run/scw-metadata.cache | cut -d '=' -f 2)
+ elif which dmidecode > /dev/null && dmidecode -s bios-vendor | grep -q Google; then
+ # Google Compute Cloud
+ external_ip=$(wget -O - -q "http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" --header 'Metadata-Flavor: Google')
+ elif [ -n "$1" ]; then
+ # Try and determine the external IP from the given hostname
+ need_pkg dnsutils
+ external_ip=$(dig +short "$1" @resolver1.opendns.com | grep '^[.0-9]*$' | tail -n1)
+ fi
+
+ # Check if the external IP reaches the internal IP
+ if [ -n "$external_ip" ] && [ "$IP" != "$external_ip" ]; then
+ if which nginx; then
+ systemctl stop nginx
+ fi
+
+ need_pkg netcat-openbsd
+
+ wait_443
+
+ nc -l -p 443 > /dev/null 2>&1 &
+ nc_PID=$!
+ sleep 1
+
+ # Check if we can reach the server through it's external IP address
+ if nc -zvw3 "$external_ip" 443 > /dev/null 2>&1; then
+ INTERNAL_IP=$IP
+ IP=$external_ip
+ echo
+ echo " Detected this server has an internal/external IP address."
+ echo
+ echo " INTERNAL_IP: $INTERNAL_IP"
+ echo " (external) IP: $IP"
+ echo
+ fi
+
+ kill $nc_PID > /dev/null 2>&1;
+
+ if which nginx; then
+ systemctl start nginx
+ fi
+ fi
+
+ if [ -z "$IP" ]; then err "Unable to determine local IP address."; fi
+}
+
+need_pkg() {
+ check_root
+ while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do echo "Sleeping for 1 second because of dpkg lock"; sleep 1; done
+
+ if [ ! "$SOURCES_FETCHED" = true ]; then
+ apt-get update
+ SOURCES_FETCHED=true
+ fi
+
+ if ! dpkg -s "${@}" >/dev/null 2>&1; then
+ LC_CTYPE=C.UTF-8 apt-get install -yq "${@}"
+ fi
+ while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do echo "Sleeping for 1 second because of dpkg lock"; sleep 1; done
+}
+
+need_ppa() {
+ need_pkg software-properties-common
+ if [ ! -f "/etc/apt/sources.list.d/$1" ]; then
+ LC_CTYPE=C.UTF-8 add-apt-repository -y "$2"
+ fi
+ if ! apt-key list "$3" | grep -q -E "1024|4096"; then # Let's try it a second time
+ LC_CTYPE=C.UTF-8 add-apt-repository "$2" -y
+ if ! apt-key list "$3" | grep -q -E "1024|4096"; then
+ err "Unable to setup PPA for $2"
+ fi
+ fi
+}
+
+check_version() {
+ if ! echo "$1" | grep -Eq "focal-27"; then err "This script can only install BigBlueButton 2.7 and is meant to be run on Ubuntu 20.04 (focal) server."; fi
+ DISTRO=${1%%-*}
+ if ! wget -qS --spider "https://$PACKAGE_REPOSITORY/$1/dists/bigbluebutton-$DISTRO/Release.gpg" > /dev/null 2>&1; then
+ err "Unable to locate packages for $1 at $PACKAGE_REPOSITORY."
+ fi
+ check_root
+ need_pkg apt-transport-https
+ if ! apt-key list | grep -q "BigBlueButton apt-get"; then
+ wget "https://$PACKAGE_REPOSITORY/repo/bigbluebutton.asc" -O- | apt-key add -
+ fi
+
+ echo "deb https://$PACKAGE_REPOSITORY/$VERSION bigbluebutton-$DISTRO main" > /etc/apt/sources.list.d/bigbluebutton.list
+}
+
+check_host() {
+ if [ -z "$PROVIDED_CERTIFICATE" ] && [ -z "$HOST" ]; then
+ need_pkg dnsutils apt-transport-https
+ DIG_IP=$(dig +short "$1" | grep '^[.0-9]*$' | tail -n1)
+ if [ -z "$DIG_IP" ]; then err "Unable to resolve $1 to an IP address using DNS lookup."; fi
+ get_IP "$1"
+ if [ "$DIG_IP" != "$IP" ]; then err "DNS lookup for $1 resolved to $DIG_IP but didn't match local $IP."; fi
+ fi
+}
+
+check_coturn() {
+ if ! echo "$1" | grep -q ':'; then err "Option for coturn must be :"; fi
+
+ COTURN_HOST=$(echo "$OPTARG" | cut -d':' -f1)
+ COTURN_SECRET=$(echo "$OPTARG" | cut -d':' -f2)
+
+ if [ -z "$COTURN_HOST" ]; then err "-c option must contain "; fi
+ if [ -z "$COTURN_SECRET" ]; then err "-c option must contain "; fi
+
+ if [ "$COTURN_HOST" == "turn.example.com" ]; then
+ err "You must specify a valid hostname (not the example given in the docs)"
+ fi
+ if [ "$COTURN_SECRET" == "1234abcd" ]; then
+ err "You must specify a new password (not the example given in the docs)."
+ fi
+
+ check_host "$COTURN_HOST"
+}
+
+check_apache2() {
+ if dpkg -l | grep -q apache2-bin; then
+ echo "You must uninstall the Apache2 server first"
+ if [ "$SKIP_APACHE_INSTALLED_CHECK" != true ]; then
+ exit 1
+ fi
+ fi
+}
+
+# If CAP_SYS_NICE is not available, then the FreeSWITCH systemctl service
+# will fail to start, with an error message like "status=214/SETSCHEDULER".
+# In this case we need to modify this service so that it does not require a realtime scheduler.
+# A similar modification needs to be done to a couple of other services as well,
+# like: bbb-html5-frontend@.service, bbb-html5-backend@.service and bbb-webrtc-sfu.service
+check_cap_sys_nice() {
+ # if we don't detect a SETSCHEDULER error message in the status of the service,
+ # then there is nothing to be modified/customized
+ { systemctl status freeswitch | grep -q SETSCHEDULER; } || return
+
+ # override /lib/systemd/system/freeswitch.service so that it does not use realtime scheduler
+ mkdir -p /etc/systemd/system/freeswitch.service.d
+ cat < /etc/systemd/system/freeswitch.service.d/override.conf
+[Service]
+IOSchedulingClass=
+IOSchedulingPriority=
+CPUSchedulingPolicy=
+CPUSchedulingPriority=
+HERE
+
+ # override /usr/lib/systemd/system/bbb-html5-frontend@.service
+ mkdir -p /etc/systemd/system/bbb-html5-frontend@.service.d
+ cat < /etc/systemd/system/bbb-html5-frontend@.service.d/override.conf
+[Service]
+CPUSchedulingPolicy=
+HERE
+
+ # override /usr/lib/systemd/system/bbb-html5-backend@.service
+ mkdir -p /etc/systemd/system/bbb-html5-backend@.service.d
+ cat < /etc/systemd/system/bbb-html5-backend@.service.d/override.conf
+[Service]
+CPUSchedulingPolicy=
+HERE
+
+ # override /usr/lib/systemd/system/bbb-webrtc-sfu.service
+ mkdir -p /etc/systemd/system/bbb-webrtc-sfu.service.d
+ cat < /etc/systemd/system/bbb-webrtc-sfu.service.d/override.conf
+[Service]
+CPUSchedulingPolicy=
+HERE
+
+ systemctl daemon-reload
+}
+
+# Check if running externally with internal/external IP addresses
+check_nat() {
+ xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_rtp_ip=")]/@data' --value "external_rtp_ip=$IP" /opt/freeswitch/conf/vars.xml
+ xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_sip_ip=")]/@data' --value "external_sip_ip=$IP" /opt/freeswitch/conf/vars.xml
+
+ if [ -n "$INTERNAL_IP" ]; then
+ xmlstarlet edit --inplace --update '//param[@name="ext-rtp-ip"]/@value' --value "\$\${external_rtp_ip}" /opt/freeswitch/conf/sip_profiles/external.xml
+ xmlstarlet edit --inplace --update '//param[@name="ext-sip-ip"]/@value' --value "\$\${external_sip_ip}" /opt/freeswitch/conf/sip_profiles/external.xml
+
+ sed -i "s/$INTERNAL_IP:/$IP:/g" /usr/share/bigbluebutton/nginx/sip.nginx
+ ip addr add "$IP" dev lo
+
+ # If dummy NIC is not in dummy-nic.service (or the file does not exist), update/create it
+ if ! grep -q "$IP" /lib/systemd/system/dummy-nic.service > /dev/null 2>&1; then
+ if [ -f /lib/systemd/system/dummy-nic.service ]; then
+ DAEMON_RELOAD=true;
+ fi
+
+ cat > /lib/systemd/system/dummy-nic.service << HERE
+[Unit]
+Description=Configure dummy NIC for FreeSWITCH
+Before=freeswitch.service
+After=network.target
+
+[Service]
+ExecStart=/sbin/ip addr add $IP dev lo
+
+[Install]
+WantedBy=multi-user.target
+HERE
+
+ if [ "$DAEMON_RELOAD" == "true" ]; then
+ systemctl daemon-reload
+ systemctl restart dummy-nic
+ else
+ systemctl enable dummy-nic
+ systemctl start dummy-nic
+ fi
+ fi
+ fi
+}
+
+check_LimitNOFILE() {
+ CPU=$(nproc --all)
+
+ if [ "$CPU" -ge 8 ]; then
+ if [ -f /lib/systemd/system/bbb-web.service ]; then
+ # Let's create an override file to increase the number of LimitNOFILE
+ mkdir -p /etc/systemd/system/bbb-web.service.d/
+ cat > /etc/systemd/system/bbb-web.service.d/override.conf << HERE
+[Service]
+LimitNOFILE=8192
+HERE
+ systemctl daemon-reload
+ fi
+ fi
+}
+
+configure_HTML5() {
+ # Use Google's default STUN server
+ if [ -n "$INTERNAL_IP" ]; then
+ sed -i "s/[;]*externalIPv4=.*/externalIPv4=$IP/g" /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini
+ sed -i "s/[;]*iceTcp=.*/iceTcp=0/g" /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini
+ fi
+}
+
+install_haproxy() {
+ need_pkg haproxy
+ if [ -n "$INTERNAL_IP" ]; then
+ TURN_IP="$INTERNAL_IP"
+ else
+ TURN_IP="$IP"
+ fi
+ HAPROXY_CFG=/etc/haproxy/haproxy.cfg
+ cat > "$HAPROXY_CFG" < /etc/haproxy/protocolmap
+ chmod 0644 /etc/haproxy/protocolmap
+
+ # cert renewal
+ mkdir -p /etc/letsencrypt/renewal-hooks/deploy
+ cat > /etc/letsencrypt/renewal-hooks/deploy/haproxy < /etc/haproxy/certbundle.pem.new
+chown root:haproxy /etc/haproxy/certbundle.pem.new
+mv /etc/haproxy/certbundle.pem.new /etc/haproxy/certbundle.pem
+systemctl reload haproxy
+HERE
+ chmod 0755 /etc/letsencrypt/renewal-hooks/deploy/haproxy
+ /etc/letsencrypt/renewal-hooks/deploy/haproxy
+}
+
+# This function will install the latest official version of greenlight-v3 and set it as the hosting Bigbluebutton default frontend or update greenlight-v3 if installed.
+# Greenlight is a simple to use Bigbluebutton room manager that offers a set of features useful to online workloads especially virtual schooling.
+# https://docs.bigbluebutton.org/greenlight/gl-overview.html
+install_greenlight_v3(){
+ # This function depends on the following files existing on their expected location so an eager check is done asserting that.
+ if [[ -z $SERVLET_DIR || ! -f $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties || ! -f $CR_TMPFILE || ! -f $BBB_WEB_ETC_CONFIG ]]; then
+ err "greenlight-v3 failed to install/update due to unmet requirements, have you followed the recommended steps to install Bigbluebutton?"
+ fi
+
+ check_root
+ install_docker
+
+ # Preparing and checking the enviroment.
+ say "preparing and checking the enviroment to install/update greelight-v3..."
+
+ if [ ! -d $GL3_DIR ]; then
+ mkdir -p $GL3_DIR && say "created $GL3_DIR"
+ fi
+
+ local GL_IMG_REPO=bigbluebutton/greenlight:v3
+
+ say "pulling latest $GL_IMG_REPO image..."
+ docker pull $GL_IMG_REPO
+
+ if [ ! -s $GL3_DIR/docker-compose.yml ]; then
+ docker run --rm --entrypoint sh $GL_IMG_REPO -c 'cat docker-compose.yml' > $GL3_DIR/docker-compose.yml
+
+ if [ ! -s $GL3_DIR/docker-compose.yml ]; then
+ err "failed to create docker compose file - is docker running?"
+ fi
+
+ say "greenlight-v3 docker compose file was created"
+ fi
+
+ # Configuring Greenlight v3.
+ say "checking the configuration of greenlight-v3..."
+
+ local ROOT_URL BIGBLUEBUTTON_URL BIGBLUEBUTTON_SECRET
+ ROOT_URL=$(cat "$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties" "$CR_TMPFILE" "$BBB_WEB_ETC_CONFIG" | grep -v '#' | sed -n '/^bigbluebutton.web.serverURL/{s/.*=//;p}' | tail -n 1 )
+ BIGBLUEBUTTON_URL=$ROOT_URL/bigbluebutton/
+ BIGBLUEBUTTON_SECRET=$(cat "$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties" "$CR_TMPFILE" "$BBB_WEB_ETC_CONFIG" | grep -v '#' | grep ^securitySalt | tail -n 1 | cut -d= -f2)
+
+ # Configuring Greenlight v3 docker-compose.yml (if configured no side effect will happen).
+ sed -i "s|^\([ \t-]*POSTGRES_PASSWORD\)\(=[ \t]*\)$|\1=$(openssl rand -hex 24)|g" $GL3_DIR/docker-compose.yml # Do not overwrite the value if not empty.
+
+ local PGUSER=postgres # Postgres db user to be used by greenlight-v3.
+ local PGTXADDR=postgres:5432 # Postgres DB transport address (pair of (@ip:@port)).
+ local RSTXADDR=redis:6379 # Redis DB transport address (pair of (@ip:@port)).
+ local PGPASSWORD
+ PGPASSWORD=$(sed -ne "s/^\([ \t-]*POSTGRES_PASSWORD=\)\(.*\)$/\2/p" $GL3_DIR/docker-compose.yml) # Extract generated Postgres password.
+
+ if [ -z "$PGPASSWORD" ]; then
+ err "failed to retrieve greenlight-v3 DB password - retry to resolve."
+ fi
+
+ local DATABASE_URL_ROOT="postgres://$PGUSER:$PGPASSWORD@$PGTXADDR"
+ local REDIS_URL_ROOT="redis://$RSTXADDR"
+
+ local PGDBNAME=greenlight-v3-production
+ local SECRET_KEY_BASE
+ SECRET_KEY_BASE=$(docker run --rm --entrypoint bundle $GL_IMG_REPO exec rails secret)
+
+ if [ -z "$SECRET_KEY_BASE" ]; then
+ err "failed to generate greenlight-v3 secret key base - is docker running?"
+ fi
+
+ if [ ! -s $GL3_DIR/.env ]; then
+ docker run --rm --entrypoint sh $GL_IMG_REPO -c 'cat sample.env' > $GL3_DIR/.env
+
+ if [ ! -s $GL3_DIR/.env ]; then
+ err "failed to create greenlight-v3 .env file - is docker running?"
+ fi
+
+ say "greenlight-v3 .env file was created"
+ fi
+
+ # A note for future maintainers:
+ # The following configuration operations were made idempotent, meaning that playing these actions will have an outcome on the system (configure it) only once.
+ # Replaying these steps are a safe and an expected operation, this gurantees the seemless simple installation and upgrade of Greenlight v3.
+ # A simple change can impact that property and therefore render the upgrading functionnality unoperationnal or impact the running system.
+
+ # Configuring Greenlight v3 .env file (if already configured this will only update the BBB endpoint and secret).
+ cp -v $GL3_DIR/.env $GL3_DIR/.env.old && say "old .env file can be retrieved at $GL3_DIR/.env.old" #Backup
+
+ sed -i "s|^[# \t]*BIGBLUEBUTTON_ENDPOINT=.*|BIGBLUEBUTTON_ENDPOINT=$BIGBLUEBUTTON_URL|" $GL3_DIR/.env
+ sed -i "s|^[# \t]*BIGBLUEBUTTON_SECRET=.*|BIGBLUEBUTTON_SECRET=$BIGBLUEBUTTON_SECRET|" $GL3_DIR/.env
+ sed -i "s|^[# \t]*SECRET_KEY_BASE=[ \t]*$|SECRET_KEY_BASE=$SECRET_KEY_BASE|" $GL3_DIR/.env # Do not overwrite the value if not empty.
+ sed -i "s|^[# \t]*DATABASE_URL=[ \t]*$|DATABASE_URL=$DATABASE_URL_ROOT/$PGDBNAME|" $GL3_DIR/.env # Do not overwrite the value if not empty.
+ sed -i "s|^[# \t]*REDIS_URL=[ \t]*$|REDIS_URL=$REDIS_URL_ROOT/|" $GL3_DIR/.env # Do not overwrite the value if not empty.
+
+ # Placing greenlight-v3 nginx file, this will enable greenlight-v3 as your Bigbluebutton frontend (bbb-fe).
+ cp -v $NGINX_FILES_DEST/greenlight-v3.nginx $NGINX_FILES_DEST/greenlight-v3.nginx.old && say "old greenlight-v3 nginx config can be retrieved at $NGINX_FILES_DEST/greenlight-v3.nginx.old" #Backup
+ docker run --rm --entrypoint sh $GL_IMG_REPO -c 'cat greenlight-v3.nginx' > $NGINX_FILES_DEST/greenlight-v3.nginx && say "added greenlight-v3 nginx file"
+
+ # For backward compatibility with deployments running greenlight-v2 and haven't picked the patch from COMMIT (583f868).
+ # Move any nginx files from greenlight-v2 to the expected location.
+ if [ -s /etc/bigbluebutton/nginx/greenlight.nginx ]; then
+ mv /etc/bigbluebutton/nginx/greenlight.nginx $NGINX_FILES_DEST/greenlight.nginx && say "found /etc/bigbluebutton/nginx/greenlight.nginx and moved to expected location."
+ fi
+
+ if [ -s /etc/bigbluebutton/nginx/greenlight-redirect.nginx ]; then
+ mv /etc/bigbluebutton/nginx/greenlight-redirect.nginx $NGINX_FILES_DEST/greenlight-redirect.nginx && say "found /etc/bigbluebutton/nginx/greenlight-redirect.nginx and moved to expected location."
+ fi
+
+ if [ -z "$COTURN" ]; then
+ # When NGINX is the frontend reverse proxy, 'X-Forwarded-Proto' proxy header will dynamically match the $scheme of the received client request.
+ # In case a builtin turn server is installed, then HAPROXY is introduced and it becomes the frontend reverse proxy.
+ # NGINX will then act as a backend reverse proxy residing behind of it.
+ # HTTPS traffic from the client then is terminated at HAPROXY and plain HTTP traffic is proxied to NGINX.
+ # Therefore the 'X-Forwarded-Proto' proxy header needs to correctly indicate that HTTPS traffic was proxied in such scenario.
+ # shellcheck disable=SC2016
+ sed -i '/X-Forwarded-Proto/s/$scheme/"https"/' $NGINX_FILES_DEST/greenlight-v3.nginx
+
+ if [ -s $NGINX_FILES_DEST/greenlight.nginx ]; then
+ # For backward compatibility with deployments running greenlight-v2 and haven't picked the patch from PR (#579).
+ # shellcheck disable=SC2016
+ sed -i '/X-Forwarded-Proto/s/$scheme/"https"/' $NGINX_FILES_DEST/greenlight.nginx
+ fi
+ fi
+
+ # For backward compatibility, any already installed greenlight-v2 application will remain but it will not be the default frontend for BigBluebutton.
+ # To access greelight-v2 an explicit /b relative root needs to be indicated, otherwise greelight-v3 will be served by default.
+
+ # Disabling the greenlight-v2 redirection rule.
+ disable_nginx_site greenlight-redirect.nginx && say "found greelight-v2 redirection rule and disabled it!"
+
+ # Disabling the Bigbluebutton default Welcome page frontend.
+ disable_nginx_site default-fe.nginx && say "found default bbb-fe 'Welcome' and disabled it!"
+
+ # Adding Keycloak
+ if [ -n "$INSTALL_KC" ]; then
+ # When attepmting to install/update Keycloak let us attempt to create the database to resolve any issues caused by postgres false negatives.
+ docker-compose -f $GL3_DIR/docker-compose.yml up -d postgres && say "started postgres"
+ wait_postgres_start
+ docker-compose -f $GL3_DIR/docker-compose.yml exec -T postgres psql -U postgres -c 'CREATE DATABASE keycloakdb;'
+ fi
+
+ if ! grep -q 'keycloak:' $GL3_DIR/docker-compose.yml; then
+ # The following logic is expected to run only once when adding Keycloak.
+ # Keycloak isn't installed
+ if [ -n "$INSTALL_KC" ]; then
+ # Add Keycloak
+ say "Adding Keycloak..."
+
+ docker-compose -f $GL3_DIR/docker-compose.yml down
+ cp -v $GL3_DIR/docker-compose.yml $GL3_DIR/docker-compose.base.yml # Persist working base compose file for admins as a Backup.
+
+ docker run --rm --entrypoint sh $GL_IMG_REPO -c 'cat docker-compose.kc.yml' >> $GL3_DIR/docker-compose.yml
+
+ if ! grep -q 'keycloak:' $GL3_DIR/docker-compose.yml; then
+ err "failed to add Keycloak service to greenlight-v3 compose file - is docker running?"
+ fi
+ say "added Keycloak to compose file"
+
+ KCPASSWORD=$(openssl rand -hex 12) # Keycloak admin password.
+ sed -i "s|^\([ \t-]*KEYCLOAK_ADMIN_PASSWORD\)\(=[ \t]*\)$|\1=$KCPASSWORD|g" $GL3_DIR/docker-compose.yml # Do not overwrite the value if not empty.
+ sed -i "s|^\([ \t-]*KC_DB_PASSWORD\)\(=[ \t]*\)$|\1=$PGPASSWORD|g" $GL3_DIR/docker-compose.yml # Do not overwrite the value if not empty.
+
+ # Updating Keycloak nginx file.
+ cp -v $NGINX_FILES_DEST/keycloak.nginx $NGINX_FILES_DEST/keycloak.nginx.old && say "old Keycloak nginx config can be retrieved at $NGINX_FILES_DEST/keycloak.nginx.old"
+ docker run --rm --entrypoint sh $GL_IMG_REPO -c 'cat keycloak.nginx' > $NGINX_FILES_DEST/keycloak.nginx && say "added Keycloak nginx file"
+ fi
+
+ else
+ # Update Keycloak nginx file only.
+ cp -v $NGINX_FILES_DEST/keycloak.nginx $NGINX_FILES_DEST/keycloak.nginx.old && say "old Keycloak nginx config can be retrieved at $NGINX_FILES_DEST/keycloak.nginx.old"
+ docker run --rm --entrypoint sh $GL_IMG_REPO -c 'cat keycloak.nginx' > $NGINX_FILES_DEST/keycloak.nginx && say "added Keycloak nginx file"
+ fi
+
+ if [ -z "$COTURN" ] && [ -s $NGINX_FILES_DEST/keycloak.nginx ]; then
+ # shellcheck disable=SC2016
+ sed -i '/X-Forwarded-Proto/s/$scheme/"https"/' $NGINX_FILES_DEST/keycloak.nginx
+ fi
+
+ # Update .env file catching new configurations:
+ if ! grep -q 'RELATIVE_URL_ROOT=' $GL3_DIR/.env; then
+ cat <> $GL3_DIR/.env
+#RELATIVE_URL_ROOT=/gl
+
+HERE
+ fi
+
+ if [ -n "$GL_PATH" ]; then
+ sed -i "s|^[# \t]*RELATIVE_URL_ROOT=.*|RELATIVE_URL_ROOT=$GL_PATH|" $GL3_DIR/.env
+ fi
+
+ local GL_RELATIVE_URL_ROOT
+ GL_RELATIVE_URL_ROOT=$(sed -ne "s/^\([ \t]*RELATIVE_URL_ROOT=\)\(.*\)$/\2/p" $GL3_DIR/.env) # Extract relative URL root path.
+ say "Deploying Greenlight on the '${GL_RELATIVE_URL_ROOT:-$GL_DEFAULT_PATH}' path..."
+
+ if [ -n "$GL_RELATIVE_URL_ROOT" ] && [ "$GL_RELATIVE_URL_ROOT" != "$GL_DEFAULT_PATH" ]; then
+ sed -i "s|^\([ \t]*location\)[ \t]*\(.*/cable\)[ \t]*\({\)$|\1 $GL_RELATIVE_URL_ROOT/cable \3|" $NGINX_FILES_DEST/greenlight-v3.nginx
+ sed -i "s|^\([ \t]*location\)[ \t]*\(@bbb-fe\)[ \t]*\({\)$|\1 $GL_RELATIVE_URL_ROOT \3|" $NGINX_FILES_DEST/greenlight-v3.nginx
+ fi
+
+ nginx -qt || err 'greenlight-v3 failed to install/update due to nginx tests failing to pass - if using the official image then please contact the maintainers.'
+ nginx -qs reload && say 'greenlight-v3 was successfully configured'
+
+ # Eager pulling images.
+ say "pulling latest greenlight-v3 services images..."
+ docker-compose -f $GL3_DIR/docker-compose.yml pull
+
+ if check_container_running greenlight-v3; then
+ # Restarting Greenlight-v3 services after updates.
+ say "greenlight-v3 is updating..."
+ say "shutting down greenlight-v3..."
+ docker-compose -f $GL3_DIR/docker-compose.yml down
+ fi
+
+ say "starting greenlight-v3..."
+ docker-compose -f $GL3_DIR/docker-compose.yml up -d
+ sleep 5
+ say "greenlight-v3 is now installed and accessible on: https://$HOST${GL_RELATIVE_URL_ROOT:-$GL_DEFAULT_PATH}"
+ say "To create Greenlight administrator account, see: https://docs.bigbluebutton.org/greenlight/v3/install#creating-an-admin-account"
+
+
+ if grep -q 'keycloak:' $GL3_DIR/docker-compose.yml; then
+ say "Keycloak is installed, up to date and accessible for configuration on: https://$HOST/keycloak/"
+ if [ -n "$KCPASSWORD" ];then
+ say "Use the following credentials when accessing the admin console:"
+ say " admin"
+ say " $KCPASSWORD"
+ fi
+
+ say "To complete the configuration of Keycloak, see: https://docs.bigbluebutton.org/greenlight/v3/external-authentication#configuring-keycloak"
+ fi
+
+ return 0;
+}
+
+# This function will install and update to the latest official version of BigBlueButton LTI framework.
+# BigBlueButton LTI tools framewrok provides a simple interface to integrate Bigbluebutton features into any LTI certified LMS.
+install_lti(){
+ # This function depends on the following files existing on their expected location so an eager check is done asserting that.
+ if [[ -z $SERVLET_DIR || ! -f $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties || ! -f $CR_TMPFILE || ! -f $BBB_WEB_ETC_CONFIG ]]; then
+ err "BBB LTI framework failed to install/update due to unmet requirements, have you followed the recommended steps to install Bigbluebutton?"
+ fi
+
+ check_root
+ install_docker
+
+ # Preparing and checking the enviroment.
+ say "preparing and checking the enviroment to install/update BBB LTI framework..."
+
+ if [ ! -d $LTI_DIR ]; then
+ mkdir -p $LTI_DIR && say "created $LTI_DIR"
+ fi
+
+ BROKER_IMG_REPO=bigbluebutton/bbb-lti-broker
+
+ # Installing/Updating the LTI broker.
+ say "pulling latest $BROKER_IMG_REPO image..."
+ docker pull $BROKER_IMG_REPO
+
+ if [ ! -s $LTI_DIR/docker-compose.yml ]; then
+ docker run --rm --entrypoint sh $BROKER_IMG_REPO -c 'cat docker-compose.yml' > $LTI_DIR/docker-compose.yml
+
+ if [ ! -s $LTI_DIR/docker-compose.yml ]; then
+ err "failed to create docker compose file - is docker running?"
+ fi
+
+ say "LTI framework docker compose file was created"
+ fi
+
+ # Configuring BBB LTI.
+ say "prepping the configuration of BBB LTI framework..."
+
+ local ROOT_URL
+ ROOT_URL=$(cat "$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties" "$CR_TMPFILE" "$BBB_WEB_ETC_CONFIG" | grep -v '#' | sed -n '/^bigbluebutton.web.serverURL/{s/.*=//;p}' | tail -n 1 )
+ BIGBLUEBUTTON_URL=$ROOT_URL/bigbluebutton/
+ BIGBLUEBUTTON_SECRET=$(cat "$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties" "$CR_TMPFILE" "$BBB_WEB_ETC_CONFIG" | grep -v '#' | grep ^securitySalt | tail -n 1 | cut -d= -f2)
+
+ # Configuring BBB LTI docker-compose.yml (if configured no side effect will happen).
+ sed -i "s|^\([ \t-]*POSTGRES_PASSWORD\)\(=[ \t]*\)$|\1=$(openssl rand -hex 24)|g" $LTI_DIR/docker-compose.yml # Do not overwrite the value if not empty.
+
+ say "installing/updating BBB LTI framework Broker and applications..."
+ local PGUSER=postgres # Postgres db user to be used by bbb-lti.
+ local PGTXADDR=postgres:5432 # Postgres DB transport address (pair of (@ip:@port)).
+ local RSTXADDR=redis:6379 # Redis DB transport address (pair of (@ip:@port)).
+ local PGPASSWORD
+ PGPASSWORD=$(sed -ne "s/^\([ \t-]*POSTGRES_PASSWORD=\)\(.*\)$/\2/p" $LTI_DIR/docker-compose.yml) # Extract generated Postgres password.
+
+ if [ -z "$PGPASSWORD" ]; then
+ err "failed to retrieve the LTI framework DB password - retry to resolve."
+ fi
+
+ DATABASE_URL_ROOT="postgres://$PGUSER:$PGPASSWORD@$PGTXADDR" # Must be global - expected by install_lti_tool.
+ REDIS_URL_ROOT="redis://$RSTXADDR" # Must be global - expected by install_lti_tool.
+ BROKER_RELATIVE_URL_ROOT=lti # Must be global - expected by install_lti_tools, will be dynamic in the future.
+ APPS_RELATIVE_URL_ROOT=apps # Must be global - expected by install_lti_tools, will be dynamic in the future.
+
+ install_lti_tools || err "BBB LTI framework failed to install/update tools!"
+
+ # Updating BBB LTI framework images.
+ say "pulling latest BBB LTI framework services images..."
+ docker-compose -f $LTI_DIR/docker-compose.yml pull
+
+ if check_container_running broker; then
+ # Restarting BBB LTI framework services after updates.
+ say "BBB LTI framework is updating..."
+ say "shutting down BBB LTI framework services..."
+ docker-compose -f $LTI_DIR/docker-compose.yml down
+ fi
+
+ say "starting BBB LTI framework services..."
+ docker-compose -f $LTI_DIR/docker-compose.yml up -d
+
+ wait_lti_broker_start
+
+ local LTI_KEY=${LTI_CREDS[0]}
+ local LTI_SECRET=${LTI_CREDS[1]}
+
+ say "Setting/updating LTI credentials for LTI KEY: $LTI_KEY..."
+
+ if ! docker-compose -f $LTI_DIR/docker-compose.yml exec -T broker bundle exec rake db:keys:update["$LTI_KEY","$LTI_SECRET"] \
+ 2> /dev/null 1>&2; then
+ docker-compose -f $LTI_DIR/docker-compose.yml exec -T broker bundle exec rake db:keys:add["$LTI_KEY","$LTI_SECRET"] \
+ 2> /dev/null 1>&2 || err "failed to set LTI credentials $LTI_KEY:$LTI_SECRET."
+
+ say "New LTI credentials for LTI KEY: $LTI_KEY were added!"
+ else
+ say "LTI credentials for LTI KEY: $LTI_KEY were updated!"
+ fi
+
+ say "BBB LTI framework is installed, up to date and accessible on: https://$HOST/$BROKER_RELATIVE_URL_ROOT"
+ say "You can refer to your LMS documentation on how to add a LTI application."
+ say " The LTI launch links for all of the installed BBB LTI framework applications can be found in https://$HOST/$BROKER_RELATIVE_URL_ROOT."
+
+ return 0;
+}
+
+install_lti_tools() {
+ # BBB LTI FRAMEWORK COMPONENTS
+ if [[ -z $BROKER_IMG_REPO || -z $DATABASE_URL_ROOT || -z $REDIS_URL_ROOT || -z $BROKER_RELATIVE_URL_ROOT || -z $APPS_RELATIVE_URL_ROOT ]]; then
+ err "BBB LTI tools installation/update failed due to unmet requirements!"
+ fi
+
+ # BBB LTI BROKER setup ↓
+ say "installing/updating BBB LTI framework broker..."
+ LTI_APP_DIR=$LTI_DIR/broker APP_IMG_REPO=$BROKER_IMG_REPO LOG_NAME='LTI Broker' RELATIVE_URL_ROOT=$BROKER_RELATIVE_URL_ROOT \
+ NGINX_NAME=bbb-lti-broker PGDBNAME=bbb_lti_broker install_lti_tool || return 1
+
+ say "BBB LTI Broker is installed, configured and up to date!"
+ # BBB LTI TOOLS setup ↓
+ say "installing/updating BBB LTI framework apps..."
+ LTI_APP_DIR=$LTI_DIR/rooms APP_IMG_REPO=bigbluebutton/bbb-app-rooms LOG_NAME='LTI Rooms' RELATIVE_URL_ROOT=$APPS_RELATIVE_URL_ROOT \
+ NGINX_NAME=bbb-app-rooms PGDBNAME=bbb_app_rooms install_lti_tool || return 1
+
+ say "All BBB LTI apps are installed, configured and up to date!"
+ # BBB LTI TOOLS registration ↓
+ register_lti_tools || return 1
+
+ say "All BBB LTI apps are registered to the LTI framework!"
+
+ return 0;
+}
+
+install_lti_tool() {
+ # Preparing and checking the enviroment.
+ if [[ -z $LTI_APP_DIR || -z $APP_IMG_REPO || -z $LOG_NAME || -z $RELATIVE_URL_ROOT || -z $NGINX_NAME || -z $PGDBNAME ]]; then
+ err "$LOG_NAME installation/update failed due to unmet requirements!"
+ fi
+
+ say "preparing and checking the enviroment to install/update $LOG_NAME..."
+
+ if [ ! -d "$LTI_APP_DIR" ]; then
+ mkdir -p "$LTI_APP_DIR" && say "created $LTI_APP_DIR"
+ fi
+
+ # Installing/Updating the LTI broker.
+ say "pulling latest $APP_IMG_REPO image..."
+ docker pull "$APP_IMG_REPO"
+
+ # Configuring BBB LTI.
+ say "checking/updating the configuration of $LOG_NAME..."
+
+ local SECRET_KEY_BASE
+ SECRET_KEY_BASE=$(docker run --rm --entrypoint bundle "$APP_IMG_REPO" exec rake secret)
+
+ if [ -z "$SECRET_KEY_BASE" ]; then
+ err "failed to generate $LOG_NAME secret key base - is docker running?"
+ fi
+
+ if [ ! -s "$LTI_APP_DIR"/.env ]; then
+ docker run --rm --entrypoint sh "$APP_IMG_REPO" -c 'cat dotenv' > "$LTI_APP_DIR"/.env
+
+ if [ ! -s "$LTI_APP_DIR"/.env ]; then
+ err "failed to create $LOG_NAME .env file - is docker running?"
+ fi
+
+ say "$LOG_NAME .env file was created"
+ fi
+
+ # A note for future maintainers:
+ # The following configuration operations were made idempotent, meaning that playing these actions will have an outcome on the system (configure it) only once.
+ # Replaying these steps are a safe and an expected operation, this gurantees the seemless simple installation and upgrade of BBB LTI framework.
+ # A simple change can impact that property and therefore render the upgrading functionnality unoperationnal or impact the running system.
+
+ # Configuring BBB LTI .env file (if already configured this will only update some expected or safe to change variables).
+ cp -v "$LTI_APP_DIR"/.env "$LTI_APP_DIR"/.env.old && say "old $LOG_NAME .env file can be retrieved at $LTI_APP_DIR/.env.old" #Backup
+
+ sed -i "s|^[# \t]*SECRET_KEY_BASE=[ \t]*$|SECRET_KEY_BASE=$SECRET_KEY_BASE|" "$LTI_APP_DIR"/.env # Do not overwrite the value if not empty.
+ sed -i "s|^[# \t]*BIGBLUEBUTTON_ENDPOINT=.*|BIGBLUEBUTTON_ENDPOINT=$BIGBLUEBUTTON_URL|" "$LTI_APP_DIR"/.env
+ sed -i "s|^[# \t]*BIGBLUEBUTTON_SECRET=.*|BIGBLUEBUTTON_SECRET=$BIGBLUEBUTTON_SECRET|" "$LTI_APP_DIR"/.env
+ sed -i "s|^[# \t]*URL_HOST=.*$|URL_HOST=$HOST|" "$LTI_APP_DIR"/.env
+ sed -i "s|^[# \t]*RELATIVE_URL_ROOT=.*$|RELATIVE_URL_ROOT=$RELATIVE_URL_ROOT|" "$LTI_APP_DIR"/.env
+ sed -i "s|^[# \t]*DATABASE_URL=.*myuser:mypass@localhost.*$|DATABASE_URL=$DATABASE_URL_ROOT/$PGDBNAME|" "$LTI_APP_DIR"/.env # Do not overwrite the value if not a default.
+ sed -i "s|^[# \t]*DATABASE_URL=[ \t]*$|DATABASE_URL=$DATABASE_URL_ROOT/$PGDBNAME|" "$LTI_APP_DIR"/.env # Do not overwrite the value if not empty.
+ sed -i "s|^[# \t]*REDIS_URL=.*myuser:mypass@localhost.*$|REDIS_URL=$REDIS_URL_ROOT/|" "$LTI_APP_DIR"/.env # Do not overwrite the value if not a default.
+ sed -i "s|^[# \t]*REDIS_URL=[ \t]*$|REDIS_URL=$REDIS_URL_ROOT/|" "$LTI_APP_DIR"/.env # Do not overwrite the value if not empty.
+ sed -i "s|^[# \t]*OMNIAUTH_BBBLTIBROKER_SITE=.*|OMNIAUTH_BBBLTIBROKER_SITE=https://$HOST|" "$LTI_APP_DIR"/.env
+ sed -i "s|^[# \t]*OMNIAUTH_BBBLTIBROKER_ROOT=.*|OMNIAUTH_BBBLTIBROKER_ROOT=$BROKER_RELATIVE_URL_ROOT|" "$LTI_APP_DIR"/.env
+ sed -i "s|^[# \t]*OMNIAUTH_BBBLTIBROKER_KEY=.*|OMNIAUTH_BBBLTIBROKER_KEY=$(openssl rand -hex 24)|" "$LTI_APP_DIR"/.env # Credentials are rotated on update.
+ sed -i "s|^[# \t]*OMNIAUTH_BBBLTIBROKER_SECRET=.*|OMNIAUTH_BBBLTIBROKER_SECRET=$(openssl rand -hex 24)|" "$LTI_APP_DIR"/.env # Credentials are rotated on update.
+
+ # Placing application nginx file.
+ say "configuring nginx for $LOG_NAME..."
+
+ cp -v $NGINX_FILES_DEST/"$NGINX_NAME.nginx" $NGINX_FILES_DEST/"$NGINX_NAME.nginx.old" && say "old $LOG_NAME nginx config can be retrieved at $NGINX_FILES_DEST/$NGINX_NAME.nginx.old" # Backup.
+ docker run --rm --entrypoint sh "$APP_IMG_REPO" -c 'cat config.nginx' > $NGINX_FILES_DEST/"$NGINX_NAME.nginx" && say "added $LOG_NAME nginx file"
+
+ if [ -z "$COTURN" ]; then
+ # When NGINX is the frontend reverse proxy, 'X-Forwarded-Proto' proxy header will dynamically match the $scheme of the received client request.
+ # In case a builtin turn server is installed, then HAPROXY is introduced and it becomes the frontend reverse proxy.
+ # NGINX will then act as a backend reverse proxy residing behind of it.
+ # HTTPS traffic from the client then is terminated at HAPROXY and plain HTTP traffic is proxied to NGINX.
+ # Therefore the 'X-Forwarded-Proto' proxy header needs to correctly indicate that HTTPS traffic was proxied in such scenario.
+ # shellcheck disable=SC2016
+ sed -i '/X-Forwarded-Proto/s/$scheme/"https"/' $NGINX_FILES_DEST/"$NGINX_NAME.nginx"
+ fi
+
+ nginx -qt || return 1
+ nginx -qs reload && say "$LOG_NAME was successfully configured"
+
+ return 0;
+}
+
+
+register_lti_tools() {
+ # Registering/Updating LTI apps.
+ wait_lti_broker_start
+
+ # BBB LTI TOOLS registration ↓
+ say "Registering All BBB LTI framework apps..."
+ LTI_APP_DIR=$LTI_DIR/rooms LOG_NAME='LTI Rooms' APP_NAME=rooms register_lti_tool || return 1
+
+ return 0;
+}
+
+wait_lti_broker_start() {
+ say "Waiting for the LTI broker to start..."
+ docker-compose -f $LTI_DIR/docker-compose.yml up -d broker || err "failed to register LTI framework apps due to LTI broker failling to start - retry to resolve"
+
+ local tries=0
+ while ! docker-compose -f $LTI_DIR/docker-compose.yml exec -T broker bundle exec rake db:version 2> /dev/null 1>&2; do
+ echo -n .
+ sleep 3
+ if (( ++tries == 3 )); then
+ err "failed to register LTI framework apps due to reaching LTI broker waiting timeout - retry to resolve"
+ fi
+ done
+
+ sleep 3 # Optimistically wait for LTI Broker to become ready.
+
+ say "LTI broker is ready!"
+
+ return 0;
+}
+
+wait_postgres_start() {
+ say "Waiting for the Postgres DB to start..."
+ docker-compose -f $GL3_DIR/docker-compose.yml up -d postgres || err "failed to start Postgres service - retry to resolve"
+
+ local tries=0
+ while ! docker-compose -f $GL3_DIR/docker-compose.yml exec -T postgres pg_isready 2> /dev/null 1>&2; do
+ echo -n .
+ sleep 3
+ if (( ++tries == 3 )); then
+ err "failed to start Postgres due to reaching waiting timeout - retry to resolve"
+ fi
+ done
+
+ say "Postgres is ready!"
+
+ return 0;
+}
+
+register_lti_tool() {
+ # Preparing and checking the enviroment.
+ if [[ -z $LTI_APP_DIR || -z $APP_NAME || -z $LOG_NAME ]]; then
+ err "$LOG_NAME registration failed due to unmet requirements!"
+ fi
+
+ say "Registering $LOG_NAME..."
+
+ local OAUTH_KEY OAUTH_SECRET RELATIVE_URL_ROOT
+ OAUTH_KEY=$(sed -ne "s/^\([ \t]*OMNIAUTH_BBBLTIBROKER_KEY=\)\(.*\)$/\2/p" "$LTI_APP_DIR"/.env) # Extract the LTI app OAUTH key.
+ OAUTH_SECRET=$(sed -ne "s/^\([ \t]*OMNIAUTH_BBBLTIBROKER_SECRET=\)\(.*\)$/\2/p" "$LTI_APP_DIR"/.env) # Extract LTI app OAUTH secret.
+ RELATIVE_URL_ROOT=$(sed -ne "s/^\([ \t]*RELATIVE_URL_ROOT=\)\(.*\)$/\2/p" "$LTI_APP_DIR"/.env) # Extract LTI app realtive URL root path.
+
+ if [ -z "$OAUTH_KEY" ] || [ -z "$OAUTH_SECRET" ] ; then
+ err "failed to retrieve the $LOG_NAME OAUTH credentials - retry to resolve."
+ fi
+
+ local CALLBACK_URI_SUFFIX=auth/bbbltibroker/callback
+ local CALLBACK_URI=https://$HOST/$RELATIVE_URL_ROOT/$APP_NAME/$CALLBACK_URI_SUFFIX
+
+ if ! check_container_running broker; then
+ err "failed to register $LOG_NAME due to LTI broker not running - retry to resolve."
+ fi
+
+ if ! docker-compose -f $LTI_DIR/docker-compose.yml exec -T broker bundle exec rake db:apps:show["$APP_NAME"] \
+ 2> /dev/null 1>&2; then
+ docker-compose -f $LTI_DIR/docker-compose.yml exec -T broker bundle exec rake db:apps:add["$APP_NAME","$CALLBACK_URI","$OAUTH_KEY","$OAUTH_SECRET"] \
+ 2> /dev/null 1>&2 && say "$LOG_NAME was successfully registered."
+ else
+ docker-compose -f $LTI_DIR/docker-compose.yml exec -T broker bundle exec rake db:apps:update["$APP_NAME","$CALLBACK_URI","$OAUTH_KEY","$OAUTH_SECRET"] \
+ 2> /dev/null 1>&2 && say "$LOG_NAME was successfully updated."
+ fi
+
+ return 0;
+}
+
+# Given a container name as $1, this function will check if there's a match for that name in the list of running docker containers on the system.
+# The result will be binded to $?.
+check_container_running() {
+ docker ps | grep -q "$1" || return 1;
+
+ return 0;
+}
+
+# Given a filename as $1, if file exists under $sites_dir then the file will be suffixed with '.disabled'.
+# sites_dir points to Bigbluebutton nginx sites, when suffixed with '.disabled' nginx will not include the site on reload/restart thus disabling it.
+disable_nginx_site() {
+ local site_path="$1"
+
+ if [ -z "$site_path" ]; then
+ return 1;
+ fi
+
+ if [ -f $NGINX_FILES_DEST/"$site_path" ]; then
+ mv $NGINX_FILES_DEST/"$site_path" $NGINX_FILES_DEST/"$site_path.disabled" && return 0;
+ fi
+
+ return 1;
+}
+
+install_docker() {
+ need_pkg apt-transport-https ca-certificates curl gnupg-agent software-properties-common openssl
+
+ # Install Docker
+ if ! apt-key list | grep -q Docker; then
+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
+ fi
+
+ if ! dpkg -l | grep -q docker-ce; then
+ echo "deb [ arch=amd64 ] https://download.docker.com/linux/ubuntu \
+ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
+
+ add-apt-repository --remove\
+ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
+ $(lsb_release -cs) \
+ stable"
+
+ apt-get update
+ need_pkg docker-ce docker-ce-cli containerd.io
+ fi
+ if ! which docker; then err "Docker did not install"; fi
+
+ # Purge older docker compose if exists.
+ if dpkg -l | grep -q docker-compose; then
+ apt-get purge -y docker-compose
+ fi
+
+ if [ ! -x /usr/local/bin/docker-compose ]; then
+ curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
+ chmod +x /usr/local/bin/docker-compose
+ fi
+
+ # Ensuring docker is running
+ if ! docker version > /dev/null ; then
+ # Attempting to auto resolve by restarting docker socket and engine.
+ systemctl restart docker.socket docker.service
+ sleep 5
+
+ docker version > /dev/null || err "docker is failing to restart, something is wrong retry to resolve - exiting"
+ say "docker is running!"
+ fi
+
+}
+
+
+install_ssl() {
+ if ! grep -q "$HOST" /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml; then
+ bbb-conf --setip "$HOST"
+ fi
+
+ mkdir -p /etc/nginx/ssl
+
+ if [ -z "$PROVIDED_CERTIFICATE" ]; then
+ add-apt-repository universe
+ apt-get update
+ need_pkg certbot
+
+ if [[ -f "/etc/letsencrypt/live/$HOST/fullchain.pem" ]] && [[ -f "/etc/letsencrypt/renewal/$HOST.conf" ]] \
+ && ! grep -q '/var/www/bigbluebutton-default/assets' "/etc/letsencrypt/renewal/$HOST.conf"; then
+ sed -i -e 's#/var/www/bigbluebutton-default#/var/www/bigbluebutton-default/assets#' "/etc/letsencrypt/renewal/$HOST.conf"
+ if ! certbot renew; then
+ err "Let's Encrypt SSL renewal request for $HOST did not succeed - exiting"
+ fi
+ fi
+ fi
+
+ if [ ! -f "/etc/letsencrypt/live/$HOST/fullchain.pem" ]; then
+ rm -f /tmp/bigbluebutton.bak
+ if ! grep -q "$HOST" /etc/nginx/sites-available/bigbluebutton; then # make sure we can do the challenge
+ if [ -f /etc/nginx/sites-available/bigbluebutton ]; then
+ cp /etc/nginx/sites-available/bigbluebutton /tmp/bigbluebutton.bak
+ fi
+ cat < /etc/nginx/sites-available/bigbluebutton
+server_tokens off;
+server {
+ listen 80;
+ listen [::]:80;
+ server_name $HOST;
+
+ access_log /var/log/nginx/bigbluebutton.access.log;
+
+ # BigBlueButton landing page.
+ location / {
+ root /var/www/bigbluebutton-default/assets;
+ try_files \$uri @bbb-fe;
+ }
+}
+HERE
+ systemctl restart nginx
+ fi
+
+ if [ -z "$PROVIDED_CERTIFICATE" ]; then
+ if ! certbot --email "$EMAIL" --agree-tos --rsa-key-size 4096 -w /var/www/bigbluebutton-default/assets/ \
+ -d "$HOST" --deploy-hook "systemctl reload nginx" "${LETS_ENCRYPT_OPTIONS[@]}" certonly; then
+ systemctl restart nginx
+ err "Let's Encrypt SSL request for $HOST did not succeed - exiting"
+ fi
+ else
+ # Place your fullchain.pem and privkey.pem files in /local/certs/ and bbb-install.sh will deal with the rest.
+ mkdir -p "/etc/letsencrypt/live/$HOST/"
+ ln -s /local/certs/fullchain.pem "/etc/letsencrypt/live/$HOST/fullchain.pem"
+ ln -s /local/certs/privkey.pem "/etc/letsencrypt/live/$HOST/privkey.pem"
+ fi
+ fi
+
+ if [ -z "$COTURN" ]; then
+ # No COTURN credentials provided, setup a local TURN server
+ cat < /etc/nginx/sites-available/bigbluebutton
+server_tokens off;
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name $HOST;
+
+ location ^~ / {
+ return 301 https://\$server_name\$request_uri; #redirect HTTP to HTTPS
+ }
+
+ location ^~ /.well-known/acme-challenge/ {
+ allow all;
+ default_type "text/plain";
+ root /var/www/bigbluebutton-default/assets;
+ }
+
+ location = /.well-known/acme-challenge/ {
+ return 404;
+ }
+}
+
+set_real_ip_from 127.0.0.1;
+real_ip_header proxy_protocol;
+real_ip_recursive on;
+server {
+ # this double listenting is intended. We terminate SSL on haproxy. HTTP2 is a
+ # binary protocol. haproxy has to decide which protocol is spoken. This is
+ # negotiated by ALPN.
+ #
+ # Depending on the ALPN value traffic is redirected to either port 82 (HTTP2,
+ # ALPN value h2) or 81 (HTTP 1.0 or HTTP 1.1, ALPN value http/1.1 or no value)
+
+ listen 127.0.0.1:82 http2 proxy_protocol;
+ listen [::1]:82 http2;
+ listen 127.0.0.1:81 proxy_protocol;
+ listen [::1]:81;
+ server_name $HOST;
+
+ # nginx does not know its external port/protocol behind haproxy, so use relative redirects.
+ absolute_redirect off;
+
+ # HSTS (uncomment to enable)
+ #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+ access_log /var/log/nginx/bigbluebutton.access.log;
+
+ # This variable is used instead of \$scheme by bigbluebutton nginx include
+ # files, so \$scheme can be overridden in reverse-proxy configurations.
+ set \$real_scheme "https";
+
+ # BigBlueButton landing page.
+ location / {
+ root /var/www/bigbluebutton-default/assets;
+ try_files \$uri @bbb-fe;
+ }
+
+ # Include specific rules for record and playback
+ include /etc/bigbluebutton/nginx/*.nginx;
+}
+HERE
+ else
+ # We've been given COTURN credentials, so HAPROXY is not installed for local TURN server
+ cat < /etc/nginx/sites-available/bigbluebutton
+server_tokens off;
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name $HOST;
+
+ location ^~ / {
+ return 301 https://\$server_name\$request_uri; #redirect HTTP to HTTPS
+ }
+
+ location ^~ /.well-known/acme-challenge/ {
+ allow all;
+ default_type "text/plain";
+ root /var/www/bigbluebutton-default/assets;
+ }
+
+ location = /.well-known/acme-challenge/ {
+ return 404;
+ }
+}
+
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name $HOST;
+
+ ssl_certificate /etc/letsencrypt/live/$HOST/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/$HOST/privkey.pem;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 10m;
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ ssl_dhparam /etc/nginx/ssl/ffdhe2048.pem;
+
+ # HSTS (comment out to enable)
+ #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+ access_log /var/log/nginx/bigbluebutton.access.log;
+
+ # This variable is used instead of \$scheme by bigbluebutton nginx include
+ # files, so \$scheme can be overridden in reverse-proxy configurations.
+ set \$real_scheme \$scheme;
+
+ # BigBlueButton landing page.
+ location / {
+ root /var/www/bigbluebutton-default/assets;
+ try_files \$uri @bbb-fe;
+ }
+
+ # Include specific rules for record and playback
+ include /etc/bigbluebutton/nginx/*.nginx;
+}
+HERE
+
+ if [[ ! -f /etc/nginx/ssl/ffdhe2048.pem ]]; then
+ cat >/etc/nginx/ssl/ffdhe2048.pem <<"HERE"
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
+87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
+YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
+7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
+ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
+-----END DH PARAMETERS-----
+HERE
+ fi
+ if [[ -f /etc/nginx/ssl/dhp-4096.pem ]]; then
+ rm /etc/nginx/ssl/dhp-4096.pem
+ fi
+ fi
+# Create the default Welcome page Bigbluebutton Frontend unless it exists.
+if [[ ! -f /usr/share/bigbluebutton/nginx/default-fe.nginx && ! -f /usr/share/bigbluebutton/nginx/default-fe.nginx.disabled ]]; then
+cat < /usr/share/bigbluebutton/nginx/default-fe.nginx
+# Default Bigbluebutton Landing page.
+
+location @bbb-fe {
+ index index.html index.htm;
+ expires 1m;
+}
+
+HERE
+fi
+
+ # Configure rest of BigBlueButton Configuration for SSL
+ xmlstarlet edit --inplace --update '//param[@name="wss-binding"]/@value' --value "$IP:7443" /opt/freeswitch/conf/sip_profiles/external.xml
+
+ # shellcheck disable=SC1091
+ eval "$(source /etc/bigbluebutton/bigbluebutton-release && declare -p BIGBLUEBUTTON_RELEASE)"
+ if [[ $BIGBLUEBUTTON_RELEASE == 2.2.* ]] && [[ ${BIGBLUEBUTTON_RELEASE#*.*.} -lt 29 ]]; then
+ sed -i "s/proxy_pass .*/proxy_pass https:\/\/$IP:7443;/g" /usr/share/bigbluebutton/nginx/sip.nginx
+ else
+ # Use nginx as proxy for WSS -> WS (see https://github.com/bigbluebutton/bigbluebutton/issues/9667)
+ yq w -i /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml public.media.sipjsHackViaWs true
+ sed -i "s/proxy_pass .*/proxy_pass http:\/\/$IP:5066;/g" /usr/share/bigbluebutton/nginx/sip.nginx
+ xmlstarlet edit --inplace --update '//param[@name="ws-binding"]/@value' --value "$IP:5066" /opt/freeswitch/conf/sip_profiles/external.xml
+ fi
+
+ sed -i 's/^bigbluebutton.web.serverURL=http:/bigbluebutton.web.serverURL=https:/g' "$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties"
+ if [ -f "$BBB_WEB_ETC_CONFIG" ]; then
+ sed -i 's/^bigbluebutton.web.serverURL=http:/bigbluebutton.web.serverURL=https:/g' "$BBB_WEB_ETC_CONFIG"
+ fi
+
+ yq w -i /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml playback_protocol https
+ chmod 644 /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml
+
+ # Update Greenlight (if installed) to use SSL
+ for gl_dir in ~/greenlight $GL3_DIR;do
+ if [ -f "$gl_dir"/.env ]; then
+ if ! grep ^BIGBLUEBUTTON_ENDPOINT "$gl_dir"/.env | grep -q https; then
+ if [[ -z $BIGBLUEBUTTON_URL ]]; then
+ BIGBLUEBUTTON_URL=$(cat "$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties" "$CR_TMPFILE" "$BBB_WEB_ETC_CONFIG" | grep -v '#' | sed -n '/^bigbluebutton.web.serverURL/{s/.*=//;p}' | tail -n 1 )/bigbluebutton/
+ fi
+
+ sed -i "s|.*BIGBLUEBUTTON_ENDPOINT=.*|BIGBLUEBUTTON_ENDPOINT=$BIGBLUEBUTTON_URL|" ~/greenlight/.env
+ docker-compose -f "$gl_dir"/docker-compose.yml down
+ docker-compose -f "$gl_dir"/docker-compose.yml up -d
+ fi
+ fi
+ done
+
+ TARGET=/usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml
+ if [ -f $TARGET ]; then
+ if grep -q kurentoIp $TARGET; then
+ # 2.0
+ yq w -i $TARGET kurentoIp "$IP"
+ else
+ # 2.2
+ yq w -i $TARGET kurento[0].ip "$IP"
+ yq w -i $TARGET freeswitch.ip "$IP"
+
+ if [[ $BIGBLUEBUTTON_RELEASE == 2.2.* ]] && [[ ${BIGBLUEBUTTON_RELEASE#*.*.} -lt 29 ]]; then
+ if [ -n "$INTERNAL_IP" ]; then
+ yq w -i $TARGET freeswitch.sip_ip "$INTERNAL_IP"
+ else
+ yq w -i $TARGET freeswitch.sip_ip "$IP"
+ fi
+ else
+ # Use nginx as proxy for WSS -> WS (see https://github.com/bigbluebutton/bigbluebutton/issues/9667)
+ yq w -i $TARGET freeswitch.sip_ip "$IP"
+ fi
+ fi
+ chown bigbluebutton:bigbluebutton $TARGET
+ chmod 644 $TARGET
+ fi
+
+ mkdir -p /etc/bigbluebutton/bbb-webrtc-sfu
+ TARGET=/etc/bigbluebutton/bbb-webrtc-sfu/production.yml
+ touch $TARGET
+
+ # Configure mediasoup IPs, reference: https://raw.githubusercontent.com/bigbluebutton/bbb-webrtc-sfu/v2.7.2/docs/mediasoup.md
+ # mediasoup IPs: WebRTC
+ yq w -i "$TARGET" mediasoup.webrtc.listenIps[0].ip "0.0.0.0"
+ yq w -i "$TARGET" mediasoup.webrtc.listenIps[0].announcedIp "$IP"
+
+ # mediasoup IPs: plain RTP (internal comms, FS <-> mediasoup)
+ yq w -i "$TARGET" mediasoup.plainRtp.listenIp.ip "0.0.0.0"
+ yq w -i "$TARGET" mediasoup.plainRtp.listenIp.announcedIp "$IP"
+
+ systemctl reload nginx
+}
+
+configure_coturn() {
+ TURN_XML=/etc/bigbluebutton/turn-stun-servers.xml
+
+ if [ -z "$COTURN" ]; then
+ # the user didn't pass '-c', so use the local TURN server's host
+ COTURN_HOST=$HOST
+ fi
+
+ cat < $TURN_XML
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+HERE
+
+ chown root:bigbluebutton "$TURN_XML"
+ chmod 640 "$TURN_XML"
+}
+
+
+install_coturn() {
+ apt-get update
+ apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" dist-upgrade
+
+ need_pkg software-properties-common certbot
+
+ need_pkg coturn
+
+ if [ -n "$INTERNAL_IP" ]; then
+ SECOND_ALLOWED_PEER_IP="allowed-peer-ip=$INTERNAL_IP"
+ fi
+ # check if this is still the default coturn config file. Replace it in this case.
+ if grep "#static-auth-secret=north" /etc/turnserver.conf > /dev/null ; then
+ COTURN_SECRET="$(openssl rand -base64 32)"
+ cat < /etc/turnserver.conf
+listening-port=3478
+
+listening-ip=${INTERNAL_IP:-$IP}
+relay-ip=${INTERNAL_IP:-$IP}
+
+min-port=32769
+max-port=65535
+verbose
+
+fingerprint
+lt-cred-mech
+use-auth-secret
+static-auth-secret=$COTURN_SECRET
+realm=$HOST
+
+keep-address-family
+
+no-cli
+no-tlsv1
+no-tlsv1_1
+
+# Block connections to IP ranges which shouldn't be reachable
+no-loopback-peers
+no-multicast-peers
+
+
+# we only need to allow peer connections from the machine itself (from mediasoup or freeswitch).
+denied-peer-ip=0.0.0.0-255.255.255.255
+denied-peer-ip=::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+allowed-peer-ip=$IP
+$SECOND_ALLOWED_PEER_IP
+
+HERE
+ chown root:turnserver /etc/turnserver.conf
+ chmod 640 /etc/turnserver.conf
+ else
+ # fetch secret for later setting up in BBB turn config
+ COTURN_SECRET="$(grep static-auth-secret= /etc/turnserver.conf |cut -d = -f 2-)"
+ fi
+
+ mkdir -p /var/log/turnserver
+ chown turnserver:turnserver /var/log/turnserver
+
+ cat < /etc/logrotate.d/coturn
+/var/log/turnserver/*.log
+{
+ rotate 7
+ daily
+ missingok
+ notifempty
+ compress
+ postrotate
+ /bin/systemctl kill -s HUP coturn.service
+ endscript
+}
+HERE
+
+ # Eanble coturn to bind to port 443 with CAP_NET_BIND_SERVICE
+ mkdir -p /etc/systemd/system/coturn.service.d
+ rm -rf /etc/systemd/system/coturn.service.d/ansible.conf # Remove previous file
+ cat > /etc/systemd/system/coturn.service.d/override.conf < /etc/bigbluebutton/bbb-conf/apply-config.sh << HERE
+#!/bin/bash
+
+# Pull in the helper functions for configuring BigBlueButton
+source /etc/bigbluebutton/bbb-conf/apply-lib.sh
+
+enableUFWRules
+HERE
+ chmod +x /etc/bigbluebutton/bbb-conf/apply-config.sh
+ fi
+}
+
+main "$@" || exit 1
+
diff --git a/roles/bbb_install/files/blankDefault.pdf b/roles/bbb_install/files/blankDefault.pdf
new file mode 100644
index 0000000..02e8b9c
Binary files /dev/null and b/roles/bbb_install/files/blankDefault.pdf differ
diff --git a/roles/bbb_install/files/ext_sipgate.xml b/roles/bbb_install/files/ext_sipgate.xml
new file mode 100644
index 0000000..3b68157
--- /dev/null
+++ b/roles/bbb_install/files/ext_sipgate.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/roles/bbb_install/files/install b/roles/bbb_install/files/install
new file mode 100644
index 0000000..e315150
--- /dev/null
+++ b/roles/bbb_install/files/install
@@ -0,0 +1 @@
+./bbb-install-2.5.sh -v focal-250 -s bbb.xitq.de -e benedikt.wismans@sdw.systems -c service.sdw.systems:3ef948d61ff4bcf3e87f068dfecbbbe6
diff --git a/roles/bbb_install/files/pub_sipgate.xml b/roles/bbb_install/files/pub_sipgate.xml
new file mode 100644
index 0000000..a2e3a9f
--- /dev/null
+++ b/roles/bbb_install/files/pub_sipgate.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/roles/bbb_install/files/rudiDefault.pdf b/roles/bbb_install/files/rudiDefault.pdf
new file mode 100644
index 0000000..8f2b1de
Binary files /dev/null and b/roles/bbb_install/files/rudiDefault.pdf differ
diff --git a/roles/bbb_install/files/taillog b/roles/bbb_install/files/taillog
new file mode 100644
index 0000000..a76b0b1
--- /dev/null
+++ b/roles/bbb_install/files/taillog
@@ -0,0 +1,2 @@
+tail -n 200 -f /var/log/bigbluebutton/bbb-web.log
+
diff --git a/roles/bbb_install/files/turn-stun-servers.xml.konfiguriert b/roles/bbb_install/files/turn-stun-servers.xml.konfiguriert
new file mode 100644
index 0000000..6a033be
--- /dev/null
+++ b/roles/bbb_install/files/turn-stun-servers.xml.konfiguriert
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/roles/bbb_install/files/update b/roles/bbb_install/files/update
new file mode 100644
index 0000000..343777d
--- /dev/null
+++ b/roles/bbb_install/files/update
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+echo Working on host `hostname`
+sudo apt-get update && yes Y | sudo apt-get upgrade && yes Y | sudo apt-get dist-upgrade && yes Y | sudo apt autoremove
+
+sudo cp ~/Scripte/turn-stun-servers.xml.konfiguriert /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml
+
+sudo cp ~/Scripte/customerDefault.pdf /var/www/bigbluebutton-default/default.pdf
+
+sudo bbb-conf --setip `hostname`
+
+exit 0
+
+vhosts=( vhost )
+
+for i in "${vhosts[@]}"; do
+echo Working on vhost $i
+ ssh $i sudo apt-get update && yes Y | sudo apt-get upgrade && yes Y | sudo apt-get dist-upgrade && yes Y | sudo apt autoremove
+done
+
+exit 0
diff --git a/roles/bbb_install/files/xitDefault.pdf b/roles/bbb_install/files/xitDefault.pdf
new file mode 100644
index 0000000..0975400
Binary files /dev/null and b/roles/bbb_install/files/xitDefault.pdf differ
diff --git a/roles/bbb_install/tasks/config_bbb.yml b/roles/bbb_install/tasks/config_bbb.yml
new file mode 100644
index 0000000..18e4a92
--- /dev/null
+++ b/roles/bbb_install/tasks/config_bbb.yml
@@ -0,0 +1,36 @@
+---
+
+- name: Set default values in settings.yml
+ yedit:
+ src: /home/core/Scripte/settings.yml
+ edits:
+ - key: public.kurento.pagination.mobilePageSizes.moderator
+ value: 6
+ - key: public.kurento.pagination.mobilePageSizes.viewer
+ value: 4
+
+- name: Set default values in file bigbluebutton.properties
+ ansible.builtin.lineinfile:
+ path: /home/core/Scripte/bigbluebutton.properties
+ ### line to be searched & matched
+ regexp: '{{ item.From }}'
+ ### line to be in placed
+ line: '{{ item.To }}'
+ state: present
+ backrefs: yes
+ backup: yes
+
+ with_items:
+ - { From: '^defaultWelcomeMessage=(.*)$', To: '{{ defaultWelcomeMessage }}'}
+ - { From: '^defaultWelcomeMessageFooter=(.*)$', To: '{{ defaultWelcomeMessageFooter }}'}
+ - { From: '^learningDashboardEnabled=(.*)$', To: '{{ learningDashboardEnabled }}'}
+ - { From: '^disableRecordingDefault=(.*)$', To: '{{ disableRecordingDefault }}'}
+ - { From: '^webcamsOnlyForModerator=(.*)$', To: '{{ webcamsOnlyForModerator }}'}
+ - { From: '^learningDashboardCleanupDelayInMinutes=(.*)$', To: '{{ learningDashboardCleanupDelayInMinutes }}'}
+ - { From: '^bigbluebutton\.web\.logoutURL=(.*)$', To: '{{ bigbluebutton_web_logoutURL }}'}
+
+- name: Configure turn and stun service and default presentation using update script and restart BBB
+ command:
+ cmd: "/home/core/Scripte/update"
+ chdir: /home/core/Scripte
+...
\ No newline at end of file
diff --git a/roles/bbb_install/tasks/dialin_bbb.yml b/roles/bbb_install/tasks/dialin_bbb.yml
new file mode 100644
index 0000000..5a45f99
--- /dev/null
+++ b/roles/bbb_install/tasks/dialin_bbb.yml
@@ -0,0 +1,43 @@
+---
+
+- name: Ensure /opt/freeswitch/etc/freeswitch/sip_profiles/external dir exists
+ file:
+ path: "/opt/freeswitch/etc/freeswitch/sip_profiles/external"
+ state: directory
+
+- name: Upload ext_sipgate.xml config to /opt/freeswitch/etc/freeswitch/sip_profiles/external/sipgate.xml
+ copy:
+ src: ext_sipgate.xml
+ dest: /opt/freeswitch/etc/freeswitch/sip_profiles/external/sipgate.xml
+ owner: root
+ group: root
+ mode: 0644
+
+- name: Ensure /opt/freeswitch/etc/freeswitch/dialplan/public dir exists
+ file:
+ path: "/opt/freeswitch/etc/freeswitch/dialplan/public"
+ state: directory
+
+- name: Upload pub_sipgate.xml config to /opt/freeswitch/etc/freeswitch/dialplan/public/sipgate.xml
+ copy:
+ src: pub_sipgate.xml
+ dest: /opt/freeswitch/etc/freeswitch/dialplan/public/sipgate.xml
+ owner: freeswitch
+ group: daemon
+ mode: 0644
+
+- name: Set defaultDialAccessNumber number in file bigbluebutton.properties
+ ansible.builtin.lineinfile:
+ path: /home/core/Scripte/bigbluebutton.properties
+ ### line to be searched & matched
+ regexp: '{{ item.From }}'
+ ### line to be in placed
+ line: '{{ item.To }}'
+ state: present
+ backrefs: yes
+ backup: yes
+
+ with_items:
+ - { From: '^defaultDialAccessNumber=(.*)$', To: '{{ defaultDialAccessNumber }}'}
+
+...
\ No newline at end of file
diff --git a/roles/bbb_install/tasks/install_bbb.yml b/roles/bbb_install/tasks/install_bbb.yml
new file mode 100644
index 0000000..f334a23
--- /dev/null
+++ b/roles/bbb_install/tasks/install_bbb.yml
@@ -0,0 +1,21 @@
+---
+
+- name: Upload bbb-install script to /root
+ copy:
+ src: bbb-install-2.7.sh
+ dest: /root
+ owner: root
+ group: root
+ mode: 0755
+
+- name: Execute bbb-install script only if /usr/share/bigbluebutton/license.txt does not exist
+ command:
+ cmd: "/root/bbb-install-2.7.sh -v focal-270 -s {{ inventory_hostname }} -e benedikt.wismans@sdw.systems -c service.sdw.systems:3ef948d61ff4bcf3e87f068dfecbbbe6"
+ chdir: /root
+ creates: /usr/share/bigbluebutton/license.txt
+
+- name: Install bbb webhooks package
+ apt:
+ name: bbb-webhooks
+ state: present
+...
\ No newline at end of file
diff --git a/roles/bbb_install/tasks/main.yml b/roles/bbb_install/tasks/main.yml
new file mode 100644
index 0000000..3a36061
--- /dev/null
+++ b/roles/bbb_install/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+- import_tasks: packages.yml
+- import_tasks: install_bbb.yml
+- import_tasks: setup_bbb.yml
+- import_tasks: config_bbb.yml
+# - import_tasks: dialin_bbb.yml
+
+...
+
diff --git a/roles/bbb_install/tasks/packages.yml b/roles/bbb_install/tasks/packages.yml
new file mode 100644
index 0000000..06c8683
--- /dev/null
+++ b/roles/bbb_install/tasks/packages.yml
@@ -0,0 +1,11 @@
+---
+
+- name: Install apparmor required by new version of docker
+ apt:
+ name:
+ - apparmor-utils
+ - apparmor-profiles
+ - apparmor-profiles-extra
+ - vim-addon-manager
+
+...
\ No newline at end of file
diff --git a/roles/bbb_install/tasks/setup_bbb.yml b/roles/bbb_install/tasks/setup_bbb.yml
new file mode 100644
index 0000000..94d9f9e
--- /dev/null
+++ b/roles/bbb_install/tasks/setup_bbb.yml
@@ -0,0 +1,48 @@
+---
+
+- name: Create or recreate symlinks for bbb config files in script-directory
+ shell: |
+ cd /home/core/Scripte
+ ln -sf /usr/local/bigbluebutton/bbb-webhooks
+ ln -sf /etc/bigbluebutton
+ ln -sf /var/www/bigbluebutton-default
+ ln -sf /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties
+ ln -sf /usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml
+ ln -sf /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml
+ ln -sf /usr/share/meteor/bundle/systemd_start.sh
+ ln -sf /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml
+ ln -sf /usr/share/bigbluebutton/nginx/sip.nginx
+
+- name: Upload turn-stun-config to core's Scripte directory
+ copy:
+ src: turn-stun-servers.xml.konfiguriert
+ dest: /home/core/Scripte
+ owner: core
+ group: users
+ mode: 0644
+
+- name: Upload update script to core's Scripte directory
+ copy:
+ src: update
+ dest: /home/core/Scripte
+ owner: core
+ group: users
+ mode: 0755
+
+- name: Install core user's crontab update-Script before at 3.00 before rebooting at 4 AM
+ ansible.builtin.cron:
+ name: run update Script at 3:00
+ user: core
+ minute: "0"
+ hour: "3"
+ job: "/home/core/Scripte/update"
+
+- name: Upload default presantation to core's Scripte directory
+ copy:
+ src: "{{ default_presentation }}"
+ dest: /home/core/Scripte/customerDefault.pdf
+ owner: core
+ group: users
+ mode: 0644
+
+...
\ No newline at end of file
diff --git a/roles/bs_scripte/addVirtualBackground b/roles/bs_scripte/addVirtualBackground
new file mode 100644
index 0000000..72754ec
--- /dev/null
+++ b/roles/bs_scripte/addVirtualBackground
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+source /home/core/Scripte/bashlib
+
+echo $1
+
+addVBackground $1
+
diff --git a/roles/bs_scripte/files/RD_Logo_Vielfalt_1280x960.jpg b/roles/bs_scripte/files/RD_Logo_Vielfalt_1280x960.jpg
new file mode 100644
index 0000000..6621e4e
Binary files /dev/null and b/roles/bs_scripte/files/RD_Logo_Vielfalt_1280x960.jpg differ
diff --git a/roles/bs_scripte/files/bashlib b/roles/bs_scripte/files/bashlib
index 493c953..2dbccd1 100644
--- a/roles/bs_scripte/files/bashlib
+++ b/roles/bs_scripte/files/bashlib
@@ -17,3 +17,50 @@ adddate() {
getnic() {
echo `ip link show | grep "state UP" | grep -v "LOOPBACK" | grep -v virbr | awk '{print $2}' | sed 's/://g'`
}
+
+#Method removes all BBB Virtual Webcam Backgrounds (except the blur thumbnail)
+removeAllVBackgrounds() {
+
+ HTML5_CONFIG=/usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml
+
+ cat /usr/share/meteor/bundle/programs/web.browser/program.json | jq '.manifest|=map(select( (.path|contains("virtual-backgrounds")) and (.path|contains("blur.jpg")|not) |not))' | sponge /usr/share/meteor/bundle/programs/web.browser/program.json >/dev/null
+ yq d -i $HTML5_CONFIG public.virtualBackgrounds.fileNames
+}
+
+#Adds a new Virtual Background image. Paramter: full path to background image
+# If a file thumbnails/ exists in the original location this thumbnail is used. Otherwise a scaled down image of the original is made
+addVBackground() {
+ PROGRAMJSON=/usr/share/meteor/bundle/programs/web.browser/program.json
+ if [ ! -f $1 ]; then
+ echo "Could not find file $1 - not adding as Virtual Background"
+ return 1
+ fi
+ FILENAME=$(basename $1)
+ DIRECTORY=$(dirname $1)
+
+ HTML5_CONFIG=/usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml
+
+ #Copy Files
+ cp $1 /usr/share/meteor/bundle/programs/web.browser/app/resources/images/virtual-backgrounds
+ if [ -f $DIRECTORY/thumbnails/$FILENAME ]; then
+ cp $DIRECTORY/thumbnails/$FILENAME /usr/share/meteor/bundle/programs/web.browser/app/resources/images/virtual-backgrounds/thumbnails
+ else
+ convert $1 -scale 50 /usr/share/meteor/bundle/programs/web.browser/app/resources/images/virtual-backgrounds/thumbnails/$FILENAME
+ fi
+
+ #Get SHA-1 Checksums
+ CHKSUM=$(sha1sum $1|cut -d" " -f1)
+ CHKSUM_TN=$(sha1sum /usr/share/meteor/bundle/programs/web.browser/app/resources/images/virtual-backgrounds/thumbnails/$FILENAME|cut -d" " -f1)
+
+ #Get File Sizes
+ SIZE=$(stat --printf="%s" $1)
+ SIZE_TN=$(stat --printf="%s" /usr/share/meteor/bundle/programs/web.browser/app/resources/images/virtual-backgrounds/thumbnails/$FILENAME)
+
+ #Generate JSON-Snippet to add to program.json
+ JSON="{ \"path\" : \"app/resources/images/virtual-backgrounds/$FILENAME\", \"where\" : \"client\", \"type\" : \"asset\", \"cacheable\": false, \"url\": \"/resources/images/virtual-backgrounds/$FILENAME\", \"size\": \"$SIZE\", \"hash\": \"$CHKSUM\", \"sri\": null }"
+ JSON_TN="{ \"path\" : \"app/resources/images/virtual-backgrounds/thumbnails/$FILENAME\", \"where\" : \"client\", \"type\" : \"asset\", \"cacheable\": false, \"url\": \"/resources/images/virtual-backgrounds/thumbnails/$FILENAME\", \"size\": \"$SIZE_TN\", \"hash\": \"$CHKSUM_TN\", \"sri\": null }"
+
+ #Append Metadata to program.json
+ cat $PROGRAMJSON |jq ".manifest += [$JSON] + [$JSON_TN]" |sponge $PROGRAMJSON
+ yq w -i $HTML5_CONFIG public.virtualBackgrounds.fileNames[+] "$FILENAME"
+}
diff --git a/roles/bs_scripte/tasks/main.yml b/roles/bs_scripte/tasks/main.yml
index 3e8faf8..7db90ce 100644
--- a/roles/bs_scripte/tasks/main.yml
+++ b/roles/bs_scripte/tasks/main.yml
@@ -37,14 +37,39 @@
- sysstat
- ifstat
-- name: Upload update to core's Scripte directory
+- name: Install moreutis soak up standard input and write to a file) und jq (The jq is a command line based JSON processor) for custom background installation script in bashlib
+ apt:
+ name:
+ - moreutils
+ - jq
+
+- name: Upload addVirtualBackground Script to core's Scripte directory
copy:
- src: update
+ src: addVirtualBackground
dest: /home/core/Scripte/
owner: core
group: users
mode: 0755
+- name: Upload VirtualBackground to core's Scripte directory
+ copy:
+ src: RD_Logo_Vielfalt_1280x960.jpg
+ dest: /home/core/Scripte/
+ owner: core
+ group: users
+ mode: 0644
+
+
+
+# Das update-Script beisst sich mit dem aus BBB
+#- name: Upload update to core's Scripte directory
+# copy:
+# src: update
+# dest: /home/core/Scripte/
+# owner: core
+# group: users
+# mode: 0755
+
- name: Install vim for script editing
apt:
diff --git a/roles/bs_snmp/files/snmpd.conf b/roles/bs_snmp/files/snmpd.conf
index 6ffa2ae..8bcba1d 100644
--- a/roles/bs_snmp/files/snmpd.conf
+++ b/roles/bs_snmp/files/snmpd.conf
@@ -13,6 +13,7 @@ rocommunity SDW 88.99.138.96 #root4.sdw.systems
rocommunity SDW 94.130.135.216 #root5.sdw.systems
rocommunity SDW 178.15.59.28 #core-open-diakonie.de
+rocommunity SDW 178.15.152.60 #core-open-diaknoie.de behind reverse proxy
# Default access to basic system info
rocommunity public default -V systemonly
@@ -84,7 +85,3 @@ load 12 10 5
# Remember to activate the 'createUser' lines above
iquerySecName internalUser
rouser internalUser
- # generate traps on UCD error conditions
-defaultMonitors yes
- # generate traps on linkUp/Down
-linkUpDownNotifications yes
diff --git a/roles/bs_snmp/tasks/main.yml b/roles/bs_snmp/tasks/main.yml
index dab3c0e..874d560 100644
--- a/roles/bs_snmp/tasks/main.yml
+++ b/roles/bs_snmp/tasks/main.yml
@@ -4,11 +4,13 @@
apt:
name:
- snmpd
+ - snmp
+ - snmp-mibs-downloader
- name: Upload snnmpd configuration file snmpd.conf to /etc/snmp
copy:
src: snmpd.conf
- dest: /etc/snmpd/
+ dest: /etc/snmp/
owner: root
group: root
mode: 0600
diff --git a/roles/bs_users/files/authorized_keys_core b/roles/bs_users/files/authorized_keys_core
index cb534f2..d087ebb 100644
--- a/roles/bs_users/files/authorized_keys_core
+++ b/roles/bs_users/files/authorized_keys_core
@@ -1,4 +1,6 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLGR3klHdPzj5rOwoce8JdvkMGXoTSXdp66JhYYO4t5hWQRB+DZjvhpSBjvtKZZH07wHS0Ya69baDmwHiOhzhNwcs3hwi/I2k/ABSjmjRNNAMlxauHvaRviFYtx5/h7ZayKW9gpxU4e22/9k0F9XAaWkN8Mc7PgvagUy9POpP19gyBBS35kjFIKjOMrz1nQ+9jwUza7lARryctnDoaiUd7DHsLfvSa8Q1fVNUka+k0H1YtRxfsdU8CdMrQf+bDtUTjJupyT5xFphXEle31E49+WAsYGwXkpmQA4zM6E1gOJ0rgnmm/DFJeJ/DYaYP79XzwjvJxNSVMRAg6t5P5z93x benediktwismans@macmini
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSqGfwbqDQdkjG8s/iCVYlsXcVzScjm/D5xZ11AnWWTZ2rL4BitjYgTNx+3SRoM6K8mUYHFi5tTw3X5ZWcjIj+4UXqONA0pCfkVSo24obIqiCXa7+ZyI7MEW/lGmt4u02fJYCrrzxZCfHd3qR3hFAfv1b188ebEMDYpDORAek0PtMoKHVpNZDK9EBNotT7v92WGFngNSLd4qqnUexEd89zsv9mDlttQe6Z5oIHeFIpu0VsaOQiKXQHcKdwwsXdoTG7q989jJ9kRb3lC/Bs+fpzKd8Q/rPGLSkpJUA4RN6f7ZXJ7fQ86zNGZ7MsskcHJyQCdFPV/ESXNV9rabE6DX73 benediktwismans@acer
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDdvEW4c8+OqO3bdc+5JonpEADbR304X5zXI5j9cOROK0XmK0BQVBrmimlcguEcBPinFRC7XaWgxH70bzPBcwTNVCQOzcAAF3zyuDFfLE5Kv5+vxp0g41AERYLC27Smwo8hQ/ckO+RSxFgM5FKTLErSqXdbtGMlFqA0b/auZhXDHXE+7ft8TSVFnTusrlYovNqwK3wuGHB2xs6gEqlVw5DVwhRsO/hq6pdoSx35GygQYWWPwY8vCSXaqrKbakG9GA0u4TqLE8StpnItEPfvQ3Fe/8AptC4u4JgYuucYZjFOQqzJdv0KHqKOriy7RdO01HxS6Ts7VnbvAc5aL8jZF9bl benediktwismans@intel
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSU++o+8yN2V9ojFnnHgkj7QgciurCxcK5b0Yei/I9BmwE8uAWgQR4DJw3iAkV+NSVJ0dsiqGwc6I9f8e9IsTStfcSlwYA8VENuFSelVu0Xph0CY8jPKV8h6gEM8+AQd4iYUgJeROtEkNZhh3D/ZC68ap5VxfF4PrHeDu0jE0C1fG6MGJ5btgI7IWAoaAkSAtoxC9latnFDhFBNmnJmq+d0DNNPBKoB5DG9wQvVxpeuuKzSZyDv87N3/28Uo8JqLm3r4ftBU0sWctymRS0Z5EDqHlLNFQdqQeSzPtQeNh5QOEKH+aa9aAsjINOaEpI2uIe0EYAmBOMjyzvi5BRy6AJ benediktwismans@vhostbbb
\ No newline at end of file
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSU++o+8yN2V9ojFnnHgkj7QgciurCxcK5b0Yei/I9BmwE8uAWgQR4DJw3iAkV+NSVJ0dsiqGwc6I9f8e9IsTStfcSlwYA8VENuFSelVu0Xph0CY8jPKV8h6gEM8+AQd4iYUgJeROtEkNZhh3D/ZC68ap5VxfF4PrHeDu0jE0C1fG6MGJ5btgI7IWAoaAkSAtoxC9latnFDhFBNmnJmq+d0DNNPBKoB5DG9wQvVxpeuuKzSZyDv87N3/28Uo8JqLm3r4ftBU0sWctymRS0Z5EDqHlLNFQdqQeSzPtQeNh5QOEKH+aa9aAsjINOaEpI2uIe0EYAmBOMjyzvi5BRy6AJ benediktwismans@vhostbbb
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC8g5FOIInITmq8oOSy/CUmIWhOWFnqpBHhNweohK1SWHRjg8/kySZo4PwS2sKCGkZpTelnJjoVY3rBaZBb75HEn0BSRhZ2FPIviD3+ymXLvGgA9ewkms2s78jvhmr3iZSOH+PXZ0vhobrzzh2e2ZuyqsP/cTdc8KQOV3HFzkXfi7sLbGbKSuXwHqEwImj6KJ5Z0g0e1YxPQtkhpwtKkMhC7kgzK5HTEE7xh7DePG6i5gD9E/XXEGxKMPcDAff6YM31MVy0n+2LQ2fz7rFdmceHtYY9f6XijYuOBiNlNmvtD+zcO2Q44nUipkDkFBUYZeTXxfE8xf3rbmpBX5f3WNprUrNmnG1elgsWOa6yxoAL0ZGCfdSboS68JxTG9JxM2lKOv/jUc/0zwkiKkOX24ZnCAmBBh+zT4rNlJbA2dYVTl0+B5PNA2JlXbpkOJgGlvt6gT7N5fvHfVhvVPWbGRPUksk8aP+0jSZWIWN0tF3aXTagOi+5fwx1pNQcZQobQThk= core@px-core4five-p1.rummelsberger.local
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCV4amm6qrzqUfdjXftZCg37875duFRpJYkexQjtHpFRSR5Jk+m01MtQEwns4Ou6qlLhXUUZDhxGaktg5Bme8tMzp/AQ8mcKO4LfXVV+yAqbkJCYNHuAGJpNOaC9H8RdjuvN0wFq8lLiE4vGIbc2L5NPDzGYzoNTU8ubpqzvLldLqm46yL6uTdTOCCDNQuJV1oW6qj28R7AU5eKqYYib040RDdLkPZeTxGaEo+yy1vbR8dO0fU1HtT6gNay2F9nKsfPCXOk3ZU8ra5qA+ri9LK1GHCg8wM4FrJF22njrEJN/WBbjR7BXii4uqmrx+3RcYQrtJsAHjW3pUjkaROgBWjonlxSTkL7hcJmSBhXw3Uop8wVY7y8ntUbS6kBMhaZkYRfs2tekDoR5NmhcBAZtDmyI+MqVDUeg0biIRLDtCA5+pXpiBxgLf3NEf/E5kHPdrW+Na/ioO3b+aHO0124XfCTWjYPasw80hkLKRl1sHR/G7ZIMwVPk/6BzkwV8V95Fms= benediktwismans@sdwmacair
diff --git a/roles/bs_users/files/authorized_keys_root b/roles/bs_users/files/authorized_keys_root
index dbb4273..2d5874b 100644
--- a/roles/bs_users/files/authorized_keys_root
+++ b/roles/bs_users/files/authorized_keys_root
@@ -1,3 +1,4 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLGR3klHdPzj5rOwoce8JdvkMGXoTSXdp66JhYYO4t5hWQRB+DZjvhpSBjvtKZZH07wHS0Ya69baDmwHiOhzhNwcs3hwi/I2k/ABSjmjRNNAMlxauHvaRviFYtx5/h7ZayKW9gpxU4e22/9k0F9XAaWkN8Mc7PgvagUy9POpP19gyBBS35kjFIKjOMrz1nQ+9jwUza7lARryctnDoaiUd7DHsLfvSa8Q1fVNUka+k0H1YtRxfsdU8CdMrQf+bDtUTjJupyT5xFphXEle31E49+WAsYGwXkpmQA4zM6E1gOJ0rgnmm/DFJeJ/DYaYP79XzwjvJxNSVMRAg6t5P5z93x benediktwismans@macmini
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSqGfwbqDQdkjG8s/iCVYlsXcVzScjm/D5xZ11AnWWTZ2rL4BitjYgTNx+3SRoM6K8mUYHFi5tTw3X5ZWcjIj+4UXqONA0pCfkVSo24obIqiCXa7+ZyI7MEW/lGmt4u02fJYCrrzxZCfHd3qR3hFAfv1b188ebEMDYpDORAek0PtMoKHVpNZDK9EBNotT7v92WGFngNSLd4qqnUexEd89zsv9mDlttQe6Z5oIHeFIpu0VsaOQiKXQHcKdwwsXdoTG7q989jJ9kRb3lC/Bs+fpzKd8Q/rPGLSkpJUA4RN6f7ZXJ7fQ86zNGZ7MsskcHJyQCdFPV/ESXNV9rabE6DX73 benediktwismans@acer
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDdvEW4c8+OqO3bdc+5JonpEADbR304X5zXI5j9cOROK0XmK0BQVBrmimlcguEcBPinFRC7XaWgxH70bzPBcwTNVCQOzcAAF3zyuDFfLE5Kv5+vxp0g41AERYLC27Smwo8hQ/ckO+RSxFgM5FKTLErSqXdbtGMlFqA0b/auZhXDHXE+7ft8TSVFnTusrlYovNqwK3wuGHB2xs6gEqlVw5DVwhRsO/hq6pdoSx35GygQYWWPwY8vCSXaqrKbakG9GA0u4TqLE8StpnItEPfvQ3Fe/8AptC4u4JgYuucYZjFOQqzJdv0KHqKOriy7RdO01HxS6Ts7VnbvAc5aL8jZF9bl benediktwismans@intel
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCV4amm6qrzqUfdjXftZCg37875duFRpJYkexQjtHpFRSR5Jk+m01MtQEwns4Ou6qlLhXUUZDhxGaktg5Bme8tMzp/AQ8mcKO4LfXVV+yAqbkJCYNHuAGJpNOaC9H8RdjuvN0wFq8lLiE4vGIbc2L5NPDzGYzoNTU8ubpqzvLldLqm46yL6uTdTOCCDNQuJV1oW6qj28R7AU5eKqYYib040RDdLkPZeTxGaEo+yy1vbR8dO0fU1HtT6gNay2F9nKsfPCXOk3ZU8ra5qA+ri9LK1GHCg8wM4FrJF22njrEJN/WBbjR7BXii4uqmrx+3RcYQrtJsAHjW3pUjkaROgBWjonlxSTkL7hcJmSBhXw3Uop8wVY7y8ntUbS6kBMhaZkYRfs2tekDoR5NmhcBAZtDmyI+MqVDUeg0biIRLDtCA5+pXpiBxgLf3NEf/E5kHPdrW+Na/ioO3b+aHO0124XfCTWjYPasw80hkLKRl1sHR/G7ZIMwVPk/6BzkwV8V95Fms= benediktwismans@sdwmacair
\ No newline at end of file
diff --git a/roles/install_image/tasks/main.yml b/roles/install_image/tasks/main.yml
index 7351c67..7327856 100644
--- a/roles/install_image/tasks/main.yml
+++ b/roles/install_image/tasks/main.yml
@@ -11,7 +11,7 @@
when: stat_result.stat.exists == false
- name: Execute installimage
- shell: "{{ install_image.path }} -a -n {{ inventory_hostname }} -b grub -r {{ install_image.raid }} -i {{ install_image.image }} -p /boot:ext3:512M,/:ext4:all -d {{ install_image.drives }}"
+ shell: "{{ install_image.path }} -a -n {{ inventory_hostname }} -b grub -r {{ install_image.raid }} -i {{ install_image.image }} -p /boot:ext3:512M,swap:swap:32G,/:ext4:all -d {{ install_image.drives }}"
- name: Rebooting...
shell: reboot
diff --git a/roles/kvm_install/files/vhost_getIPv4 b/roles/kvm_install/files/vhost_getIPv4
index 0357166..f56eec6 100644
--- a/roles/kvm_install/files/vhost_getIPv4
+++ b/roles/kvm_install/files/vhost_getIPv4
@@ -13,7 +13,7 @@ buf=`/usr/sbin/arp -an | grep $mac`
#echo arp reports ipv4 config for MAC $mac is:$buf
# Die IPv4-Adresse steht in der Ausgabe von arp in runden Klammern.
-# Das sind auch die einziegen runden Klammern in der Asugabe.
+# Das sind auch die einzigen runden Klammern in der Ausgabe.
buf=${buf#*(}
buf=${buf%)*}
diff --git a/roles/kvm_install/tasks/packages_install.yml b/roles/kvm_install/tasks/packages_install.yml
index ad7c9b0..4c8426a 100644
--- a/roles/kvm_install/tasks/packages_install.yml
+++ b/roles/kvm_install/tasks/packages_install.yml
@@ -14,6 +14,7 @@
- virt-manager
- dnsmasq
- python3-libvirt
+ - python3-lxml
- libguestfs-tools
- name: Check KVM ok
diff --git a/roles/kvm_installvm/tasks/main.yml b/roles/kvm_installvm/tasks/main.yml
index 47b7407..7d80a12 100644
--- a/roles/kvm_installvm/tasks/main.yml
+++ b/roles/kvm_installvm/tasks/main.yml
@@ -1,6 +1,7 @@
---
-- import_tasks: template_upload.yml
-- import_tasks: vm_create.yml
-- import_tasks: hosts_vm2ip.yml
+#- import_tasks: template_upload.yml
+#- import_tasks: vm_create.yml
+#- import_tasks: hosts_vm2ip.yml
+- import_tasks: virtnet_config.yml
...
\ No newline at end of file
diff --git a/roles/kvm_installvm/tasks/virtnet_config.yml b/roles/kvm_installvm/tasks/virtnet_config.yml
new file mode 100644
index 0000000..fb6d810
--- /dev/null
+++ b/roles/kvm_installvm/tasks/virtnet_config.yml
@@ -0,0 +1,20 @@
+---
+
+#
+- name: Retrieve MAC-address
+ shell: /home/core/Scripte/vhost_getMAC "{{ vm_name }}"
+ register: vm_mac
+ changed_when: "False"
+
+
+- name: Debug MAC-address
+ debug: msg={{ vm_mac["stdout"] }}
+ changed_when: "False"
+
+- name: Add a new host in the dhcp pool
+ community.libvirt.virt_net:
+ name: br_nat
+ command: modify
+ xml: ""
+
+...
\ No newline at end of file