Files
OpenLog/install.sh
2026-02-24 10:22:09 -05:00

494 lines
18 KiB
Bash
Executable File

#!/bin/bash
# install.sh
# OpenLog Online Logbook
# Copyright (C) 2026 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"
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" != 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" == "" || "$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" || "$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
# put app in maintenance mode
echo "Putting the application in maintenance mode..."
# make sure mod_rewrite is enabled
if [[ ! -e "$APACHE_CONF_DIR/../mods-enabled/rewrite.load" ]]
then
a2enmod -q rewrite
systemctl restart apache2
fi
# disable the app
a2disconf -q $install_loc_in
systemctl reload apache2
# modify the apache conf file
if ! grep -q "RewriteEngine" "$APACHE_CONF_DIR/$install_loc_in.conf"
then
# this is an old version of the conf file. Replace with new version
cp -f default-apache.conf $APACHE_CONF_DIR/$install_loc_in.conf
sed -i "s|_APPNAME_|$APP_NAME|g" $APACHE_CONF_DIR/$install_loc_in.conf
sed -i "s|_BASEURL_|$install_loc_in|g" $APACHE_CONF_DIR/$install_loc_in.conf
sed -i "s|_DOCROOTIN_|$doc_root_in|g" $APACHE_CONF_DIR/$install_loc_in.conf
fi
sed -i "s|#Rewrite|Rewrite|g" $APACHE_CONF_DIR/$install_loc_in.conf
# copy in the default maintenancemode.php if it's not already there
if [[ ! -e "$install_path/maintenancemode.php" ]]
then
cp maintenancemode.php $install_path/
# modify the maintenancemode.php file
sed -i "s|_APPNAME_|$APP_NAME|g" $install_path/maintenancemode.php
fi
# re-enable the app in maintenance mode
a2enconf -q $install_loc_in
systemctl reload apache2
datestamp=$(date +%Y-%m-%d_%H:%M:%S)
backupdir=backups/$datestamp
mkdir -p $backupdir
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 > $backupdir/$curr_dbname-$datestamp-backup.sql
# back up existing installation
echo "Backing up current installation to the package directory."
cp -R $install_path $backupdir/$install_loc_in-$datestamp-backup
# delete all existing installation files except db.php and maintenancemode.php
find $install_path/ -mindepth 1 ! \( -name 'db.php' -o -name 'maintenancemode.php' \) -delete
echo "Performing database updates..."
# apply database updates from sql file
mysql --defaults-extra-file=$mysql_opt_file --force < database-update.sql >/dev/null 2>&1
# apply database updates via script
bash ./database-update.sh $mysql_opt_file
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
echo "Backups of the previous openlog files and the previous database were made"
echo "and are located in the $backupdir directory."
# take app out of maintenance mode
echo "Taking the app out of maintenance mode..."
# disable the app
a2disconf -q $install_loc_in
systemctl reload apache2
# modify the apache conf file
sed -i "s|Rewrite|#Rewrite|g" $APACHE_CONF_DIR/$install_loc_in.conf
# re-enable the app in production mode
a2enconf -q $install_loc_in
systemctl reload apache2
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" || "$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
# Create maintenancemode.php if it doesn't exist
if [[ ! -f "$install_path/maintenancemode.php" ]]
then
cp maintenancemode.php $install_path/maintenancemode.php
sed -i "s|_APPNAME_|$APP_NAME|g" $install_path/maintenancemode.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" == "upgraded" ]]
then
a2enconf -q $base_url
systemctl reload apache2
fi
if [[ "$operation" == "installed" ]]
then
cp -f default-apache.conf $APACHE_CONF_DIR/$base_url.conf
sed -i "s|_APPNAME_|$APP_NAME|g" $APACHE_CONF_DIR/$base_url.conf
sed -i "s|_BASEURL_|$base_url|g" $APACHE_CONF_DIR/$base_url.conf
sed -i "s|_DOCROOTIN_|$doc_root_in|g" $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" == "" || "$enconf" == "Y" || "$enconf" == "y" ]]
then
a2enconf -q $base_url.conf >/dev/null
systemctl reload apache2
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