#!/bin/bash set -e PYTHON=python3 cecho() { local code="\033[" case "$1" in black | bk) color="${code}0;30m";; red | r) color="${code}1;31m";; green | g) color="${code}1;32m";; yellow | y) color="${code}1;33m";; blue | b) color="${code}1;34m";; purple | p) color="${code}1;35m";; cyan | c) color="${code}1;36m";; gray | gr) color="${code}0;37m";; *) local text="$1" esac [ -z "$text" ] && local text="$color$2${code}0m" echo -e "$text" } do_install_instance() { NGINX_PORT=${NGINX_PORT-80} NGINX_AVAILABLE_PATH='/etc/nginx/sites-available' NGINX_ENABLE_PATH='/etc/nginx/sites-enabled' UWSGI_AVAILABLE_PATH='/etc/uwsgi/apps-available' UWSGI_ENABLE_PATH='/etc/uwsgi/apps-enabled' PG_VERSION=9.6 POSTGIS_VERSION=2.3.1 echo "" cecho g "*******************************************************************************" cecho g "++++++ Ishtar instance preparation script ++++++" cecho g "*******************************************************************************" echo "" # check user user="$(id -un 2>/dev/null || true)" sh_c='sh -c' if [ "$user" != 'root' ]; then if command_exists sudo; then sh_c='sudo -E sh -c' elif command_exists su; then sh_c='su -c' else cecho r " Error: this installer needs the ability to run commands as root." cecho r " We are unable to find either "sudo" or "su" available to make this happen." exit 1 fi fi if [ -z "$CONFIG_PATH" ]; then CONFIG_PATH="/etc/ishtar/" fi if [ ! -f $CONFIG_PATH/config ]; then echo ""; cecho r ""$CONFIG_PATH" is not a valid config file." echo "Have you properly install Ishtar sources?" echo "Run ishtar-install before this script."; echo ""; exit 1; fi source $CONFIG_PATH/config export LANG=$ISHTAR_LOCALE.UTF-8 if [ "$(locale 2>&1 >/dev/null|wc -l)" != 0 ]; then cecho r "Unable to set LANG=$LANG properly" cecho "Try: 'dpkg-reconfigure locales' or install the 'locales-all' package" exit 1 fi cd $ISHTAR_PATH INSTANCES_FILE=$CONFIG_PATH/instances if [ ! -f $INSTANCES_FILE ]; then touch $INSTANCES_FILE fi if [ -n "$INSTANCE" ]; then if [ -d "$INSTANCE" ]; then cecho r "Sorry, $INSTANCE already exists." echo "Give another code name." exit 1 fi fi if [ -z "$INSTANCE" ]; then INSTANCE='' cat >&2 <<-'EOF' ------------------------------------------------------------------------------- You should select a code name for this instance. This code name should have only lower alphanumeric characters, with no spaces, no accents and should not begin with an alphabetical character. The only special character allowed is "_". EOF while [ "$INSTANCE" == '' ] do cecho y "* Which instance code name? [my_ishtar_instance] " read choice if [ -z "$choice" ]; then INSTANCE='my_ishtar_instance' else INSTANCE=$choice fi if [ -d "$INSTANCE" ]; then echo "Sorry, $INSTANCE already exists. Give another name." INSTANCE='' fi done fi if [ -z "$URL" ]; then URL='' cat >&2 <<-'EOF' ------------------------------------------------------------------------------- You should select an url to join your instance. Only a full domain is accepted. Don't forget to set up your DNS to point this url name to this server. Only put the url not the protocol part (no http://). For instance: ishtar.mydomain.org EOF while [ "$URL" == '' ] do cecho y "* Which url? " read choice URL=$choice done fi if [ -z "$MAX_UPLOAD_SIZE" ]; then MAX_UPLOAD_SIZE='' cat >&2 <<-'EOF' ------------------------------------------------------------------------------- A maximum size for file upload is set. By default, the limit is set to 100 Mo. Consider raising or lowering this value to fit to your needs. Note: to change this value after the installation change client_max_body_size it in the nginx configuration file and MAX_UPLOAD_SIZE in local_settings. EOF re_number='^[0-9]+$' while ! [[ "$MAX_UPLOAD_SIZE" =~ $re_number ]] do cecho y "* Max upload size in Mo (default: 100)? " read choice MAX_UPLOAD_SIZE=$choice if [ "$MAX_UPLOAD_SIZE" == '' ]; then MAX_UPLOAD_SIZE=100 fi done fi DEST=$ISHTAR_PATH cat >&2 <<-'EOF' ------------------------------------------------------------------------------- EOF echo "Preparing ishtar instance: $INSTANCE under $DEST" echo "" # register instance echo "$INSTANCE" >> $INSTANCES_FILE mkdir -p /var/log/django chown root:www-data /var/log/django touch "/var/log/django/ishtar-$INSTANCE.log" chown root:www-data "/var/log/django/ishtar-$INSTANCE.log" chmod g+w "/var/log/django/ishtar-$INSTANCE.log" cecho y " * duplicate example_project into our instance" # Duplicate example_project into our instance: cd $ISHTAR_PATH mkdir -p $INSTANCE cp -ra example_project/* $INSTANCE/ rm $INSTANCE/settings.py ln -s $DEST/example_project/settings.py $DEST/$INSTANCE/settings.py rm $INSTANCE/urls.py ln -s $DEST/example_project/urls.py $DEST/$INSTANCE/urls.py # Permissions: mkdir -p -m 755 "$INSTANCE/media" mkdir -p -m 755 "$INSTANCE/media/imported" mkdir -p -m 755 "$INSTANCE/media/upload" mkdir -p -m 755 "$INSTANCE/static/CACHE" chown -R www-data:www-data "$INSTANCE/media" chown -R www-data:www-data "$INSTANCE/static/CACHE" # Preparing DB: DB_HOST=${ISHTAR_DB-127.0.0.1} DB_PORT=${ISHTAR_DB_PORT-5432} DB_PASSWORD=${DB_PASSWORD-''} DB_NAME="ishtar-$INSTANCE" # Generate a password on the fly if none was specified: if [ -z "$DB_PASSWORD" ]; then DB_PASSWORD=$(apg -a 0 -M ncl -n 1 -x 10 -m 10) fi # dnsmasq if [ -f /etc/dnsmasq.d/ ]; then echo "* adding domain to local dnsmasq entry" echo "address=/"$URL"/127.0.0.1" >> /etc/dnsmasq.d/ishtar systemctl restart dnsmasq fi export PG_VERSION DB_HOST DB_PORT DB_PASSWORD DB_NAME POSTGIS_VERSION su postgres <<'EOF' echo " * Checking database $DB_NAME" if ! psql -l | grep -qs "$DB_NAME"; then echo " - not present, creating" createuser --echo --adduser --createdb --encrypted $DB_NAME psql --command "ALTER USER \""$DB_NAME"\" with password '"$DB_PASSWORD"';" createdb -T template0 --echo --owner $DB_NAME --encoding UNICODE $DB_NAME psql -d $DB_NAME -c "CREATE EXTENSION postgis;" else echo " - already present" fi EOF ### LOCAL SETTINGS cecho y " * creating config files" # Set some variables to avoid changing sed calls too much compared to # the initial install/install.sh script: INSTALL_PATH=$DEST INSTALL_PREFIX=$DEST APP_DIR="$DEST/$INSTANCE" DATE=`date +%F` SECRET_KEY=$(apg -a 0 -M ncl -n 1 -x 10 -m 40) PORT_FILE=$CONFIG_PATH/last_uswgi_port if [ -f $PORT_FILE ]; then UWSGI_PORT=`cat $PORT_FILE` UWSGI_PORT=`expr $UWSGI_PORT + 1` else UWSGI_PORT=8889 fi echo $UWSGI_PORT > $PORT_FILE # manage celery daemon CELERY_CONF="" if [ $USE_CELERY == 'yes' ]; then RBMQ_PASSWORD=$(apg -a 0 -M ncl -n 1 -x 10 -m 10) /usr/sbin/rabbitmqctl add_vhost /ishtar$INSTANCE /usr/sbin/rabbitmqctl add_user ishtar$INSTANCE $RBMQ_PASSWORD /usr/sbin/rabbitmqctl set_permissions -p /ishtar$INSTANCE ishtar$INSTANCE ".*" ".*" ".*" CELERY_CONF="CELERY_BROKER_URL = 'amqp://ishtar"$INSTANCE":"$RBMQ_PASSWORD"@localhost//ishtar"$INSTANCE"'" CELERY_BIN_PATH=`which celery` sed -s "s|#APP_NAME#|$INSTANCE|g;\ s|#CELERY_BIN_PATH#|$CELERY_BIN_PATH|g;" \ "install/celeryd.default.template" > \ "/etc/default/celeryd-"$INSTANCE sed -s "s|#APP_NAME#|$INSTANCE|g;\ s|#INSTALL_PATH#|$INSTALL_PATH|g;"\ "install/celery.service.template" > \ "/etc/systemd/system/celery-"$INSTANCE".service" sed -s "s|example_project|$INSTANCE|g;" \ $INSTANCE"/celery_app.py.sample" > \ $INSTANCE"/celery_app.py" if [ -d "$DIRECTORY" ]; then sed -s "s|#APP_NAME#|$INSTANCE|g;" \ "install/monit.template" > \ "/etc/monit/conf-available/celery-"$INSTANCE fi systemctl daemon-reload fi ### __init__.py cd $INSTANCE if [ $USE_CELERY = 'yes' ]; then ln -s __init__.py.celery.sample __init__.py else ln -s __init__.py.base.sample __init__.py fi cd - ### local_settings.py sed -s "s|#APP_NAME#|$INSTANCE|g;\ s|#INSTALL_PATH#|$INSTALL_PATH|g;\ s|#DB_HOST#|$DB_HOST|g;\ s|#DB_NAME#|$DB_NAME|g;\ s|#DB_PORT#|$DB_PORT|g;\ s|#DB_PASSWORD#|$DB_PASSWORD|g;\ s|#MAX_UPLOAD_SIZE#|$MAX_UPLOAD_SIZE|g;\ s|#URL#|$URL|g;\ s|#APP_DIR#|$APP_DIR|g;\ s|#SECRET_KEY#|$SECRET_KEY|g;" \ "install/local_settings.py.sample" > \ "$INSTANCE/local_settings.py" echo $CELERY_CONF >> "$INSTANCE/local_settings.py" if [ $USE_CELERY = 'yes' ]; then echo "USE_BACKGROUND_TASK = True" >> "$INSTANCE/local_settings.py" fi if [ $USE_LIBREOFFICE = 'yes' ]; then echo "USE_LIBREOFFICE = True" >> "$INSTANCE/local_settings.py" fi if [ -f $CONFIG_PATH"extra_settings.py" ]; then rm -f "$INSTANCE/extra_settings.py" ln -s $CONFIG_PATH"extra_settings.py" "$DEST/$INSTANCE/extra_settings.py" fi if [ -f $CONFIG_PATH"tasks_settings.py" ]; then rm -f "$INSTANCE/tasks_settings.py" ln -s $CONFIG_PATH"tasks_settings.py" "$DEST/$INSTANCE/tasks_settings.py" fi if [ -f $CONFIG_PATH"libreoffice_settings.py" ]; then rm -f "$INSTANCE/libreoffice_settings.py" ln -s $CONFIG_PATH"libreoffice_settings.py" "$DEST/$INSTANCE/libreoffice_settings.py" fi ### UWSGI sed -s "s|#APP_NAME#|$INSTANCE|g;\ s|#INSTALL_PREFIX#|$INSTALL_PREFIX|g;\ s|#URL#|$URL|g;\ s|#UWSGI_PORT#|$UWSGI_PORT|g;" \ "install/uwsgi.ini.template" > \ "$INSTANCE/uwsgi.ini" ln -sf "$DEST/$INSTANCE/uwsgi.ini" \ "$UWSGI_AVAILABLE_PATH/ishtar-$INSTANCE.ini" ln -sf "$UWSGI_AVAILABLE_PATH/ishtar-$INSTANCE.ini" \ "$UWSGI_ENABLE_PATH/ishtar-$INSTANCE.ini" ### NGINX sed -s "s|#APP_NAME#|$INSTANCE|g;\ s|#UWSGI_PORT#|$UWSGI_PORT|g;\ s|#NGINX_PORT#|$NGINX_PORT|g;\ s|#INSTALL_PATH#|$INSTALL_PATH|g;\ s|#MAX_UPLOAD_SIZE#|$MAX_UPLOAD_SIZE|g;\ s|#URL#|$URL|g;" \ "install/nginx.conf.template" > \ "$INSTANCE/nginx.conf" ln -sf "$DEST/$INSTANCE/nginx.conf" \ "$NGINX_AVAILABLE_PATH/ishtar-$INSTANCE.conf" ln -sf "$NGINX_AVAILABLE_PATH/ishtar-$INSTANCE.conf" \ "$NGINX_ENABLE_PATH/ishtar-$INSTANCE.conf" cecho y " * collect static data" cd $INSTANCE $PYTHON ./manage.py collectstatic --noinput > /dev/null cd - # only language available LOCALE=fr cecho y " * compile translations" $PYTHON $INSTANCE/manage.py compilemessages -l $LOCALE ### DB feeding cd $INSTANCE cecho y " * db feeding" cecho y " - migrations" $PYTHON ./manage.py migrate cecho y " - loading fixtures" FIXTURES="$DEST/fixtures/initial_data-auth-fr.json $ISHTAR_LIB_PATH/ishtar_common/fixtures/initial_data-fr.json $ISHTAR_LIB_PATH/ishtar_common/fixtures/initial_importtypes-fr.json $ISHTAR_LIB_PATH/archaeological_operations/fixtures/initial_data-fr.json $ISHTAR_LIB_PATH/archaeological_operations/fixtures/initial_data_relation_type_norel-fr.json $ISHTAR_LIB_PATH/archaeological_operations/fixtures/initial_data_relation_type-fr.json $ISHTAR_LIB_PATH/archaeological_context_records/fixtures/initial_data-fr.json $ISHTAR_LIB_PATH/archaeological_context_records/fixtures/initial_data_relation_type_norel-fr.json $ISHTAR_LIB_PATH/archaeological_context_records/fixtures/initial_data_relation_type-fr.json $ISHTAR_LIB_PATH/archaeological_files/fixtures/initial_data-fr.json $ISHTAR_LIB_PATH/archaeological_finds/fixtures/initial_data-fr.json $ISHTAR_LIB_PATH/archaeological_warehouse/fixtures/initial_data-fr.json" for data in $FIXTURES; do echo $data; $PYTHON ./manage.py loaddata $data; done ### Celery - start worker if [ $USE_CELERY = 'yes' ]; then systemctl enable celery-$INSTANCE systemctl start celery-$INSTANCE fi cecho y " - create superuser" if [ -z "$SUPERUSER_NAME" ]; then $PYTHON ./manage.py createsuperuser else $PYTHON ./manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('"$SUPERUSER_NAME"', '', '"$SUPERUSER_PASSWORD"')" fi cecho y " - post install script" cd .. $PYTHON ./install/post_install_script.py $INSTANCE $URL cat >&2 <<-'EOF' ------------------------------------------------------------------------------- EOF cecho g " Your instance has been configured." echo "" cecho g " * instance name: "$INSTANCE cecho g " * url: http://"$URL cat >&2 <<-'EOF' You should restart uwsgi and nginx: EOF cecho y "systemctl restart uwsgi nginx" echo "" echo " And then enjoy ishtar!" echo "" if [ $USE_CELERY = 'yes' ]; then cat >&2 <<-'EOF' If you use monit a configuration file has been generated for the celery daemon: EOF cecho g "/etc/monit/conf-available/celery-"$INSTANCE cat >&2 <<-'EOF' To activate it: EOF cecho y "ln -s /etc/monit/conf-available/celery-"$INSTANCE" /etc/monit/conf-enabled/celery-"$INSTANCE cecho y "systemctl restart monit" fi } do_install_instance