From 1ddf192f2ac2cf475594f5bda18671f73a91700c Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 30 Mar 2020 21:22:53 +0200 Subject: [PATCH] Add script 'bbb-greenlight-install.sh'. --- bbb-greenlight-install.sh | 647 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 647 insertions(+) create mode 100755 bbb-greenlight-install.sh diff --git a/bbb-greenlight-install.sh b/bbb-greenlight-install.sh new file mode 100755 index 0000000..76d8523 --- /dev/null +++ b/bbb-greenlight-install.sh @@ -0,0 +1,647 @@ +#!/usr/bin/env bash + +cript_name="$(basename $(realpath $0))" +working_dir="$(dirname $(realpath $0))" + +conf_file="${working_dir}/conf/${script_name%%.*}.conf" + +LOCK_DIR="/tmp/$(basename $0).$$.LOCK" +log_file="${LOCK_DIR}/${script_name%%.*}.log" + +DIST="ubuntu" +DIST_RELEASE="xenial" + +GREENLIGTH_DIR="/usr/local/greenlight" + +FQDN_HOSTNAME="bbb.oopen.de" +HOSTNAME=" ${FQDN_HOSTNAME%%.*}" + + +# ---------- +# Base Function(s) +# ---------- + +clean_up() { + + # Perform program exit housekeeping + rm -rf "$LOCK_DIR" + blank_line + exit $1 +} + +echononl(){ + if $terminal ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n " $*\\c" 1>&2 + else + echo -e -n " $*" 1>&2 + fi + rm /tmp/shprompt$$ + fi +} +fatal(){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mFatal\033[m ] $*" + else + echo -e " [ Fatal ] $*" + fi + echo "" + if $terminal ; then + echo -e " \033[1mScript terminated\033[m.." + else + echo -e " Script terminated.." + fi + echo "" + rm -rf $LOCK_DIR + exit 1 +} +error (){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mError\033[m ] $*" + else + echo " [ Error ] $*" + fi + echo "" +} +info () { + if $terminal ; then + echo "" + echo -e " [ \033[32m\033[1mInfo\033[m ] $*" + echo "" + fi +} +note () { + if $terminal ; then + echo "" + echo -e " [ \033[33m\033[1mNote\033[m ] $*" + echo "" + fi +} + +echo_ok() { + if $terminal ; then + echo -e "\033[85G[ \033[32mok\033[m ]" + fi +} +echo_failed(){ + if $terminal ; then + echo -e "\033[85G[ \033[1;31mfailed\033[m ]" + fi +} +echo_skipped() { + if $terminal ; then + echo -e "\033[85G[ \033[37m\033[1mskipped\033[m ]" + fi +} +echo_wait(){ + if $terminal ; then + echo -en "\033[85G[ \033[5m\033[1m..\033[m ]" + fi +} + +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + +blank_line() { + if $terminal ; then + echo "" + fi +} + + + +# ---------- +# - Jobhandling +# ---------- + +# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM +# - +trap clean_up SIGHUP SIGINT SIGTERM + +# - Create lock directory '$LOCK_DIR" +# +mkdir "$LOCK_DIR" + + +# ---------- +# - Some checks .. +# ---------- + +# - Running in a terminal? +# - +if [[ -t 1 ]] ; then + terminal=true +else + fatal "Script must run in a terminal." +fi + + +# ========== +# - Begin Main Script +# ========== + +# ---------- +# - Headline +# ---------- + +if $terminal ; then + echo "" + echo -e "\033[1m----------\033[m" + echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" + echo -e "\033[1m----------\033[m" +fi + +blank_line + +# Remove old versions of Docker +# +echononl "Remove old versions of Docker .." +apt-get remove -y docker docker-engine docker.io containerd runc > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +# Stop Service if started +# +echononl "Stop Greenlight Service.." +if $(ps ax | grep -v grep | grep -q /usr/bin/docker-proxy ) ; then + cd $GREENLIGTH_DIR && docker-compose down > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +else + echo_skipped +fi + + +# Install packages to allow apt to use a repository over HTTPS +# +echononl "Install packages to allow apt to use a repository over HTTPS .." +apt-get install \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common -y > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +blank_line + + +# Add Docker’s official GPG key +# +echononl "Add Docker’s official GPG key .." +curl -fsSL https://download.docker.com/linux/ubuntu/gpg 2> "$log_file" | sudo apt-key add - >> "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +# Add Dockers stable repository +# +echononl "Add Dockers stable repositor .." +cat < /etc/apt/sources.list.d/docker.list 2> "$log_file" +deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable +EOF +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +# Update the apt package index. +# +echononl "Update the apt package index. .." +apt-get update > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +# Install the latest version of Docker Engine - Community and containerd +# +echononl "Install the latest version of Docker Engine - Community and containerd .." +DEBIAN_FRONTEND=noninteractive apt-get -y install docker-ce docker-ce-cli containerd.io > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +blank_line + +# Deinstall apparmor +# +# Needed if docker is running in a LX Conatiner +# +echononl "Deinstall apparmor - Needed because docker is running in a LX-Container .." +DEBIAN_FRONTEND=noninteractive apt-get -y remove apparmor > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + + +blank_line + +# Create the Greenlight directory for its configuration to live in. +# +echononl "Create the Greenlight directory for its configuration to live in. .." +if [[ -d "$GREENLIGTH_DIR" ]] ; then + echo_skipped +else + mkdir "$GREENLIGTH_DIR" > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +fi + +echononl "Enter Greenlight directory .." +cd "$GREENLIGTH_DIR" > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + + +# Greenlight will read its environment configuration from the .env file. To generate this +# file and install the Greenlight Docker image, run (inside greenlight directory): +# +# docker run --rm bigbluebutton/greenlight:v2 cat ./sample.env > .env +# +_new_env=false +echononl "Generate environment configuration and install Greenlight Docker image .." +if [[ -s ${GREENLIGTH_DIR}/.env ]]; then + echo_skipped +else + docker run --rm bigbluebutton/greenlight:v2 cat ./sample.env > .env 2> "$log_file" + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + _new_env=true + fi +fi + + +# Greenlight needs a secret key in order to run in production. To generate this, run: +# +# docker run --rm bigbluebutton/greenlight:v2 bundle exec rake secret +# +_secret_key_found=false +echononl "Generating a Secret Key (in order to run in production).." +if [[ -z "$(grep -E "^\s*SECRET_KEY_BASE\s*=" ${GREENLIGTH_DIR}/.env 2> /dev/null | cut -d '=' -f2)" ]] ; then + _greenlight_secret="$(docker run --rm bigbluebutton/greenlight:v2 bundle exec rake secret 2> "$log_file")" + if [[ -s "$log_file" ]] ; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +else + echo_skipped + _secret_key_found=true +fi + + +# Set 'SECRET_KEY_BASE' with generated Secret Key +# +_key="SECRET_KEY_BASE" +_val="$_greenlight_secret" +echononl "Set 'SECRET_KEY_BASE' env with generated Secret Key at file '.env'.." +if $_secret_key_found ; then + echo_skipped +else + perl -i -n -p -e "s/^(\s*${_key}\s*=.*)/##! \1\n${_key}=${_val}/" \ + ${GREENLIGTH_DIR}/.env > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +fi + + +# Get BigBlueButtons secret .. +# +echononl "Get BigBlueButtons secret .." +_bbb_secret="$(bbb-conf --secret 2> $log_file | grep -i -E "^\s*Secret" 2> $log_file | awk '{print$2}' 2> $log_file)" +if [[ -s "$log_file" ]] ; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + + +# Set 'BIGBLUEBUTTON_SECRET' with generated Secret Key +# +_key="BIGBLUEBUTTON_SECRET" +_val="$_bbb_secret" +echononl "Set 'BIGBLUEBUTTON_SECRET' env with BBB's Secret Key at file '.env'.." +if $(grep -E -q "^\s*${_key}\s*=\s*${_val}" ${GREENLIGTH_DIR}/.env 2> /dev/null) ; then + echo_skipped +else + perl -i -n -p -e "s/^(\s*${_key}\s*=.*)/##! \1\n${_key}=${_val}/" \ + ${GREENLIGTH_DIR}/.env > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +fi + + +# Get BigBlueButtons url .. +# +echononl "Get BigBlueButtons URL .." +_bbb_url="$(bbb-conf --secret 2> $log_file | grep -i -E "^\s*URL" 2> $log_file | awk '{print$2}' 2> $log_file)" +if [[ -s "$log_file" ]] ; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + + +# Set 'BIGBLUEBUTTON_ENDPOINT' with generated Secret Key +# +_key="BIGBLUEBUTTON_ENDPOINT" +_val="$_bbb_url" +echononl "Set 'BIGBLUEBUTTON_ENDPOINT' env with BBB's Secret Key at file '.env'.." +if $(grep -E -q "^\s*${_key}\s*=\s*${_val}" ${GREENLIGTH_DIR}/.env 2> /dev/null) ; then + echo_skipped +else + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#\#\#! \1\n${_key}=${_val}#" \ + ${GREENLIGTH_DIR}/.env > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +fi + + +# Set ALLOW_GREENLIGHT_ACCOUNTS +# +_key="ALLOW_GREENLIGHT_ACCOUNTS" +_val="false" +echononl "Set 'ALLOW_GREENLIGHT_ACCOUNTS' to false (file .env).." +if $(grep -E -q "^\s*${_key}\s*=\s*${_val}" ${GREENLIGTH_DIR}/.env 2> /dev/null) ; then + echo_skipped +else + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#\#\#! \1\n${_key}=${_val}#" \ + ${GREENLIGTH_DIR}/.env > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +fi + +blank_line + + +# randomly generate a password for the PostgreSQL database and replace the entries +# in the .env and docker-compose.yml +# +# export pass=$(openssl rand -hex 8) +# sed -i 's/POSTGRES_PASSWORD=password/POSTGRES_PASSWORD='$_postgresql_pass'/g' docker-compose.yml +# sed -i 's/DB_PASSWORD=password/DB_PASSWORD='$_postgresql_pass'/g' .env +# +_postgresql_pass="" +_pass_generated=false +echononl "Generate password for the PostgreSQL database.." +if $_new_env ; then + _postgresql_pass="$(openssl rand -hex 8 2> $log_file)" + if [[ -s "$log_file" ]] ; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + _pass_generated=true + fi +else + echo_skipped +fi + + +# Set DB_PASSWORD' +# +_key="DB_PASSWORD" +_val="$_postgresql_pass" +echononl "Set DB_PASSWORD (file .env).." +if $_pass_generated ; then + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#\#\#! \1\n${_key}=${_val}#" \ + ${GREENLIGTH_DIR}/.env > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +else + echo_skipped +fi + + + +blank_line + +echononl "Verify the configuration settings (.env file).." +cd "${GREENLIGTH_DIR}" \ + && docker run --rm --env-file .env bigbluebutton/greenlight:v2 bundle exec rake conf:check > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +blank_line + + +# Greenlight will be configured to deploy at the /b subdirectory. This is necessary so +# it doesn’t conflict with the other BigBlueButton components. The Nginx configuration +# for this subdirectory is stored in the Greenlight image. To add this configuration file +# to your BigBlueButton server, run: +# +# docker run --rm bigbluebutton/greenlight:v2 cat ./greenlight.nginx | sudo tee /etc/bigbluebutton/nginx/greenlight.nginx +# +echononl "Add nginx configuration to BigBlueButton's service .." +if [[ -f "/etc/bigbluebutton/nginx/greenlight.nginx" ]] ; then + echo_skipped +else + docker run --rm bigbluebutton/greenlight:v2 cat ./greenlight.nginx \ + > /etc/bigbluebutton/nginx/greenlight.nginx 2> $log_file + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +fi + + +blank_line + +# Download the current stable release of Docker Compose: +# +echononl "Download the current stable release (v 1.25.4) of Docker Compose .." +curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" \ + -o /usr/local/bin/docker-compose > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +echononl "Set executable bit to 'docker-compose'.." +chmod +x /usr/local/bin/docker-compose > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +info "To install a different version of Compose, substitute 1.25.4 with the + version of Compose you want to use." + +echononl "Create cronjob to start Greenlight service after booting the system.." +if $(crontab -l 2>/dev/null | grep -q -E "^@reboot\s+.*\s+docker-compose up -d" 2> /dev/null) ; then + echo_skipped +else + _crontab_tmp_file="${LOCK_DIR}/crontab_root.$$" + crontab -l > $_crontab_tmp_file 2> /dev/null + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo "" >> $_crontab_tmp_file + echo "# Start greenlight service (docker)" >> $_crontab_tmp_file + echo "#" >> $_crontab_tmp_file + echo "@reboot cd \"$GREENLIGTH_DIR\" && docker-compose up -d" >> $_crontab_tmp_file + crontab $_crontab_tmp_file > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi + fi +fi + +blank_line + + +echononl "Copy the docker-compose.yml file from the Greenlight image in to greenlight directory.." +cd ${GREENLIGTH_DIR} \ + && docker run --rm bigbluebutton/greenlight:v2 cat ./docker-compose.yml > docker-compose.yml 2> $log_file +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +echononl "Set 'POSTGRES_PASSWORD' (file docker-compose.yml).." +if $_pass_generated ; then + sed -i 's/POSTGRES_PASSWORD=password/POSTGRES_PASSWORD='$_postgresql_pass'/g' \ + ${GREENLIGTH_DIR}/docker-compose.yml > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" + else + echo_ok + fi +else + echo_skipped +fi + +echononl "Start Greenlight service (vi docker).." +cd ${GREENLIGTH_DIR} && docker-compose up -d > $log_file 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + +echononl "Restart nginx service.." +systemctl restart nginx > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat "$log_file")" +else + echo_ok +fi + + + +blank_line + +note "To create an Administrator account with the default values, in the Greenlight directory, + run the following command: + + # cd $GREENLIGTH_DIR + # \033[1mdocker exec greenlight-v2 bundle exec rake admin:create\033[m + + If you would like to configure the name, email, or password of the Administrator account, + replace the previous command with this: + + # cd $GREENLIGTH_DIR + # \033[1mdocker exec greenlight-v2 bundle exec rake user:create[\"name\",\"email\",\"password\",\"admin\"]\033[m + + Once the command has finished it will print the account’s email and password." + +note "Optionally, if you wish to have the default landing page at the root of your BigBlueButton + server redirect to Greenlight, add the following entry to the bottom + of /etc/nginx/sites-available/bigbluebutton just before the last } character. + + \033[33mlocation = / { + return 307 /b; + }\033[m + + To have this change take effect, you must once again restart Nginx." + + +clean_up 0 +