#!/bin/bash
# Filename:      ${GRML_FAI_CONFIG}/scripts/GRMLBASE/98-clean-chroot
# Purpose:       clean up chroot system
# Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
# Bug-Reports:   see http://grml.org/bugs/
# License:       This file is licensed under the GPL v2.
################################################################################

set -u
set -e

# FAI sets $target, but shellcheck does not know that.
target=${target:?}

if ! ls "$target"/boot/config-* &>/dev/null ; then
  echo "No kernel config files (/boot/config-*) found. No kernel-image package installed?" >&2
  exit 1
fi

echo "Installing files into /etc/skel"
fcopy -M -i -B -v -r /etc/skel

# deliver files which need to be executable as such.
for file in /etc/skel/.xinitrc /etc/skel/.xsession /etc/skel/.xinitrc.d ; do
  if [ -e "${target}/${file}" ] ; then
    $ROOTCMD chmod -R a+rx "${file}"
  fi
done

echo "Creating ~/.zshrc"
touch "$target"/root/.zshrc

$ROOTCMD rm -f /etc/apt/apt.conf.d/90grml-apt-proxy.conf

if [ -x "$target"/usr/sbin/localepurge ] ; then
  echo "Running localepurge"
  $ROOTCMD localepurge
else
  echo "Warning: localepurge not installed"
fi

# revert dpkg-divert of hooks/instsoft.GRMLBASE, which is
# used to work around /etc/kernel/postinst.d/zz-update-grub failing
# inside openvz environment, see #597084
if [ '/usr/sbin/update-grub' != "$($ROOTCMD dpkg-divert --truename '/usr/sbin/update-grub')" ]; then
  echo "Undoing dpkg-divert of update-grub executable"
  $ROOTCMD rm -f /usr/sbin/update-grub
  $ROOTCMD dpkg-divert --rename --remove /usr/sbin/update-grub
fi

# revert dpkg-divert of hooks/instsoft.GRMLBASE, which is
# used to work around a grub-probe<->openvz bug
if [ '/usr/sbin/grub-probe' != "$($ROOTCMD dpkg-divert --truename '/usr/sbin/grub-probe')" ]; then
  echo "Undoing dpkg-divert of grub-probe executable"
  $ROOTCMD rm -f /usr/sbin/grub-probe
  $ROOTCMD dpkg-divert --rename --remove /usr/sbin/grub-probe
fi

# revert udev workaround of hooks/updatebase.GRMLBASE
if grep -q 'updatebase.GRMLBASE' "$target"/etc/udev/kernel-upgrade 2>/dev/null ; then
  echo "Removing /etc/udev/kernel-upgrade created by updatebase.GRMLBASE"
  $ROOTCMD rm -f /etc/udev/kernel-upgrade
fi

echo "Cleaning apt places"
$ROOTCMD apt-get check 2>/dev/null
$ROOTCMD dpkg --clear-avail
$ROOTCMD apt-cache gencaches 2>/dev/null
$ROOTCMD apt-get clean

rm -f "$target"/var/lib/dpkg/status-old "$target"/var/lib/dpkg/available-old

if ! [ -x "$target"/usr/bin/grep-dctrl ] ; then
  echo "Warning: grep-dctrl not installed"
else
  echo "Cleaning up /var/lib/dpkg/status"
  if $ROOTCMD grep-dctrl -v -F Status "purge ok not-installed" \
    /var/lib/dpkg/status > "$target"/var/lib/dpkg/status.new ; then
    mv "$target"/var/lib/dpkg/status.new "$target"/var/lib/dpkg/status
    chmod 644 "$target"/var/lib/dpkg/status
    chown root:root "$target"/var/lib/dpkg/status
  fi
fi

echo "Removing host ssh-keys"
rm -f "$target"/etc/ssh/*key*

echo "Removing dbus machine-id"
rm -f "$target"/var/lib/dbus/machine-id

if [ -d "$target"/var/spool/squid/ ] ; then
  echo "Cleaning /var/spool/squid/0*"
  rm -rf "$target"/var/spool/squid/0*
fi

echo "Cleaning and removing some misc files and directories"
rm -rf --one-file-system "$target"/etc/sysconfig/* \
       "$target"/etc/motd.dpkg-* "$target"/etc/auto.master.*dpkg* \
       "$target"/etc/samba/*.SID "$target"/etc/samba/*.tdb \
       "$target"/var/log/ksymoops/* \
       "$target"/var/state/* "$target"/var/log/nessus/* \
       "$target"/halt "$target"/reboot "$target"/ash.static \
       "$target"/etc/dhcpc/*.info "$target"/etc/dhcpc/resolv* \
       "$target"/etc/*passwd- "$target"/etc/*shadow- \
       "$target"/etc/*group- \
       "$target"/etc/*.old "$target"/etc/*.original \
       "$target"/etc/lvm/.cache "$target"/etc/lvm/cache/.cache \
       "$target"/etc/lvm/backup/* "$target"/tmp/* \
       "$target"/var/tmp/* "$target"/var/backups/* \
       "$target"/core* \
       "$target"/etc/blkid.tab

# remove only "temporary" or saved files in the given directories
nuke(){
  find "$@" \( -name "*.gz" -o -name "*.bz2" -o -name "*.xz" -o -name "*.0" \) -delete
}

# set all files in the given directories to a length of zero
zero(){
  find "$@" -type f -size +0 -not -name \*.ini -print0 2>/dev/null | \
  while IFS= read -r -d '' file ; do
    :> "$file"
  done
}

echo "Removing possible leftovers from update-pciids runs"
rm -f "${target}"/wget-log*

echo "Cleaning log and cache directories"
nuke "$target"/var/log       "$target"/var/cache
zero "$target"/var/account/pacct \
     "$target"/var/cache/man \
     "$target"/var/lib/games \
     "$target"/var/lib/nfs   \
     "$target"/var/lib/xkb   \
     "$target"/var/local     \
     "$target"/var/log       \
     "$target"/var/mail/grml

echo "Updating ca-certificates"
$ROOTCMD update-ca-certificates

# regenerate ls.so.cache
if ! [ -x "$target"/sbin/ldconfig ] ; then
  echo "Warning: ldconfig not installed"
else
  echo "Updating ld.so.cache"
  $ROOTCMD ldconfig
fi

if ! [ -x "$target"/usr/bin/update-menus ] ; then
  echo "Warning: update-menus not installed"
else
  echo "Updating windowmanager menus"
  $ROOTCMD update-menus -v
fi

if ! [ -x "$target"/usr/bin/mandb ] ; then
  echo "Warning: mandb not installed"
else
  echo "Updating mandb"
  $ROOTCMD mandb -c
  $ROOTCMD man doesnotexist >/dev/null 2>&1 || true
fi

if ! [ -r "$target"/etc/ld.so.nohwcap ] ; then
   echo "Creating /etc/ld.so.nohwcap"
   touch "$target"/etc/ld.so.nohwcap
fi

if ! [ -d "$target"/etc/resolvconf ] ; then
  echo "Warning: resolvconf not installed"
else
  echo "Setting up resolvconf"
  rm -f "$target"/etc/resolvconf/resolv.conf.d/original
  rm -f "$target"/etc/resolv.conf
  ln -s /run/resolvconf/resolv.conf "$target"/etc/resolv.conf
fi

# make sure we don't leak any mdadm configurations
# that are present on the build system to the live system
if [ -f "$target/etc/mdadm/mdadm.conf" ] ; then
  echo "Found /etc/mdadm/mdadm.conf, getting rid of any possible enabled ARRAY settings."
  sed -i '/^ARRAY/d' "$target"/etc/mdadm/mdadm.conf
fi

if ! $ROOTCMD test -x /usr/bin/updatedb ; then
  echo "Warning: updatedb not installed (install plocate?)"
else
  echo "Updating locate-database"

  if ! [ -x "$target"/usr/bin/plocate ] ; then
    echo "* Detected old locate implementation, directly invoking updatedb"
    $ROOTCMD updatedb --prunepaths='/tmp /usr/tmp /var/tmp /grml /root /proc /sys'
  else
    echo "* Detected plocate implementation, invoking its /etc/cron.daily/plocate"

    # we need /proc, otherwise updatedb of plocate fails
    # hard with `linkat: No such file or directory`
    MOUNTED_PROC=0
    if $ROOTCMD mount -t proc proc /proc ; then
      # The mount call typically fails within restricted build contexts
      # like podman/docker etc. If this happens, plocate just won't work.
      MOUNTED_PROC=1
    fi

    # plocate has sane defaults in /etc/updatedb.conf and
    # its cronob does the right thing for our needs
    $ROOTCMD /etc/cron.daily/plocate

    if [ "$MOUNTED_PROC" = 1 ] ; then
      $ROOTCMD umount /proc
    fi
  fi
fi

if [ -r "$target"/etc/machine-id ] ; then
  echo "Removing /etc/machine-id generated by systemd"
  rm -f "$target"/etc/machine-id
fi

## END OF FILE #################################################################
# vim:ft=sh expandtab ai tw=80 tabstop=4 shiftwidth=2
