pkgsrc/mk/bulk/mksandbox

391 lines
9.8 KiB
Bash
Executable file

#! /bin/sh
# $NetBSD: mksandbox,v 1.52 2009/09/20 10:24:00 wiz Exp $
#
#
# Copyright (c) 2002 Alistair G. Crooks. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Alistair G. Crooks
# for the NetBSD project.
# 4. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Usage: mksandbox [--pkgsrc=dir] [--src=srcdir] [--xsrc=xsrcdir] [--without-x] [--verbose] sandbox-dir
#
# A small shell script to set up a sandbox (usually for a pkgsrc bulk
# build), using null mounts.
pkgsrc=/usr/pkgsrc
src=/usr/src
xsrc=/usr/xsrc
with_x=yes
kernel=""
sandboxMountDirs="/bin /sbin /lib /libexec /usr/X11R7 /usr/bin /usr/games /usr/include /usr/lib /usr/libdata /usr/libexec /usr/lkm /usr/share /usr/sbin /var/mail"
sandboxEmptyDirs="/var/run /var/log /var/spool/lock /var/spool/mqueue"
sandboxEmptyFiles="/var/run/utmp /var/run/utmpx /var/log/wtmp /var/log/wtmpx /var/log/lastlog /var/log/lastlogx"
usage()
{
echo "Usage: mksandbox [--pkgsrc=dir] [--src=srcdir] [--xsrc=xsrcdir] [--without-x] [--verbose] sandbox-dir"
exit 1
}
err()
{
echo "error: $1"
exit 1
}
# by default, don't require src and xsrc to be available
need_src=no
need_xsrc=no
opsys=`uname -s`
case "$opsys" in
Darwin)
bmakeprog=bmake
chmodprog=/bin/chmod
chownprog=/usr/sbin/chown
cpprog=/bin/cp
gtarprog=/usr/bin/gnutar
idprog=/usr/bin/id
mkdirprog="/bin/mkdir -p"
mountflags="-t null"
mountprog=/sbin/mount
paxprog=/bin/pax
sedprog=/usr/bin/sed
;;
Interix)
echo >&2 "This script cannot be used on Interix; a different procedure is required."
echo >&2 "(To be documented.)"
exit 1
;;
Linux)
bmakeprog=bmake
chmodprog=/bin/chmod
chownprog=/bin/chown
cpprog=/bin/cp
gtarprog=/bin/tar
idprog=/usr/bin/id
mkdirprog="/bin/mkdir -p"
mountflags="--bind"
if [ -f /bin/mount ]; then
mountprog=/bin/mount
else
mountprog=/sbin/mount
fi
paxprog=""
sedprog=/bin/sed
sandboxMountDirs="$sandboxMountDirs /proc /usr/kerberos"
;;
NetBSD)
bmakeprog=make
chmodprog=/bin/chmod
chownprog=/usr/sbin/chown
cpprog=/bin/cp
gtarprog=/usr/bin/tar
idprog=/usr/bin/id
kernel=/netbsd
mkdirprog="/bin/mkdir -p"
mountflags="-t null"
mountprog=/sbin/mount
paxprog=/bin/pax
sedprog=/usr/bin/sed
need_src=yes
need_xsrc=yes
;;
SunOS)
bmakeprog=bmake
chmodprog=/usr/bin/chmod
chownprog=/usr/bin/chown
cpprog=/usr/bin/cp
gtarprog=""
idprog=/usr/xpg4/bin/id
mkdirprog="/usr/bin/mkdir -p"
mountflags="-F lofs"
mountprog=/sbin/mount
paxprog=/bin/pax
sedprog=/usr/xpg4/bin/sed
sandboxMountDirs="/bin /sbin /kernel /lib /proc /opt/SUNWspro /usr/X11R6 /usr/5bin /usr/bin /usr/ccs /usr/dt /usr/games /usr/include /usr/lib /usr/openwin /usr/share /usr/sbin /usr/sadm /usr/ucb /usr/ucblib /usr/xpg4 /var/mail /var/sadm"
sandboxEmptyDirs="$sandboxEmptyDirs /usr/tmp /var/tmp"
;;
*)
echo "Unknown Operating System ($opsys) - good luck"
bmakeprog=bmake
chmodprog=chmod
chownprog=chown
cpprog=cp
gtarprog="tar"
idprog="id"
mkdirprog="mkdir -p"
mountflags="-t null"
mountprog=mount
paxprog=pax
sedprog=sed
;;
esac
while [ $# -gt 0 ]; do
case "$1" in
--pkgsrc=*) pkgsrc=`echo $1 | $sedprog -e 's|^--pkgsrc=||'` ;;
--src=*) src=`echo $1 | $sedprog -e 's|^--src=||'` ;;
--xsrc=*) xsrc=`echo $1 | $sedprog -e 's|^--xsrc=||'` ;;
--without-x) with_x=no ;;
--verbose) set -x ;;
-*) usage ;;
*) break ;;
esac
shift
done
if [ $# -ne 1 ]; then
usage
fi
if [ "$with_x" = "no" ]; then
need_xsrc=no
fi
if [ `$idprog -u` -ne 0 ]; then
err "You must be root to run this script."
fi
if [ ! -d $pkgsrc ]; then
err "pkgsrc directory $pkgsrc does not exist."
fi
if [ ! -d $src -a "$need_src" = "yes" ]; then
err "source directory $src does not exist."
fi
if [ ! -d $xsrc -a "$need_xsrc" = "yes" ]; then
err "xsrc directory $xsrc does not exist."
fi
sandbox=$1
sandbox_script="$sandbox/sandbox"
packages=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=PACKAGES)`
distfiles=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=DISTDIR)`
localbase=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=LOCALBASE)`
pkg_dbdir=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=PKG_DBDIR)`
localpatches=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=LOCALPATCHES)`
test -d "$localpatches" || echo "WARNING: LOCALPATCHES directory does not exist - ignoring"
$mkdirprog $sandbox
cat > $sandbox_script <<EOS
#! /bin/sh -
sandbox=$sandbox
r3() {
_R=
while [ \$# -ge 3 ]
do
_R="\$1 \$2 \$3 \$_R"
shift; shift; shift
done
echo "\$_R"
}
fses="\\
EOS
if [ ! -z "$kernel" ]; then
echo "Copying the kernel"
$cpprog $kernel $sandbox
fi
echo "Checking package hierarchy in $localbase and package database in $pkg_dbdir exist"
$mkdirprog $sandbox/$localbase $sandbox/$pkg_dbdir
echo "Make and populate $sandbox/dev"
$mkdirprog $sandbox/dev
case "$opsys" in
SunOS)
/usr/sbin/devfsadm -r $sandbox
if [ -f /usr/ucblib/ucblinks.awk -a -x /usr/ucb/ucblinks ]; then
/usr/ucb/ucblinks -r $sandbox
fi
;;
Linux)
$cpprog /dev/MAKEDEV* $sandbox/dev
(cd $sandbox/dev; ./MAKEDEV generic random)
;;
FreeBSD)
$mountprog -t devfs devfs $sandbox/dev
;;
*)
$cpprog /dev/MAKEDEV* $sandbox/dev
(cd $sandbox/dev; ./MAKEDEV all)
esac
echo "Make and populate $sandbox/etc"
$mkdirprog $sandbox/etc
case "$paxprog" in
"") (cd /etc; $gtarprog -cf - . | (cd $sandbox/etc; $gtarprog xf - )) ;;
*) (cd /etc; $paxprog -rwpe . $sandbox/etc) ;;
esac
rm -f $sandbox/etc/localtime
case "$opsys" in
SunOS)
$cpprog /etc/TIMEZONE $sandbox/etc/TIMEZONE
;;
*)
$cpprog /usr/share/zoneinfo/GMT $sandbox/etc/localtime
;;
esac
echo "Make empty dirs upon which to mount the null mounts"
for d in $sandboxMountDirs; do
test -d $d || continue;
case $d in
*X11*) test "$with_x" = "yes" || continue ;;
esac
$mkdirprog $sandbox$d;
$mountprog $mountflags -r $d $sandbox$d;
echo "$d $d ro \\" >> $sandbox_script
done
echo "Making /tmp in $sandbox"
$mkdirprog $sandbox/tmp $sandbox/var/tmp
$chmodprog 1777 $sandbox/tmp $sandbox/var/tmp
echo "Making /var/games in $sandbox"
$mkdirprog $sandbox/var/games
$chownprog games:games $sandbox/var/games
$chmodprog 2775 $sandbox/var/games
for d in $sandboxEmptyDirs; do
test -d $d || continue
echo "Making $d in $sandbox"
$mkdirprog $sandbox$d
done
for f in $sandboxEmptyFiles; do
test -f $f || continue
echo "Making $f in $sandbox"
$cpprog /dev/null $sandbox$f
done
if [ "$need_src" = "yes" ]; then
echo "Mount $src from $sandbox"
$mkdirprog $sandbox/usr/src
$mountprog $mountflags -r $src $sandbox/usr/src
echo "$src /usr/src ro \\" >> $sandbox_script
fi
echo "Mount $pkgsrc from $sandbox"
$mkdirprog $sandbox/usr/pkgsrc
$mountprog $mountflags $pkgsrc $sandbox/usr/pkgsrc
echo "$pkgsrc /usr/pkgsrc rw \\" >> $sandbox_script
if [ "$need_xsrc" = "yes" ]; then
echo "Mount $xsrc from $sandbox"
$mkdirprog $sandbox/usr/xsrc
$mountprog $mountflags -r $xsrc $sandbox/usr/xsrc
echo "$xsrc /usr/xsrc ro \\" >> $sandbox_script
fi
echo "Mounting $packages and $distfiles from $sandbox"
$mkdirprog $sandbox/$packages $sandbox/$distfiles
$mkdirprog $packages $distfiles
$mountprog $mountflags $packages $sandbox/$packages
$mountprog $mountflags $distfiles $sandbox/$distfiles
echo "$packages $packages rw \\" >> $sandbox_script
echo "$distfiles $distfiles rw \\" >> $sandbox_script
if [ -n "$localpatches" ] && [ -d "$localpatches" ]; then
echo "Mounting $localpatches from $sandbox"
$mkdirprog $sandbox/$localpatches
$mountprog $mountflags $localpatches $sandbox/$localpatches
echo "$localpatches $localpatches rw \\" >> $sandbox_script
fi
cat >> $sandbox_script <<EOS
"
case x\$1 in
xmount)
set dummy \$fses
shift
while [ \$# -ge 3 ]; do
fs=\$1; shift
mntpoint=\$1; shift
rwro=\$1; shift
case \$rwro in
ro) mount $mountflags -r \$fs \$sandbox/\$mntpoint || exit 1 ;;
rw) mount $mountflags \$fs \$sandbox/\$mntpoint || exit 1 ;;
esac
done
;;
xumount)
set dummy \`r3 \$fses\`
shift
while [ \$# -ge 3 ]; do
fs=\$1; shift
mntpoint=\$1; shift
dummy=\$1; shift
umount \$sandbox/\$mntpoint
done
;;
xchroot)
case x\$2 in
x) rootshell=/bin/ksh ;;
*) rootshell="\$2" ;;
esac
script="\$sandbox/tmp/script.\$\$"
echo "#!/bin/sh" > \$script
echo "ENV=/etc/shrc \$rootshell" >> \$script
chmod +x \$script
ENV=/etc/shrc chroot \$sandbox /tmp/\`basename \$script\`
rm -f \$script
;;
*)
if [ \$# -eq 0 ]; then
set dummy /bin/sh
shift
fi
chroot \$sandbox "\$@"
;;
esac
EOS
chmod +x $sandbox_script
case $opsys in
SunOS)
$cpprog /etc/mnttab $sandbox/etc/mnttab
;;
*)
esac
echo "Sandbox creation is now complete"
exit 0