#!/bin/sh

#
# Copyright (C) 2016 Cumulus Networks, Inc.
#
# Cumulus specific rootfs snapper apt hooks
#

set -e

# Do not run if rootfs is not btrfs
fstype=$(findmnt -nf -o FSTYPE /)
if [ "$fstype" != "btrfs" ] ; then
    exit 0
fi

APT_SNAPSHOT_ENABLE=no
[ -r /etc/cumulus/apt-snapshot.conf ] && . /etc/cumulus/apt-snapshot.conf
[ "$APT_SNAPSHOT_ENABLE" = "yes" ] || exit 0

# Do not run hooks when cumulus-installer uses apt-get
#
# TODO: Find a better way to determine whether the installer is
# running or not.
if [ -d "/repo-archive" ] ; then
    exit 0
fi

STATE_DIR=/var/run/apt-snapshot
PRE_SNAP_ID="${STATE_DIR}/pre-snap-id"
APT_LOG="${STATE_DIR}/apt-log"

[ "$(id -u)" = "0" ] || {
    echo "ERROR:$0: This program requires root privileges." 1>&2
    exit 1
}

handle_pre_invoke() {
    mkdir -p "$STATE_DIR"
    rm -f "$PRE_SNAP_ID"
    echo -n "Creating pre-apt snapshot... "
    local pre_id=$(snapper create                     \
                           --type pre                 \
                           --print-number             \
                           --description "pre-apt"    \
                           --cleanup-algorithm number \
                           --userdata important=yes   \
                          || echo fail)
    if [ "$pre_id" = "fail" ] ; then
        echo "ERROR:$0: Unable to create pre snapshot" 1>&2
        exit 1
    fi
    echo "$pre_id" > $PRE_SNAP_ID
    echo "$pre_id done."
}

check_pre_invoke() {
    [ -r "$PRE_SNAP_ID" ] || exit 0
}

# Capture package modifications for post snapshot meta data.
handle_pre_install_pkgs() {
    check_pre_invoke
    # apt passes package info on stdin.  Skip the initial preamble
    # dump of the apt configuration.
    sed -e '/^VERSION 3/,/^$/d' - > "$APT_LOG"
}

handle_post_invoke() {
    check_pre_invoke
    local pre_id=$(cat "$PRE_SNAP_ID")
    rm -f "$PRE_SNAP_ID"

    [ -r "$APT_LOG" ]  || {
        echo "ERROR:$0: Hooks called out of sequence" 1>&2
        echo "Expecting to find apt_log: $APT_LOG" 1>&2
        exit 1
    }

    # Store apt log in the post snapshot for later analysis.
    local apt_log_dir="/var/lib/cumulus/snapshot"
    local apt_log="${apt_log_dir}/apt.log"
    mkdir -p "$apt_log_dir"
    printf "APT operations since snapshot $pre_id\n\n" > "$apt_log"
    cat "$APT_LOG" >> "$apt_log"
    rm -f "$APT_LOG"
    echo -n "Creating post-apt snapshot... "
    local post_id=$(snapper create                     \
                            --type post                \
                            --print-number             \
                            --pre-number $pre_id       \
                            --description "post-apt"   \
                            --cleanup-algorithm number \
                            --userdata "important=yes" \
                           || echo fail)
    if [ "$post_id" = "fail" ] ; then
        echo "ERROR:$0: Unable to create post snapshot" 1>&2
        exit 1
    fi
    echo "$post_id done."
    rm -rf "$apt_log_dir"
}

cmd="$1"

case "$cmd" in
    pre-invoke)
        handle_pre_invoke
        ;;
    pre-install-pkgs)
        handle_pre_install_pkgs
        ;;
    post-invoke)
        handle_post_invoke
        ;;
    *)
        echo "ERROR:$0: Unknown command: $cmd" 1>&2
        exit 1
esac

exit 0
