445 lines
16 KiB
Bash
Executable File
445 lines
16 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# install.sh
|
|
# OpenLog Online Logbook
|
|
# Copyright (C) 2025 Rod Wright
|
|
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
APP_NAME="OpenLog"
|
|
DEFAULT_DB_NAME="openlog"
|
|
APP_VERSION="5.3.0"
|
|
DOC_ROOT="/var/www"
|
|
INSTALL_LOC="openlog"
|
|
APACHE_CONF_DIR="/etc/apache2/conf-available"
|
|
BACKUP_DIR="openlog-previous-installation"
|
|
LANDING_PAGE="lognotes.php"
|
|
CONFIG_TABLE="configs"
|
|
CONFIG_NAME_COLUMN="confname"
|
|
CONFIG_VALUE_COLUMN="confvalue"
|
|
CONFIG_DEFAULT_COLUMN=""
|
|
|
|
|
|
function privilege_check() {
|
|
# test for superuser rights
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo "This script must be run with superuser privileges. Try sudo $0"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function get_new_password() {
|
|
# Stores new password in the variable $newpassword
|
|
pwgood=false
|
|
while ! $pwgood
|
|
do
|
|
read -p "New password: " -s -r newpassword
|
|
echo ""
|
|
read -p "Re-type new password: " -s -r rnewpw
|
|
echo ""
|
|
if [ "$newpassword" = "" -o "$rnewpw" = "" ]
|
|
then
|
|
echo "Password cannot be blank. Please try again."
|
|
echo ""
|
|
elif [ "$newpassword" != "$rnewpw" ]
|
|
then
|
|
echo "Passwords do not match. Please try again."
|
|
echo ""
|
|
else
|
|
pwgood=true
|
|
fi
|
|
done
|
|
}
|
|
|
|
function install_required_packages() {
|
|
# Positional parameters supplied to this function should be quoted
|
|
# apt-get installable package names.
|
|
# Note: Each package supplied to the for loop below can either be a
|
|
# single package name or a list of alternatives separated by the word "or".
|
|
# If supplying a list, the last one in the list will be the one that
|
|
# gets installed.
|
|
for prereq in "$@"
|
|
do
|
|
echo "Checking for $prereq installation..."
|
|
gpattern=""
|
|
for pkg_option in $(echo $prereq)
|
|
do
|
|
if [ "$pkg_option" != "or" ]
|
|
then
|
|
gpattern+=" -e $pkg_option"
|
|
preferred_pkg=$pkg_option
|
|
fi
|
|
done
|
|
if dpkg -l|grep $gpattern >/dev/null 2>&1
|
|
then
|
|
echo "$prereq is installed. Continuing."
|
|
else
|
|
echo "$APP_NAME requires $prereq, but it doesn't seem to be installed. "
|
|
echo -n "Install $preferred_pkg now? [Y/n]: "
|
|
read reqinstall
|
|
if [ "$reqinstall" = "N" -o "$reqinstall" = "n" ]
|
|
then
|
|
echo "$APP_NAME requires $prereq, but you have elected not to install it."
|
|
echo "Installation cannot continue."
|
|
abort_exit
|
|
else
|
|
echo ""
|
|
echo "Proceeding with $preferred_pkg installation"
|
|
echo ""
|
|
sleep 3
|
|
apt-get install -y $preferred_pkg
|
|
echo ""
|
|
echo "Finished with $preferred_pkg installation"
|
|
echo ""
|
|
sleep 3
|
|
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
function clean_exit() {
|
|
# Re-enable unattended-upgrades
|
|
if $restart_uu; then systemctl start unattended-upgrades; fi
|
|
exit 0
|
|
}
|
|
|
|
function abort_exit() {
|
|
# Re-enable unattended-upgrades
|
|
if $restart_uu; then systemctl start unattended-upgrades; fi
|
|
exit 1
|
|
}
|
|
|
|
function spinner() {
|
|
local pid="$1"
|
|
local delay="0.1"
|
|
local spinstr='|/-\\'
|
|
local i=0
|
|
|
|
while ps -p "$pid" > /dev/null; do
|
|
i=$(( (i+1) % 4 ))
|
|
printf "\r[%c]" "${spinstr:$i:1}"
|
|
sleep "$delay"
|
|
done
|
|
printf "\r \r" # Clear the spinner line
|
|
}
|
|
|
|
# test for superuser rights
|
|
privilege_check
|
|
|
|
|
|
echo ""
|
|
echo ""
|
|
echo "* * * * * Welcome to $APP_NAME $APP_VERSION Installation * * * * *"
|
|
echo ""
|
|
echo ""
|
|
sleep 3
|
|
echo "Preparing for installation. Please wait..."
|
|
|
|
# Prevent unattended-upgrades from interfering
|
|
restart_uu=false
|
|
while dpkg -l|grep unattended-upgrades >/dev/null 2>&1
|
|
do
|
|
systemctl stop unattended-upgrades
|
|
sleep 5
|
|
restart_uu=true
|
|
done
|
|
|
|
apt-get update -qq
|
|
|
|
# Check for prerequisites and prompt to install
|
|
echo "Checking for required packages..."
|
|
echo ""
|
|
install_required_packages "apache2" "php" "mysql-server or mariadb-server" "php-mysql" "uuid-runtime"
|
|
echo ""
|
|
echo "Finished required package installation."
|
|
echo ""
|
|
|
|
# Determine the correct Apache2 user and group
|
|
APACHE_USER=$(grep APACHE_RUN_USER /etc/apache2/envvars | cut -d= -f2)
|
|
APACHE_GROUP=$(grep APACHE_RUN_GROUP /etc/apache2/envvars | cut -d= -f2)
|
|
httpd_user_group="$APACHE_USER:$APACHE_GROUP"
|
|
|
|
sleep 3
|
|
# prompt for install location
|
|
echo "Where would you like to install this version of $APP_NAME? This should"
|
|
echo "be somewhere the webserver can find it. If you don't know, refer to the"
|
|
echo "webserver's documentation and check the server's configuration files."
|
|
echo "Note that this is where the directory containing $APP_NAME's files will be"
|
|
echo "created."
|
|
echo -n "Enter the webserver's install location [$DOC_ROOT]:"
|
|
read doc_root_in
|
|
echo ""
|
|
echo -n "Enter name of $APP_NAME installation directory [$INSTALL_LOC] :"
|
|
read install_loc_in
|
|
echo ""
|
|
if [ "$doc_root_in" = "" ]
|
|
then
|
|
doc_root_in=$DOC_ROOT
|
|
fi
|
|
if [ "$install_loc_in" = "" ]
|
|
then
|
|
install_loc_in=$INSTALL_LOC
|
|
fi
|
|
install_path="$doc_root_in/$install_loc_in"
|
|
if [ -d "$install_path" ]
|
|
then
|
|
echo "The installation path you chose already exists."
|
|
# Install path exists.
|
|
if [ -e "$install_path/db.php" ]
|
|
then
|
|
# A db.php file was found in the install path
|
|
if grep -q -e "$APP_NAME" $install_path/db.php
|
|
then
|
|
# the db.php file is part of a previous installation
|
|
echo "Would you like to upgrade an existing installation or cancel "
|
|
echo "and restart the install using a new installation location."
|
|
echo -n "[U]pgrade or [C]ancel? [U] :"
|
|
read upgrade_choice
|
|
if [[ $upgrade_choice == "C" || $upgrade_choice == "c" ]] # Cancel chosen
|
|
then
|
|
echo "Cancelling installation"
|
|
abort_exit
|
|
else
|
|
# proceed with upgrade
|
|
mkdir -p backups
|
|
operation="upgraded"
|
|
curr_dbname=$(grep dbname $install_path/db.php | head -1 | cut -d\" -f2)
|
|
|
|
# create mysql option file with data for this installation
|
|
mysql_opt_file=$(mktemp --tmpdir=/run/shm/)
|
|
echo "[client]" > $mysql_opt_file
|
|
echo "user = $(grep username $install_path/db.php | head -1 | cut -d\" -f2)" >> $mysql_opt_file
|
|
echo "password = $(grep dbpass $install_path/db.php | head -1 | cut -d\" -f2)" >> $mysql_opt_file
|
|
echo "" >> $mysql_opt_file
|
|
echo "[mysql]" > $mysql_opt_file
|
|
echo "database = $curr_dbname" >> $mysql_opt_file
|
|
echo "batch" >> $mysql_opt_file
|
|
echo "disable-column-names" >> $mysql_opt_file
|
|
|
|
# back up existing database
|
|
echo "Backing up the current database to the package directory."
|
|
mysqldump --defaults-extra-file=$mysql_opt_file --no-tablespaces $curr_dbname > backups/$curr_dbname-$(date +%Y-%m-%d_%H:%M:%S)-backup.sql
|
|
|
|
# back up existing installation
|
|
echo "Backing up current installation to the package directory."
|
|
cp -R $install_path backups/$install_loc_in-`date +%Y-%m-%d_%H:%M:%S`-backup
|
|
|
|
# delete all existing installation files except db.php
|
|
find $install_path/ -mindepth 1 -not -name 'db.php' -delete
|
|
|
|
echo "Performing database updates. This may take a while..."
|
|
# apply database updates from sql file
|
|
(mysql --defaults-extra-file=$mysql_opt_file --force < database-update.sql >/dev/null 2>&1) &
|
|
task_pid=$!
|
|
spinner $task_pid
|
|
|
|
# apply database updates via script
|
|
(bash ./database-update.sh $mysql_opt_file) &
|
|
task_pid=$!
|
|
spinner $task_pid
|
|
|
|
echo "... finished with database updates."
|
|
rm -f $mysql_opt_file
|
|
|
|
# apply updates to other files
|
|
bash ./files-update.sh $install_path
|
|
|
|
# copy distribution to install location
|
|
echo "Installing distribution . . ."
|
|
cp -R distfiles/* $install_path
|
|
# set symlink for jquery-ui
|
|
if [ ! -L "$install_path/jquery-ui" ]
|
|
then
|
|
ln -s $install_path/jquery-ui* $install_path/jquery-ui
|
|
fi
|
|
# set symlink for index.php
|
|
if [ ! -L "$install_path/index.php" ]
|
|
then
|
|
ln -s $install_path/$LANDING_PAGE $install_path/index.php
|
|
fi
|
|
# add the local timezone to .htaccess
|
|
local_tz=$(timedatectl show -p Timezone|cut -d= -f2)
|
|
echo "Your local timezone is $local_tz"
|
|
echo "php_value date.timezone \"$local_tz\"">$install_path/.htaccess
|
|
|
|
# set ownership
|
|
echo ""
|
|
echo "Setting file ownership . . ."
|
|
chown -R $httpd_user_group $install_path
|
|
fi
|
|
else
|
|
# This was a mistake. Exit now to avoid clobbering another app.
|
|
echo "The installation directory you chose exists, but no previous installation"
|
|
echo "of $APP_NAME was found. Please investigate the situation. Aborting now."
|
|
abort_exit
|
|
fi
|
|
else
|
|
# This was a mistake. Exit now to avoid clobbering another app.
|
|
echo "The installation directory you chose exists, but no previous installation"
|
|
echo "of $APP_NAME was found."
|
|
echo ""
|
|
echo " CAUTION: If there is anything else in this directory, it will be deleted!"
|
|
echo ""
|
|
echo "Would you like to use this location for a fresh installation or quit and"
|
|
echo "investigate further? It's probably safest to quit and investigate."
|
|
proceed=""
|
|
while [[ $proceed != "P" && $proceed != "p" && $proceed != "Q" && $proceed != "q" ]]
|
|
do
|
|
read proceed -p "[P]roceed with new install or [Q]uit? : "
|
|
done
|
|
if [[ $proceed == "Q" || $proceed == "q" ]]
|
|
then
|
|
abort_exit
|
|
fi
|
|
fi
|
|
else
|
|
# This is a fresh install
|
|
operation="installed"
|
|
echo ""
|
|
echo "What would you like to call this installation of $APP_NAME? If you accept"
|
|
echo "the default, it will be called $APP_NAME. If you will be running multiple"
|
|
echo "instances of $APP_NAME on this server, you should choose a distinctive name."
|
|
echo "This can be changed later in the application itself."
|
|
echo -n "Installation name [$APP_NAME]: "
|
|
read new_inst_name
|
|
if [ "$new_inst_name" = "" ]
|
|
then
|
|
new_inst_name="$APP_NAME"
|
|
fi
|
|
echo ""
|
|
|
|
# Create initial database
|
|
db_create_fail=true
|
|
while $db_create_fail
|
|
do
|
|
echo "What would you like to call the database for this installation of $APP_NAME?"
|
|
echo "If you accept the default, it will be called $DEFAULT_DB_NAME. Again, this is fine"
|
|
echo "if you will only be running this one instance, but if you will be running"
|
|
echo "multiple instances of $APP_NAME on this server, you should choose a "
|
|
echo "distinctive name."
|
|
echo -n "database name [$DEFAULT_DB_NAME]: "
|
|
read new_db_name
|
|
if [ "$new_db_name" = "" ]
|
|
then
|
|
new_db_name=$DEFAULT_DB_NAME
|
|
fi
|
|
echo ""
|
|
if mysql -e "create database $new_db_name"
|
|
then
|
|
db_create_fail=false
|
|
else
|
|
echo "An error was encountered when trying to create the database."
|
|
echo "This probably means the database already exists."
|
|
echo -n "Try again with a different database name? [Y/N]: "
|
|
read dbcreatetry
|
|
if [ "$dbcreatetry" != "Y" -o "$dbcreatetry" != "y" ]
|
|
then
|
|
abort_exit
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Create user and give rights to database
|
|
db_user="$new_db_name`date +%Y%m%d%H%M%S`"
|
|
db_pass=`uuidgen`
|
|
mysql -e "create user if not exists '$db_user'@'localhost' identified by '$db_pass'"
|
|
mysql -e "grant all on $new_db_name.* to '$db_user'@'localhost'"
|
|
mysql -e "flush privileges"
|
|
|
|
# Populate initial database
|
|
mysql $new_db_name < database-initial.sql
|
|
|
|
# Set the installation name
|
|
export MYSQL_PWD="$db_pass"
|
|
mysql -u"$db_user" $new_db_name -e "update $CONFIG_TABLE set $CONFIG_VALUE_COLUMN=\"$new_inst_name\" where $CONFIG_NAME_COLUMN=\"log_name\""
|
|
if [ "$CONFIG_DEFAULT_COLUMN" != "" ]
|
|
then
|
|
mysql -u"$db_user" $new_db_name -e "update $CONFIG_TABLE set $CONFIG_DEFAULT_COLUMN=\"$new_inst_name\" where $CONFIG_NAME_COLUMN=\"log_name\""
|
|
fi
|
|
# Create install path
|
|
echo "Creating installation directory . . ."
|
|
mkdir $install_path
|
|
|
|
# Create db.php if it doesn't exist
|
|
if [ ! -f "$install_path/db.php" ]
|
|
then
|
|
cp db.php.template $install_path/db.php
|
|
sed -i "s/DBNAME/$new_db_name/g" $install_path/db.php
|
|
sed -i "s/DBUSER/$db_user/g" $install_path/db.php
|
|
sed -i "s/DBPASS/$db_pass/g" $install_path/db.php
|
|
sed -i "s/APPNAME/$APP_NAME/g" $install_path/db.php
|
|
fi
|
|
|
|
# copy distribution to install location
|
|
echo "Installing distribution . . ."
|
|
cp -R distfiles/* $install_path
|
|
if [ ! -L "$install_path/jquery-ui" ]
|
|
then
|
|
ln -s $install_path/jquery-ui* $install_path/jquery-ui
|
|
fi
|
|
if [ ! -L "$install_path/index.php" ]
|
|
then
|
|
ln -s $install_path/$LANDING_PAGE $install_path/index.php
|
|
fi
|
|
# add the local timezone to .htaccess
|
|
local_tz=$(timedatectl show -p Timezone|cut -d= -f2)
|
|
echo "Your local timezone is $local_tz"
|
|
echo "php_value date.timezone \"$local_tz\"">$install_path/.htaccess
|
|
|
|
# set ownership
|
|
echo ""
|
|
echo "Setting file ownership . . ."
|
|
chown -R $httpd_user_group $install_path
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# tell user to launch web browser to continue
|
|
echo ""
|
|
echo ""
|
|
echo ""
|
|
echo "$APP_NAME has been $operation."
|
|
base_url=$install_loc_in
|
|
if [ "$operation" = "installed" ]
|
|
then
|
|
echo "# $APP_NAME default Apache configuration" > $APACHE_CONF_DIR/$base_url.conf
|
|
echo "" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo "Alias /$base_url $doc_root_in/$base_url" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo "" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo "<Directory $doc_root_in/$base_url>" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo " AllowOverride Options" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo " Options FollowSymLinks" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo " DirectoryIndex index.php" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo "</Directory>" >> $APACHE_CONF_DIR/$base_url.conf
|
|
echo -n "The apache2 $base_url configuration must be enabled. Would you like to do that now? [Y/n] :"
|
|
read enconf
|
|
if [ "$enconf" = "" -o "$enconf" = "Y" -o "$enconf" = "y" ]
|
|
then
|
|
a2enconf $base_url.conf >/dev/null
|
|
service apache2 reload
|
|
echo "You can now point a web browser to $base_url on your web server "
|
|
echo "to set up and configure $APP_NAME."
|
|
echo ""
|
|
echo "IMPORTANT: The default login credentials for the initial admin user are:"
|
|
echo ""
|
|
echo "login: ${APP_NAME}Admin"
|
|
echo "password: $APP_NAME-1"
|
|
echo ""
|
|
echo "Remember these credentials. Otherwise, you will not be able to log in and"
|
|
echo "configure your new installation."
|
|
echo "It is highly recommended that you change the initial password to something"
|
|
echo "secure after logging in for the first time."
|
|
else
|
|
echo "You will need to manually enable the configuration by executing:"
|
|
echo " a2enconf $base_url.conf"
|
|
echo " systemctl reload apache2"
|
|
echo "as a superuser before it can be accessed."
|
|
fi
|
|
else
|
|
echo "You can now point a web browser to http://$HOSTNAME/$base_url "
|
|
echo "to use your upgraded $APP_NAME."
|
|
fi
|
|
|
|
clean_exit
|