diff options
Diffstat (limited to 'sbrun')
| -rwxr-xr-x | sbrun | 182 |
1 files changed, 106 insertions, 76 deletions
@@ -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" |
