#!/bin/bash
#
# Copyright (C) 2007-2009 Eric Shubert <ejs@shubes.net>
#
# Mount a sandbox for using fuse-unionfs overlay file system
#
#   *** Dependencies ***
#   Sub scripts:
#     .) qtp-config
# 
###############################################################################
# change log
# 10/03/09 shubes - added dkms-fuse package for COS5
# 08/14/09 shubes - modified for single overlay (FUSE) unionfs filesystem
# 10/07/08 shubes - added mkdir for /sys to eliminate error message from rpm
# 10/03/08 shubes - removed proc and sys from directories, create proc though
#                   proc is mounted by qtp-build-rpms, once inside of chroot
# 09/29/08 shubes - added lib64 to directories for x86_64 machines
# 03/22/07 shubes - created
#                   thanks to Justice London <jlondon@lawinfo.com>
#                   for pioneering unionfs usage with qtp-newmodel!
###############################################################################
###############################################################################
## check and set up the environment
#

a1_initialization(){

# Make sure we're root
if [ "$UID" != "0" ]; then
  echo "$me: Error: You are not root, please su -"
  exit 1
fi

echo "$me $myver"

. qtp-config -s
. qtp-whatami -s

mtab_entry=$(grep "^$OVERLAY" /etc/mtab)

if [ $? == "0" ]; then
  echo "$me: sandbox already mounted"
  exit 0
fi

SBFILE="$SANDBOX/boot/.${SANDBOX##*/}"
FSTYPE=U
}

###############################################################################
## install dependent packages if they're not already installed
#
a2_check_dependencies(){

pkglist=""
rpmforge=""
dep_pkgs="fuse-unionfs"

case "$DISTRO" in
  "CentOS" )
#   FC10+ doesn't need this. COS6 might not either. Depends on kernel version.
#   COS4 and COS5 do need them.
#   if [ "${OSVER%.*}" == "4" ]; then
      dep_pkgs="dkms-fuse $dep_pkgs"
      rpmforge="--enablerepo=rpmforge"
#   fi
    ;;
esac

for pkg in $dep_pkgs; do
  rpm --query $pkg >/dev/null 2>&1
  if [ $? != "0" ]; then
    pkglist="$pkglist $pkg"
  fi
done

if [ ! -z "$pkglist" ]; then
  echo "$me - installing $pkglist ..."
  echo "$me - this could take a few moments - please be patient "
  yum --enablerepo=qtp-$DISTRO $rpmforge -y install $pkglist
  rc=$?
  if [ "$rc" != "0" ]; then
    echo "$me - installation of dependent packages failed"
    echo "$me - is your qmailtoaster-plus.repo package up to date?"
    exit $rc
  fi
else
  echo "$me - updating dependencies ..."
  yum --enablerepo=qtp-$DISTRO $rpmforge -y update $dep_pkgs
fi

mount_pgm=$(which unionfs 2>/dev/null)
if [ -z "$mount_pgm" ]; then
  echo "$me - unionfs program not found, please notify support"
  exit 1
fi
}

###############################################################################
## check to see if the $SANDBOX variable's value is safe to use
#
a3_check_valid_sandbox(){

if [ -d "$SANDBOX" ]; then
  if [ ! -f "$SBFILE" ]; then
    echo "$SANDBOX exists, but apparently is not a sandbox"
    echo "Please use a different value for SANDBOX or remove what's there,"
    echo "then try again."
    exit 1
  else
    SBTYPE=$(cat $SBFILE)
    if [ "$SBTYPE" != "$FSTYPE" ]; then
      echo "$SANDBOX exists, but is the wrong type ($SBTYPE) for this kernel"
      echo "Please rerun, and answer 'y' when asked to build a new sandbox"
      exit 1
    fi
  fi
fi

mkdir -p $SANDBOX/proc
mkdir -p $OVERLAY/proc
mkdir -p $SANDBOX/sys
mkdir -p $OVERLAY/sys
}

###############################################################################
## load fuse module into the running kernel if necessary
#
a4_load_module(){

branch=tmp
mkdir -p $SANDBOX/$branch
mkdir -p $OVERLAY/$branch
$mount_pgm -o cow,nonempty,suid,dev \
           -o fsname=$OVERLAY/$branch \
           $OVERLAY/$branch=rw:/$branch=ro \
           $SANDBOX/$branch \
           2>&1 | grep "try 'modprobe fuse' first"

if [ $? == "0" ]; then
  modprobe fuse
else
  umount $SANDBOX/$branch
fi
}

###############################################################################
## mount the sandbox
#
a5_mount_sandbox(){

# We need to do this to make the underlying mountpoints
# invisible to the chroot'ed filesystem.
# Leaving the unioned fs visible screws with RPM's
cp -p /etc/mtab /tmp/mtab.old

#List of directories necessary for sandbox root
branches="bin boot dev etc home lib lib64 opt/qmailtoaster-plus root sbin tmp usr var"

for branch in $branches; do
  b55_mount_each_branch
done

b57_mount_tmpfs_workarounds

# We're done mounting all of the directories.
# Now we'll move our saved mtab to the sandbox
mv /tmp/mtab.old $SANDBOX/etc/mtab

# write a file that the scripts will look for to see if this is a valid sandbox
echo "$FSTYPE" > $SBFILE
}

###############################################################################
## create/mount each branch of the sandbox
#
# The $SBFILE is created so that qtp-build-rpms can tell
# if it's running in the sandbox or not,
# and so we can tell if a directory is a sandbox or a 'real' one
# so we don't go deleting something important.
#
b55_mount_each_branch(){

mkdir -p $SANDBOX/$branch
mkdir -p $OVERLAY/$branch

# we need to create the SBFILE here too so that the sandbox is recognized
# in the event that it's not mounted

if [ "$branch" == "boot" ]; then
  echo "$FSTYPE" > $SBFILE
fi

if [ -d "/$branch" ]; then
  $mount_pgm -o cow,nonempty,suid,dev \
             -o fsname=$OVERLAY/$branch \
             $OVERLAY/$branch=rw:/$branch=ro \
             $SANDBOX/$branch
fi
}

###############################################################################
## Mount a tmpfs with the contents of /var/lib/rpm to work around a bug
## with older version of fuse+mmap-writes.

b57_mount_tmpfs_workarounds(){

# Mount the tmpfs. Note the 'var' as the mtab name,
# as var/lib/rpmo would require changes to umount script.
mount -t tmpfs $OVERLAY/var $SANDBOX/var/lib/rpm
#Copy over rpm-lib content
cp /var/lib/rpm/* $SANDBOX/var/lib/rpm	

# Mount /var/tmp into tmpfs so %{buildroot} can use mkfifo successfully.
# This appeared to work at first, but then bombed later on.
# fixed this problem by changing the qmail-toaster.spec file to not create
# the named pipe in the sandbox.
#mount -t tmpfs $OVERLAY/var $SANDBOX/var/tmp
}

###############################################################################
## main script execution begins here
#

me=${0##*/}
myver=v0.3.3

if [ ! -z "$1" ]; then
  case $1 in
    -b )
      background=$1
      ;;
    * )
      echo "$me usage: $me [-b]"
      exit 1
      ;;
  esac
fi

a1_initialization
a2_check_dependencies
a3_check_valid_sandbox
a4_load_module
a5_mount_sandbox

mtab_entry=$(grep "^$OVERLAY" /etc/mtab)

if [ $? != "0" ]; then
  echo "$me: sandbox was not mounted successfully"
  exit 1
fi

echo "$me: sandbox mounted successfully"
exit 0
