#!/usr/bin/bash -e
#
# This setup script will install an OS environment by default into
# /usr/lib/qm/rootfs and create a Podman quadlet containerized environment
# running systemd as PID1 inside.
#

# Globals
SYSTEMCTL_SKIP="N"
INSTALLDIR="/usr/share/qm"
ROOTFS="/usr/lib/qm/rootfs"
AGENT_HOSTNAME="$(hostname)"
AGENTCONF="/etc/bluechi/agent.conf"
QM_CONTAINER_IDS=1000000000:1500000000
CONTAINER_IDS=2500000000:1500000000

CMDLINE_ARGUMENT_LIST=(
  "installdir"
  "rootfs"
  "hostname"
)

root_check() {
    if [ "$(id -u)" -ne 0 ];then
        echo "Please run this script as root"
        exit 1
    fi
}

usage()
{
   echo "The setup script will install an OS environment by default into"
   echo "/usr/lib/qm/rootfs and create a Podman quadlet containerized environment"
   echo "running systemd as PID1 inside."
   echo
   echo "Usage: setup [OPTIONS]"
   echo
   echo "OPTIONS:"
   echo
   echo "--help                Print this message."
   echo "--installdir          qm install directory (default: /usr/share/qm)"
   echo "--rootfs              set rootfs (default: /usr/lib/qm/rootfs)"
   echo "--skip-systemctl      skip systemctl daemon commands (default: false)"
   echo "--hostname            custom agent hostname to use (default: \$\(hostname\))"
   echo
   echo "Example:"
   echo "  $ sudo ./setup --installdir=/usr/share/qm --rootfs=/usr/lib/qm/rootfs"
}

replaceIDs() {
    touch "$1"
    grep -q "^$2:" "$1" || echo "$2":"$3" >> "$1"
}

bluechiSetup() {
    ROOTFS=$1
    if test ! -f "${ROOTFS}${AGENTCONF}"; then
	if test -f "${AGENTCONF}"; then
	    sed -e 's,^NodeName=,NodeName=qm.,g' "${AGENTCONF}" >  "${ROOTFS}${AGENTCONF}"
	fi
    fi
    hostname=$AGENT_HOSTNAME
    if test -f "${ROOTFS}${AGENTCONF}"; then
	sed -e "s,^NodeName=qm.$,NodeName=qm.${hostname},g" \
	    -e "s,^NodeName=$,NodeName=qm.${hostname},g" \
	    -i "${ROOTFS}${AGENTCONF}"
    else
	cat > "${ROOTFS}${AGENTCONF}" <<EOF
[bluechi-agent]
NodeName=qm.${hostname}
EOF
    fi
}

storage() {
    ROOTFS=$1
    if ! test -f "${ROOTFS}/etc/containers/storage.conf"; then
	mkdir -p "${ROOTFS}/var/lib/shared/overlay-images" \
	      "${ROOTFS}/var/lib/shared/overlay-layers"
	touch "${ROOTFS}/var/lib/shared/overlay-images/images.lock" \
	      "${ROOTFS}/var/lib/shared/overlay-layers/layers.lock"

	sed -e '/additionalimage.*/a "/var/lib/shared",' \
            -e 's|^#.*transient_store.*|transient_store=true|g' \
            "${ROOTFS}/usr/share/containers/storage.conf" \
            > "${ROOTFS}/etc/containers/storage.conf"
    fi
}

install() {
    ROOTFS=$1
    # shellcheck source=/dev/null
    . /etc/os-release
    mkdir -Z -p "${ROOTFS}"
    dnf -y install --releasever="${VERSION_ID}" --installroot "${ROOTFS}" selinux-policy-targeted podman systemd bluechi-agent procps-ng
    dnf -y update --installroot "${ROOTFS}"
    rm -rf "${ROOTFS}"/etc/selinux/targeted/contexts/files/file_contexts/*
    cp "${INSTALLDIR}/containers.conf" "${ROOTFS}/etc/containers/"
    cp "${INSTALLDIR}/contexts" "${ROOTFS}/usr/share/containers/selinux/"
    cp "${INSTALLDIR}/file_contexts" "${ROOTFS}/etc/selinux/targeted/contexts/files/file_contexts"
    replaceIDs "${ROOTFS}/etc/subuid" containers ${QM_CONTAINER_IDS}
    replaceIDs "${ROOTFS}/etc/subgid" containers ${QM_CONTAINER_IDS}
    bluechiSetup "${ROOTFS}"
    
    if [ "$SYSTEMCTL_SKIP" == "N" ]; then
        unshare --mount-proc -R "${ROOTFS}" -m systemctl enable bluechi-agent.service
    else
        ln -s \
            ${ROOTFS}/usr/lib/systemd/system/bluechi-agent.service \
            ${ROOTFS}/etc/systemd/system/multi-user.target.wants/bluechi-agent.service
    fi

    storage "${ROOTFS}"
    restorecon -R "${ROOTFS}"
}

# read command line arguments
opts=$(getopt \
  --longoptions "$(printf "help,skip-systemctl,%s:," "${CMDLINE_ARGUMENT_LIST[@]}")" \
  --name "$(basename "$0")" \
  --options "" \
  -- "$@"
)

eval set --"${opts}"

# main()
root_check

while [[ $# -gt 0 ]]; do
  case "$1" in
    --installdir)
      INSTALLDIR="${2}"
      shift 2
      ;;
    --rootfs)
      ROOTFS="${2}"
      shift 2
      ;;
    --skip-systemctl)
      SYSTEMCTL_SKIP="Y"
      shift
      ;;
    --hostname)
      AGENT_HOSTNAME="${2}"
      shift 2
      ;;
    --help)
      usage
      exit 1
      ;;
    *)
      break
      ;;
  esac
done

# Figure out the options, execute setup
echo "setup has started..."
echo  "  * rootfs: ${ROOTFS}"
echo  "  * install dir: ${INSTALLDIR}"
echo

case "$1" in
    bluechi-agent)
	rm -f "${ROOTFS}${AGENTCONF}"
	bluechiSetup "${ROOTFS}"
	;;
    *)

    if [ "$SYSTEMCTL_SKIP" == "N" ]; then
	    if systemctl is-active --quiet "qm.service" ; then
	    	systemctl stop qm.service
	    fi
    fi

	install "${ROOTFS}"
	replaceIDs /etc/subuid qmcontainers ${QM_CONTAINER_IDS}
	replaceIDs /etc/subgid qmcontainers ${QM_CONTAINER_IDS}
	replaceIDs /etc/subuid containers   ${CONTAINER_IDS}
	replaceIDs /etc/subgid containers   ${CONTAINER_IDS}
    
    if [ "$SYSTEMCTL_SKIP" == "N" ]; then
	    systemctl daemon-reload
	    systemctl start qm.service
    else
      /usr/libexec/podman/quadlet /run/systemd/generator/ 
    fi
	;;
esac
