#!/bin/sh # # server-side script to setup the portbuild ZFS volume, delegate its # administration, and check out the repository. Must be run as root. # # Designed to be run before anything else. # DEFAULT_PORTBUILD_USER="portbuild" DEFAULT_SRCBUILD_USER="srcbuild" DEFAULT_VCS_CHECKOUT_COMMAND="svn checkout" DEFAULT_VCS_REPOSITORY="svn://svn.FreeBSD.org" DEFAULT_ZFS_VOLUME="a" DEFAULT_ZFS_MOUNTPOINT="/a" DEFAULT_ZFS_PERMISSIONSET="clone,create,destroy,mount,promote,rename,rollback,send,share,snapshot" DEFAULT_ZFS_PERMISSIONSET_SNAPS="clone,snapshot" SNAP_DIRECTORY=snap # define ownership of subdirectories of DEFAULT_ZFS_VOLUME/ SRCBUILD_OWNED_SUBDIRS="pxeroot ${SNAP_DIRECTORY} worlddir" PORTBUILD_OWNED_SUBDIRS="portbuild" # define ownership of subdirectories of DEFAULT_ZFS_VOLUME/portbuild/ SRCBUILD_OWNED_VCS_SUBDIRS="admin docs" PORTBUILD_OWNED_VCS_SUBDIRS="conf errorlogs qmanager scripts sources tools" SRCBUILD_OWNED_CONVENIENCE_SUBDIRS="lockfiles log" PORTBUILD_OWNED_CONVENIENCE_SUBDIRS="lockfiles log" if [ `id -u` != 0 ]; then echo "$0 must be run as root." exit 1 fi if [ -z "${PORTBUILD_USER}" ]; then echo "You must export PORTBUILD_USER, for example, export PORTBUILD_USER=${DEFAULT_PORTBUILD_USER}." exit 1 fi if [ ! `id -u ${PORTBUILD_USER} 2> /dev/null` ]; then echo "User ${PORTBUILD_USER} must exist." exit 1 fi if [ -z "${SRCBUILD_USER}" ]; then echo "You must export SRCBUILD_USER, for example, export SRCBUILD_USER=${DEFAULT_SRCBUILD_USER}." exit 1 fi if [ ! `id -u ${SRCBUILD_USER} 2> /dev/null` ]; then echo "User ${SRCBUILD_USER} must exist." exit 1 fi if [ -z "${ZFS_MOUNTPOINT}" ]; then echo "You must export ZFS_MOUNTPOINT, for example, export ZFS_MOUNTPOINT=${DEFAULT_ZFS_MOUNTPOINT}." exit 1 fi if [ -z "${VCS_CHECKOUT_COMMAND}" ]; then VCS_CHECKOUT_COMMAND="${DEFAULT_VCS_CHECKOUT_COMMAND}" fi if [ -z "${VCS_PORTBUILD_REPOSITORY}" ]; then echo "You have not set VCS_PORTBUILD_REPOSITORY. I will try to set it from VCS_REPOSITORY." if [ -z "${VCS_REPOSITORY}" ]; then echo "You have not set VCS_REPOSITORY. I will use the default: ${DEFAULT_VCS_REPOSITORY}." VCS_REPOSITORY=${DEFAULT_VCS_REPOSITORY} fi VCS_PORTBUILD_REPOSITORY="${VCS_REPOSITORY}/base/projects/portbuild" fi if [ -z "${ZFS_VOLUME}" ]; then echo "You must export ZFS_VOLUME, for example, export ZFS_VOLUME=${DEFAULT_ZFS_VOLUME}." exit 1 fi if [ -z "${ZFS_PERMISSIONSET}" ]; then echo "You have not set ZFS_PERMISSIONSET. I will use the default: ${DEFAULT_ZFS_PERMISSIONSET}." ZFS_PERMISSIONSET="${DEFAULT_ZFS_PERMISSIONSET}" fi if [ -z "${ZFS_PERMISSIONSET_SNAPS}" ]; then echo "You have not set ZFS_PERMISSIONSET_SNAPS. I will use the default: ${DEFAULT_ZFS_PERMISSIONSET_SNAPS}." ZFS_PERMISSIONSET_SNAPS="${DEFAULT_ZFS_PERMISSIONSET_SNAPS}" fi # sprinkle magic fairy dust to help delegate zfs permissions sysctl vfs.usermount=1 sysctl vfs.zfs.super_owner=1 name=`zfs list -H -t filesystem -o name ${ZFS_VOLUME}` if [ -z "${name}" ]; then echo "ZFS volume ${ZFS_VOLUME} does not exist. You must create it first." exit 1 fi mounted=`zfs list -H -t filesystem -o mounted ${ZFS_VOLUME}` if [ ! -z "${mounted}" -a "${mounted}" != "no" ]; then echo "ZFS volume ${ZFS_VOLUME} is mounted. I'll unmount it for you then remount it later." zfs umount ${ZFS_VOLUME} 2> /dev/null fi # create subdirectories for portbuild-managed files. All other ZFS_VOLUME # subdirectories are managed by srcbuild. for subdir in ${PORTBUILD_OWNED_SUBDIRS}; do name=`zfs list -H -t filesystem -o name ${ZFS_VOLUME}/${subdir}` if [ -z "${name}" ]; then echo "ZFS volume ${ZFS_VOLUME}/${subdir} does not exist. I'll create it for you." zfs create ${ZFS_VOLUME}/${subdir} || exit 1 fi done # create subdirectories for srcbuild-managed files. for subdir in ${SRCBUILD_OWNED_SUBDIRS}; do name=`zfs list -H -t filesystem -o name ${ZFS_VOLUME}/${subdir}` if [ -z "${name}" ]; then echo "ZFS volume ${ZFS_VOLUME}/${subdir} does not exist. I'll create it for you." zfs create ${ZFS_VOLUME}/${subdir} || exit 1 fi done # reset the "zfsalladmin" permission set if it already exists. zfs unallow -s @zfsalladmin ${ZFS_VOLUME} 2> /dev/null zfs unallow -u ${SRCBUILD_USER} ${ZFS_VOLUME} 2> /dev/null # reset the "zfsportbuildadmin" permission set if it already exists. zfs unallow -s @zfsportbuildadmin ${ZFS_VOLUME} 2> /dev/null # reset the "zfssnapadmin" permission set if it already exists. zfs unallow -s @zfssnapadmin ${ZFS_VOLUME} 2> /dev/null zfs unallow -u ${PORTBUILD_USER} ${ZFS_VOLUME} 2> /dev/null # create the "zfsalladmin" permission set. zfs allow -s @zfsalladmin ${ZFS_PERMISSIONSET} ${ZFS_VOLUME} || exit 1 # create the "zfsportbuildadmin" permission set. zfs allow -s @zfsportbuildadmin ${ZFS_PERMISSIONSET} ${ZFS_VOLUME}/portbuild || exit 1 # create the "zfssnapadmin" permission set. zfs allow -s @zfssnapadmin ${ZFS_PERMISSIONSET_SNAPS} ${ZFS_VOLUME}/${SNAP_DIRECTORY} || exit 1 # delegate the "zfsalladmin" permission set to the SRCBUILD_USER. zfs allow -du ${SRCBUILD_USER} @zfsalladmin ${ZFS_VOLUME} || exit 1 zfs allow -lu ${SRCBUILD_USER} @zfsalladmin ${ZFS_VOLUME} || exit 1 # after (possibly) modifying permissions, now it's permissable to remount. mounted=`zfs list -H -t filesystem -o mounted ${ZFS_VOLUME}` if [ -z "${mounted}" -o "${mounted}" = "no" ]; then echo "ZFS volume ${ZFS_VOLUME} is not mounted. I'll remount it for you." zfs mount ${ZFS_VOLUME} || exit 1 fi chown ${SRCBUILD_USER} ${ZFS_MOUNTPOINT} 2> /dev/null # delegate the "zfsportbuildadmin" permission set to the PORTBUILD_USER. zfs allow -du ${PORTBUILD_USER} @zfsportbuildadmin ${ZFS_VOLUME}/portbuild || exit 1 zfs allow -lu ${PORTBUILD_USER} @zfsportbuildadmin ${ZFS_VOLUME}/portbuild || exit 1 # delegate the "zfssnapadmin" permission set to the PORTBUILD_USER. zfs allow -du ${PORTBUILD_USER} @zfssnapadmin ${ZFS_VOLUME}/${SNAP_DIRECTORY} || exit 1 zfs allow -lu ${PORTBUILD_USER} @zfssnapadmin ${ZFS_VOLUME}/${SNAP_DIRECTORY} || exit 1 # (re)mount various subdirectories to be managed by portbuild. for subdir in ${PORTBUILD_OWNED_SUBDIRS}; do mounted=`zfs list -H -t filesystem -o mounted ${ZFS_VOLUME}/${subdir}` if [ -z "${mounted}" -o "${mounted}" = "no" ]; then echo "ZFS volume ${ZFS_VOLUME}/${subdir} is not mounted. I'll (re)mount it for you." zfs mount ${ZFS_VOLUME}/${subdir} || exit 1 fi chown ${PORTBUILD_USER} ${ZFS_MOUNTPOINT}/${subdir} 2> /dev/null done # (re)mount various subdirectories to be managed by srcbuild. for subdir in ${SRCBUILD_OWNED_SUBDIRS}; do mounted=`zfs list -H -t filesystem -o mounted ${ZFS_VOLUME}/${subdir}` if [ -z "${mounted}" -o "${mounted}" = "no" ]; then echo "ZFS volume ${ZFS_VOLUME}/${subdir} is not mounted. I'll (re)mount it for you." zfs mount ${ZFS_VOLUME}/${subdir} || exit 1 fi chown ${SRCBUILD_USER} ${ZFS_MOUNTPOINT}/${subdir} 2> /dev/null done echo "results of ZFS operations:" zfs list ${ZFS_VOLUME} zfs allow ${ZFS_VOLUME} # perform the repository magic to allow SRCBUILD_USER to edit everything, # but PORTBUILD_USER to only edit files under its own responsibility. chown ${SRCBUILD_USER}:${PORTBUILD_USER} ${ZFS_MOUNTPOINT}/portbuild chmod 775 ${ZFS_MOUNTPOINT}/portbuild for subdir in ${PORTBUILD_OWNED_VCS_SUBDIRS}; do echo "checking out the ${subdir} repository as user ${PORTBUILD_USER} ..." if [ ! -d ${ZFS_MOUNTPOINT}/portbuild/${subdir} ]; then mkdir ${ZFS_MOUNTPOINT}/portbuild/${subdir} 2> /dev/null || exit 1 fi chown ${PORTBUILD_USER}:${PORTBUILD_USER} ${ZFS_MOUNTPOINT}/portbuild/${subdir} chmod 755 ${ZFS_MOUNTPOINT}/portbuild/${subdir} echo "su -m ${PORTBUILD_USER} -c \"svn checkout ${VCS_REPOSITORY}/base/projects/portbuild/${subdir} ${ZFS_MOUNTPOINT}/portbuild/${subdir}\"" su -m ${PORTBUILD_USER} -c "svn checkout ${VCS_REPOSITORY}/base/projects/portbuild/${subdir} ${ZFS_MOUNTPOINT}/portbuild/${subdir}" done for subdir in ${SRCBUILD_OWNED_VCS_SUBDIRS}; do echo "checking out the ${subdir} repository as user ${SRCBUILD_USER} ..." if [ ! -d ${ZFS_MOUNTPOINT}/portbuild/${subdir} ]; then mkdir ${ZFS_MOUNTPOINT}/portbuild/${subdir} 2> /dev/null || exit 1 fi chown ${SRCBUILD_USER}:${SRCBUILD_USER} ${ZFS_MOUNTPOINT}/portbuild/${subdir} chmod 755 ${ZFS_MOUNTPOINT}/portbuild/${subdir} echo "su -m ${SRCBUILD_USER} -c \"svn checkout ${VCS_REPOSITORY}/base/projects/portbuild/${subdir} ${ZFS_MOUNTPOINT}/portbuild/${subdir}\"" su -m ${SRCBUILD_USER} -c "svn checkout ${VCS_REPOSITORY}/base/projects/portbuild/${subdir} ${ZFS_MOUNTPOINT}/portbuild/${subdir}" done echo "$0: you should now be able to edit files in the following directories:" echo "$0: in ${ZFS_MOUNTPOINT}/portbuild/admin/conf as ${SRCBUILD_USER}, and" echo "$0: in ${ZFS_MOUNTPOINT}/portbuild/conf as ${PORTBUILD_USER}." # create convenience directories for PORTBUILD_USER. failure is annoying # but non-fatal. for extra_dir in ${PORTBUILD_OWNED_CONVENIENCE_SUBDIRS}; do if [ ! -d ${ZFS_MOUNTPOINT}/portbuild/${extra_dir} ]; then su -m ${PORTBUILD_USER} -c "mkdir ${ZFS_MOUNTPOINT}/portbuild/${extra_dir}" 2> /dev/null || exit 1 fi chgrp ${PORTBUILD_USER} ${ZFS_MOUNTPOINT}/portbuild/${extra_dir} 2> /dev/null done # create convenience directories for SRCBUILD_USER. for extra_dir in ${SRCBUILD_OWNED_CONVENIENCE_SUBDIRS}; do if [ ! -d ${ZFS_MOUNTPOINT}/portbuild/admin/${extra_dir} ]; then su -m ${SRCBUILD_USER} -c "mkdir ${ZFS_MOUNTPOINT}/portbuild/admin/${extra_dir}" 2> /dev/null || exit 1 fi chgrp ${SRCBUILD_USER} ${ZFS_MOUNTPOINT}/portbuild/${extra_dir} 2> /dev/null done echo "$0: done."