#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only

# Copyright (c) 2017-2021, AT&T Intellectual Property.
# All Rights Reserved.

# Copyright (c) 2014-2017 by Brocade Communications Systems, Inc.
# All rights reserved.

usage ()
{
    echo "usage: [VY_ADD_IMG_USER=username VY_ADD_IMG_PASS=password] $(basename $0) [ --root DEV ] [ --config FILE ] [ URL ]"
}

_clean_up ()
{
    local TEMP_DIR=$(mktempdir)
    try_umount "${TEMP_DIR}"
    lecho "$(rm -frv "${TEMP_DIR}")"

    # backwards compatibility
    try_umount /mnt/wroot
    umount "$CD_SQUASH_ROOT" >&/dev/null || true
}

if [ -z "$vit_chrooted" ]; then
    source /etc/os-release
    echo -e "\nWelcome to the ${PRETTY_NAME} image installer."
fi

: ${vyatta_prefix:=/opt/vyatta}
: ${vyatta_exec_prefix:=$vyatta_prefix}
: ${vyatta_bindir:=${vyatta_exec_prefix}/bin}
: ${vyatta_sbindir:=${vyatta_exec_prefix}/sbin}
: ${vyatta_sysconfdir:=${vyatta_prefix}/etc}
export PATH="$PATH:${vyatta_sbindir}:${vyatta_bindir}"

# read our dependencies
source ${vyatta_sbindir}/vyatta-live-image.functions
source ${vyatta_sbindir}/vyatta-install-image.functions
source ${vyatta_sbindir}/vyatta-multiple-partition
source ${vyatta_sbindir}/install-get-partition

# read our version dependent defaults
if [ -f "${vyatta_sysconfdir}/install-image/vii.config" ]; then
    parse_vii_config "${vyatta_sysconfdir}/install-image/vii.config"
fi

OPTS=$(getopt --name $(basename $0) \
    --options "c:r:yd" --longoptions "config:,root:,yes,defer-boot" -- "$@") || exit $?

eval set -- ${OPTS}

while [ $# -gt 0 ] ; do
    case $1 in
        -c|--config)
            OPT_CONFIG=$(eval echo $2)
            shift
            ;;
        -r|--root)
            OPT_ROOT=$(eval echo $2)
            shift
            ;;
        -y|--yes)
            OPT_YES="1"
            shift
            ;;
        --defer-boot)
            OPT_DEFER_BOOT="1"
            shift
            ;;
        (--)
            shift
            break
            ;;
        (*)
            break
            ;;
    esac
    shift
done

if grep -q -w cloud-init /proc/cmdline ; then
    fail_exit 'add/install image is not permitted for cloud images'
fi

if [ $# -gt 1 ] || [ "${VY_ADD_IMG_USER:+X}" != "${VY_ADD_IMG_PASS:+X}" ]; then
    usage
    exit 1
fi

# set default values for important variables
: ${OPT_CONFIG:=""} # optional vyatta.config
: ${OPT_ROOT:="$(get_live_rootfs_path)"}
: ${OPT_YES:=""} # the vyatta autoinstaller
: ${OPT_URL:=${1}} # url to the image to be added
: ${OPT_URL_USERNAME:=${VY_ADD_IMG_USER}}
: ${OPT_URL_PASSWORD:=${VY_ADD_IMG_PASS}}
: ${OPT_VYATTA_CONFIG:=""} # Using a non-default vyatta config.boot
: ${OPT_DEFER_BOOT:="0"} # If set, don't use the new image as the default boot
export OPT_DEFER_BOOT

# This points to the running live CD and in case of an installed system we
# change the INSTALL_SOURCE_DIR later
: "${INSTALL_SOURCE_DIR:="$(get_live_rootfs_path)"}"

# export INSTALL_LOG to let subshells, postinstalls, etc. write to it too
if skip_if_chrooted; then
    INSTALL_LOG=$(mktemp /tmp/install-XXXXXXXX.log) \
        || fail_exit 'Failed to create install log'
    export INSTALL_LOG
fi
lecho "Setting the install log to: $INSTALL_LOG"
# return value of prepare_install_root(), this is the root where we install
# the vyatta image to.
export INSTALL_ROOT_DIR=''

# Reset umask to properly create directory permissions
umask 022

# from here on be strict with unset variables that we use
#set -o nounset
set -o errtrace

# Get the default answers for installation from config file. The variables
# holding the default answers have the prefix "VII_", e.g. "VII_IMAGE_NAME".
#
vii_config="${OPT_CONFIG##file:}"

if [ "${OPT_CONFIG%%:*}" != "${OPT_CONFIG}" ]; then
    vii_config=$(fetch_by_url "${OPT_CONFIG}" "$(mktempdir)/vii.config")
    [ -z "${vii_config}" ] &&
        fail_exit "Unable to fetch configuration from ${OPT_CONFIG}!"
fi

if [ -n "${vii_config}" ]; then
    becho "Using configuration from ${OPT_CONFIG}"
    parse_vii_config "${vii_config}" ||
	fail_exit "Unable to parse configuration file ${vii_config}!"
fi

# on live boot (cd, pxe, usb) force the partition detector to run
is_live_cd_boot && OPT_ROOT="auto"

#
# Now we have everything to start installation
#

# before we exit lets cleanup all temporary mounts, directories, etc.
trap _clean_up EXIT

# Additional output of important variables to log
lecho "get_vyatta_version $(get_vyatta_version)"
lecho OPT_CONFIG="${OPT_CONFIG}"
lecho OPT_ROOT="${OPT_ROOT}"
lecho OPT_URL="$(get_display_url "${OPT_URL}")"
lecho OPT_YES="${OPT_YES}"
lecho OPT_DEFER_BOOT="${OPT_DEFER_BOOT}"

if [ -n "${OPT_YES}" ] ; then
    export VYATTA_PROCESS_CLIENT="yes"

    # automatically hit return when prompted
    exec < <( yes "" )
fi

# Check if this is an ONIE environment
unset ONIE_BOOT
is_onie_boot && export ONIE_BOOT='true' || export ONIE_BOOT='false'
[ "${ONIE_BOOT-}" = 'true' ] && lecho "Found ONIE environment"

# Download, check and/or mount installation source, If vit_chrooted is set,
# we have been run recursively which means installation source has
# already been setup.
#
if [[ -n "${OPT_URL}" && -z "${vit_chrooted}" ]] ; then
    export INSTALL_SOURCE_DIR
    INSTALL_SOURCE_DIR="$(mktempdir medium)"
    prepare_install_source "${INSTALL_SOURCE_DIR}" "${OPT_URL}" \
        "${OPT_URL_USERNAME}" "${OPT_URL_PASSWORD}" || \
        fail_exit "Unable to prepare installation source."

    check_install_source "${INSTALL_SOURCE_DIR}"

    CD_SQUASH_ROOT=/mnt/cdsquash
    mkdir -p ${CD_SQUASH_ROOT}
    if ! try_mount "-o loop,ro ${INSTALL_SOURCE_DIR}/live/filesystem.squashfs \
        $CD_SQUASH_ROOT"; then
        fail_exit 'Failed to mount the squashfs image.'
    fi

    if ! check_binary_signatures "${CD_SQUASH_ROOT}"; then
        echo "Warning: secure boot is enabled, but not all signed binaries "
        echo "could be verified for the image to be installed. Do not proceed "
        echo "unless the risk of not being able to boot shim, grub or kernel "
        echo "after installation has been mitigated against."
        echo -n "Continue with installation? (Yes/No) [No]: "
        response=$(get_response "No" "Yes No Y N")
        if [[ "$response" != Y* ]]; then
            fail_exit "Quitting installation"
        fi
    fi

    # Now execute the installer from the downloaded image. But first change
    # the vyatta_prefix to ensure sources from the downloaded image get used.
    export vyatta_prefix=${CD_SQUASH_ROOT}${vyatta_prefix}
    unset vyatta_exec_prefix
    # Unset directory defaults
    for evar in $(env | grep 'dir=' | cut -d'=' -f1); do
        unset $evar
    done
    export vit_chrooted=true
    args=( $@ )
    becho "Executing installer from downloaded image..."
    (/./${CD_SQUASH_ROOT}/opt/vyatta/sbin/vyatta-install-image ${args[@]})
    # Recursive exit...
    exit
fi

# source our vii defaults, do this after checking/recursing install source
# so that we get the proper image name.
source ${vyatta_sysconfdir}/install-image/vii.defaults

echo -n "What would you like to name this image? [${VII_IMAGE_NAME}]: "
VII_IMAGE_NAME=$(get_response_raw "${VII_IMAGE_NAME}")
validate_image_name "${VII_IMAGE_NAME}"
becho "This image will be named: ${VII_IMAGE_NAME}"

# if not on live-CD always ask to copy setup of running system
[ "${OPT_ROOT}" != "auto" ] && save_running_info

# Check for existing image with such a name
if [ -d "${OPT_ROOT}" ] &&  [ -d "${OPT_ROOT}/boot/${VII_IMAGE_NAME}" ] ; then
    echo "An image named ${VII_IMAGE_NAME} is already installed on this system."
    echo "Proceeding with this installation will delete this copy of"
    echo "$VII_IMAGE_NAME and replace it with a new copy."
    if [ "$(what_is_mounted_on "${OPT_ROOT}/boot/${VII_IMAGE_NAME}.*")" ] ; then
        becho "This is the running image and can not be replaced."
        fail_exit "Quitting installation"
    fi
    echo -n "Do you want to replace it (Yes/No)? [$VII_IMAGE_REPLACE]: "
    VII_IMAGE_REPLACE=$(get_response "$VII_IMAGE_REPLACE" "Yes No Y N")
    if [[ ${VII_IMAGE_REPLACE} != Y* ]] ; then
        fail_exit "Quitting installation"
    fi
    becho "Replacing existing ${VII_IMAGE_NAME} image with new one"
fi

# Check drives for previous vyatta configuration
if is_live_cd_boot; then
    check_drives
fi

# If previous configuration not saved from HDD or a custom config was not loaded
# via kcmd, continue to ask user for new config. We skip this on autoinstall
# because all parameters should have already been set via a vii.config
# file (or defaults are used).
#
if ! is_opt_vyatta_config && \
    [ "$VYATTA_PROCESS_CLIENT" != 'yes' ]; then
    _get_config_settings
fi
# We may have been given an custom local config in _get_config_settings, so
# check again if we need to gather below configuration parameters.
#
if ! is_opt_vyatta_config && \
    [ "$VYATTA_PROCESS_CLIENT" != 'yes' ]; then
    _get_admin_settings
    _get_console_settings
    _get_admin_grub_settings
fi

prepare_install_root "${OPT_ROOT}" "${VII_IMAGE_NAME}" || \
    fail_exit "Unable to prepare installation root."

install_image "${INSTALL_SOURCE_DIR}" "${VII_IMAGE_NAME}" "${INSTALL_ROOT_DIR}"

mount_filesystems_for_post_install "${INSTALL_ROOT_DIR}" "${VII_IMAGE_NAME}"

run_post_install "${INSTALL_ROOT_DIR}" "${VII_IMAGE_NAME}"

run_post_install_hooks "${INSTALL_ROOT_DIR}" "${VII_IMAGE_NAME}"

umount_filesystems_for_post_install "${INSTALL_ROOT_DIR}" "${VII_IMAGE_NAME}"

if [ -n "${OPT_URL}" ] ; then
    run_command umount -l -d "${INSTALL_SOURCE_DIR}"
fi

becho "Done."
