#!/usr/bin/env bash script_name="$(basename $(realpath $0))" working_dir="$(dirname $(realpath $0))" #conf_file="${working_dir}/conf/${script_name%%.*}.conf" conf_file="${working_dir}/conf/bbb.conf" LOCK_DIR="/tmp/$(basename $0).$$.LOCK" log_file="${LOCK_DIR}/${script_name%%.*}.log" # ---------- # 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 } 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[33m\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 } detect_os () { if $(which lsb_release > /dev/null 2>&1) ; then DIST="$(lsb_release -i | awk '{print tolower($3)}')" DIST_VERSION="$(lsb_release -r | awk '{print tolower($2)}')" DIST_CODENAME="$(lsb_release -c | awk '{print tolower($2)}')" if [[ "$DIST" = "debian" ]]; then if $(echo "$DIST_VERSION" | grep -q '\.') ; then DIST_VERSION=$(echo "$DIST_VERSION" | cut --delimiter='.' -f1) fi fi elif [[ -e "/etc/os-release" ]]; then . /etc/os-release DIST=$ID DIST_VERSION=${VERSION_ID} fi # remove whitespace from DIST and DIST_VERSION DIST="${DIST// /}" DIST_VERSION="${DIST_VERSION// /}" } # ---------- # - 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 # ---------- # Read Configurations from $conf_file # ---------- # - Give your default values here # - DEFAULT_FQDN_HOSTNAME="$(hostname -f)" declare -a needed_debian_package_arr=() NEEDED_DEBIAN_PACKAGES=" haveged apt-utils apt-transport-https ca-certificates curl software-properties-common " if [[ -f "$conf_file" ]]; then source "$conf_file" else warn "No configuration file '$conf_file' present.\n Loading default values.." fi [[ -n "$FQDN_HOSTNAME" ]] && DEFAULT_FQDN_HOSTNAME="$FQDN_HOSTNAME" blank_line echononl "Detect distribution/release of running OS.." detect_os > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" else echo_ok fi FQDN_HOSTNAME= echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert full qualified hostname for BigBlueButton Service" echo "" if [[ -n "$DEFAULT_FQDN_HOSTNAME" ]]; then while [[ "X${FQDN_HOSTNAME}" = "X" ]]; do echononl "Full qualified hostname [${DEFAULT_FQDN_HOSTNAME}]: " read FQDN_HOSTNAME if [[ "X${FQDN_HOSTNAME}" = "X" ]]; then FQDN_HOSTNAME=$DEFAULT_FQDN_HOSTNAME fi if [[ ! $FQDN_HOSTNAME =~ \. ]]; then echo -e "\n\tGiven Host \033[33m\033[1m$FQDN_HOSTNAME\033[m seems not to be a full qualified hostname.\n" FQDN_HOSTNAME="" fi done else while [[ "X${FQDN_HOSTNAME}" = "X" ]]; do echononl "Full qualified hostname: " read FQDN_HOSTNAME if [[ "X${FQDN_HOSTNAME}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mFull qualified hostname is reqired\033[m\n" fi if [[ ! $FQDN_HOSTNAME =~ \. ]]; then echo -e "\n\tGiven Host \033[33m\033[1m$FQDN_HOSTNAME\033[m seems not to be a full qualified hostname.\n" FQDN_HOSTNAME="" fi done fi HOSTNAME="${FQDN_HOSTNAME%%.*}" echo "" echo "" echo -e "\t\033[32mStart pre-install script for BigBlueButton Service with the following parameters\033[m" echo "" echo -e "\tFull qualified Hostname..: $FQDN_HOSTNAME" echo -e "\tHostname.................: $HOSTNAME" echo "" echo -e "\tOS Distribution..........: $DIST" echo -e "\tDistribution's codename..: $DIST_CODENAME" echo -e "\tDistribution's version...: $DIST_VERSION" echo "" echononl "einverstanden (yes/no): " read OK OK=${OK,,} while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do echononl "Wrong entry! [yes/no]: " read OK OK=${OK,,} done [ $OK = "yes" ] || fatal Repeat with other settings.. echo "" echo "" echononl "Set FQDN hostname (IPv4).." perl -i -n -p -e "s/^127\.0\.1\.1.*/127.0.1.1 $FQDN_HOSTNAME $HOSTNAME/" /etc/hosts > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi blank_line #echononl "Create sources.list for '$DIST $DIST_CODENAME'.." #cat < /etc/apt/sources.list 2> "$log_file" #deb http://archive.ubuntu.com/ubuntu ${DIST_CODENAME} main restricted universe multiverse #deb http://archive.ubuntu.com/ubuntu ${DIST_CODENAME}-updates main restricted universe multiverse # #deb http://security.ubuntu.com/ubuntu ${DIST_CODENAME}-security main restricted universe multiverse # #deb http://archive.ubuntu.com/ubuntu ${DIST_CODENAME}-backports main restricted universe multiverse #EOF #if [[ $? -ne 0 ]]; then # echo_failed # error "$(cat "$log_file")" #else # echo_ok #fi blank_line # --- # Install missing Debian packages # --- echo "" echo -e " \033[1m---\033[m" echo -e " \033[32mInstall missing Debian packages\033[m" echo -e " \033[1m---\033[m" echo "" _error=false : > $log_file echononl "Check if needed packages are installed.." for _pkg in $NEEDED_DEBIAN_PACKAGES ; do if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" >> "$log_file" 2>&1 ; then continue else needed_debian_package_arr+=("$_pkg") fi [[ $? -gt 0 ]] && _error=true done if $_error ; then echo_failed error "$(cat $log_file)" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi if [[ ${#needed_debian_package_arr[@]} -gt 0 ]]; then echononl "Update repositories.." apt-get update > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi echononl "Upgrade System.." DEBIAN_FRONTEND=noninteractive apt-get full-upgrade --assume-yes > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." for _debian_pkg in ${needed_debian_package_arr[@]} ; do echononl "Installing $_debian_pkg .." DEBIAN_FRONTEND=noninteractive apt-get -y install $_debian_pkg > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." fi done else echo_ok fi else info "All needed debian packages already installed." fi # --- # Set the locale of the server to 'en_US.UTF-8'. # --- echo "" echo -e " \033[1m---\033[m" echo -e " \033[32mCheck locale settings - should be \033[1men_US.UTF-8\033[m" echo -e " \033[1m---\033[m" echo "" if $(grep -Eq "LANG=\"?en_US.UTF-8\"?" /etc/default/locale) ; then echononl "Take care \033[1mLANG=en_US.UTF-8\033[m is only the single line of /etc/default/locale" echo "LANG=en_US.UTF-8" > /etc/default/locale 2> /dev/null if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" else echo_ok fi else echononl "Install 'language-pack-en'.." if $(dpkg -s language-pack-en > /dev/null 2>&1 ) ; then echo_skipped else DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes language-pack-en > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi fi echononl "Set the locale of the server to 'en_US.UTF-8'.." update-locale LANG=en_US.UTF-8 > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi fi blank_line info "The settings in the \033[1etc/default/locale\033[m file are correct." blank_line echononl "Set system environment to 'en_US.UTF-8'.." if $(systemctl show-environment | grep -Eq "LANG=\"?en_US.UTF-8\"?") ; then echo_skipped else systemctl set-environment LANG=en_US.UTF-8 > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi fi blank_line # --- # Install latest version of docker # --- echo "" echo -e " \033[1m---\033[m" echo -e " \033[32mInstall latest version of docker\033[m" echo -e " \033[1m---\033[m" :> "$log_file" #if ! $(grep -Eq "^\s*deb\s+.*https://download.docker.com/linux/ubuntu\s+$DIST_CODENAME\s+stable" /etc/apt/sources.list) \ # && ! $(grep -r -Eq "^\s*deb\s+.*https://download.docker.com/linux/ubuntu\s+$DIST_CODENAME\s+stable" /etc/apt/sources.list.d/*) if ! $(grep -r -Eq "^\s*deb\s+.*https://download.docker.com/linux/ubuntu\s+$DIST_CODENAME\s+stable" /etc/apt/*) then blank_line echononl "Add GPG key for official Docker repository.." curl -fsSL https://download.docker.com/linux/ubuntu/gpg 2> "$log_file" | apt-key add - >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi echononl "Add (official) Docker-Repository to APT sources.." add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu ${DIST_CODENAME} stable" > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi echononl "Update repositories.." apt-get update > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi else info "Docker repository already present." fi echononl "Install docker-ce .." if $(dpkg -s docker-ce> /dev/null 2>&1 ) ; then echo_skipped else DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes docker-ce > "$log_file" 2>&1 if [[ $? -ne 0 ]]; then echo_failed error "$(cat "$log_file")" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." else echo_ok fi fi blank_line _service_name="containerd" echononl "Enable '${_service_name}.service' - start at boot time.." if $(systemctl is-enabled ${_service_name}.service --quiet 2> /dev/null) ; then echo_skipped else systemctl enable ${_service_name}.service > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." fi fi _service_name="docker" echononl "Enable '${_service_name}.service' - start at boot time.." if $(systemctl is-enabled ${_service_name}.service --quiet 2> /dev/null) ; then echo_skipped else systemctl enable ${_service_name}.service > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" info "You can try to manually set the symlink that causes automatic booting: \033[1mln -s /lib/systemd/system/docker.service /etc/systemd/system/multi-user.target.wants/\033[m" echononl "continue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/no]: " read OK done [[ $OK = "yes" ]] || fatal "Interrupted by user." fi fi clean_up 0