#!/bin/bash

set -e -x

# Variable(s) and default values
VM_NAME=$1
MAC=$2
ARCH=$(uname -m)
FW_CODE=/usr/share/qemu/ovmf-${ARCH}-smm-suse-code.bin
FW_VARS=$(realpath ../assets/ovmf-template-vars.fd)
EMULATED_TPM="none"

# Configure hugepages if needed
NR_HUGEPAGES=$(</proc/sys/vm/nr_hugepages)
if (( NR_HUGEPAGES == 0 && USE_HUGEPAGES != 0 )); then
  # Not configured, do it now!
  MEMTOTAL_KB=$(awk '/^MemTotal:/ { print $2 }' /proc/meminfo)

  # Number of hugepages (with hugepagesize set to 2MB)
  # NOTE: keep 24GB by default for the hypervisor/Rancher Manager Server
  # And this value can be modified with HOST_MEMORY_RESERVED variable
  (( VALUE = (MEMTOTAL_KB - ${HOST_MEMORY_RESERVED:-24576} * 1024) / 2048 ))

  # Set nr_hugepage
  (( VALUE > 0 )) \
    && sudo bash -c "echo ${VALUE} > /proc/sys/vm/nr_hugepages"

  # Set memory config on command line
  INSTALL_FLAG+=" --memorybacking hugepages=yes,size=2,unit=M,locked=yes --memory ${VM_MEM:-2048},hugepages=yes"
else
  # Set memory config on command line
  INSTALL_FLAG+=" --memory ${VM_MEM:-2048}"
fi

# Don't configure TPM if software emulation (EMULATE_TPM=true) is used
if [[ ${EMULATE_TPM} != "true" ]]; then
  EMULATED_TPM="emulator,model=tpm-crb,version=2.0"
fi

# Create directories: dedicated one for storage pool + logs one
mkdir -p logs ${VM_NAME}

# iPXE stuff will not be used if ISO is set
if [[ ${ISO_BOOT} == "true" ]]; then
  ISO=$(realpath ../../elemental-*.iso 2>/dev/null)

  # Exit if ISO is not available
  [[ ! -f ${ISO} ]] \
    && echo "File ${ISO} not found! Exiting!" >&2 \
    && exit 1

  # Soft-link the ISO to avoid "Could not define storage pool" error
  ln -s ${ISO} ${VM_NAME}/

  # Force ISO boot
  INSTALL_FLAG+=" --cdrom ${VM_NAME}/${ISO##*/}"
  
  # Use noautoconsole to check SeedImage cloud-config
  # because we need to ssh into the VM when it is installing
  [[ ${POOL} == "master" ]] && INSTALL_FLAG+=" --noautoconsole"
else
  # Create symlink for binary but only if it doesn't exist
  SYM_LINK=../../ipxe.efi
  if [[ ! -h ${SYM_LINK} ]]; then
    # Exit if binary is not available
    IPXE_BIN=$(realpath ../assets/ipxe-${ARCH}.efi)
    [[ ! -f ${IPXE_BIN} ]] \
      && echo "File ${IPXE_BIN} not found! Exiting!" >&2 \
      && exit 1

    # Force remove, to avoid issue with 'ln'
    # Only useful if an EFI file exists and it's not a symlink
    rm -f ${SYM_LINK}
    ln -s ${IPXE_BIN} ${SYM_LINK}
  fi

  # Force PXE boot
  INSTALL_FLAG+=" --pxe"
fi

# VM variables
LOG_FILE=logs/bootstrap_${VM_NAME}.log
CMD="sudo virt-install \
       --name ${VM_NAME} \
       --os-variant opensuse-unknown \
       --virt-type kvm \
       --machine q35 \
       --boot loader=${FW_CODE},loader.readonly=yes,loader.secure=yes,loader.type=pflash,nvram.template=${FW_VARS} \
       --features smm.state=yes \
       --vcpus ${VM_CPU:-2} \
       --cpu host \
       --disk path=${VM_NAME}/${VM_NAME}.img,bus=scsi,size=35 \
       --check disk_size=off \
       --graphics none \
       --serial pty \
       --console pty,target_type=virtio \
       --rng random \
       --tpm ${EMULATED_TPM} \
       --noreboot \
       --network network=default,bridge=virbr0,model=virtio,mac=${MAC} \
       ${INSTALL_FLAG}"

# Create VM
# But before, sync all and wait a little bit before executing virt-install
# To try to avoid sporadic issue where sometimes the media is not found by virt-install
sync \
  && sleep 20s \
  && script -E never -e -f -q -O ${LOG_FILE} -c "${CMD}" >/dev/null 2>&1
