diff options
| author | Danilo M. <danix@danix.xyz> | 2026-06-22 12:18:19 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-06-22 12:18:19 +0200 |
| commit | e39d54ff7dcd17a3ab64c66aba6a2e9f75585485 (patch) | |
| tree | 3f97a769e8a8dec2df0a0c928956d9b5ba675061 /overlay-chroot.sh | |
| download | sbo-batch-tester-e39d54ff7dcd17a3ab64c66aba6a2e9f75585485.tar.gz sbo-batch-tester-e39d54ff7dcd17a3ab64c66aba6a2e9f75585485.zip | |
Initial commit: sbo-batch-test
Batch-test SlackBuilds against a clean Slackware 15.0 overlay chroot.
Non-interactive, local-tree-only dependency resolution with topological
sort, per-target disposable overlay, persistent per-package logs, and a
color summary.
Includes README.md, CLAUDE.md working notes, the reference overlay-chroot.sh,
the original spec, and test-logic.sh (resolver + BLOCKED-BY-DEP self-check,
12 checks passing).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'overlay-chroot.sh')
| -rw-r--r-- | overlay-chroot.sh | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/overlay-chroot.sh b/overlay-chroot.sh new file mode 100644 index 0000000..332311b --- /dev/null +++ b/overlay-chroot.sh @@ -0,0 +1,257 @@ +#!/bin/bash +# +# Copyright 2023-2025 Jeremy Hansen <jebrhansen -at- gmail.com> +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 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. + +# ----------------------------------------------------------------------------- + +# Create a chroot from a maintained and updated Slackware stable base to allow +# easy testing of SlackBuild scripts in a clean environment. Ensure that base +# is updated every time this script is ran along with updating sbopkg and +# running sqg to update all queues. Offer to remove chroot files when exiting +# the chroot. + +# Supports passing "cleanup" to remove any existing chroots and their files. + +# Supports passing "update" to update the base image with slackpkg and sbopkg +# and then exiting without starting the chroot. + +# TODO +# Currently empty + +# ----------------------------------------------------------------------------- + +# --------------------------Global Settings Beginning-------------------------- + +# Set where you want the chroot located and the base name of the folder +CHROOT_LOCATION=/tmp/ +CHROOT_TEMPLATE_BASE="chroot" + +# Set variables for the base image and location of the local Slackware mirror +VERSION=15.0 +SLACKWARE_BASE=/share/gothrough/sbo-build/$VERSION +LOCAL_MIRROR=/share/gothrough/slackware-mirrors/slackware64-$VERSION/ + +# To allow you to open GUI programs from within the chroot, you need to +# allow "remote" access to the x server. This could possibly open up +# security issues, but it is limited to non-network local connections. +# Change to "no" if you want this disabled or pass ACCESS=no to the script. +ACCESS=${ACCESS:-yes} + +# ---------------------------Global Settings Ending---------------------------- + +# --------------------------Custom Commands Beginning-------------------------- +# This will allow you to add custom aliases or functions into the chroot +# Make sure you escape single quotes and variables and that all commands are on +# their own lines +custom_cmd=' +# Check all listed deps in a .info to see if they are installed +alias checkdeps=". *.info; for i in \$REQUIRES; do ls /var/log/packages/*SBo* | cut -d/ -f5 | rev | cut -d- -f4- | rev | grep ^\$i$; done" +' +# ---------------------------Custom Commands Ending---------------------------- + +# Check that we're root +if [ "$EUID" -ne 0 ]; then + echo "Please run as root" + exit +fi + +# Provide an easy cleanup for older tmp files and exit +if [ "$1" == "cleanup" ]; then + + for i in "$CHROOT_LOCATION"/"$CHROOT_TEMPLATE_BASE".*; do + if [ -d "$i" ]; then + echo "Found $i" + else + echo "No chroots to clean up." + exit 2 + fi + + if mountpoint -q "$i"/chroot/dev/pts; then + printf "\tUnmounting %s/chroot/dev/pts\n" "$i" + umount "$i"/chroot/dev/pts + fi + for j in dev proc sys; do + if mountpoint -q "$i"/chroot/$j; then + printf "\tUnmounting %s/chroot/%s\n" "$i" "$j" + umount "$i"/chroot/$j + fi + done + + if mountpoint -q "$i"/chroot/etc/resolv.conf; then + printf "\tUnmounting %s/chroot/etc/resolv.conf\n" "$i" + umount "$i"/chroot/etc/resolv.conf + fi + + if mountpoint -q "$i"/chroot/var/lib/dbus/machine-id; then + printf "\tUnmounting %s/chroot/var/lib/dbus/machine-id\n" "$i" + umount "$i"/chroot/var/lib/dbus/machine-id + fi + + # umount overlayfs + if mountpoint -q "$i"/chroot; then + printf "\tUnmounting %s/chroot/%s/chroot\n" "$i" "$j" + umount "$i"/chroot + fi + + # Remove dirs + if [ -d "$i" ]; then + printf "\tRemoving %s.\n" "$i" + rm -r "$i" + fi + done + echo "Cleanup complete" + exit +fi + +# Track the latest updates to prevent attempting to update system +# packages and rebuilding sbopkg's queues +touch $SLACKWARE_BASE/last-base-update + +# Make sure the base image is up-to-date +if [ "$(head -n1 $LOCAL_MIRROR/ChangeLog.txt)" != "$(cat $SLACKWARE_BASE/last-base-update)" ]; then + for i in "$LOCAL_MIRROR"/patches/packages/*.t?z; do + if [ ! -e "$SLACKWARE_BASE"/var/lib/pkgtools/packages/"$(basename "${i%.*}")" ]; then + ROOT=$SLACKWARE_BASE upgradepkg --install-new "$i" + fi + done + echo "Slackware has been updated with local mirror." + head -n1 $LOCAL_MIRROR/ChangeLog.txt > $SLACKWARE_BASE/last-base-update +else + echo "Slackware is up-to-date with the local mirror." +fi + +# Set up directories for the chroot +echo "Creating required directories for the overlay" +TMPDIR=$(mktemp -d "$CHROOT_LOCATION"/"$CHROOT_TEMPLATE_BASE".XXXXX) +mkdir "$TMPDIR"/{changes,tmp,chroot} + +# Mount the overlayfs +echo "Mounting the overlay" +mount -t overlay overlay -olowerdir="$SLACKWARE_BASE",upperdir="$TMPDIR"/changes,workdir="$TMPDIR"/tmp "$TMPDIR"/chroot + +# Bind mount the pertinent system dirs +echo "Binding required directories" +mkdir -p "$TMPDIR"/changes/{dev,proc,sys} +for i in dev proc sys; do + mount -o bind /$i "$TMPDIR"/chroot/$i +done + +# Mount /dev/pts for sudo +mkdir -p "$TMPDIR"/changes/dev/pts +mount -o bind /dev/pts "$TMPDIR"/chroot/dev/pts + +# Give the chroot internet +echo "Setting up internet" +mount -o bind /etc/resolv.conf "$TMPDIR"/chroot/etc/resolv.conf +chroot "$TMPDIR"/chroot /bin/bash -c "/usr/sbin/update-ca-certificates --fresh > /dev/null" + +# Setting up DBUS binding required for certain apps +echo "Binding DBUS to local machine" +touch "$TMPDIR"/chroot/var/lib/dbus/machine-id +mount -o bind /var/lib/dbus/machine-id "$TMPDIR"/chroot/var/lib/dbus/machine-id + +# Update sbopkg (if installed) and queues +# Do it in the chroot to prevent GPG errors, but copy files back to the +# base image so we only need to do it during updates. +if [ -e "$SLACKWARE_BASE"/usr/sbin/sbopkg ]; then + echo "Checking for SBo updates for sbopkg" + # Get the latest changelog date from server + SERVDATE="$(wget -qO- https://slackbuilds.org/slackbuilds/15.0/ChangeLog.txt | head -n1)" + if [ -z "$SERVDATE" ]; then + echo "Upstream address did not provide a changelog." + echo "Please validate internet is working and address is correct" + echo "This will continue in 5 seconds. Ctrl+C if you'd like to exit." + sleep 5 + fi + # Get latest changelog date on local copy + LOCALDATE="$(head -n1 $SLACKWARE_BASE/var/lib/sbopkg/SBo/15.0/ChangeLog.txt)" + # If they don't match, update sbopkg and run sqg. Copy updates back to base image. + if [ "$SERVDATE" != "$LOCALDATE" ]; then + chroot "$TMPDIR"/chroot /bin/bash -c "/usr/sbin/sbopkg -r; /usr/sbin/sqg -a" + rsync -a --delete "$TMPDIR"/chroot/var/lib/sbopkg/ "$SLACKWARE_BASE"/var/lib/sbopkg + rsync -a --delete "$TMPDIR"/chroot/root/.gnupg "$SLACKWARE_BASE"/root/ + else + echo "sbopkg is up-to-date." + fi +fi + +# Only set up X server access and launch the chroot if update isn't passed +if [ "$1" != "update" ]; then + # Checking if we can add local connection access + if [ "$ACCESS" == "yes" ]; then + echo "Setting up X server access" + echo "STATUS: $(xhost +local:hosts)" + fi + + # Check if there are custom commands to add by checking for text + if [[ "$custom_cmd" =~ [a-zA-Z] ]]; then + echo "Adding custom commands to chroot's /etc/profile.d/chroot_custom_cmds.sh" + echo "$custom_cmd" > "$TMPDIR"/chroot/etc/profile.d/chroot_custom_cmds.sh + chmod +x "$TMPDIR"/chroot/etc/profile.d/chroot_custom_cmds.sh + fi + + # Let's save the following in the root of the chroot structure to allow + # the user to enter into that chroot from another prompt and/or if they + # accidentally leave the chroot. + # Then we'll just execute the file to actually enter the chroot. + cat << EOH > "$TMPDIR"/start-chroot.sh +#!/bin/bash +# Time to actually chroot and do our work +# Need to type 'exit' to leave the chroot and start the cleanup +# Use custom PS1 so we know we're in the chroot +echo "Entering chroot. Please type \"exit\" to exit it." +echo "You can add files to the chroot by placing them in $TMPDIR/chroot/" +chroot "$TMPDIR"/chroot env PS1="\[\e[41m\]\u\[\e[49m\]@\[\e[33m\]$(basename "$TMPDIR")\[\e[0m\]:\w$ " bash -l +EOH + + # Start the chroot + bash "$TMPDIR"/start-chroot.sh +fi + +# Start cleanup + +# Undo bind mounts +umount "$TMPDIR"/chroot/dev/pts +for i in dev proc sys; do + umount "$TMPDIR"/chroot/$i +done + +umount "$TMPDIR"/chroot/etc/resolv.conf +umount "$TMPDIR"/chroot/var/lib/dbus/machine-id + +# umount overlayfs +umount "$TMPDIR"/chroot + +# Only ask to delete chroot if update isn't passed, otherwise delete without asking +if [ "$1" != "update" ]; then + # Ask if tmp dirs should be removed + # Could be kept to review filesystem changes + echo -n "Would you like to remove the unneeded overlay directories? y/N " + read -r answer + # If anything other than y, rm them + if ! /usr/bin/grep -qi "y" <<< "$answer"; then + echo "Temp overlay dirs will not be removed. They can be found at $TMPDIR." + else + rm -r "$TMPDIR" + fi +else + rm -r "$TMPDIR" +fi |
