Merge and track latest features on stable #6

Merged
Ark74 merged 71 commits from unstable into master 2020-08-08 06:41:50 +00:00
3 changed files with 134 additions and 38 deletions

View File

@ -26,6 +26,11 @@ ENABLE_BLESSM="TBD"
CHD_LST="$(curl -sL https://chromedriver.storage.googleapis.com/LATEST_RELEASE)" CHD_LST="$(curl -sL https://chromedriver.storage.googleapis.com/LATEST_RELEASE)"
CHDB="$(whereis chromedriver | awk '{print$2}')" CHDB="$(whereis chromedriver | awk '{print$2}')"
DOMAIN="$(ls /etc/prosody/conf.d/ | grep -v localhost | awk -F'.cfg' '{print $1}' | awk '!NF || !seen[$0]++')" DOMAIN="$(ls /etc/prosody/conf.d/ | grep -v localhost | awk -F'.cfg' '{print $1}' | awk '!NF || !seen[$0]++')"
NC_DOMAIN="TBD"
JITSI_MEET_PROXY="/etc/nginx/modules-enabled/60-jitsi-meet.conf"
if [ -f $JITSI_MEET_PROXY ];then
PREAD_PROXY=$(grep -nr "preread_server_name" $JITSI_MEET_PROXY | cut -d ":" -f1)
fi
INT_CONF="/usr/share/jitsi-meet/interface_config.js" INT_CONF="/usr/share/jitsi-meet/interface_config.js"
jibri_packages="$(grep Package /var/lib/apt/lists/download.jitsi.org_*_Packages |sort -u|awk '{print $2}'|sed 's|jigasi||'|paste -s -d ' ')" jibri_packages="$(grep Package /var/lib/apt/lists/download.jitsi.org_*_Packages |sort -u|awk '{print $2}'|sed 's|jigasi||'|paste -s -d ' ')"
AVATAR="$(grep -r avatar /etc/nginx/sites-*/ 2>/dev/null)" AVATAR="$(grep -r avatar /etc/nginx/sites-*/ 2>/dev/null)"
@ -154,6 +159,22 @@ fi
printf "${Purple}========== Disable Blur my background ==========${Color_Off}\n" printf "${Purple}========== Disable Blur my background ==========${Color_Off}\n"
sed -i "s|'videobackgroundblur', ||" $INT_CONF sed -i "s|'videobackgroundblur', ||" $INT_CONF
if [ ! "$NC_DOMAIN" = "TBD" ];
printf "${Purple}========== Enable $NC_DOMAIN for sync client ==========${Color_Off}\n"
if [ -z $PREAD_PROXY ]; then
echo "
Setting up Nextcloud domain on Jitsi Meet turn proxy
"
sed -i "/server {/i \ \ map \$ssl_preread_server_name \$upstream {" $JITSI_MEET_PROXY
sed -i "/server {/i \ \ \ \ \ \ $DOMAIN web;" $JITSI_MEET_PROXY
sed -i "/server {/i \ \ \ \ \ \ $NC_DOMAIN web;" $JITSI_MEET_PROXY
sed -i "/server {/i \ \ }" $JITSI_MEET_PROXY
else
echo "$NC_DOMAIN seems to be on place, skipping..."
fi
fi
restart_services restart_services

View File

@ -171,7 +171,7 @@ echo "opcache.validate_timestamps=1"
systemctl restart php$PHPVER-fpm.service systemctl restart php$PHPVER-fpm.service
#-------------------------------------------------- #--------------------------------------------------
# Create MySQL user # Create DB user
#-------------------------------------------------- #--------------------------------------------------
echo -e "\n---- Creating the PgSQL DB & User ----" echo -e "\n---- Creating the PgSQL DB & User ----"
@ -186,6 +186,7 @@ echo "Done!
#nginx - configuration #nginx - configuration
cat << NC_NGINX > $NC_NGINX_CONF cat << NC_NGINX > $NC_NGINX_CONF
#nextcloud config
upstream php-handler { upstream php-handler {
#server 127.0.0.1:9000; #server 127.0.0.1:9000;
server unix:/run/php/php${PHPVER}-fpm.sock; server unix:/run/php/php${PHPVER}-fpm.sock;
@ -346,7 +347,7 @@ if [ "$ENABLE_HSTS" = "yes" ]; then
sed -i "s|# add_header Strict-Transport-Security|add_header Strict-Transport-Security|g" $NC_NGINX_CONF sed -i "s|# add_header Strict-Transport-Security|add_header Strict-Transport-Security|g" $NC_NGINX_CONF
fi fi
if [ "$DISTRO_RELEASE" = "bionic" ] && [ -z $PREAD_PROXY ]; then if [ ! "$DISTRO_RELEASE" = "xenial" ] && [ -z $PREAD_PROXY ]; then
echo " echo "
Setting up Nextcloud domain on Jitsi Meet turn proxy Setting up Nextcloud domain on Jitsi Meet turn proxy
" "

View File

@ -21,8 +21,6 @@ fi
# SYSTEM SETUP # SYSTEM SETUP
JITSI_REPO=$(apt-cache policy | grep http | grep jitsi | grep stable | awk '{print $3}' | head -n 1 | cut -d "/" -f1) JITSI_REPO=$(apt-cache policy | grep http | grep jitsi | grep stable | awk '{print $3}' | head -n 1 | cut -d "/" -f1)
CERTBOT_REPO=$(apt-cache policy | grep http | grep certbot | head -n 1 | awk '{print $2}' | cut -d "/" -f4)
CERTBOT_REL_FILE="http://ppa.launchpad.net/certbcertbot/ubuntu/dists/$(lsb_release -sc)/Release"
APACHE_2=$(dpkg-query -W -f='${Status}' apache2 2>/dev/null | grep -c "ok installed") APACHE_2=$(dpkg-query -W -f='${Status}' apache2 2>/dev/null | grep -c "ok installed")
NGINX=$(dpkg-query -W -f='${Status}' nginx 2>/dev/null | grep -c "ok installed") NGINX=$(dpkg-query -W -f='${Status}' nginx 2>/dev/null | grep -c "ok installed")
DIST=$(lsb_release -sc) DIST=$(lsb_release -sc)
@ -94,6 +92,17 @@ else
wget -qO - https://prosody.im/files/prosody-debian-packages.key | apt-key add - wget -qO - https://prosody.im/files/prosody-debian-packages.key | apt-key add -
fi fi
} }
dpkg-compare() {
dpkg --compare-versions $(dpkg-query -f='${Version}' --show $1) $2 $3
}
wait_seconds() {
secs=$(($1))
while [ $secs -gt 0 ]; do
echo -ne "$secs\033[0K\r"
sleep 1
: $((secs--))
done
}
clear clear
echo ' echo '
######################################################################## ########################################################################
@ -161,7 +170,9 @@ else
fi fi
if [ "$CPU_MIN" = "Y" ] && [ "$MEM_MIN" = "Y" ];then if [ "$CPU_MIN" = "Y" ] && [ "$MEM_MIN" = "Y" ];then
echo "All requirements seems meet!" echo "All requirements seems meet!"
echo "We hope you have a nice recording/streaming session" echo "
- We hope you have a nice recording/streaming session
"
else else
echo "CPU ($(nproc --all))/RAM ($((mem_available/1024)) MiB) does NOT meet minimum recommended requirements!" echo "CPU ($(nproc --all))/RAM ($((mem_available/1024)) MiB) does NOT meet minimum recommended requirements!"
echo "Even when you can use the videconference sessions, we advice to increase the resoruces in order to user Jibri." echo "Even when you can use the videconference sessions, we advice to increase the resoruces in order to user Jibri."
@ -177,9 +188,12 @@ else
done done
fi fi
#Prosody repository #Prosody repository
#add_prosody_repo add_prosody_repo
# Jitsi-Meet Repo # Jitsi-Meet Repo
echo "Add Jitsi key" echo "
Add Jitsi repo
"
if [ "$JITSI_REPO" = "stable" ]; then if [ "$JITSI_REPO" = "stable" ]; then
echo "Jitsi stable repository already installed" echo "Jitsi stable repository already installed"
else else
@ -192,7 +206,7 @@ do
read -p "> Do you plan to use Let's Encrypt SSL certs?: (yes or no)"$'\n' -r LE_SSL read -p "> Do you plan to use Let's Encrypt SSL certs?: (yes or no)"$'\n' -r LE_SSL
if [ $LE_SSL = yes ]; then if [ $LE_SSL = yes ]; then
echo "We'll defaul to Let's Encrypt SSL certs." echo "We'll defaul to Let's Encrypt SSL certs."
elif [ $LE_SSL = no ]; then else
echo "We'll let you choose later on for it." echo "We'll let you choose later on for it."
fi fi
done done
@ -305,7 +319,7 @@ echo '{ "CommandLineFlagSecurityWarningsEnabled": false }' > $GCMP_JSON
echo ' echo '
######################################################################## ########################################################################
Please Setup Your Instalation Please Setup Your Installation
######################################################################## ########################################################################
' '
# MEET / JIBRI SETUP # MEET / JIBRI SETUP
@ -325,6 +339,10 @@ LE_RENEW_LOG="/var/log/letsencrypt/renew.log"
MOD_LISTU="https://prosody.im/files/mod_listusers.lua" MOD_LISTU="https://prosody.im/files/mod_listusers.lua"
MOD_LIST_FILE="/usr/lib/prosody/modules/mod_listusers.lua" MOD_LIST_FILE="/usr/lib/prosody/modules/mod_listusers.lua"
ENABLE_SA="yes" ENABLE_SA="yes"
CERTBOT_REPO=$(apt-cache policy | grep http | grep certbot | head -n 1 | awk '{print $2}' | cut -d "/" -f4)
CERTBOT_REL_FILE="http://ppa.launchpad.net/certbot/certbot/ubuntu/dists/$(lsb_release -sc)/Release"
GC_SDK_REL_FILE="http://packages.cloud.google.com/apt/dists/cloud-sdk-$(lsb_release -sc)/Release"
#Sysadmin email #Sysadmin email
while [[ -z $SYSADMIN_EMAIL ]] while [[ -z $SYSADMIN_EMAIL ]]
do do
@ -359,7 +377,7 @@ else
read -p "> Do you want to setup LetsEncrypt with your domain: (yes or no)"$'\n' -r ENABLE_SSL read -p "> Do you want to setup LetsEncrypt with your domain: (yes or no)"$'\n' -r ENABLE_SSL
if [ "$ENABLE_SSL" = "no" ]; then if [ "$ENABLE_SSL" = "no" ]; then
echo "Please run letsencrypt.sh manually post-installation." echo "Please run letsencrypt.sh manually post-installation."
elif [ "$ENABLE_SSL" = "yes" ]; then else
echo "SSL will be enabled." echo "SSL will be enabled."
fi fi
done done
@ -406,7 +424,7 @@ done
#Enable static avatar #Enable static avatar
while [[ "$ENABLE_SA" != "yes" && "$ENABLE_SA" != "no" ]] while [[ "$ENABLE_SA" != "yes" && "$ENABLE_SA" != "no" ]]
do do
read -p "> Do you want to enable static avatar?: (yes or no)"$'\n' -r ENABLE_SA read -p "> (Legacy) Do you want to enable static avatar?: (yes or no)"$'\n' -r ENABLE_SA
if [ "$ENABLE_SA" = "no" ]; then if [ "$ENABLE_SA" = "no" ]; then
echo "Static avatar won't be enabled" echo "Static avatar won't be enabled"
elif [ "$ENABLE_SA" = "yes" ]; then elif [ "$ENABLE_SA" = "yes" ]; then
@ -441,20 +459,39 @@ do
read -p "> Do you want to setup Jibri Records Access via Nextcloud: (yes or no) read -p "> Do you want to setup Jibri Records Access via Nextcloud: (yes or no)
( Please check requirements at: https://github.com/switnet-ltd/quick-jibri-installer )"$'\n' -r ENABLE_NC_ACCESS ( Please check requirements at: https://github.com/switnet-ltd/quick-jibri-installer )"$'\n' -r ENABLE_NC_ACCESS
if [ "$ENABLE_NC_ACCESS" = "no" ]; then if [ "$ENABLE_NC_ACCESS" = "no" ]; then
echo "JRA via Nextcloud won't be enabled." echo "-- JRA via Nextcloud won't be enabled."
elif [ "$ENABLE_NC_ACCESS" = "yes" ]; then elif [ "$ENABLE_NC_ACCESS" = "yes" ]; then
echo "JRA via Nextcloud will be enabled." echo "-- JRA via Nextcloud will be enabled."
fi fi
done done
#Jigasi #Jigasi
if [ "$(curl -s -o /dev/null -w "%{http_code}" $GC_SDK_REL_FILE )" == "404" ]; then
echo "> Sorry Google SDK doesn't have support yet for $(lsb_release -sd),"
echo "thus, Jigasi Transcript can't be enable."
elif [ "$(curl -s -o /dev/null -w "%{http_code}" $GC_SDK_REL_FILE )" == "200" ]; then
while [[ "$ENABLE_TRANSCRIPT" != "yes" && "$ENABLE_TRANSCRIPT" != "no" ]] while [[ "$ENABLE_TRANSCRIPT" != "yes" && "$ENABLE_TRANSCRIPT" != "no" ]]
do do
read -p "> Do you want to setup Jigasi Transcription: (yes or no) read -p "> Do you want to setup Jigasi Transcription: (yes or no)
( Please check requirements at: https://github.com/switnet-ltd/quick-jibri-installer )"$'\n' -r ENABLE_TRANSCRIPT ( Please check requirements at: https://github.com/switnet-ltd/quick-jibri-installer )"$'\n' -r ENABLE_TRANSCRIPT
if [ "$ENABLE_TRANSCRIPT" = "no" ]; then if [ "$ENABLE_TRANSCRIPT" = "no" ]; then
echo "Jigasi Transcription won't be enabled." echo "-- Jigasi Transcription won't be enabled."
elif [ "$ENABLE_TRANSCRIPT" = "yes" ]; then elif [ "$ENABLE_TRANSCRIPT" = "yes" ]; then
echo "Jigasi Transcription will be enabled." echo "-- Jigasi Transcription will be enabled."
fi
done
else
echo "No valid option for Jigasi.Please report this to
https://github.com/switnet-ltd/quick-jibri-installer/issues "
fi
#Grafana
while [[ "$ENABLE_GRAFANA_DSH" != "yes" && "$ENABLE_GRAFANA_DSH" != "no" ]]
do
read -p "> Do you want to setup Grafana Dashboard: (yes or no)
( Please check requirements at: https://github.com/switnet-ltd/quick-jibri-installer )"$'\n' -r ENABLE_GRAFANA_DSH
if [ "$ENABLE_GRAFANA_DSH" = "no" ]; then
echo "-- Grafana Dashboard won't be enabled."
elif [ "$ENABLE_GRAFANA_DSH" = "yes" ]; then
echo "-- Grafana Dashboard will be enabled."
fi fi
done done
#Grafana #Grafana
@ -507,8 +544,7 @@ Checking for updates...
" "
apt-get -q2 update apt-get -q2 update
apt-get -yq2 dist-upgrade apt-get -yq2 dist-upgrade
else elif [ "$(curl -s -o /dev/null -w "%{http_code}" $CERTBOT_REL_FILE )" == "200" ]; then
if [ "$(curl -s -o /dev/null -w "%{http_code}" $CERTBOT_REL_FILE )" == "200" ]; then
echo " echo "
Adding cerbot (formerly letsencrypt) PPA repository for latest updates Adding cerbot (formerly letsencrypt) PPA repository for latest updates
" "
@ -516,13 +552,11 @@ Adding cerbot (formerly letsencrypt) PPA repository for latest updates
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 75BCA694 apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 75BCA694
apt-get -q2 update apt-get -q2 update
apt-get -yq2 dist-upgrade apt-get -yq2 dist-upgrade
fi elif [ "$(curl -s -o /dev/null -w "%{http_code}" $CERTBOT_REL_FILE )" == "404" ]; then
if [ "$(curl -s -o /dev/null -w "%{http_code}" $CERTBOT_REL_FILE )" == "404" ]; then
echo " echo "
Certbot PPA is not available for $(lsb_release -sc) just yet, it won't be installed... Certbot PPA is not available for $(lsb_release -sc) just yet, it won't be installed...
" "
fi fi
fi
else else
echo "SSL setup will be skipped." echo "SSL setup will be skipped."
@ -550,6 +584,7 @@ restart_services() {
# Configure Jibri # Configure Jibri
## PROSODY ## PROSODY
if dpkg-compare prosody lt 0.11.0 ; then
cat << MUC-JIBRI >> $PROSODY_FILE cat << MUC-JIBRI >> $PROSODY_FILE
-- internal muc component, meant to enable pools of jibri and jigasi clients -- internal muc component, meant to enable pools of jibri and jigasi clients
@ -561,7 +596,7 @@ Component "internal.auth.$DOMAIN" "muc"
muc_room_cache_size = 1000 muc_room_cache_size = 1000
MUC-JIBRI MUC-JIBRI
fi
cat << REC-JIBRI >> $PROSODY_FILE cat << REC-JIBRI >> $PROSODY_FILE
VirtualHost "recorder.$DOMAIN" VirtualHost "recorder.$DOMAIN"
@ -571,12 +606,17 @@ VirtualHost "recorder.$DOMAIN"
authentication = "internal_plain" authentication = "internal_plain"
REC-JIBRI REC-JIBRI
#Enable Jibri withelist
sed -i "s| -- muc_lobby_whitelist| muc_lobby_whitelist|" $PROSODY_FILE
#Fix Jibri conectivity issues #Fix Jibri conectivity issues
#if dpkg-compare prosody lt 0.11.0 ; then
sed -i "s|c2s_require_encryption = .*|c2s_require_encryption = false|" $PROSODY_SYS sed -i "s|c2s_require_encryption = .*|c2s_require_encryption = false|" $PROSODY_SYS
sed -i "/c2s_require_encryption = false/a \\ sed -i "/c2s_require_encryption = false/a \\
\\ \\
consider_bosh_secure = true" $PROSODY_SYS consider_bosh_secure = true" $PROSODY_SYS
#fi
if [ ! -z $L10N_PARTICIPANT ]; then if [ ! -z $L10N_PARTICIPANT ]; then
sed -i "s|PART_USER=.*|PART_USER=\"$L10N_PARTICIPANT\"|" jm-bm.sh sed -i "s|PART_USER=.*|PART_USER=\"$L10N_PARTICIPANT\"|" jm-bm.sh
fi fi
@ -763,11 +803,11 @@ if [ "$ENABLE_SA" = "yes" ] && [ -f $WS_CONF ]; then
sed -i "/RANDOM_AVATAR_URL_SUFFIX/ s|false|\'.png\'|" $INT_CONF sed -i "/RANDOM_AVATAR_URL_SUFFIX/ s|false|\'.png\'|" $INT_CONF
fi fi
#nginx -tlsv1/1.1 #nginx -tlsv1/1.1
if [ "$DROP_TLS1" = "yes" ] && [ "$DIST" = "bionic" ];then if [ "$DROP_TLS1" = "yes" ] && [ ! "$DIST" = "xenial" ];then
echo "Dropping TLSv1/1.1 in favor of v1.3" echo "Dropping TLSv1/1.1 in favor of v1.3"
sed -i "s|TLSv1 TLSv1.1|TLSv1.3|" /etc/nginx/nginx.conf sed -i "s|TLSv1 TLSv1.1|TLSv1.3|" /etc/nginx/nginx.conf
#sed -i "s|TLSv1 TLSv1.1|TLSv1.3|" $WS_CONF #sed -i "s|TLSv1 TLSv1.1|TLSv1.3|" $WS_CONF
elif [ "$DROP_TLS1" = "yes" ] && [ ! "$DIST" = "bionic" ];then elif [ "$DROP_TLS1" = "yes" ] && [ "$DIST" = "xenial" ];then
echo "Only dropping TLSv1/1.1" echo "Only dropping TLSv1/1.1"
sed -i "s|TLSv1 TLSv1.1||" /etc/nginx/nginx.conf sed -i "s|TLSv1 TLSv1.1||" /etc/nginx/nginx.conf
#sed -i "s|TLSv1 TLSv1.1||" $WS_CONF #sed -i "s|TLSv1 TLSv1.1||" $WS_CONF
@ -778,16 +818,41 @@ fi
# Disable "Blur my background" until new notice # Disable "Blur my background" until new notice
sed -i "s|'videobackgroundblur', ||" $INT_CONF sed -i "s|'videobackgroundblur', ||" $INT_CONF
#Setup prosody conf file==================================
#Setup secure rooms #Setup secure rooms
SRP_STR=$(grep -n "VirtualHost \"$DOMAIN\"" $PROSODY_FILE | head -n1 | cut -d ":" -f1)
SRP_END=$((SRP_STR + 10))
sed -i "$SRP_STR,$SRP_END{s|authentication = \"anonymous\"|authentication = \"internal_plain\"|}" $PROSODY_FILE
if dpkg-compare prosody gt 0.11.0 ; then
cat << P_SR >> $PROSODY_FILE
VirtualHost "guest.$DOMAIN"
authentication = "anonymous"
c2s_require_encryption = false
speakerstats_component = "speakerstats.$DOMAIN"
conference_duration_component = "conferenceduration.$DOMAIN"
lobby_muc = "lobby.$DOMAIN"
main_muc = "conference.$DOMAIN"
modules_enabled = {
"speakerstats";
"conference_duration";
"muc_lobby_rooms";
}
P_SR
else
cat << P_SR >> $PROSODY_FILE cat << P_SR >> $PROSODY_FILE
VirtualHost "$DOMAIN"
authentication = "internal_plain"
VirtualHost "guest.$DOMAIN" VirtualHost "guest.$DOMAIN"
authentication = "anonymous" authentication = "anonymous"
c2s_require_encryption = false c2s_require_encryption = false
P_SR P_SR
fi
#======================
#Secure room initial user #Secure room initial user
if [ "$ENABLE_SC" = "yes" ]; then if [ "$ENABLE_SC" = "yes" ]; then
echo "Secure rooms are being enabled..." echo "Secure rooms are being enabled..."
@ -821,6 +886,15 @@ restart_services
enable_letsencrypt enable_letsencrypt
if dpkg-compare prosody gt 0.11.0 && [ "$ENABLE_SC" = "yes" ]; then
echo "Let's try wait 15s"
wait_seconds 15
#Temporary fix? - https://community.jitsi.org/t/27752/112
sed -i "s| lobby_muc = \"lobby.|-- lobby_muc = \"lobby.|" $PROSODY_FILE
sed -i "s| main_muc = \"conference.|-- main_muc = \"conference.|" $PROSODY_FILE
#EO_TF
fi
#SSL workaround #SSL workaround
if [ "$(dpkg-query -W -f='${Status}' nginx 2>/dev/null | grep -c "ok installed")" -eq 1 ]; then if [ "$(dpkg-query -W -f='${Status}' nginx 2>/dev/null | grep -c "ok installed")" -eq 1 ]; then
ssl_wa nginx nginx $DOMAIN $WS_CONF $SYSADMIN_EMAIL $DOMAIN ssl_wa nginx nginx $DOMAIN $WS_CONF $SYSADMIN_EMAIL $DOMAIN
@ -836,7 +910,8 @@ if [ "$ENABLE_BLESSM" = "yes" ]; then
fi fi
#JRA via Nextcloud #JRA via Nextcloud
if [ "$ENABLE_NC_ACCESS" = "yes" ]; then if [ "$ENABLE_NC_ACCESS" = "yes" ]; then
echo "Jigasi Transcription will be enabled." echo "JRA via Nextcloud will be enabled."
sed -i "s|NC_DOMAIN=.*|NC_DOMAIN=\"$NC_DOMAIN\"|" jitsi-updater.sh
bash $PWD/jra_nextcloud.sh bash $PWD/jra_nextcloud.sh
fi fi
} > >(tee -a qj-installer.log) 2> >(tee -a qj-installer.log >&2) } > >(tee -a qj-installer.log) 2> >(tee -a qj-installer.log >&2)
@ -852,8 +927,12 @@ if [ "$ENABLE_GRAFANA_DSH" = "yes" ]; then
bash $PWD/grafana.sh bash $PWD/grafana.sh
fi fi
#Prevent Jibri conecction issue #Prevent Jibri conecction issue
if [ -z "$(grep -n $DOMAIN /etc/hosts)" ];then
sed -i "/127.0.0.1/a \\ sed -i "/127.0.0.1/a \\
127.0.0.1 $DOMAIN" /etc/hosts 127.0.0.1 $DOMAIN" /etc/hosts
else
echo "Local host already in place..."
fi
echo " echo "
######################################################################## ########################################################################
@ -865,11 +944,6 @@ apt-get -y autoremove
apt-get autoclean apt-get autoclean
echo "Rebooting in..." echo "Rebooting in..."
secs=$((15)) wait_seconds 15
while [ $secs -gt 0 ]; do
echo -ne "$secs\033[0K\r"
sleep 1
: $((secs--))
done
} > >(tee -a qj-installer.log) 2> >(tee -a qj-installer.log >&2) } > >(tee -a qj-installer.log) 2> >(tee -a qj-installer.log >&2)
reboot reboot