#!/bin/sh
# $UFP$
#set -x

# Specify where to place the typescripts.
TYPESCRIPT_DIR="/root/tmp"

# Specify the ZFS filesystems where synth's files go.
SYNTH_BASE_FS="zroot/var/synth"
SYNTH_SYSTEMS_FS="${SYNTH_BASE_FS}/systems"

# Specify the mountpoints where synth's files go.
SYNTH_BASE_MOUNTPOINT="/var/synth"
SYNTH_SYSTEMS_MOUNTPOINT="${SYNTH_BASE_MOUNTPOINT}/systems"

# Determine which svn executable to run.
SVN_CANDIDATES="/usr/local/bin/svn /usr/bin/svn /usr/bin/svnlite"

for cand in ${SVN_CANDIDATES}; do
  if [ -x ${cand} ]; then
    SVN=${cand}
    break
  fi
done

if [ -z "${SVN}" ]; then
  echo "${0}: neither of ${SVN_CANDIDATES} are useable" >/dev/stderr
  exit 69
fi

# Ensure / is of type ZFS.
if [ -z "`/bin/df -Tt zfs /`" ]; then
  echo $0: root filesystem must be of type ZFS >/dev/stderr
  exit 69
fi

# Ensure /usr/src is mounted, be it NFS or local fs.
if [ ! -f /usr/src/Makefile ]; then
  /sbin/mount /usr/src

  if [ ! -f /usr/src/Makefile ]; then
    echo $0: unable to mount /usr/src >/dev/stderr
    exit 69
  fi
fi

# Ensure /usr/obj is mounted, be it NFS or local fs.
if [ ! -d /usr/obj/usr ]; then
  /sbin/mount /usr/obj

  if [ ! -d /usr/obj/usr ]; then
    echo $0: unable to mount /usr/obj >/dev/stderr
    exit 69
  fi
fi

# What's the running architecture?
MACHINE=`uname -m`

if [ -z "${MACHINE}" ]; then
  echo "$0: zero length MACHINE" >/dev/stderr
  exit 69
fi

MACHINE_ARCH=`uname -p`

if [ -z "${MACHINE_ARCH}" ]; then
  echo "$0: zero length MACHINE_ARCH" >/dev/stderr
  exit 69
fi

if [ "${MACHINE}" = "${MACHINE_ARCH}" ]; then
  ARCH="${MACHINE_ARCH}"
else
  ARCH="${MACHINE}-${MACHINE_ARCH}"
fi

if [ -z "${ARCH}" ]; then
  echo "$0: zero length ARCH" >/dev/stderr
  exit 69
fi

# What's the branch?
BRANCH=`svn info --show-item url /usr/src | sed 's|^svn.*/base/||' | sed 's|/|-|g'`

if [ -z "${BRANCH}" ]; then
  echo "$0: zero length BRANCH" >/dev/stderr
  exit 69
fi

# What's the global revision number?
SVN_REVISION=`${SVN} info --show-item revision /usr/src`

if [ -z "${SVN_REVISION}" ]; then
  echo "$0: zero length SVN_REVISION" >/dev/stderr
  exit 69
fi

# Construct the name of the new synth system snapshot.
SYSTEM_SNAPSHOT_NAME="${BRANCH}-${ARCH}-r${SVN_REVISION}"

# Construct the full name of the new synth system snapshot.
SYSTEM_SNAPSHOT="${SYNTH_SYSTEMS_FS}/${SYSTEM_SNAPSHOT_NAME}"

# Where to install the new synth system snapshot.
DESTDIR="${SYNTH_SYSTEMS_MOUNTPOINT}/${SYSTEM_SNAPSHOT_NAME}"

# Run pre-flight checks. This is an interactive step.
/usr/sbin/mergemaster -Fp || exit

# Create the new synth system snapshot.
/sbin/zfs create ${SYSTEM_SNAPSHOT} || exit

# Ensure we have somewhere to place the typescripts.
if [ ! -d ${TYPESCRIPT_DIR} ]; then
  /bin/mkdir -p ${TYPESCRIPT_DIR}

  if [ ! -d ${TYPESCRIPT_DIR} ]; then
    echo $0: unable to create ${TYPESCRIPT_DIR} >/dev/stderr
    exit 69
  fi
fi

# Install a new world into the new synth system snapshot.
/usr/bin/script -at 0 ${TYPESCRIPT_DIR}/synth-system-snapshot-${SYSTEM_SNAPSHOT_NAME}.txt /usr/bin/make -C /usr/src -j `/sbin/sysctl -n hw.ncpu` DESTDIR=${DESTDIR} installworld || exit

# Create /boot/opt in the new synth system snapshot.
/bin/mkdir -p ${DESTDIR}/boot/opt || exit

# Copy the source tree.
echo $0: copying /usr/src to ${DESTDIR}/usr/src
/bin/cp -Rp /usr/src ${DESTDIR}/usr || exit

# Set the readonly property.
/sbin/zfs set readonly=on ${SYSTEM_SNAPSHOT} || exit

# Unmount the NFS mounted filesystems if needed.
if [ "`/bin/df -T /usr/src | /usr/bin/tail -1 | /usr/bin/awk '{print $2}'`" = "nfs" ]; then
  /sbin/umount /usr/src || exit
fi
if [ "`/bin/df -T /usr/obj | /usr/bin/tail -1 | /usr/bin/awk '{print $2}'`" = "nfs" ]; then
  /sbin/umount /usr/obj || exit
fi

# Ready to use the new synth system snapshot.
echo $0: ready to use ${DESTDIR} as a new synth system snapshot

# EOF
