#!/bin/sh
set -e

CFRUDDER_FIRST_INSTALL="$1"
CFRUDDER_OS="$2"
CFRUDDER_USE_SYSTEMD="$3"
CFRUDDER_SERVER="$4"

CFE_DIR="/var/rudder/cfengine-community"
RUDDER_CMD="/opt/rudder/bin/rudder"
UUID_FILE="/opt/rudder/etc/uuid.hive"
LOG_FILE="/var/log/rudder/install/rudder-agent-$(date +%Y%m%d).log"

# Do we reinstall after an uninstallation?
# On Debian it is not detected as an installation but an update if the package was not purged,
# but we still need to enable the services.
#
#  [ actual first install                 ] || [ upgrade           ]
if [ "${CFRUDDER_FIRST_INSTALL}" = "true" ] || [ -f "${UUID_FILE}" ]; then
  REINSTALL="false"
else
  REINSTALL="true"
fi

# Closing all parents fd which are inherited, otherwise it can lead to
# a postinst unable to terminate (relevant at least on debian 7)
if [ -d /proc/self/fd ] && [ "$(uname -s)" != "SunOS" ]
then
  for f in /proc/self/fd/*; do
    fd=$(basename "${f}")
    # posix shell doesn't support 2 digits fd
    if [ "$fd" -gt 2 ] && [ "$fd" -lt 10 ]
    then
      eval "exec $fd>&-"
    fi
  done
fi

if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
then
  echo "Usage: $0 <CFRUDDER_FIRST_INSTALL> <CFRUDDER_OS> <CFRUDDER_USE_SYSTEMD>"
  echo " This should only be called from a package postinstall command"
  echo " CFRUDDER_OS: currently ignored"
  exit 1
fi

echo "$(date) - Starting rudder-agent post installation script" >> ${LOG_FILE}

if [ "${CFRUDDER_USE_SYSTEMD}" = "true" ]
then
  /bin/systemctl daemon-reload
fi

# setup the policy server if we are asked to
if [ "${CFRUDDER_SERVER}" != "" ]
then
  echo "${CFRUDDER_SERVER}" > /var/rudder/cfengine-community/policy_server.dat
fi

# should not be used anymore (9.0)
rm -r -f ${CFE_DIR}/bin/

# Not used since 4.3
rm -f /etc/init.d/rudder

# migrate hooks to their new place (9.0)
OLD_HOOKS="/var/rudder/hooks.d"
NEW_HOOKS="/opt/rudder/var/hooks.d"
if [ -d "${OLD_HOOKS}" ] && [ ! -L "${OLD_HOOKS}" ]
then
  if [ -d "${NEW_HOOKS}" ]; then
    if [ -n "$(ls -A ${OLD_HOOKS})" ]; then
      mv "${OLD_HOOKS}"/* "${NEW_HOOKS}"/
    fi
    rmdir "${OLD_HOOKS}"
  else
    mv "${OLD_HOOKS}" "${NEW_HOOKS}"
  fi
  ln -s "${NEW_HOOKS}" "${OLD_HOOKS}"
elif [ ! -e "${OLD_HOOKS}" ]
then
  # hooks directory must exist to make sure it is redirected properly
  mkdir -p "${NEW_HOOKS}"
  ln -s "${NEW_HOOKS}" "${OLD_HOOKS}"
fi

# Setup service at first install - or reinstallation after removal
if [ "${CFRUDDER_FIRST_INSTALL}" = "true" ] || [ "${REINSTALL}" = "true" ]
then
  # Set rudder-agent as service on OS that are not packaged to do it
  if [ "${CFRUDDER_USE_SYSTEMD}" = "true" ]
  then
    /bin/systemctl enable rudder-agent rudder-cf-execd rudder-cf-serverd >/dev/null 2>&1
  elif type chkconfig > /dev/null 2>/dev/null
  then
    chkconfig --add rudder-agent
    chkconfig rudder-agent on
  fi
  # old debian are packaged with a call to update-rc.d
else
  # Stop the service to make sure new binaries will be run (agent check will restart it)
  rudder agent stop >> ${LOG_FILE} || true
fi

# Make sure the configuration is available in a standard place
ln -sf "${CFE_DIR}/policy_server.dat" "/opt/rudder/etc/policy_server.dat"

# Ensure the modification date of the capability file is correct
# as it is used for cache invalidation in ncf lis-compatible-inputs
touch /opt/rudder/etc/agent-capabilities

# agent is disabled
if [ -f /opt/rudder/etc/disable-agent ]
then
  echo "********************************************************************************"
  echo "rudder-agent has been updated, but was not started as it is disabled."
  echo "To enable and start Rudder agent:"
  echo "# rudder agent enable -s"
  echo "********************************************************************************"
fi

# Try to send an inventory after upgrade to see the new agent version on the server
# We can do it a first install to since bootstrap policies won't send an inventory
echo "INFO: Scheduling an inventory during next run..." >> ${LOG_FILE}
touch /opt/rudder/etc/force_inventory

# Try to remove POSIX ACL if present, only during the first install
# https://issues.rudder.io/issues/8065
if [ "${CFRUDDER_FIRST_INSTALL}" = "true" ] && [ "$(uname -s)" != "SunOS" ]
then
  if type setfacl > /dev/null 2>&1; then
    setfacl -R -k /var/rudder/
  fi
fi

# launch rudder agent check script, it will generate an UUID on first install or repair it if needed
# If properly configured, this will run "agent reset" which will run "agent update" which will bootstrap then update ncf with cf-agent
if command -v "setsid" >/dev/null 2>&1; then
  # detach from process group otherwise dpkg may wait forever
  setsid ${RUDDER_CMD} agent check -f >> ${LOG_FILE} 2>&1
else
  nohup ${RUDDER_CMD} agent check -f >> ${LOG_FILE} 2>&1 &
fi

echo "$(date) - Ending rudder-agent post installation script" >> ${LOG_FILE}

# force exit otherwise the shell may be waiting for something
exit 0
