#! /bin/bash
#################################################
#       Title:  mk-install-iso                  #
#        Date:  2014-11-26                      #
#     Version:  1.0                             #
#      Author:  dthaluru@vmware.com             #
#     Options:                                  #
#################################################
#   Overview
#       Generates a photon iso
#   End
#

set -e
set -x

SCRIPT_PATH=$(dirname $(realpath -s $0))
PRGNAME=${0##*/}    # script name minus the path

INSTALLER_PATH=$1
WORKINGDIR=$2
shift 2
ISO_OUTPUT_NAME=$1
RPMS_PATH=$2
PACKAGE_LIST_FILE=$3
RPM_LIST=$4
STAGE_PATH=$5
ADDITIONAL_FILES_TO_COPY_FROM_STAGE=$6
OUTPUT_DATA_PATH=$7
PHOTON_COMMON_DIR=$(dirname "${PACKAGE_LIST_FILE}")
PACKAGE_LIST_FILE_BASE_NAME=$(basename "${PACKAGE_LIST_FILE}")
INITRD=${WORKINGDIR}/photon-chroot
PACKAGES=$8
PHOTON_DOCKER_IMAGE=$9

rm -rf $WORKINGDIR/*
mkdir -p $INITRD
chmod 755 $INITRD

tar -xf $SCRIPT_PATH/open_source_license.tar.gz -C $WORKINGDIR/
cp $STAGE_PATH/NOTICE-Apachev2 $WORKINGDIR/
cp $STAGE_PATH/NOTICE-GPL2.0 $WORKINGDIR/

# 1. install rpms into initrd path
cat > ${WORKINGDIR}/photon-local.repo <<EOF
[photon-local]
name=VMware Photon Linux
baseurl=file://${RPMS_PATH}
gpgcheck=0
enabled=1
skip_if_unavailable=True
EOF

cat > ${WORKINGDIR}/tdnf.conf <<EOF
[main]
gpgcheck=0
installonly_limit=3
clean_requirements_on_remove=true
repodir=${WORKINGDIR}
EOF

rpm --root $INITRD --initdb --dbpath /var/lib/rpm

TDNF_CMD="tdnf install -y --installroot $INITRD --rpmverbosity 10 -c ${WORKINGDIR}/tdnf.conf -q $PACKAGES"

# run host's tdnf, if fails - try one from photon:latest docker image
$TDNF_CMD || docker run -v $RPMS_PATH:$RPMS_PATH -v $WORKINGDIR:$WORKINGDIR $PHOTON_DOCKER_IMAGE $TDNF_CMD

rm -f ${WORKINGDIR}/photon-local.repo ${WORKINGDIR}/tdnf.conf

# 2. copy installer code to initrd
cp -r $INSTALLER_PATH $INITRD

# 3. finalize initrd system (mk-finalize-system.sh)
chroot ${INITRD} /usr/sbin/pwconv
chroot ${INITRD} /usr/sbin/grpconv
chroot ${INITRD} /bin/systemd-machine-id-setup
echo "LANG=en_US.UTF-8" > $INITRD/etc/locale.conf
echo "photon-installer" > $INITRD/etc/hostname
# locales/en_GB should be moved to glibc main package to make it working
#chroot ${INITRD} /usr/bin/localedef -c -i en_US -f UTF-8 en_US.UTF-8
# Importing the pubkey (photon-repos required)
#chroot ${INITRD} rpm --import /etc/pki/rpm-gpg/*

# Move entire /boot from initrd to ISO
mv ${INITRD}/boot ${WORKINGDIR}/

cp -r $SCRIPT_PATH/BUILD_DVD/isolinux $SCRIPT_PATH/BUILD_DVD/boot ${WORKINGDIR}/

#Generate efiboot image
# efiboot is a fat16 image that has at least EFI/BOOT/bootx64.efi

EFI_IMAGE=boot/grub2/efiboot.img
EFI_FOLDER=`readlink -f ${STAGE_PATH}/efiboot`
dd if=/dev/zero of=${WORKINGDIR}/${EFI_IMAGE} bs=3K count=1024
mkdosfs ${WORKINGDIR}/${EFI_IMAGE}
mkdir $EFI_FOLDER
mount -o loop ${WORKINGDIR}/${EFI_IMAGE} $EFI_FOLDER
mv ${WORKINGDIR}/boot/efi/EFI $EFI_FOLDER/
ls -lR $EFI_FOLDER
umount $EFI_FOLDER
rm -rf $EFI_FOLDER
#mcopy -s -i ${WORKINGDIR}/${EFI_IMAGE} ./EFI '::/'

cp $INSTALLER_PATH/sample_ks.cfg ${WORKINGDIR}/isolinux/

mv ${WORKINGDIR}/boot/vmlinuz* ${WORKINGDIR}/isolinux/vmlinuz

rm -f ${INITRD}/installer/*.pyc
# Copy package list json files, dereference symlinks
cp -rf -L $OUTPUT_DATA_PATH/*.json ${INITRD}/installer/
#ID in the initrd.gz now is PHOTON_VMWARE_CD . This is how we recognize that the cd is actually ours. touch this file there.
touch ${WORKINGDIR}/PHOTON_VMWARE_CD

# Step 4.5 Create necessary devices
mkfifo ${INITRD}/dev/initctl
mknod ${INITRD}/dev/ram0 b 1 0
mknod ${INITRD}/dev/ram1 b 1 1
mknod ${INITRD}/dev/ram2 b 1 2
mknod ${INITRD}/dev/ram3 b 1 3
mknod ${INITRD}/dev/sda b 8 0

#- Step 5 - Creating the boot script
mkdir -p ${INITRD}/etc/systemd/scripts

# Step 6 create fstab
cp $SCRIPT_PATH/BUILD_DVD/fstab ${INITRD}/etc/fstab

mkdir -p ${INITRD}/etc/yum.repos.d
cat > ${INITRD}/etc/yum.repos.d/photon-iso.repo << EOF
[photon-iso]
name=VMWare Photon Linux 1.0(x86_64)
baseurl=file:///mnt/media/RPMS
gpgkey=file:///etc/pki/rpm-gpg/VMWARE-RPM-GPG-KEY
gpgcheck=1
enabled=1
skip_if_unavailable=True
EOF

#- Step 7 - Create installer script
cat >> ${INITRD}/bin/bootphotoninstaller << EOF
#!/bin/bash
cd /installer

ACTIVE_CONSOLE="\$(< /sys/devices/virtual/tty/console/active)"

install() {
  LANG=en_US.UTF-8 ./isoInstaller.py --json-file=$PACKAGE_LIST_FILE_BASE_NAME && shutdown -r now
}

try_run_installer() {
  if [ "\$ACTIVE_CONSOLE" == "tty0" ]; then
      [ "\$(tty)" == '/dev/tty1' ] && install
  else
      [ "\$(tty)" == "/dev/\$ACTIVE_CONSOLE" ] && install
  fi
}

try_run_installer || exec /bin/bash

EOF

chmod 755 ${INITRD}/bin/bootphotoninstaller

cat >> ${INITRD}/init << EOF
mount -t proc proc /proc
/lib/systemd/systemd
EOF
chmod 755 ${INITRD}/init

#adding autologin to the root user
# and set TERM=linux for installer
sed -i "s/ExecStart.*/ExecStart=-\/sbin\/agetty --autologin root --noclear %I linux/g" ${INITRD}/lib/systemd/system/getty@.service
sed -i "s/ExecStart.*/ExecStart=-\/sbin\/agetty --autologin root --keep-baud 115200,38400,9600 %I screen/g" ${INITRD}/lib/systemd/system/serial-getty@.service

#- Step 7 - Create installer script
sed -i "s/root:.*/root:x:0:0:root:\/root:\/bin\/bootphotoninstaller/g" ${INITRD}/etc/passwd

mkdir -p ${INITRD}/mnt/photon-root/photon-chroot
rm -rf ${INITRD}/RPMS

echo ${RPMS_PATH}
#cp -r ${RPMS_PATH} ${WORKINGDIR}/
(
cd ${RPMS_PATH}
mkdir ${WORKINGDIR}/RPMS
for rpm_name in $RPM_LIST; do
    cp --parent $rpm_name ${WORKINGDIR}/RPMS/
    chmod 644 ${WORKINGDIR}/RPMS/$rpm_name
done
)

# Work in sub-shell using ( ... ) to come back to original folder.
(
cd $STAGE_PATH
for file_name in $ADDITIONAL_FILES_TO_COPY_FROM_STAGE; do
    [ -n "$file_name" ] &&  cp $file_name ${WORKINGDIR}
done
)

#creating rpm repo in cd..
createrepo --database ${WORKINGDIR}/RPMS

repodatadir=${WORKINGDIR}/RPMS/repodata
if [ -d $repodatadir ]; then
    pushd $repodatadir
    metaDataFile=`find -type f -name "*primary.xml.gz"`
    ln -sfv $metaDataFile primary.xml.gz
    popd
fi

rm -rf ${INITRD}/LOGS

# Cleaning up
find ${INITRD}/usr/lib/ -maxdepth 1 -mindepth 1 -type f | xargs -i sh -c "grep ELF {} >/dev/null 2>&1 && strip {} || :"

rm -rf ${INITRD}/home/*         \
        ${INITRD}/var/lib/rpm   \
        ${INITRD}/cache         \
        ${INITRD}/boot          \
        ${INITRD}/usr/include   \
        ${INITRD}/usr/sbin/sln  \
        ${INITRD}/usr/bin/iconv \
        ${INITRD}/usr/bin/oldfind       \
        ${INITRD}/usr/bin/localedef     \
        ${INITRD}/usr/bin/sqlite3       \
        ${INITRD}/usr/bin/grub2-*       \
        ${INITRD}/usr/bin/bsdcpio       \
        ${INITRD}/usr/bin/bsdtar        \
        ${INITRD}/usr/bin/networkctl    \
        ${INITRD}/usr/bin/machinectl    \
        ${INITRD}/usr/bin/pkg-config    \
        ${INITRD}/usr/bin/openssl       \
        ${INITRD}/usr/bin/timedatectl   \
        ${INITRD}/usr/bin/localectl     \
        ${INITRD}/usr/bin/systemd-cgls  \
        ${INITRD}/usr/bin/systemd-analyze       \
        ${INITRD}/usr/bin/systemd-nspawn        \
        ${INITRD}/usr/bin/systemd-inhibit       \
        ${INITRD}/usr/bin/systemd-studio-bridge \
        ${INITRD}/usr/lib/python2.7/lib2to3     \
        ${INITRD}/usr/lib/python2.7/lib-tk      \
        ${INITRD}/usr/lib/python2.7/ensurepip   \
        ${INITRD}/usr/lib/python2.7/distutils   \
        ${INITRD}/usr/lib/python2.7/pydoc_data  \
        ${INITRD}/usr/lib/python2.7/idlelib     \
        ${INITRD}/usr/lib/python2.7/unittest    \
        ${INITRD}/usr/lib/librpmbuild.so*       \
        ${INITRD}/usr/lib/libdb_cxx*            \
        ${INITRD}/usr/lib/libnss_compat*        \
        ${INITRD}/usr/lib/grub/i386-pc/*.module \
        ${INITRD}/usr/lib/grub/x86_64-efi/*.module \
        ${INITRD}/lib64/libmvec*        \
        ${INITRD}/usr/lib64/gconv

find "${INITRD}/usr/sbin" -mindepth 1 -maxdepth 1 -name "grub2*" \
                        ! -name grub2-install -exec rm -rvf {} \;

find "${INITRD}/usr/share" -mindepth 1 -maxdepth 1 \
                        ! -name terminfo \
                        ! -name cracklib \
                        ! -name grub    \
                        ! -name factory \
                        ! -name dbus-1 -exec rm -rvf {} \;

# Set password max days to 99999 (disable aging)
chroot ${INITRD} /bin/bash -c "chage -M 99999 root"

# Generate the initrd
pushd $INITRD
(find . | cpio -o -H newc --quiet | gzip -9) > ${WORKINGDIR}/isolinux/initrd.img
popd
rm -rf $INITRD

#Step 9 Generate the ISO!!!!
pushd $WORKINGDIR
mkisofs -R -l -L -D -b isolinux/isolinux.bin -c isolinux/boot.cat \
        -no-emul-boot -boot-load-size 4 -boot-info-table \
        -eltorito-alt-boot -e ${EFI_IMAGE} -no-emul-boot \
        -V "PHOTON_$(date +%Y%m%d)" \
        $WORKINGDIR >$ISO_OUTPUT_NAME
popd