.github: drop rootfs.squashfs from release tarballs

Release tarballs waste ~131MB per architecture by including both
rootfs.itb and rootfs.squashfs, even though rootfs.itb already
contains the squashfs (itb = 4096-byte header + squashfs).

This change removes rootfs.squashfs from releases and provides two
solutions for users who need it:

1. utils/extract-squashfs.sh - Full-featured utility for extracting
   squashfs from release tarballs or .itb files. Includes validation
   and helpful error messages.

2. board/common/qemu/qemu.sh - Auto-extraction support. When running
   in initrd mode, automatically extracts rootfs.squashfs from
   rootfs.itb if missing. Zero user impact - ./qemu.sh just works!

Space savings: ~262MB per release (2 architectures × 131MB)

Fixes #858

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2025-11-08 12:57:35 +01:00
parent 7a6b1ea311
commit 94fa7ea21c
3 changed files with 134 additions and 0 deletions
+4
View File
@@ -100,6 +100,10 @@ jobs:
mv cpe.json images/sbom/
mv legal-info/*.csv images/sbom/
# Remove rootfs.squashfs from release (can be extracted from rootfs.itb)
# Saves ~131MB per architecture. See issue #858
rm -f images/rootfs.squashfs
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
+27
View File
@@ -313,8 +313,35 @@ gdb_args()
echo -n "-gdb chardev:gdbqemu"
}
extract_squashfs()
{
# Extract rootfs.squashfs from rootfs.itb if missing
# The .itb file is rootfs.itbh (4096 bytes) + rootfs.squashfs
input="${1:-rootfs.itb}"
output="${2:-rootfs.squashfs}"
[ -f "$input" ] || die "Cannot extract $output: $input not found"
echo "Extracting $output from $input (skipping 4096-byte FIT header)..."
dd if="$input" of="$output" bs=4096 skip=1 2>/dev/null \
|| die "Failed to extract $output from $input"
echo "Successfully created $output"
}
run_qemu()
{
# Auto-extract rootfs.squashfs from rootfs.itb if needed for initrd mode
if [ "$CONFIG_QEMU_ROOTFS_INITRD" = "y" ]; then
if [ "$CONFIG_QEMU_ROOTFS" = "rootfs.squashfs" ] && [ ! -f "rootfs.squashfs" ]; then
if [ -f "rootfs.itb" ]; then
extract_squashfs "rootfs.itb" "rootfs.squashfs"
else
die "Missing rootfs.squashfs and cannot find rootfs.itb to extract it from"
fi
fi
fi
if [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
if ! qemu-img check "qemu.qcow2"; then
rm -f "qemu.qcow2"
+103
View File
@@ -0,0 +1,103 @@
#!/bin/sh
#
# Extract rootfs.squashfs from a release tarball's rootfs.itb file
#
# Usage: extract-squashfs.sh <tarball-or-itb-file> [output-file]
#
set -e
usage() {
cat <<EOF
Usage: $(basename "$0") <tarball-or-itb-file> [output-file]
Extract rootfs.squashfs from a release tarball or .itb file.
Arguments:
<tarball-or-itb-file> Release tarball (*.tar.gz) or rootfs.itb file
[output-file] Output squashfs file (default: rootfs.squashfs)
Examples:
# From release tarball
$(basename "$0") infix-x86_64-25.09.0.tar.gz
# From .itb file directly
$(basename "$0") output/images/rootfs.itb
# Custom output location
$(basename "$0") infix-x86_64-25.09.0.tar.gz /tmp/my-rootfs.squashfs
The script skips the 4096-byte FIT header to extract the SquashFS image.
EOF
}
die() {
echo "ERROR: $*" >&2
exit 1
}
# Parse arguments
case "$1" in
-h|--help)
usage
exit 0
;;
"")
usage
exit 1
;;
esac
input="$1"
output="${2:-rootfs.squashfs}"
[ -f "$input" ] || die "File not found: $input"
# Detect if input is a tarball or .itb file
case "$input" in
*.tar.gz)
echo "Extracting rootfs.itb from tarball..."
itb_file=$(tar -tzf "$input" | grep -m1 'rootfs\.itb$') \
|| die "No rootfs.itb found in tarball"
echo "Found: $itb_file"
echo "Extracting SquashFS (skipping 4096-byte FIT header)..."
tar -xzOf "$input" "$itb_file" | dd bs=4096 skip=1 of="$output" 2>/dev/null \
|| die "Failed to extract SquashFS"
;;
*.itb)
echo "Extracting SquashFS from .itb file (skipping 4096-byte FIT header)..."
dd if="$input" of="$output" bs=4096 skip=1 2>/dev/null \
|| die "Failed to extract SquashFS"
;;
*)
die "Unsupported file type. Expected *.tar.gz or *.itb"
;;
esac
# Verify output
if [ -f "$output" ]; then
size=$(stat --format=%s "$output" 2>/dev/null || stat -f%z "$output")
file_type=$(file "$output")
# Try to format size nicely, fall back to bytes if numfmt not available
if command -v numfmt >/dev/null 2>&1; then
size_str=$(numfmt --to=iec-i --suffix=B "$size")
else
size_str="$size bytes"
fi
echo "Success! Created: $output ($size_str)"
echo "Type: $file_type"
# Quick sanity check for squashfs magic
if echo "$file_type" | grep -qi squashfs; then
echo "✓ Verified: Valid SquashFS filesystem"
else
echo "⚠ Warning: Output may not be a valid SquashFS image"
exit 1
fi
else
die "Failed to create output file"
fi