#!/bin/bash
#  /usr/bin/upgrade
#
# v2.  Modified by fish, Dec 2017, to support Affinity
# v3.  Modified by fish, May 2021, after support tickets 23738 and 27108
#      Now checks for presence of remove-rsync-temp and adds it if it was missing

UPGRADE_LOG="/var/log/upgrade.log"

if [ -e "/etc/system_type" ]
then
    . "/etc/system_type"
fi

if [ -n "${BUILD_MACHINE}" ]
then
    RSYNC_MODULE="${BUILD_MACHINE}"
else
    echo "Warning: falling back to uname to guess platform type."

    case "$(uname -m)" in
    armv4l)
        RSYNC_MODULE="CMG-DCM-mk2x"
        ;;

    armv5tel)
        RSYNC_MODULE="CMG-DCM-mk4"
        ;;

    armv5tejl)
        RSYNC_MODULE="CMG-DAS"
        ;;

    x86)
        RSYNC_MODULE="CMG-NAM"
        ;;

    x86_64)
        RSYNC_MODULE="CMG-NAM64"
    esac
fi

case $# in
0)
    EXCLUDE_LOCAL_CHANGES=( \
        "--exclude" "/etc/passwd" \
        "--exclude" "/etc/shadow" \
        "--exclude" "/etc/group" \
        "--exclude" "/etc/shadow_http" \
        "--exclude" "*.local" \
        "--exclude" "/home" \
        "--exclude" "/root" \
        "--exclude" "/usr/local" \
        "--exclude" "/var" \
        "--exclude" "/etc/dhcpcd.enter-hook" \
        "--exclude" "/etc/dhcpcd.exit-hook" \
        "--exclude" "/etc/resolv.conf.head" \
        "--exclude" "/etc/resolv.conf.tail" \
    )
    ;;

1)
    case "$1" in
    --restore-defaults)
        EXCLUDE_LOCAL_CHANGES=( \
            "--exclude" "/home" \
            "--exclude" "/root" \
            "--exclude" "/usr/local" \
            "--exclude" "/var" \
        )
        ;;

    --force-factory-settings)
        EXCLUDE_LOCAL_CHANGES=( )
        ;;

    --help)
        echo "Usage: upgrade [--restore-defaults | --force-factory-settings]"
        exit 0
        ;;

    *)
        echo "Unknown option."
        exit 1
        ;;
    esac
    ;;

*)
    echo "Usage: upgrade [--restore-defaults | --force-factory-settings]"
    exit 1
    ;;
esac

#
# logging function
#
ulog() {
    MSG="$*"

    echo "${MSG}"
    echo "`isodate -se` -- ${MSG}" >> "/var/log/upgrade.log"
}



#
# report start of upgrade
#
. "/etc/build.version"
ulog "Beginning upgrade from disk, module '${RSYNC_MODULE}'. Upgrading from ${BUILD_LABEL} build ${BUILD_VERSION}."



#
# cope with parts of the filesystem that are normally mounted read-only
#
RDONLY_MOUNTS=""
case "${BUILD_MACHINE}" in
CMG-DAS)
    RDONLY_MOUNTS="/boot /usr"
    ;;
esac

for MOUNT in ${RDONLY_MOUNTS}
do
    echo " * Remounting ${MOUNT} as read-write"
    mount -o remount,rw "${MOUNT}" || exit 1
done

# Unlike a conventional upgrade, we can remount these later


# Clean rsync temporary files (in case a previous upgrade was aborted)
echo " * Cleaning rsync temporary files"

# Is our binary in place?
if [ ! -x /sbin/remove-rsync-temp ]
then
	cp /mnt/${RSYNC_MODULE}/sbin/remove-rsync-temp /sbin
	chmod ugo+x /sbin/remove-rsync-temp
fi

remove-rsync-temp --auto
if [ $? -ne 0 ]
then
    ulog "Failed to clean rsync temporary files; aborting upgrade."
    exit 1
fi



rsync \
    --super \
    --verbose --stats --human-readable --progress --itemize-changes \
    --archive --no-perms --no-owner --no-group --chmod=ugo=rwX \
    --delete --delete-delay --force \
    --exclude "/dev" --exclude "lost+found" --exclude "/mnt" --exclude "/media" \
    --exclude "/proc" --exclude "/sys" --exclude "/tmp" --exclude "resolv.conf" \
    --exclude "/run" --exclude "/boot/grub" \
    ${EXCLUDE_LOCAL_CHANGES[@]} \
    "/mnt/${RSYNC_MODULE}/" "/"

RET=$?

if [ ${RET} -eq 20 ]
then
    echo "Rsync interrupted. Aborting." >&2
    ulog "Upgrade aborted by user."
    exit 20
fi

if [ ${RET} -ne 0 ]
then
    remove-rsync-temp --auto
    ulog "Upgrade failed (rsync exit code ${RET})."
    exit 1
fi

# report the new version
. "/etc/build.version"
ulog "Rsync to ${BUILD_LABEL} build ${BUILD_VERSION} completed, running post-upgrade scripts."


# run post upgrade scripts
export POST_UPGRADE_CACHE="/var/cache/post_upgrade"
mkdir -p "${POST_UPGRADE_CACHE}"
for script in `find /usr/lib/upgrade -type f | sort`
do
    [ -e "${POST_UPGRADE_CACHE}/`basename ${script}`" ] && continue
    [ -x "${script}" ] && "${script}"
done

# Sync the files in case the user decides to powercycle
sync


# Show an upgrade complete message
ulog "Upgrade complete. Now at ${BUILD_LABEL} build ${BUILD_VERSION}."

# Remount filesystems read-only, if required

for MOUNT in ${RDONLY_MOUNTS}
do
    echo " * Remounting ${MOUNT} as read-only"
    mount -o remount,ro "${MOUNT}" || exit 1
done




cat <<EOF

===================================
Upgrade complete, please reboot now
===================================

EOF

# vim: ts=4:sw=4:expandtab
