#!/bin/bash

## Copyright (C) 2012 - 2023 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

set -x
set -e

true "INFO: Currently running script: $BASH_SOURCE $@"

MYDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

cd "$MYDIR"
cd ..
cd help-steps

source pre
source colors
source variables

## Debugging function.
apt_get_parse_unmet_dependency() {
   local pkg_unmet
   pkg_unmet="$1"
   true "INFO: Running \"dpkg -l | grep $pkg_unmet\"..."
   $SUDO_TO_ROOT $CHROOT dpkg -l | grep "$pkg_unmet" || true
   $SUDO_TO_ROOT $CHROOT apt-cache policy "$pkg_unmet" || true

   local line

   ## Thanks to:
   ## http://blog.edwards-research.com/2010/01/quick-bash-trick-looping-through-output-lines/

   set +x

   declare -A -g remember_pkg

   while read -r -d $'\n' line; do
      local unmet_dependency=""
      unmet_dependency="$(echo "$line" | grep -o "Depends:.*" | awk '{print $2}')" || true
      if [ "$unmet_dependency" = "" ]; then
         ## no match
         continue
      else
         ## match
         if [ "${remember_pkg[$unmet_dependency]}" = "true" ]; then
            continue
         fi
         echo "${bold}${cyan}INFO: Found unmet dependency: $unmet_dependency. \
Will try to manually install it for debugging...${reset}"
         remember_pkg[$unmet_dependency]="true"
         set -x
         true "INFO: Running \"dpkg -l | grep $unmet_dependency\"..."
         $SUDO_TO_ROOT $CHROOT dpkg -l | grep "$unmet_dependency" || true
         $SUDO_TO_ROOT $CHROOT apt-cache policy "$unmet_dependency" || true
         pkg-install "$unmet_dependency" || true
         set +x
         echo "${bold}${cyan}INFO: Attempt to install unmet_dependency: $unmet_dependency done.${reset}"
         continue
      fi
   done < <( echo "$apt_get_output" )

   set -x
}

pkg-install() {
   exception_handler_setup "exception_handler_unchroot_unmount" ERR INT TERM

   local pkg_install_item
   pkg_install_item="$1"
   local skip_package
   for skip_package in $dist_build_script_skip_package_install; do
      if [ "$skip_package" = "$pkg_install_item" ]; then
         unset skip_package
         true "${bold}${cyan}INFO: Skipping installation of '$pkg_install_item', because variable dist_build_script_skip_package_install includes it.${reset}"
         return 0
      fi
   done
   unset skip_package

   true "${cyan}INFO: Installing of '$@', because variable dist_build_script_skip_package_install does not include it... \
This may take a while...${reset}"

   ## apt: no way to view dpkg commandline and still run dpkg
   ## https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=52670
   local apt_get_exit_code="0"
   $SUDO_TO_ROOT \
      $CHROOT \
         apt-get-noninteractive \
            ${APTGETOPT[@]} \
            $apt_sourcelist_empty \
            $apt_sourceparts \
            $apt_unattended_opts \
            --yes \
            --no-install-recommends \
            install \
            "$@" \
            || { apt_get_exit_code="$?" ; true; };

   $SUDO_TO_ROOT $CHROOT sync
   $SUDO_TO_ROOT sync

   if [ "$apt_get_exit_code" = "0" ]; then
      true "${cyan}INFO: Installed '$@', no error detected.${reset}"
      return 0
   fi

   true "${bold}${red}ERROR: Failed to install '$@'. (apt_get_exit_code: $apt_get_exit_code) \
Attempting to gather debug output to diagnose the problem...${reset}"

   true "${bold}${cyan}INFO: Read output of apt-get-noninteractive trying to install '$@' into a \
variable for debugging. This may take a while...${reset}"

   local apt_get_exit_code="0"
   apt_get_output=" \
         $( \
            $SUDO_TO_ROOT \
               $CHROOT \
                  apt-get-noninteractive \
                     ${APTGETOPT[@]} \
                     $apt_sourcelist_empty \
                     $apt_sourceparts \
                     $apt_unattended_opts \
                     --yes \
                     --no-install-recommends \
                     install \
                     "$@" \
                     2>&1 \
         ) \
      " \
      || { apt_get_exit_code="$?" ; true; };

   $SUDO_TO_ROOT $CHROOT sync
   sync

   if [ "$apt_get_exit_code" = "0" ]; then
      true "${bold}${red}ERROR: Second attempt installing '$@' did not fail?!?${reset}"
      error "See above!"
      return 0
   fi

   true "${bold}${red}ERROR: As expected, failed again to install '$@'. (apt_get_exit_code: $apt_get_exit_code) \
Trying to diagnose the problem using function apt_get_parse_unmet_dependency...${reset}"

   apt_get_parse_unmet_dependency "$@"

   true "INFO: Tried to diagnose the problem using function apt_get_parse_unmet_dependency."

   error "See above!"
   return 0
}

pkg-add-to-install-list() {
   exception_handler_setup "exception_handler_unchroot_unmount" ERR INT TERM

   local pkg_install_item
   pkg_install_item="$1"
   local skip_package
   for skip_package in $dist_build_script_skip_package_install; do
      if [ "$skip_package" = "$pkg_install_item" ]; then
         unset skip_package
         true "${bold}${cyan}INFO: Skipping package $pkg_install_item, because dist_build_script_skip_package_install includes it.${reset}"
         return 0
      fi
   done
   unset skip_package

   if [ "$pkg_install_item" = "none" ]; then
      true "${bold}${cyan}INFO: Skipping package $pkg_install_item (none).${reset}"
      return 0
   fi

   if [ "$pkg_install_debug" = "true" ]; then
      pkg-install "$pkg_install_item"
   else
      pkg_install_list+=" $pkg_install_item "
   fi
}

pkg-list-install() {
   exception_handler_setup "exception_handler_unchroot_unmount" ERR INT TERM

   if [ "$pkg_install_list" = "" ]; then
      true "INFO: pkg_install_list still empty, ok."
      return 0
   else
      pkg-install $pkg_install_list
   fi
}

install-packages() {
   exception_handler_setup "exception_handler_unchroot_unmount" ERR INT TERM

   ## provided by: help-steps/pre
   apt-cacher-ng_config_check

   sync

   "$dist_source_help_steps_folder/mount-raw" "$@"

   $SUDO_TO_ROOT cp "$source_code_folder_dist/packages/kicksecure/usability-misc/usr/bin/apt-get-noninteractive" "$CHROOT_FOLDER/usr/bin/apt-get-noninteractive"

   "$dist_source_help_steps_folder/prevent-daemons-from-starting" "$@"

   sync

   ## Sanity tests.
   $SUDO_TO_ROOT $CHROOT sync
   $SUDO_TO_ROOT $CHROOT ls -la /

   sync

   "$dist_source_help_steps_folder/chroot-raw" "$@"
   "$dist_source_help_steps_folder/create-local-temp-apt-repo" "$@"

   ## Debugging.
   $SUDO_TO_ROOT $CHROOT ls -la /mnt/initialdeb/dists/local/ || true
   $SUDO_TO_ROOT $CHROOT ls -la /mnt/initialdeb/dists/local/main/binary-*/ || true

   "$dist_source_help_steps_folder/unchroot-raw" "$@"

   ## {{ controversy of: /etc/resolv.conf /etc/hosts /etc/hostname,
   ##    see help-steps/chroot-raw for more information.

   dist_chroot_mount_resolv_conf="0" "$dist_source_help_steps_folder/chroot-raw" "$@"
   "$dist_source_help_steps_folder/create-local-temp-apt-repo" "$@"

   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts update

#    if [ "$dist_build_target_arch" = "arm64" ]; then
#       ## Install package helper-scripts first so pre.bsh and initramfs-debug-enable is available.
#       pkg-install helper-scripts
#
#       ## initramfs-debug-enable is provided by package helper-scripts.
#       ## TODO: disable once arm64 build issues are resolved
#       $CHROOT initramfs-debug-enable
#    fi

   ## Install legacy-dist earlier so debconf questions are answered before
   ## meta package installation.
   pkg-install legacy-dist

   if [ "$dist_build_type_short" = "kicksecure" ]; then
      pkg-install kicksecure-packages-dependencies-pre
   elif [ "$dist_build_type_short" = "whonix" ]; then
      if [ "$dist_build_type_long" = "gateway" ];then
         pkg-install whonix-gateway-packages-dependencies-pre
      elif [ "$dist_build_type_long" = "workstation" ];then
         pkg-install whonix-workstation-packages-dependencies-pre
      else
         true "${bold}${cyan}INFO: No packages-dependencies-pre package, ok.${reset}"
      fi
   else
      error "ERROR: Invalid dist_build_type_short '$dist_build_type_short'. Please report this bug!"
   fi

   "$dist_source_help_steps_folder/unchroot-raw" "$@"

   ## }}

   "$dist_source_help_steps_folder/chroot-raw" "$@"
   "$dist_source_help_steps_folder/create-local-temp-apt-repo" "$@"

   if echo "${BUILD_INITRAMFS_PKGS}" | grep -q dracut ; then
      true "INFO: Prevent running dracut needlessly. Will be run at the end. This is only to speed up the build."
      export INITRD=No
   fi

   ## Reading Debian apt repository and local repository containing derivative packages.
   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts update

   ## Debugging.
   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts clean
   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts autoclean
   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts --fix-broken --yes install
   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts --fix-missing --yes install
   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts --fix-broken --fix-missing --yes install
   $SUDO_TO_ROOT $CHROOT dpkg --configure -a
   $SUDO_TO_ROOT $CHROOT dpkg --audit

   ## XXX: once installed a newer kernel, which then messed up /boot/grub/grub.cfg to then include root=/dev/mapper which will fail to boot.
   $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts --yes dist-upgrade

   ## Debugging.
   $SUDO_TO_ROOT $CHROOT apt-cache ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts show nano || true
   $SUDO_TO_ROOT $CHROOT apt-cache ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts show helper-scripts || true

   if [ "$dist_build_script_skip_package_install" = "" ]; then
      true "${bold}${cyan}INFO $BASH_SOURCE: Variable dist_build_script_skip_package_install is empty. \
No packages will be excluded from installation. This information is relevant for builders using custom configurations, \
skipping packages such as Terminal-Only.${reset}"
   else
      true "${bold}${cyan}INFO $BASH_SOURCE: List of packages to be excluded from installation. This information is relevant for \
builders using custom configurations, skipping packages such as Terminal-Only. dist_build_script_skip_package_install: \
$dist_build_script_skip_package_install${reset}"
   fi

   if [ "$dist_build_install_to_root" = "true" ]; then
      true "${bold}${cyan}INFO: dist_build_install_to_root is set to true. Skipping kernel installation (one should already be installed), ok.${reset}"
   else
      ## Need to install initramfs tool before kernel. Otherwise kernel would pull Debian's default which is initramfs-tools.
      if [ "$BUILD_INITRAMFS_PKGS" = "none" ]; then
         true "${bold}${cyan}INFO: BUILD_INITRAMFS_PKGS: ${BUILD_INITRAMFS_PKGS} - Skipping initramfs tool installation.${reset}"
      else
         true "${bold}${cyan}INFO: dist_build_install_to_root is not set to true. Add initramfs tool to installation list...${reset}"
         true "${bold}${cyan}INFO: BUILD_INITRAMFS_PKGS: ${BUILD_INITRAMFS_PKGS}${reset}"
         local build_header
         for build_initramfs in $BUILD_INITRAMFS_PKGS; do
            pkg-add-to-install-list "$build_initramfs"
         done
      fi
      if [ "$BUILD_KERNEL_PKGS" = "none" ]; then
         true "${bold}${cyan}INFO: BUILD_KERNEL_PKGS: ${BUILD_KERNEL_PKGS} - Skipping kernel installation.${reset}"
      else
         true "${bold}${cyan}INFO: dist_build_install_to_root is not set to true. Add to kernel image to installation list...${reset}"
         true "${bold}${cyan}INFO: BUILD_KERNEL_PKGS: ${BUILD_KERNEL_PKGS}${reset}"
         local build_kernel
         for build_kernel in $BUILD_KERNEL_PKGS; do
            pkg-add-to-install-list "$build_kernel"
         done
      fi
      if [ "$BUILD_HEADER_PKGS" = "none" ]; then
         true "${bold}${cyan}INFO: BUILD_HEADER_PKGS: ${BUILD_HEADER_PKGS} - Skipping kernel header installation.${reset}"
      else
         true "${bold}${cyan}INFO: dist_build_install_to_root is not set to true. Add kernel header to installation list...${reset}"
         true "${bold}${cyan}INFO: BUILD_HEADER_PKGS: ${BUILD_HEADER_PKGS}${reset}"
         local build_header
         for build_header in $BUILD_HEADER_PKGS; do
            pkg-add-to-install-list "$build_header"
         done
      fi
   fi

   #if [ "$dist_build_flavor" != "whonix-gateway-rpi" ] && [ "$dist_build_target_arch" = "arm64" ]; then
      #pkg-add-to-install-list grub2-common
      #pkg-add-to-install-list grub-efi-arm64
   #fi

   ## Weak recommended packages. No other package depends on it. Can be
   ## easily uninstalled. For better usability.
   if [ "$dist_build_virtualbox" = "true" ] || [ "$dist_build_iso" = "true" ]; then
      ## See also build-steps.d/*_create-debian-packages function
      ## download_virtualbox_packages_from_debian_sid

      ## At time of writing, available for architectures amd64 i386 only.
      if [ "$dist_build_target_arch" = "amd64" ] || [ "$dist_build_target_arch" = "i386" ]; then
         pkg-add-to-install-list virtualbox-guest-utils
         pkg-add-to-install-list virtualbox-guest-x11
      else
         true "${cyan}INFO: skipping installation of virtualbox-guest-utils, virtualbox-guest-x11 because architecture is neither amd64 nor i386..${reset}"
      fi

      ## https://packages.debian.org/virtualbox-guest-additions-iso is available for architecture "all".
      ##
      ## Not required but keeping in case above packages become unavailable.
      ## Allows for higher flexibility if later switches from/to
      ## virtualbox.org repository or Debian fasttrack repository are required.
      ##
      ## https://packages.debian.org/sid/virtualbox-guest-additions-iso
      ##
      ## provides:
      ## /usr/share/virtualbox/VBoxGuestAdditions.iso
      pkg-add-to-install-list virtualbox-guest-additions-iso
   else
      true "${cyan}INFO: skipping installation of weak recommended guest additions, because not using --target virtualbox, ok.${reset}"
   fi

   ## Executing pkg-list-install already this this point for the first time to
   ## make sure linux kernel(s) and linux header(s) as well as
   ## virtualbox-guest-additions-iso get installed now so it is available
   ## during later package vm-config-dist postinst (vbox-guest-installer by
   ## derivative maintainers) without having to add `Depends:` to
   ## vm-config-dist.
   pkg-list-install

   local efi_weak_recommended_packages_list
   ## Availability (and usefulness) is architecture specific.
   efi_weak_recommended_packages_list="sbsigntool efibootmgr mokutil keyutils shim-signed-common efivar fwupd fwupd-signed"

   for iso_weak_recommended_packages_item in $efi_weak_recommended_packages_list ; do
      ## Test if available. Might be unavailable (and unneeded) on some architectures.
      if $SUDO_TO_ROOT $CHROOT apt-get-noninteractive ${APTGETOPT[@]} $apt_sourcelist_empty $apt_sourceparts $apt_unattended_opts --yes --dry-run install "$iso_weak_recommended_packages_item" &>/dev/null ; then
         true "INFO: Yes, adding weak recommended package to the installation list: $iso_weak_recommended_packages_item"
         pkg-add-to-install-list "$iso_weak_recommended_packages_item"
      else
         true "INFO: No, not adding weak recommended package to the installation list: $iso_weak_recommended_packages_item"
      fi
   done

   if [ "$dist_build_raw" = "true" ] || [ "$dist_build_iso" = "true" ]; then
      ## XXX: Superfluous for non-libvirt raw image builds.
      pkg-add-to-install-list spice-vdagent
      #pkg-add-to-install-list serial-console-enable
   elif [ "$dist_build_qcow2" = "true" ] || [ "$dist_build_iso" = "true" ]; then
      pkg-add-to-install-list spice-vdagent
      #pkg-add-to-install-list serial-console-enable
   else
      true "${cyan}INFO: skipping installation of weak recommended guest additions packages spice-vdagent because not using --target qcow2, ok.${reset}"
   fi

   ## Debugging.
   #pkg-add-to-install-list debug-misc

   ## Weak recommended packages so calamares can remove them.
   if [ "$dist_build_iso" = "true" ]; then
      pkg-add-to-install-list calamares
      pkg-add-to-install-list calamares-settings-debian

      ## contains derivative calamares-settings
      pkg-add-to-install-list live-config-dist

      pkg-add-to-install-list live-config

      ## https://forums.whonix.org/t/whonix-host-operating-system/3931/99
      ## 'live-boot' conflicts with 'dracut' because 'live-boot' 'Depends:' on 'initramfs-tools'.
      ## 'live-boot' is not required when suing 'dracut'.
      #pkg-add-to-install-list live-boot

      ## https://forums.whonix.org/t/whonix-host-operating-system/3931/107
      pkg-add-to-install-list user-setup

      ## TODO: not needed?
      pkg-add-to-install-list squashfs-tools

      ## /usr/sbin/bootloader-config by calamares-settings-debian might install cryptsetup-initramfs
      pkg-add-to-install-list cryptsetup-initramfs
   fi

   if [ "$flavor_meta_packages_to_install" = "none" ] || [ "$flavor_meta_packages_to_install" = "" ] || [ "$flavor_meta_packages_to_install" = " " ]; then
      true "${cyan}INFO: variable flavor_meta_packages_to_install is set to '$flavor_meta_packages_to_install', skipping.${reset}"
   else
      for flavor_meta_package_item in $flavor_meta_packages_to_install ; do
         true "${cyan}INFO: flavor_meta_packages_to_install: '$flavor_meta_packages_to_install'${reset}"
         pkg-add-to-install-list "$flavor_meta_package_item"
      done
   fi

   if [ "$install_package_list" = "none" ] || [ "$install_package_list" = "" ] || [ "$install_package_list" = " " ]; then
      true "${cyan}INFO: variable install_package_list (custom additional packages list) is set to '$install_package_list', skipping, ok.${reset}"
   else
      for install_package_item in $install_package_list ; do
         true "${cyan}INFO: install_package_item: '$install_package_item'${reset}"
         pkg-add-to-install-list "$install_package_item"
      done
   fi

   pkg-add-to-install-list "$meta_package_firmware"

   pkg-list-install

   ## repository-dist-initializer
   ## requires: variable CHROOT_FOLDER
   repository_dist_initializer_setup

   if echo "${BUILD_INITRAMFS_PKGS}" | grep -q dracut ; then
      ## dracut is automatically run during above package installation through the usual
      ## Debian package triggers might break the boot process. Re-running dracut with
      ## the correct command line parameters is required in order to fix that.

      true "INFO: Undo above 'export INITRD=No' by unsetting the INITRD environment variable. In other words, allow running dracut."
      unset INITRD

      ## Debugging.
      $SUDO_TO_ROOT $CHROOT cat /etc/fstab || true
      $SUDO_TO_ROOT $CHROOT dracut --print-cmdline --fstab || true

      ## For documentation on how to install dracut in a chroot, see:
      ## https://github.com/dracutdevs/dracut/issues/1596

      KERNELIMG="$($SUDO_TO_ROOT $CHROOT ls -1 "/boot/")"
      KERNELIMG="$(echo "$KERNELIMG" | grep "vmlinuz")"

      KERNELIMG="$(echo "$KERNELIMG" | sed -n '1p')"
      ## example KERNELIMG:
      ## vmlinuz-6.1.0-9-amd64

      KERNELVER="${KERNELIMG#vmlinuz-}"
      ## example KERNELVER:
      ## 6.1.0-9-amd64

      ## Add dracut support to grml-debootstrap:
      ## https://github.com/grml/grml-debootstrap/pull/196
      ##
      ## INITRD_GENERATOR_OPTS is set in help-steps/variables.
      $SUDO_TO_ROOT \
         $CHROOT \
            dracut \
               --no-hostonly \
               --kver "$KERNELVER" \
               --force \
               --reproducible \
               --fstab \
               --add-fstab /etc/fstab \
               --verbose \
               $INITRD_GENERATOR_OPTS
   fi

   ## Debugging.
   ## grub-mkconfig does this.
   $SUDO_TO_ROOT $CHROOT grub-probe --target=device / || true
   ## Sometimes this outputs:
   ## /dev/mapper/loop0p2
   ## Which results in:
   ## GRUB_DEVICE=/dev/mapper/loop0p2
   ## which results in:
   ## root=/dev/mapper/loop0p2
   ## which then results in an unbootable system.
   $SUDO_TO_ROOT $CHROOT grub-probe --target=device /boot || true

   ## TODO: comment in
   #$SUDO_TO_ROOT $CHROOT update-grub

   ## TODO: comment out
   ## Debugging.
   ## update-grub is a wrapper that essentially runs:
   ## grub-mkconfig -o /boot/grub/grub.cfg
   ## Run grub-mkconfig with sh xtrace enabled for debug output.
   ## Full path to /usr/sbin/grub-mkconfig required because using sh -xv.
   $SUDO_TO_ROOT $CHROOT sh -xv /usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg
   ## TODO: enable verbose output during execution of /etc/grub.d/10_linux somehow.
   ##       It is being executed by grub-mkconfig. Needed to investigate where the
   ##       root=/dev/mapper issue is coming from

   ## Debugging.
   true "/boot/grub/grub.cfg root= :"
   $SUDO_TO_ROOT $CHROOT cat /boot/grub/grub.cfg | grep --color "root=" || true

   ## Sanity test.
   if $SUDO_TO_ROOT $CHROOT cat /boot/grub/grub.cfg | grep --quiet "root=/dev/mapper" ; then
      ## If an issue in the future, the following code from grml-debootstrap could be adjusted for derivative-maker.
      ## XXX: TARGET_UUID=todo
      #$SUDO_TO_ROOT sed -i "s;root=[^ ]\\+;root=UUID=$TARGET_UUID;" /boot/grub/grub.cfg
      error "chroot /boot/grub/grub.cfg contains root=/dev/mapper - image most likely unbootable!"
   fi

   "$dist_source_help_steps_folder/remove-local-temp-apt-repo" "$@"
   "$dist_source_help_steps_folder/unprevent-daemons-from-starting" "$@"

   ## Forget about local repository containing derivative packages.
   #$SUDO_TO_ROOT $CHROOT apt-get-noninteractive --no-download --list-cleanup update

   $SUDO_TO_ROOT $CHROOT sync
   sync

   "$dist_source_help_steps_folder/unchroot-raw" "$@"
   "$dist_source_help_steps_folder/unmount-raw" "$@"

   sync
}

main() {
   if [ "$build_dry_run" = "true" ]; then
      true "${bold}${cyan}INFO: dry-run, skipping $BASH_SOURCE. ${reset}"
      return 0
   fi

   if [ "$dist_build_iso" = "true" ]; then
       true "${green}INFO: Skipping $BASH_SOURCE, because dist_build_iso is set to true.${reset}"
       return 0
   fi

   if [ "$dist_build_flavor" = "whonix-custom-workstation" ]; then
      true "${cyan}INFO: Skipping installing packages for $VMNAME.${reset}"
   else
      install-packages "$@"
   fi
}

main "$@"
