You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
8.4 KiB
212 lines
8.4 KiB
4 years ago
|
#! /bin/bash
|
||
|
|
||
|
script_dir="$(dirname $(readlink -f $0))"
|
||
|
|
||
|
install_dir_parent="/opt"
|
||
|
default_app_name='biscd'
|
||
|
start_script='run.sh'
|
||
|
|
||
|
# exit when any command fails
|
||
|
set -e
|
||
|
|
||
|
# Make sure running as root
|
||
|
if [ `id -u` -ne 0 ]; then
|
||
|
echo 'Please run as root'
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
function help () {
|
||
|
echo "Usage: $0 [OPTIONS] <application name>"
|
||
|
echo ' -w install this application as WSGI application. Overrules -d'
|
||
|
echo ' -d install this application to be run using the flask development webserver.'
|
||
|
echo ' -u update: ignore existing app/user/group warning (to update/overwrite already installed app).'
|
||
|
echo ' -p port: On which port the internal webserver runs. Default = 5000. Ignored in WSGI mode'
|
||
|
echo ' -h display this output.'
|
||
|
echo ''
|
||
|
echo "This script installs $default_app_name, by downloading dependancies when not present,"
|
||
|
echo 'creating a python virtualenv, unpacking any necessary files and creates a systemd integration if the user wishes so.'
|
||
|
echo ''
|
||
|
echo 'For more info visit https://git.sciuro.org/Burathar/biscd'
|
||
|
exit 1
|
||
|
}
|
||
|
|
||
|
function echo_header () {
|
||
|
echo -e "\e[33m== $1 ==\e[0;m"
|
||
|
}
|
||
|
|
||
|
unset use_wsgi
|
||
|
while getopts ':uhdwp:' opt ; do
|
||
|
case "$opt" in
|
||
|
u) ignore_name='true';;
|
||
|
d) use_wsgi='false';;
|
||
|
w) use_wsgi='true';;
|
||
|
p) internal_port="${OPTARG}";;
|
||
|
h) help ;;
|
||
|
:)
|
||
|
echo "$0: Must supply an argument to -$OPTARG." >&2
|
||
|
exit 1
|
||
|
;;
|
||
|
?)
|
||
|
echo "Invalid option: -${OPTARG}."
|
||
|
exit 2
|
||
|
;;
|
||
|
esac
|
||
|
done
|
||
|
arg_name=${@:$OPTIND:1}
|
||
|
|
||
|
if [ -n "$arg_name" ]; then
|
||
|
[[ $arg_name =~ ^[a-zA-Z0-9][a-zA-Z0-9_-]*$ ]] || { echo "'$arg_name' is not allowed as an app name. Please only use letters, numbers, underscores(_) and dashes(-). The first character must be a letter or number." && exit 1; }
|
||
|
if [ "$ignore_name" != 'true' ]; then
|
||
|
compgen -G "/etc/systemd/system/$arg_name.*" >/dev/null && echo "An app called '$arg_name' already exists. Please choose another name, or run with -u to update existing app with this name." && exit 1
|
||
|
id -u "$arg_name" >/dev/null 2>&1 && echo "A user called '$arg_name' already exists. Please choose another name." && exit 1
|
||
|
egrep "^$arg_name" /etc/group >/dev/null && echo "A group called '$arg_name' already exists. Please choose another name." && exit 1
|
||
|
fi
|
||
|
app_name="$arg_name"
|
||
|
else
|
||
|
app_name="$default_app_name"
|
||
|
fi
|
||
|
|
||
|
install_dir="$install_dir_parent/$app_name"
|
||
|
logging_dir="/var/log/$app_name"
|
||
|
|
||
|
if [ -z "$use_wsgi" ]; then
|
||
|
echo "Should this application be installed as WSGI app (recommended), or as local daemon using flask's built-in webserver, with apache as a proxy?"
|
||
|
read -p "Use WSGI? (Y/n) " use_wsgi
|
||
|
[ -z "$use_wsgi" ] && use_wsgi='y' # if no input, assume yes
|
||
|
case ${use_wsgi:0:1} in
|
||
|
y|Y|1 )
|
||
|
use_wsgi='true';;
|
||
|
* )
|
||
|
use_wsgi='false';;
|
||
|
esac
|
||
|
fi
|
||
|
|
||
|
if [ "$use_wsgi" != 'true' ]; then
|
||
|
echo "Do you want to daemonize this application using systemd? (you'll have to start it manually every login session if you choose no)"
|
||
|
read -p "Use Systemd? (Y/n) " use_systemd
|
||
|
[ -z "$use_systemd" ] && use_systemd='y' # if no input, assume yes
|
||
|
case ${use_systemd:0:1} in
|
||
|
y|Y|1 )
|
||
|
use_systemd='true';;
|
||
|
* )
|
||
|
use_systemd='false';;
|
||
|
esac
|
||
|
|
||
|
if [ -z "$internal_port" ]; then
|
||
|
echo "Please specify an internal port for the built-in webserver. This port will only be used locally."
|
||
|
read -p "Port [5000]" internal_port
|
||
|
[ -z "$internal_port" ] && internal_port=5000
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
echo_header "Check if Apache2 is installed"
|
||
|
which apache2 >/dev/null 2>&1 && echo "Apache OK" || { echo "Apache2 doesn't seem te be installed. Please fix this before installing this application." && exit 1; }
|
||
|
|
||
|
if [ "$use_wsgi" = 'true' ]; then
|
||
|
echo_header "Make sure mod-wsgi-py3 is installed"
|
||
|
apt-get install -y libapache2-mod-wsgi-py3
|
||
|
fi
|
||
|
|
||
|
echo_header "Copy over application files"
|
||
|
mkdir -vp "$install_dir"
|
||
|
cp -rv "$script_dir/$default_app_name/." "$install_dir"
|
||
|
sed -i "s+^app_name=.*+app_name='${flask_app_name}'+g" "$install_dir/run.sh"
|
||
|
|
||
|
cp -v "$script_dir/$default_app_name/config_example.yml" "$install_dir/config.yml"
|
||
|
sed -i "s/^port =.*/port = $internal_port/g" "$install_dir/config.yml"
|
||
|
sed -i "s+^logfile :.*+logfile : $logging_dir/reports.log+g" "$install_dir/config.yml"
|
||
|
sed -i "s+^errorfile :.*+errorfile : $logging_dir/error.log+g" "$install_dir/config.yml"
|
||
|
|
||
|
cp -v "$script_dir/bin/uninstall.sh" "$install_dir"
|
||
|
sed -i "s+^app_name=.*+app_name='${app_name}'+g" "$install_dir/uninstall.sh"
|
||
|
sed -i "s+^install_dir=.*+install_dir='${install_dir}'+g" "$install_dir/uninstall.sh"
|
||
|
|
||
|
cp -v "$script_dir/version" "$install_dir"
|
||
|
cp -v "$script_dir/README.md" "$install_dir"
|
||
|
|
||
|
|
||
|
echo_header "Copy over and enable apache vhost"
|
||
|
if [ "$use_wsgi" = 'true' ]; then
|
||
|
cp -v "$script_dir/bin/$default_app_name-wsgi.conf" "/etc/apache2/sites-available/$app_name.conf"
|
||
|
sed -i "s/APPNAME/$app_name/g" "/etc/apache2/sites-available/$app_name.conf"
|
||
|
sed -i "s/USER/$app_name/g" "/etc/apache2/sites-available/$app_name.conf"
|
||
|
sed -i "s/GROUP/$app_name/g" "/etc/apache2/sites-available/$app_name.conf"
|
||
|
|
||
|
ln -sfv "/etc/apache2/sites-available/$app_name.conf" "/etc/apache2/sites-enabled/$app_name.conf"
|
||
|
|
||
|
echo_header "Installing wsgi-script"
|
||
|
mkdir -vp "/var/www/wsgi-scripts"
|
||
|
cp -v "$script_dir/bin/$default_app_name.wsgi" "/var/www/wsgi-scripts/app_name.wsgi"
|
||
|
sed -i "s+INSTALLDIR+$install_dir+g" "/var/www/wsgi-scripts/$app_name.wsgi"
|
||
|
sed -i "s/APPNAME/$flask_app_name/g" "/var/www/wsgi-scripts/$app_name.wsgi"
|
||
|
else
|
||
|
cp -v "$script_dir/bin/$default_app_name-proxy.conf" "/etc/apache2/sites-available/$app_name.conf"
|
||
|
sed -i "s/PORT/$internal_port/g" "/etc/apache2/sites-available/$app_name.conf"
|
||
|
|
||
|
ln -sfv "/etc/apache2/sites-available/$app_name.conf" "/etc/apache2/sites-enabled/$app_name.conf"
|
||
|
fi
|
||
|
|
||
|
|
||
|
echo_header "Create $app_name user"
|
||
|
adduser --debug --system --home "$install_dir" --shell "/usr/sbin/nologin" --group --gecos "CSP violation report application" -q "$app_name"
|
||
|
usermod -a -G "$app_name" root # Add root to group to prevent warnings when editing config file
|
||
|
|
||
|
|
||
|
echo_header "Create logging directory"
|
||
|
mkdir -p "$logging_dir"
|
||
|
chown -v --from=root:root root:"$app_name" "$logging_dir"
|
||
|
chmod -v 770 "$logging_dir"
|
||
|
touch "$logging_dir/reports.log"
|
||
|
chown -v --from=root:root "$app_name":"$app_name" "$logging_dir/reports.log"
|
||
|
|
||
|
|
||
|
echo_header "Install Logrotate config"
|
||
|
cp -v "$script_dir/bin/logrotate-conf" "/etc/logrotate.d/$app_name"
|
||
|
sed -i "s/log-dir/$logging_dir/g" "/etc/logrotate.d/$app_name"
|
||
|
|
||
|
|
||
|
echo_header "Make sure python3 and virtualenv are installed"
|
||
|
python3 --version || apt-get install -y python3
|
||
|
|
||
|
# Testing to check if venv is installed does not work, venv command can respond to a versioncheck, and still not have neccesary libraries present.
|
||
|
apt-get install -y python3-venv
|
||
|
|
||
|
|
||
|
echo_header "Create virualenv"
|
||
|
[ -f "$install_dir/venv/bin/activate" ] || python3 -m venv "$install_dir/venv"
|
||
|
source "$install_dir/venv/bin/activate"
|
||
|
pip install setuptools wheel
|
||
|
pip install -r "$script_dir/$default_app_name/requirements.txt"
|
||
|
|
||
|
python_version=`ls "$install_dir/venv/lib" | grep python3 | head -1`
|
||
|
echo "$install_dir/" > "$install_dir/venv/lib/$python_version/site-packages/$flask_app_name.pth"
|
||
|
[ "$use_wsgi" = 'true' ] && sed -i "s/PYTHON_VERSION/$python_version/g" "/var/www/wsgi-scripts/$default_app_name.wsgi"
|
||
|
|
||
|
|
||
|
echo_header "Give $app_name user ownership of application dir"
|
||
|
chown --recursive "$app_name":"$app_name" "$install_dir"
|
||
|
chown -v root:"$app_name" "$install_dir"
|
||
|
chmod -v 775 "$install_dir"
|
||
|
chmod -v 754 "$install_dir/run.sh" "$install_dir/runserver.py"
|
||
|
chmod -v 744 "$install_dir/uninstall.sh"
|
||
|
#chmod -v 660 "$install_dir/config.yml"
|
||
|
|
||
|
|
||
|
if [ "$use_wsgi" != 'true' ] && [ "$use_systemd" = 'true' ]; then
|
||
|
echo_header "Enable as systemd service"
|
||
|
cp "$script_dir/bin/$default_app_name.service" "/etc/systemd/system/$app_name.service"
|
||
|
sed -i "s+^ExecStart=.*+ExecStart=${install_dir}/${start_script}+g" "/etc/systemd/system/$app_name.service"
|
||
|
sed -i "s+^User=.*+User=${app_name}+g" "/etc/systemd/system/$app_name.service"
|
||
|
systemctl daemon-reload
|
||
|
systemctl enable "$app_name.service"
|
||
|
systemctl restart "$app_name.service"
|
||
|
systemctl status "$app_name.service"
|
||
|
fi
|
||
|
|
||
|
|
||
|
echo_header "$app_name is installed!"
|
||
|
|
||
|
echo "If everything works, it is safe to remove this installation directory"
|
||
|
echo -e "\e[1;35mNow please review/edit /etc/apache2/sites-enabled/$app_name.conf, and then run 'systemctl restart apache2.service'\e[0m"
|
||
|
exit 0
|