diff --git a/15.0/makechroot-minimal.sh b/15.0/makechroot-minimal.sh new file mode 100755 index 0000000..cc06be5 --- /dev/null +++ b/15.0/makechroot-minimal.sh @@ -0,0 +1,148 @@ +#!/bin/sh +set -eu + +if [ "$(id -u)" != 0 ]; then + echo "This script needs root permissions!" 1>&2 + exit 1 +fi + +if [ "$#" -lt 1 ]; then + echo "Usage: $0 [-a arch] [-m mirror] " 1>&2 + exit 1 +fi + + +arch="$(uname -m)" +mirror='https://mirrors.slackware.com/slackware/slackware64-current' + +# Minimal amount of packages required to run installpkg, removepkg, upgradepkg, explodepkg and makepkg +# All of these exist in the 'a' package set +packages_pkgtools=' +aaa_base +aaa_elflibs +bash +coreutils +etc +findutils +glibc-solibs +grep +pkgtools +sed +tar +util-linux +which +xz +' + +# Minimal amount of packages required to run slackpkg without the dialog interface +# Supporting https, gpg, and upgrade-all. +# These exist over the 'a', 'ap', 'n' and 'l' package sets +# ca-certificates needs to be installed after openssl for the doinst.sh to run correctly +packages_extra=' +bzip2 +diffutils +gawk +gnupg +gzip +libpsl +libunistring +pcre2 +slackpkg +wget + +openssl +ca-certificates +' + +# Parse arguments +while getopts "a:m:" opt; do + case "$opt" in + a) arch="$OPTARG" ;; + m) + if [ -d "$OPTARG" ]; then + mirror="$(realpath "$OPTARG")" + else + mirror="$OPTARG" + fi + ;; + esac +done +shift $(expr $OPTIND - 1) +[ "$#" -ge 1 ] && [ "$1" = "--" ] && shift + +# Build final variables +case "$arch" in + x86_64) + pkgmain='slackware64' + ;; + + *) + pkgmain='slackware' + ;; +esac +initrd='isolinux/initrd.img' +checksums='CHECKSUMS.md5' +chroot="$(realpath "$1")" + +# Create working directory +temp="$(mktemp -d -t "$(basename "$0")".XXXXXX)" +cleanup() { + if mountpoint -q "$temp/mnt/pkg"; then + umount "$temp/mnt/pkg" + rmdir "$temp/mnt/pkg" + fi + mountpoint -q "$temp/mnt" && umount "$temp/mnt" + rm -rf "$temp" +} +trap 'cleanup' EXIT +cd "$temp" + +# Function to download (or copy) a file +get() { + if [ -d "$mirror" ]; then + cp "$mirror/$1" "$2" + else + wget "$mirror/$1" -O "$2" + fi +} + +# Function to verify files based on the checksums file +check() { + printf '%s' "$(tail +13 CHECKSUMS.md5 | grep "^[0-9a-f]* ./$1$" | cut -d ' ' -f 1) $2" | md5sum -c --quiet - +} + +# Get the full path to a package +package() { + tail +13 CHECKSUMS.md5 | grep "^[0-9a-f]* ./$pkgmain/[^/]*/$1-[^-]*-[^-]*-[^-]*\.t.z$" | cut -d ' ' -f 3- | cut -c 3- +} + +# Download checksums +get "$checksums" CHECKSUMS.md5 + +# Download installer initrd.img +get "$initrd" initrd.img +check "$initrd" initrd.img + +# Unpack and prepare the installer +xz -cd initrd.img | cpio -id +rm -f initrd.img +mkdir -p pkg "$chroot" +mount --bind "$chroot" mnt +mkdir -p mnt/pkg +mount --bind pkg mnt/pkg + +# Download packages +for pkg in $packages_pkgtools $packages_extra; do + path="$(package "$pkg")" + name="$(basename "$path")" + get "$path" "pkg/$name" + check "$path" "pkg/$name" +done +for pkg in $packages_pkgtools; do echo "$(basename "$(package "$pkg")")" >> pkg/__; done +for pkg in $packages_extra; do echo "$(basename "$(package "$pkg")")" >> pkg/_; done + +# Bootstrap pkgtools and its dependencies +env -i chroot . sh -l -c 'while read pkg; do /sbin/installpkg --root /mnt --terse "/pkg/$pkg"; done < /pkg/__' + +# Install slackpkg and its dependencies +env -i chroot mnt sh -l -c 'while read pkg; do /sbin/installpkg --terse "/pkg/$pkg"; done < /pkg/_'