#!/bin/bash

top=`pwd`

. ./scripts/blkdev_utils

##==============================================================================
##
## Check usage:
##
##==============================================================================

if [ "$#" != "0" ]; then
    echo "Usage $0"
    exit 1
fi

##==============================================================================
##
## Save the current working directory:
##
##==============================================================================

cwd=`pwd`

##==============================================================================
##
## Be sure lsvmtool is built:
##
##==============================================================================

lsvmtool=${top}/build/bin/lsvmtool

if [ ! -x "${lsvmtool}" ]; then
    echo "$0: executable not found: ${lsvmtool}"
    exit 1
fi

##==============================================================================
##
## Resolve vendor EFI directory name:
##
##==============================================================================

vendor=`grep "^ID=" /etc/os-release | cut -d "=" -f2 | sed "s/\"//g"`

case ${vendor} in
    centos)
        ;;
    rhel)
        vendor=redhat
        ;;
    sles)
        ;;
    ubuntu)
        ;;
    *)
        echo "$0: failed to resolve vendor EFI directory name"
        exit 1
esac

##==============================================================================
##
## Be sure boot partition is encrypted:
##
##==============================================================================

bootdev=`./scripts/bootdev`
bootdevbase=`basename $bootdev`

if [ -z "${bootdev}" ]; then
    echo "$0: failed to resolve boot device"
    exit 1
fi

cryptsetup isLuks ${bootdev}

if [ "$?" != "0" ]; then
    echo "$0: boot partition is not encrypted: ${bootdev}"
    exit 1
fi

##==============================================================================
##
## Be sure root partition is encrypted:
##
##==============================================================================

rootdev=`./scripts/rootdev`
rootdevbase=`basename $rootdev`

if [ -z "${rootdev}" ]; then
    echo "$0: failed to resolve root device"
    exit 1
fi

cryptsetup isLuks ${rootdev}

if [ "$?" != "0" ]; then
    echo "$0: root partition is not encrypted: ${rootdev}"
    exit 1
fi

##==============================================================================
##
## Find grub.cfg:
##
##==============================================================================

case ${vendor} in
    centos|redhat)
        grubcfg=/boot/grub2/grub.cfg
        ;;
    sles)
        grubcfg=/boot/grub2/grub.cfg
        ;;
    ubuntu)
        grubcfg=/boot/grub/grub.cfg
        ;;
esac

if [ ! -f ${grubcfg} ]; then
    echo "$0: failed to resolve location of grub.cfg"
    exit 1
fi

##==============================================================================
##
## Be sure "lsvmtool grubcfginitrd" command works.
##
##==============================================================================

initrd=`${lsvmtool} grubcfginitrd ${grubcfg} | head -1`
initrd=`basename ${initrd}`

if [ ! -f "/boot/${initrd}" ]; then
    echo "$0: file not found: /boot/${initrd}"
    exit 1
fi

##==============================================================================
##
## Check existence of /EFI/boot directory:
##
##==============================================================================

bootdir=/boot/efi/EFI/boot

if [ ! -d "${bootdir}" ]; then
    echo "$0: directory not found: ${bootdir}"
    exit 1
fi

##==============================================================================
##
## Check existence of /EFI/boot/bootx64.efi:
##
##==============================================================================

if [ ! -x "${bootdir}/bootx64.efi" ]; then
    echo "$0: executable not found: ${bootdir}/bootx64.efi"
    exit 1
fi

##==============================================================================
##
## Check existence of /EFI/boot/lsvmconf:
##
##==============================================================================

lsvmconf=${bootdir}/lsvmconf

if [ ! -f "${lsvmconf}" ]; then
    echo "$0: file not found: ${lsvmconf}"
    exit 1
fi

##==============================================================================
##
## Check existence of /EFI/boot/sealedkeys:
##
##==============================================================================

#if [ ! -f "${bootdir}/sealedkeys" ]; then
#    echo "$0: file not found: ${bootdir}/sealedkeys"
#    exit 1
#fi

##==============================================================================
##
## Check contents of /EFI/boot/lsvmconf:
##
##==============================================================================

check_lsvmconf()
{
    local lsvmconf=$1
    local vendor=$2
    local grubcfg=$3
    local bootdev=$4
    local rootdev=$5
    
    if [ "$#" != "5" ]; then
        echo "$0: $FUNCNAME(): wrong # of args"
        exit 1
    fi

    if [ ! -f ${lsvmconf} ]; then
        echo "$0: $FUNCNAME(): not found: ${lsvmconf}"
        exit 1
    fi

    ##
    ## Check EFIVendorDir:
    ##
    local line=`grep "EFIVendorDir=" ${lsvmconf}`
    local value=${line#EFIVendorDir=}
    if [ "${value}" != "${vendor}" ]; then
        echo "$0: $FUNCNAME(): Wrong EFIVendorDir value in ${lsvmconf}"
        exit 1
    fi

    ##
    ## Check BootDeviceLUKS:
    ##
    local line=`grep "BootDeviceLUKS=" ${lsvmconf}`
    local value=${line#BootDeviceLUKS=}
    local uuid=`blkid ${bootdev} | sed 's-.* UUID="--g' | sed 's-".*--g'`
    if [ "${value}" != "${uuid}" ]; then
        echo "$0: $FUNCNAME(): Wrong BootDeviceLUKS value in ${lsvmconf}"
        exit 1
    fi

    ##
    ## Check RootDeviceLUKS:
    ##
    local line=`grep "RootDeviceLUKS=" ${lsvmconf}`
    local value=${line#RootDeviceLUKS=}
    local uuid=`blkid ${rootdev} | sed 's-.* UUID="--g' | sed 's-".*--g'`
    if [ "${value}" != "${uuid}" ]; then
        echo "$0: $FUNCNAME(): Wrong RootDeviceLUKS value in ${lsvmconf}"
        exit 1
    fi

    ##
    ## Check BootDevice:
    ##
    local line=`grep "BootDevice=" ${lsvmconf}`
    local value=${line#BootDevice=}
    local uuid=$(physical_dev_to_gpt_uuid "$bootdev")
    if [ "${value}" != "${uuid}" ]; then
        echo "$0: $FUNCNAME(): Wrong BootDevice value in ${lsvmconf}"
        exit 1
    fi

    ##
    ## Check RootDeviceLUKS:
    ##
    local line=`grep "RootDevice=" ${lsvmconf}`
    local value=${line#RootDevice=}
    local uuid=$(physical_dev_to_gpt_uuid "$rootdev")
    if [ "${value}" != "${uuid}" ]; then
        echo "$0: $FUNCNAME(): Wrong RootDevice value in ${lsvmconf}"
        exit 1
    fi
}

check_lsvmconf ${lsvmconf} ${vendor} ${grubcfg} ${bootdev} ${rootdev}

##==============================================================================
##
## Check for existence /boot/lsvmload/shimx64.efi
##
##==============================================================================

shim=/boot/lsvmload/shimx64.efi

if [ ! -x "${shim}" ]; then
    echo "$0: executable not found: ${shim}"
    exit 1
fi

##==============================================================================
##
## Check for existence /boot/lsvmload/grubx64.efi
##
##==============================================================================

grub=/boot/lsvmload/grubx64.efi

if [ ! -x "${grub}" ]; then
    echo "$0: executable not found: ${grub}"
    exit 1
fi

##==============================================================================
##
## Check initrd:
##
##==============================================================================

get_compression()
{
    local filename=$1
    read -N 6 hdr < ${filename}
    if [[ ${hdr} =~ $'\x1f\x8b'* ]]; then
        printf "zcat"
    elif [[ ${hdr} == "070701" ]]; then
        printf "cat"
    else
        printf "xzcat"
    fi
}

check_initrd()
{
    local cwd=$1
    local initrd=$2

    if [ "$#" != "2" ]; then
        echo "$0: $FUNCNAME(): wrong # of args"
        exit 1
    fi

    if [ ! -f "/boot/${initrd}" ]; then
        echo "$0: $FUNCNAME(): file not found: /boot/${initrd}"
        exit 1
    fi

    local tempdir=`/bin/mktemp`
    rm -rf ${tempdir}
    mkdir ${tempdir}
    if [ "$?" != "0" ]; then
        echo "$0: $FUNCNAME(): failed to create directory: ${tempdir}"
        exit 1
    fi

    cp /boot/${initrd} ${tempdir}/initrd.img
    if [ "$?" != "0" ]; then
        echo "$0: $FUNCNAME(): copy failed"
        exit 1
    fi

    ${lsvmtool} cpio split ${tempdir}/initrd.img
    if [ "$?" != "0" ]; then
        echo "$0: $FUNCNAME(): failed to split initrd.img"
        exit 1
    fi

    mkdir -p ${tempdir}/initrd

    if [ -f "${tempdir}/initrd.img.2" ]; then
        cmd=$(get_compression ${tempdir}/initrd.img.2)
        ( cd ${tempdir}/initrd; cpio -i --quiet < ../initrd.img.1 )
        ( cd ${tempdir}/initrd; $cmd ../initrd.img.2 | cpio -i --quiet )
    else
        cmd=$(get_compression ${tempdir}/initrd.img.1)
        ( cd ${tempdir}/initrd; $cmd ../initrd.img.1 | cpio -i --quiet )
    fi

    rm -rf ${tempdir}
}

check_initrd ${cwd} ${initrd}
