aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsbrun182
1 files changed, 106 insertions, 76 deletions
diff --git a/sbrun b/sbrun
index 44d34db..fe5f809 100755
--- a/sbrun
+++ b/sbrun
@@ -29,6 +29,8 @@ if [ "$(id -u)" != "0" ]; then
"$0" "$@"
fi
+source /etc/profile
+
[ -e "$BUILDLOG" ] && mv "$BUILDLOG" "$BUILDLOG".old
# Inherit MAKEFLAGS from env, if present.
@@ -52,10 +54,6 @@ SELF=$(basename $0)
# able to mess with /mnt already has root access.
NONET_PATH=/mnt/nonet.$SELF.$$
-# Possible future options:
-# -f Run script with fakeroot. (still need root/sudo for unshare/nsenter,
-# and trackfs won't track failed writes, maybe this isn't that useful?)
-
long_help() {
# note: root's pager is used, not the user's, since we use sudo.
# not going to care about this one.
@@ -76,9 +74,6 @@ sudo. If you hate sudo, just run $SELF as root.
$SELF is designed for use with SBo scripts, but will work for any
SlackBuild (it doesn't refer to the SBo .info file).
-You'll want to install system/trackfs from SBo for filesystem tracking
-to work.
-
$SELF written by B. Watson (yalhcru@gmail.com) and released
under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details.
@@ -87,6 +82,8 @@ Usage: $SELF [-jN] [-n] [script] [variable=value ...]
Options may not be bundled (use -t -n, not -tn or -nt). All options
beginning with - must occur before [script] or [variable=value].
+-l Lint the package after it's built, with sbopkglint(1).
+
-jN Run N make jobs in parallel. Default is to use MAKEFLAGS from
the environment if set, otherwise "$DEFAULT_MAKEFLAGS". If a SlackBuild fails
without -j1, this is a bug in the SlackBuild and you should ask
@@ -96,11 +93,6 @@ beginning with - must occur before [script] or [variable=value].
fails without this flag, that's a bug in the SlackBuild and
should be reported to its maintainer (EMAIL in the .info file).
--t Don't use trackfs to watch for writes to system files. If a
- SlackBuild fails without this flag, it's a bug in either
- $SELF or trackfs, and should be reported to the maintainer
- at yalhcru@gmail.com.
-
-s Run the script with strace. This option implies -t (trackfs
will be disabled). The strace log will be written to the
current directory as "strace.out".
@@ -126,7 +118,7 @@ beginning with - must occur before [script] or [variable=value].
-D Use distcc for the compile. You still have to set DISTCC_HOSTS in the
environment, or in one of distcc's config files. This option sets
- CC and CXX, allows network access, and disables filesystem tracking.
+ CC and CXX, and allows network access.
-i Install the package after building it. This just runs "upkg" in the
SlackBuild directory, so "sbrun -i" is just a shortcut for typing
@@ -165,11 +157,13 @@ beginning with - must occur before [script] or [variable=value].
After the SlackBuild exits, any files written to outside of \$TMP,
\$OUTPUT, /tmp, /var/tmp, or /root/.ccache (collectively referred to
-as "the sandbox") are logged to stdout. See trackfs(1) for details of
-the log format, but any write outside the sandbox means a bug in the
-SlackBuild and should be reported to its maintainer.
+as "the sandbox") are logged to stdout. Any write outside the
+sandbox means a bug in the SlackBuild and should be reported to its
+maintainer.
-The exit status of $SELF is the exit status of the SlackBuild.
+The exit status of $SELF is the exit status of the SlackBuild,
+unless the -l option is used. With -l, the exit status is that
+of sbopkglint.
Note: the current directory needs to be writable, since the log and
(with -s/-S) strace output are written there.
@@ -180,7 +174,7 @@ include any more usage information. Feel free to stop reading at any
time :)
======================================================================
-Why does sbrun exist? Why not use sbopkg or sbotools? sbrun is targeted
+Why does sbrun exist? Why not use sbopkg or sbotools? sbrun is targeted
more towards a SlackBuild developer/maintainer than an end user. My
workflow is to edit the script in one terminal and repeatedly execute it
in another. If you're editing a SlackBuild, you keep running it over &
@@ -193,13 +187,15 @@ PITA to pass environment variables using the above script (sudo strips
them out of the env). So I made the script take arguments, and treat
those as env vars (place them between 'sudo' and 'sh').
-Then I added MAKEFLAGS support to it (-jN option). Then I found out some
-of my builds were writing outside of $TMP (due to either my own mistakes,
-or upstream bugs) and decided I needed a way to reliably detect that,
-hence the trackfs stuff. Also someone on the mailing list posted output
-from running a SlackBuild under bubblewrap, which prevented network access
-the script was trying to do. Which seems like a nifty feature to have,
-but bubblewrap is overkill for just running a shell script.
+Then I added MAKEFLAGS support to it (-jN option). Then I found out
+some of my builds were writing outside of $TMP (due to either my own
+mistakes, or upstream bugs) and decided I needed a way to reliably
+detect that, hence the trackfs stuff (which has since been removed
+and replaced with an overlay mount). Also someone on the mailing
+list posted output from running a SlackBuild under bubblewrap, which
+prevented network access the script was trying to do. Which seems like
+a nifty feature to have, but bubblewrap is overkill for just running a
+shell script.
The strace and sh -x options were added because those are things I do
fairly often with buggy SlackBuilds. The elapsed time display is a nice
@@ -258,14 +254,13 @@ Usage: $SELF [-option [-option ...]] [script] [variable=value ...]
-jN Run N make jobs in parallel.
-n Allow the SlackBuild to access the network.
--t Don't use trackfs to watch for writes to system files.
-s Run the script with strace, output in "strace.out".
-S Run the script with strace -ff, outputs in "strace.out.<pid>".
-x Run the script with "sh -x", enables shell command tracing.
-c Clean up (remove) source and package dirs after build completes.
-I Run an interactive shell in the source directory.
-p Run an interactive shell in the \$PKG directory.
--u Install built package with 'upkg'.
+-i Install built package with 'upkg'.
-d Download sources with 'sbodl'.
-h, --help
Show short usage message (you're reading it now) and exit.
@@ -367,18 +362,17 @@ ensure_path /usr/share/texmf/bin
# parse -options
while printf -- "$1" | grep -q ^-; do
case "$1" in
+ -l) LINTPKG="yes" ;;
-j*) MAKEFLAGS="$1" ;;
-n) NETWORK=yes ;;
- -t) TRACK=no ;;
- -s) TRACK=no; STRACE=-f ;;
- -S) TRACK=no; STRACE=-ff ;;
+ -s) STRACE=-f ;;
+ -S) STRACE=-ff ;;
-x) X="-x" ;;
-c) CLEANUP="yes" ;;
-I) SRCSH="yes" ;;
-p) PKGSH="yes" ;;
-D) CC="distcc gcc"
CXX="distcc g++"
- TRACK=no
NETWORK=yes
export CC CXX ;;
-i) UPKG=yes ;;
@@ -455,41 +449,9 @@ fi
# harm done (it was already killed by SIGINT), just irritating.
trap signal_handler INT TERM
-if [ "$TRACK" = "yes" ]; then
- if ! /bin/which trackfs &>/dev/null; then
- warn "File tracking enabled, but trackfs not installed!"
- #die "Install system/trackfs or re-run $SELF with -t."
- warn "Proceeding without trackfs."
- TRACK=no
- else
- LOGDIR="$( mktemp -d /tmp/sbrun.XXXXXX )"
- if [ -z "$LOGDIR" ] || [ ! -d "$LOGDIR" ]; then
- die "Can't create temp log dir in /tmp, bailing"
- fi
-
- LOG=$LOGDIR/log
-
- # Fun fact: trackfs uses GNU-style -- to mean "no more options",
- # but it's undocumented in the man page and --help output.
- # The readlink stuff is here in case $TMP or $OUTPUT has a symlink
- # in its path: trackfs will log the real path, with the links resolved.
- TRACKFS=\
-"trackfs -l $LOG \
- -I$( readlink -f "$TMP" )/\\* \
- -I$( readlink -f "$OUTPUT")/\\* \
- -I/tmp/\\* \
- -I/proc/\\* \
- -I/var/tmp/\\* \
- -I/root/.ccache/\\* \
- -I/root/.cache/\\* \
- -I/dev/pts/\\* \
- -I/dev/shm/\\* \
- --"
- fi
-fi
if [ "$STRACE" != "" ]; then
- TRACKFS="strace $STRACE -ostrace.out"
+ PRECMD="strace $STRACE"
fi
# Used to do this, but it doesn't allow for cases where the directory
@@ -528,12 +490,33 @@ fi
START_TIME="$( date +%s )"
-# Actually run the script. Note that the 'tee' command isn't being
-# tracked by trackfs. The rigmarole with $? and RET might not be the
+# Actually run the script.
+# The rigmarole with $? and RET might not be the
# best way to get the exit status, TODO: see if I can do this cleaner.
# Also, using { } instead of ( ) utterly fails.
-( eval $NSENTER $TRACKFS sh $X $SCRIPT 2>&1; echo "$?" > $LOGDIR/ret ) | tee -a $BUILDLOG
-RET="$( cat $LOGDIR/ret )"
+
+### 20260923 bkw: mount the overlay here!
+PRIVDIR="$( mktemp -td sbrun.priv.XXXXXXXXXX )"
+UPPERDIR=$PRIVDIR/upperdir
+WORKDIR=$PRIVDIR/workdir
+FAKEROOT=$PRIVDIR/fake_root
+mkdir -p $UPPERDIR $WORKDIR $FAKEROOT
+
+# Force-load the module
+modprobe overlay &> /dev/null
+mount -t overlay overlay \
+ -olowerdir=/,upperdir=$UPPERDIR,workdir=$WORKDIR \
+ $FAKEROOT
+# writes to $FAKEROOT/$TMP will pass through to the real $TMP
+mount --bind $TMP $FAKEROOT/$TMP
+mount --bind $OUTPUT $FAKEROOT/$OUTPUT
+
+echo cd "'$( pwd )'" > $PRIVDIR/runme
+echo $PRECMD bash $X $SCRIPT >> $PRIVDIR/runme
+cat $PRIVDIR/runme
+(
+ $NSENTER chroot $FAKEROOT bash $PRIVDIR/runme 2>&1; echo "$?" > $PRIVDIR/ret ) | tee -a $BUILDLOG
+RET="$( cat $PRIVDIR/ret )"
END_TIME="$( date +%s )"
@@ -545,20 +528,67 @@ echo "$SCRIPT exit status: $RET" | tee -a $BUILDLOG
} | tee -a $BUILDLOG
cleanup_nonet
+umount $FAKEROOT/$OUTPUT
+umount $FAKEROOT/$TMP
+umount $FAKEROOT
+if [ "$?" != "0" ]; then
+ cat <<EOF | tee -a $BUILDLOG
+
+********************
+*
+* \$FAKEROOT $FAKEROOT still mounted!
+*
+********************
-if [ "$TRACK" = "yes" ]; then
- if [ -s $LOG ]; then
- warn "WARNING: files altered outside the sandbox:"
- cat $LOG 1>&2
- cat $LOG >> $BUILDLOG
- fi
+EOF
+fi
- cleanup_log
+### 20260923 bkw:
+# Anything in $UPPERDIR after umount was written there by the
+# SlackBuild. Not everything there is worth bitching about.
+# After overlay umount, exclude these dirs from complaints:
+# /tmp /proc /var/tmp /root/.ccache /root/.cache /dev/pts /dev/shm
+# also $TMP and $OUTPUT.
+# For some reason, "root" gets created, too.
+# Have to specify each dir by itself *without* trailing slash,
+# then again with \/* to catch files/dirs under that dir.
+( cd $PRIVDIR/upperdir
+ find * \
+ \! -path root \
+ \! -path root/.cache/\* \
+ \! -path root/.ccache/\* \
+ \! -path tmp/\* \
+ \! -path var/tmp/\* \
+ \! -path proc/\* \
+ \! -path dev/pts/\* \
+ \! -path dev/shm/\* \
+ \! -path $TMP/\* \
+ \! -path $OUTPUT/\* \
+ \! -path root/.cache \
+ \! -path root/.ccache \
+ \! -path tmp \
+ \! -path var/tmp \
+ \! -path proc \
+ \! -path dev/pts \
+ \! -path dev/shm \
+ \! -path $TMP \
+ \! -path $OUTPUT \
+ -print0 | xargs -r0 ls -bld > $TMP/sbrun.turds.$$
+)
+if [ -s $TMP/sbrun.turds.$$ ]; then
+ warn "WARNING: files altered outside the sandbox:"
+ cat $TMP/sbrun.turds.$$ 1>&2
+ cat $TMP/sbrun.turds.$$ >> $BUILDLOG
fi
+rm -f $TMP/sbrun.turds.$$
+
+# If linting + installation were both requested, don't install
+# the package if it fails to lint.
+[ "$LINTPKG" = "yes" ] && sbopkglint || UPKG=""
# spawn shell(s) if requested. -i and -p are not mutually exclusive.
-# TODO: maybe do this cleaner, using trackfs?
+# TODO: do this cleaner?
if [ "$SRCSH" = "yes" ]; then
if [ "$RET" != "0" ]; then
warn "Script failed (status $RET), ignoring -i option"