#!/bin/sh
#
# Perform necessary datadog-agent setup steps after package is installed.
# NOTE: for .rpm, see posttrans instead
#
# .deb: STEP 5 of 5
# .rpm: STEP 3 of 6

INSTALL_DIR=/opt/datadog-agent
LOG_DIR=/var/log/datadog
CONFIG_DIR=/etc/datadog-agent
SERVICE_NAME=datadog-agent

KNOWN_DISTRIBUTION="(Debian|Ubuntu|RedHat|CentOS|openSUSE|Amazon|Arista|SUSE)"
DISTRIBUTION=$(lsb_release -d 2>/dev/null | grep -Eo $KNOWN_DISTRIBUTION  || grep -Eo $KNOWN_DISTRIBUTION /etc/issue 2>/dev/null || grep -Eo $KNOWN_DISTRIBUTION /etc/Eos-release 2>/dev/null || grep -m1 -Eo $KNOWN_DISTRIBUTION /etc/os-release 2>/dev/null || uname -s)

# If we are inside the Docker container, do nothing
if [ -n "$DOCKER_DD_AGENT" ]; then
    echo "Installation from docker-dd-agent, nothing to do in postinst"
    exit 0
fi

# Linux installation
if [ "$DISTRIBUTION" != "Darwin" ]; then
    if [ -f "/etc/debian_version" ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then
        DISTRIBUTION_FAMILY="Debian"
    fi

    if [ "$DISTRIBUTION_FAMILY" = "Debian" ]; then
        set -e
        case "$1" in
            configure)
                # Only create dd-agent group and/or user if they don't already exist
                getent group dd-agent >/dev/null || (echo "Creating dd-agent group" && addgroup --system dd-agent --quiet)
                set +e
                id -u dd-agent >/dev/null 2>&1
                USER_EXISTS=$?
                set -e
                if [ ! $USER_EXISTS -eq 0 ]; then
                    echo "Creating dd-agent user"
                    adduser --system dd-agent --disabled-login --shell /usr/sbin/nologin --home ${INSTALL_DIR} --no-create-home --group --quiet
                elif id -nG dd-agent | grep --invert-match --word-regexp --quiet 'dd-agent'; then
                    # User exists but is not part of the dd-agent group
                    echo "Adding dd-agent user to dd-agent group"
                    usermod -g dd-agent dd-agent
                fi

                # Create a symlink to the agent's binary
                ln -sf $INSTALL_DIR/bin/agent/agent /usr/bin/datadog-agent
            ;;
            abort-upgrade|abort-remove|abort-deconfigure)
            ;;

            *)
            ;;
        esac
        #DEBHELPER#
    fi

    # Set proper rights to the dd-agent user
    chown -R dd-agent:dd-agent ${CONFIG_DIR}
    chown -R dd-agent:dd-agent ${LOG_DIR}
    chown -R dd-agent:dd-agent ${INSTALL_DIR}

    # Make system-probe configs read-only
    chmod 0440 ${CONFIG_DIR}/system-probe.yaml.example || true
    if [ -f "$CONFIG_DIR/system-probe.yaml" ]; then
      chmod 0440 ${CONFIG_DIR}/system-probe.yaml || true
    fi

    # Make the system-probe and security-agent binaries and eBPF programs owned by root
    chown root:root ${INSTALL_DIR}/embedded/bin/system-probe
    chown root:root ${INSTALL_DIR}/embedded/bin/security-agent
    chown -R root:root ${INSTALL_DIR}/embedded/share/system-probe/ebpf

    # Enable and restart the agent service here on Debian platforms
    # On RHEL, this is done in the posttrans script
    if [ "$DISTRIBUTION_FAMILY" = "Debian" ]; then
        # Only supports systemd and upstart
        echo "Enabling service $SERVICE_NAME"
        if command -v systemctl >/dev/null 2>&1; then
            # Force systemd to ignore the sysvinit scripts. Only cosmetic, remove some irrelevant warnings during upgrade
            SYSTEMCTL_SKIP_SYSV=true systemctl enable $SERVICE_NAME || echo "[ WARNING ]\tCannot enable $SERVICE_NAME with systemctl"
            SYSTEMCTL_SKIP_SYSV=true systemctl enable $SERVICE_NAME-process || echo "[ WARNING ]\tCannot enable $SERVICE_NAME-process with systemctl"
            SYSTEMCTL_SKIP_SYSV=true systemctl enable $SERVICE_NAME-trace || echo "[ WARNING ]\tCannot enable $SERVICE_NAME-trace with systemctl"
            SYSTEMCTL_SKIP_SYSV=true systemctl enable $SERVICE_NAME-security || echo "[ WARNING ]\tCannot enable $SERVICE_NAME-security with systemctl"
        elif command -v initctl >/dev/null 2>&1; then
            # Nothing to do, this is defined directly in the upstart job file
            :
        elif command -v update-rc.d >/dev/null 2>&1; then
            update-rc.d $SERVICE_NAME defaults || echo "[ WARNING ]\tCannot enable $SERVICE_NAME with update-rc.d"
            update-rc.d $SERVICE_NAME-process defaults || echo "[ WARNING ]\tCannot enable $SERVICE_NAME-process with update-rc.d"
            update-rc.d $SERVICE_NAME-trace defaults || echo "[ WARNING ]\tCannot enable $SERVICE_NAME-trace with update-rc.d"
            update-rc.d $SERVICE_NAME-security defaults || echo "[ WARNING ]\tCannot enable $SERVICE_NAME-security with update-rc.d"
        else
            echo "[ WARNING ]\tCannot detect a supported init system. The datadog-agent package only provides service files for systemd, upstart and sysvinit."
        fi


        # TODO: Use a configcheck command on the agent to determine if it's safe to restart,
        # and avoid restarting when a check conf is invalid
        if [ -f "$CONFIG_DIR/datadog.yaml" ]; then
            echo "(Re)starting $SERVICE_NAME now..."
            if command -v systemctl >/dev/null 2>&1; then
                systemctl restart $SERVICE_NAME || true
            elif command -v initctl >/dev/null 2>&1; then
                initctl start $SERVICE_NAME || initctl restart $SERVICE_NAME || true
            elif command -v service >/dev/null 2>&1; then
                service $SERVICE_NAME restart || true
            else
                echo "[ WARNING ]\tCannot detect a supported init system. The datadog-agent package only provides service files for systemd, upstart and sysvinit."
            fi
        else
            # No datadog.yaml file is present. This is probably a clean install made with the
            # step-by-step instructions/an automation tool, and the config file will be added next.
            echo "No datadog.yaml file detected, not starting the agent"
        fi
    fi
else
    # macOS

    # macOS-specific variables
    OPT_APP_DIR="$INSTALL_DIR/Datadog Agent.app"
    APP_DIR="/Applications/Datadog Agent.app"
    CONF_DIR=$INSTALL_DIR/etc
    RUN_DIR=$INSTALL_DIR/run

    # Let's log the standard outputs of this script
    LOG_FILE="$LOG_DIR/postinstall.log"
    mkdir -vp $LOG_DIR
    exec > $LOG_FILE 2>&1

    # Let's talk to our user installing the Agent a bit
    echo "# State at the beginning"
    echo "## Agent version"
    datadog-agent version || echo "No datadog-agent binary version (agent 6)"
    echo "## $INSTALL_DIR"
    ls -al $INSTALL_DIR || "No agent installed"
    echo "## $APP_DIR/Contents/Resources"
    ls -al "$APP_DIR/Contents/Resources" || echo "No app installed"

    # Determine current user if he is using the Graphical installer
    # shellcheck disable=SC2009
    INSTALL_USER=$(ps aux | grep "CoreServices/Installer" | grep -v grep | awk '{print $1;}')

    # Otherwise, we hope he is using the install script and try to use this user
    # If it fails, no choice but to use root :'(
    if [ -z "$INSTALL_USER" ] || [ "$INSTALL_USER" = "root" ]; then
        SCRIPT_INSTALL="yes"
        INSTALL_USER=`cat /tmp/datadog-install-user || echo 'root'`
        rm -v /tmp/datadog-install-user || true
    fi
    echo "INSTALL_USER: $INSTALL_USER"

    echo "# Preparing log dir"
    chown -vR "${INSTALL_USER}:admin" "$LOG_DIR"
    chmod -v 755 $LOG_DIR

    echo "# Installing the app"
    mv -v "$OPT_APP_DIR" /Applications || echo "App already installed"

    # Set the run directory for the agent
    mkdir -vp "$RUN_DIR"
    chown -vR "${INSTALL_USER}:admin" "$RUN_DIR"
    chmod -v 755 "$RUN_DIR"

    echo "# Copying conf"
    mkdir -vp $CONF_DIR/checks.d

    if [ -e "/tmp/datadog.conf" ] || [ -e "/tmp/datadog.yaml" ]; then
        mv -vf /tmp/datadog.conf /tmp/datadog.yaml $CONF_DIR
        cp -vfR /tmp/conf.d/* $CONF_DIR/conf.d
        cp -vn /tmp/checks.d/* $CONF_DIR/checks.d
        rm -vrf /tmp/datadog.conf /tmp/conf.d /tmp/checks.d
    fi
    # Or copying default
    if [ ! -e "$CONF_DIR/datadog.yaml" ]; then
        sed -E 's/^api_key:$/api_key: APIKEY/' $CONF_DIR/datadog.yaml.example > $CONF_DIR/datadog.yaml
    fi

    echo "# Setting correct rights on conf"
    chown -vR "${INSTALL_USER}:admin" $CONF_DIR

    # `datadog-agent` command line
    mkdir -vp /usr/local/bin
    ln -vs $INSTALL_DIR/bin/agent/agent /usr/local/bin/datadog-agent

    # Link for conf files (let's ease the user's life)
    USER_HOME=$(sudo -Hu "$INSTALL_USER" sh -c 'echo $HOME')
    sudo -Hu "$INSTALL_USER" mkdir -vp "$USER_HOME/.datadog-agent"
    rm -vf "$USER_HOME/.datadog-agent/conf.d" "$USER_HOME/.datadog-agent/datadog.yaml" "$USER_HOME/.datadog-agent/checks.d"
    sudo -Hu "$INSTALL_USER" ln -vs $CONF_DIR/conf.d "$USER_HOME/.datadog-agent/conf.d"
    sudo -Hu "$INSTALL_USER" ln -vs $CONF_DIR/datadog.yaml "$USER_HOME/.datadog-agent/datadog.yaml"
    sudo -Hu "$INSTALL_USER" ln -vs $CONF_DIR/checks.d "$USER_HOME/.datadog-agent/checks.d"

    # Error if app not properly installed or root
    if [ "$INSTALL_USER" = "root" ]; then
        echo 'INSTALL_USER is set to root, Datadog Agent app has been installed'
        echo 'but is not configured. Running Datadog Agent as root is not advised!'
        exit 1
    fi

    echo "# Configuring the agent as a launchd service for the current user (LaunchAgent)"
    sudo -Hu "$INSTALL_USER" mkdir -vp "$USER_HOME/Library/LaunchAgents"
    sudo -Hu "$INSTALL_USER" cp -vf "$CONF_DIR/com.datadoghq.agent.plist.example" "$USER_HOME/Library/LaunchAgents/com.datadoghq.agent.plist"
    sudo -Hu "$INSTALL_USER" launchctl load -w "$USER_HOME/Library/LaunchAgents/com.datadoghq.agent.plist"

    if [ ! -e "$CONF_DIR/datadog.yaml" ]; then
        exit 1
    fi

    # Start the app only if it's not a script install
    if [ -z "$SCRIPT_INSTALL" ]; then
        echo "# Starting the app"
        # -a for application, -F for fresh, do not restore old app
        TMPDIR=$(sudo -u "$INSTALL_USER" getconf DARWIN_USER_TEMP_DIR)
        export TMPDIR
        sudo -u "$INSTALL_USER" open -Fa 'Datadog Agent'
    fi

    echo "# Configuring the login launch of the app"
    sudo -u "$INSTALL_USER" osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/Datadog Agent.app", name:"Datadog Agent", hidden:false}'

    # A little debriefing won't hurt
    echo "# State at the end"
    echo "## Agent version"
    grep AGENT_VERSION $INSTALL_DIR/agent/config.py || echo "No config.py file (agent 5)"
    datadog-agent version || echo "No datadog-agent binary version (agent 6)"
    echo "## $INSTALL_DIR"
    ls -al $INSTALL_DIR || echo "No agent installed :("
    echo "## $APP_DIR/Contents/Resources"
    ls -al "$APP_DIR/Contents/Resources" || echo "No app installed ;-("
fi

exit 0
