#!/bin/bash
# Pt-web/src/app-root/scripts/TriggerConfig/new.sh
# 
#  Copyright: ©2012, Güralp Systems Ltd.
#  Author: Laurence Withers <lwithers@guralp.com>
#  License: GPLv3
#

# New configuration saved in a temporary directory
NEW_TEMP_DIR="$1"

# Instance number being saved/replaced
INSTANCE="$2"

#
# This script performs the following actions:
#
#  1. Stops any running services from an existing instance.
#
#  2. Moves the old instance out of the way.
#     Every single file in etc, including init scripts, are located in one
#     subdirectory. This subdirectory is renamed. Symlinks into it are then
#     removed.
#
#  3. Moves the new instance into place (renames temporary directory).
#
#  4. Creates new symlinks in /etc.
#
#  5. Starts the new services.
#
#  6. Removes old instance altogether.
#
# While it might look as though some of this could be optimised (not removing
# and then recreating a symlink), it's designed to minimise damage that could
# occur should we be interrupted part way through.
#

CONFIG_DIR="/etc/gdi-trigger"
INSTANCE_DIR="${CONFIG_DIR}/${INSTANCE}.local"
INITSCRIPT_DIR="/etc/init.local"
INITSCRIPT_AUTOSTART="${INITSCRIPT_DIR}/autostart"
DIRECTORY_CLEANER_DIR="/etc/directory-cleaner"
DIRECTORY_CLEANER_SYMLINK="${DIRECTORY_CLEANER_DIR}/gdi-trigger.${INSTANCE}.local"
DIRECTORY_CLEANER_CF="${INSTANCE_DIR}/directory-cleaner.cf"



#
# Stop any running services from an existing instance
# (we also remove the initscript symlinks at this stage)
#
for SVC in "${INITSCRIPT_DIR}/gdi-trigger.${INSTANCE}."*
do
    [ -e "${SVC}" ] || continue
    "${SVC}" stop
    rm -f "${SVC}"
done



#
# Move old instance out of the way
#
if [ -e "${INSTANCE_DIR}" ]
then
    OLD_INSTANCE_DIR="$(mktemp -d "${CONFIG_DIR}/old.XXXXXX")"
    mv "${INSTANCE_DIR}" "${OLD_INSTANCE_DIR}" || exit 1

    # remove symlinks into old instance (initscripts already done)
    rm -f "${DIRECTORY_CLEANER_SYMLINK}"
fi



#
# Filter old initscripts from autostart
#
if [ -e "${INITSCRIPT_AUTOSTART}" ]
then
    grep -v "^gdi-trigger\.${INSTANCE}\." \
        < "${INITSCRIPT_AUTOSTART}" \
        > "${INITSCRIPT_AUTOSTART}.new"
    [ -e "${INITSCRIPT_AUTOSTART}.new" ] || exit 2
    mv "${INITSCRIPT_AUTOSTART}.new" "${INITSCRIPT_AUTOSTART}" || exit 3
else
    touch "${INITSCRIPT_AUTOSTART}" || exit 3
fi



#
# Sort permissions on new instance
#
chgrp -R conf "${NEW_TEMP_DIR}" || exit 4
find "${NEW_TEMP_DIR}" -type d -exec chmod 0775 {} \; || exit 5
find "${NEW_TEMP_DIR}" -type f -exec chmod 0664 {} \; || exit 5
find "${NEW_TEMP_DIR}/init" -type f -exec chmod 0775 {} \; || exit 5
chmod 0775 "${NEW_TEMP_DIR}/proc/user-script" || exit 5



#
# Move new instance into place
# (TODO: ideally we want to call rename(2) directly, to avoid mv(1)
# dereferencing a symlink and allowing an attack vector here).
#
mv "${NEW_TEMP_DIR}" "${INSTANCE_DIR}" || exit 6



#
# Create new symlinks
#
ln -s "${INSTANCE_DIR}/init/"* "${INITSCRIPT_DIR}" || exit 7
if [ -e "${DIRECTORY_CLEANER_CF}" ]
then
    ln -s "${DIRECTORY_CLEANER_CF}" "${DIRECTORY_CLEANER_SYMLINK}" || exit 8
fi



#
# Add new initscripts to autostart
#
cp "${INITSCRIPT_AUTOSTART}" "${INITSCRIPT_AUTOSTART}.new" || exit 9
for i in "${INSTANCE_DIR}/init/"*
do
    [ -e "${i}" ] || continue
    basename "${i}" >> "${INITSCRIPT_AUTOSTART}.new" || exit 9
done
mv "${INITSCRIPT_AUTOSTART}.new" "${INITSCRIPT_AUTOSTART}" || exit 9



#
# Start new services
#
for SVC in "${INITSCRIPT_DIR}/gdi-trigger.${INSTANCE}."*
do
    [ -e "${SVC}" ] || continue
    "${SVC}" start
done



#
# Remove old instance's files
#
[ -n "${OLD_INSTANCE_DIR}" ] && rm -rf "${OLD_INSTANCE_DIR}"



true

# options for text editors:
# vim: expandtab:ts=4:sw=4
