#!/bin/sh
#
# Copyright (C) 2019 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or later as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# File: build-vmware-image
# Purpose:
# Build VyOS image for VMWARE.

if [ ! $(which vmdk-convert) ]; then
   echo "Your system doesn't have vmdk-convert. Please install it from https://github.com/vmware/open-vmdk."
   exit 1
else
   echo "Your system has vmdk-convert."
fi

if [ ! $(which ovftool) ]; then
   echo "Your system doesn't have ovftool. Please install it from https://www.vmware.com/support/developer/ovf/."
   exit 1
else
   echo "Your system has ovftool."
fi

lb bootstrap

lb chroot
lb installer
lb binary_chroot
lb chroot_devpts install
lb chroot_proc install
lb chroot_selinuxfs install
lb chroot_sysfs install
lb chroot_hosts install
lb chroot_resolv install
lb chroot_hostname install
lb chroot_sysv-rc install
lb chroot_upstart install
lb chroot_apt install-binary
lb chroot_archives chroot install
lb binary_rootfs
lb binary_manifest
lb binary_package-lists
lb binary_linux-image
lb binary_memtest
lb binary_grub
lb binary_grub2
lb binary_syslinux
lb binary_disk
lb binary_loadlin
lb binary_win32-loader
lb binary_includes
lb binary_hooks
lb binary_checksums

# get vyos build version
version=$(cat version)
dateymd=$(date +%Y%m%d)

######################################
### Prepare the HDD (format, ext.) ###
######################################
PARTED=/sbin/parted
OUTPUT=disk.raw
OUTPUTVMDK=VyOS-"$dateymd".vmdk
IMAGE_SIZE=2
qemu-img create -f raw ${OUTPUT} ${IMAGE_SIZE}G

${PARTED} -s ${OUTPUT} mktable msdos
${PARTED} -s -a optimal ${OUTPUT} mkpart primary ext4 1Mi 100%
${PARTED} -s ${OUTPUT} set 1 boot on
RESULT_KPARTX=`kpartx -asv ${OUTPUT} 2>&1`

if echo "${RESULT_KPARTX}" | grep "^add map" ; then
	LOOP_DEVICE=$(echo ${RESULT_KPARTX} | cut -d" " -f3)
	LOOPRAW_DEVICE=${LOOP_DEVICE%p*}
	echo "kpartx mounted using: ${LOOP_DEVICE} via ${LOOPRAW_DEVICE}"
else
	echo "It seems kpartx didn't mount the image correctly: exiting."
	exit 1
fi

cleanup(){
	error=$?
	[ ! -d "${MOUNT_DIR}" ] && return
	if [ "$error" -gt 0 ]; then
		echo
		echo "Error $error"
	else
		echo "Finished."
	fi

	set +e

	sync
	umount -l ${MOUNT_DIR}
	rmdir ${MOUNT_DIR}

        umount devpts-live
        umount proc-live
        umount sysfs-live

	dmsetup remove --deferred ${LOOP_DEVICE}
	losetup -d /dev/${LOOPRAW_DEVICE}
	exit $error
}
trap "cleanup" EXIT TERM INT

mkfs.ext4 /dev/mapper/${LOOP_DEVICE} -L persistence
UUID=$(blkid -o value -s UUID /dev/mapper/${LOOP_DEVICE})

# No fsck because of X days without checks
tune2fs -i 0 /dev/mapper/${LOOP_DEVICE}

MOUNT_DIR=`mktemp -d -t build-debimg.XXXXXX`
mount /dev/mapper/${LOOP_DEVICE} ${MOUNT_DIR}

########################
### Setting-up files ###
########################
mkdir -p ${MOUNT_DIR}/boot/grub
mkdir -p ${MOUNT_DIR}/boot/"$version"/rw

echo "/ union" > ${MOUNT_DIR}/persistence.conf
cp binary/live/filesystem.squashfs ${MOUNT_DIR}/boot/"$version"/"$version.squashfs"
cp binary/live/initrd.img ${MOUNT_DIR}/boot/"$version"/initrd.img
cp binary/live/vmlinuz ${MOUNT_DIR}/boot/"$version"/vmlinuz

########################
### Create grub menu ###
########################
cat > ${MOUNT_DIR}/boot/grub/grub.cfg << EOF
set timeout=5
set default=0

menuentry "VyOS  (KVM console)" {
        linux /boot/"$version"/vmlinuz boot=live quiet vyos-union=/boot/"$version" console=ttyS0,115200 console=tty0 systemd.show_status=true
        initrd /boot/"$version"/initrd.img
}

menuentry "Lost password change  (KVM console)" {
        linux /boot/"$version"/vmlinuz boot=live vyos-union=/boot/"$version" console=ttyS0,115200 console=tty0 systemd.show_status=true init=/opt/vyatta/sbin/standalone_root_pw_reset
        initrd /boot/"$version"/initrd.img
}

menuentry "VyOS $version (Serial console)" {
        linux /boot/"$version"/vmlinuz boot=live vyos-union=/boot/"$version" console=tty0 console=ttyS0,115200n8d consoleblank=0 systemd.show_status=true
        initrd /boot/"$version"/initrd.img
}

menuentry "Lost password change $version (Serial console)" {
        linux /boot/"$version"/vmlinuz boot=live vyos-union=/boot/"$version" console=tty0 console=ttyS0,115200n8d consoleblank=0 systemd.show_status=true init=/opt/vyatta/sbin/standalone_root_pw_reset
        initrd /boot/"$version"/initrd.img
}
EOF


#############################
### Setting-up bootloader ###
#############################
grub-install  --boot-directory ${MOUNT_DIR}/boot --force --no-floppy --skip-fs-probe /dev/${LOOPRAW_DEVICE}

###################
### HOOK SCRIPT ###
###################
fstrim ${MOUNT_DIR}
sync

qemu-img convert -f raw ${OUTPUT} -O vmdk -o adapter_type=lsilogic ${OUTPUTVMDK}
rm ${OUTPUT}

vmdk=vyos_vmware_image.vmdk
ovf=vyos_vmware_image.ovf
vmdk-convert ${OUTPUTVMDK} ${vmdk}

# Generate OVF
echo 'Generating OVF file...'
vmdk_file_size=$(du --bytes ${vmdk} | cut -f1)
vmdk_populated_size=$(vmdk-convert -i ${vmdk} | jq .used)
sed ../scripts/template.ovf \
  -e "s/{{vmdk_file_size}}/${vmdk_file_size}/" \
  -e "s/{{vmdk_populated_size}}/${vmdk_populated_size}/" \
  -e "s/{{version}}/${version}/" \
  > ${ovf}

# Generate manifest file
openssl sha1 *.vmdk *.ovf > vyos_vmware_image.mf

# Convert the OVF to signed OVA...
echo 'Converting the OVF to signed OVA...'
private_key=${PRIVATE_KEY_PATH:-"../key/privatekey.pem"}
if [ ! -f ${private_key} ]; then
  echo 'Please put your key to "key/privatekey.pem" in repository root, or set PRIVATE_KEY_PATH to environment variables.'
  exit 1
fi
ovftool --privateKey=${private_key} vyos_vmware_image.ovf vyos_vmware_image-signed.ova
#ovftool vyos_vmware_image.ovf vyos_vmware_image-signed.ova

# Convert the OVF to signed OVF...
echo 'Converting the OVF to signed OVF...'
ovftool --privateKey=${private_key} vyos_vmware_image.ovf vyos_vmware_image-signed.ovf
#ovftool vyos_vmware_image.ovf vyos_vmware_image-signed.ovf