ISO: add --offline bundle so the kiosk installs with no internet
`iso/build-iso.sh --offline` (and the workflow's new `offline` box, on by default) adds ~420 MB to the ISO and copies it to /opt/kiosk-offline: - apt/: local repository with every package install.sh's provisioning and the CUPS addon install ask for, NodeSource's nodejs, and all dependencies a fresh server install doesn't already have. Resolved against the source ISO's own package manifest via a synthesized dpkg status (iso/offline/fake-dpkg-status.py), so apt downloads only what's missing and makes the same virtual/alternative choices as the target. - npm/: prebuilt kiosk-app (Electron 42, binary included - it no longer downloads at npm install time) and Web UI node_modules. On first boot, kiosk-firstboot installs online as before when there's internet; with none it waits KIOSK_OFFLINE_WAIT (90s), then runs `kiosk-offline-apt on` (apt.conf.d drop-in: bundle is the ONLY source) and turns it off again afterwards. install.sh notices offline mode via offline_mode_active (lib/config.sh) and installs nodejs from the bundle and unpacks prebuilt node_modules instead of npm install. Package lists moved into PROVISION_APT_PACKAGES / PROVISION_INTEL_APT_PACKAGES / CUPS_APT_PACKAGES so the bundler reads the same lists install.sh installs from. Tested: built against the 26.04.1 ISO, then in a network-less chroot of the ISO's own server filesystem installed every package set, ran provision_create_kiosk_user/install_nodejs/install_app and webui_install_app_files in offline mode (Electron runs, no missing libraries, chrome-sandbox setuid), and ran kiosk-firstboot through the offline switch with a stub install.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
This commit is contained in:
+28
-2
@@ -26,6 +26,8 @@
|
||||
#
|
||||
# Requirements (on the build machine, any recent Ubuntu/Debian):
|
||||
# sudo apt install xorriso curl git openssl
|
||||
# plus, for --offline (amd64 build machine only):
|
||||
# sudo apt install apt-utils python3 gnupg ubuntu-keyring
|
||||
#
|
||||
# Usage:
|
||||
# iso/build-iso.sh [options]
|
||||
@@ -65,6 +67,15 @@
|
||||
# --repo-url URL git remote recorded in the copied repo, used by
|
||||
# Advanced -> Upgrade (default: this checkout's
|
||||
# origin, else the upstream GitHub repo).
|
||||
# --offline Also bundle everything install.sh downloads (~420 MB:
|
||||
# every apt package incl. the CUPS printing addon,
|
||||
# Node.js, prebuilt Electron/Web UI node_modules), so
|
||||
# first boot can install the kiosk with NO internet.
|
||||
# With internet it still installs online as usual;
|
||||
# offline it waits 90s, then uses the bundle. The
|
||||
# bundle stays on the kiosk at /opt/kiosk-offline
|
||||
# (see iso/firstboot/kiosk-offline-apt for using it
|
||||
# later, e.g. adding CUPS while offline).
|
||||
#
|
||||
# The repo copied onto the ISO is a clone of this checkout's current HEAD
|
||||
# (committed changes only - uncommitted edits are NOT included).
|
||||
@@ -91,6 +102,7 @@ AUTO_STORAGE=0
|
||||
AUTO_NETWORK=0
|
||||
NO_CONFIRM=0
|
||||
UNATTENDED=0
|
||||
OFFLINE=0
|
||||
REPO_URL=""
|
||||
|
||||
# Usernames the Ubuntu installer rejects (system users/groups) - copied
|
||||
@@ -136,6 +148,7 @@ while [[ $# -gt 0 ]]; do
|
||||
--unattended) UNATTENDED=1; shift ;;
|
||||
--fully-automatic) AUTO_STORAGE=1; AUTO_NETWORK=1; NO_CONFIRM=1; UNATTENDED=1; shift ;;
|
||||
--repo-url) REPO_URL="$2"; shift 2 ;;
|
||||
--offline) OFFLINE=1; shift ;;
|
||||
-h|--help) usage 0 ;;
|
||||
*) echo "Unknown option: $1" >&2; usage 1 ;;
|
||||
esac
|
||||
@@ -212,8 +225,9 @@ fi
|
||||
|
||||
if [[ -z "$OUTPUT" ]]; then
|
||||
src_base="$(basename "$SRC_ISO" .iso)"
|
||||
OUTPUT="$BUILD_DIR/${src_base/-live-server/-kiosk}.iso"
|
||||
[[ "$OUTPUT" != "$BUILD_DIR/$src_base.iso" ]] || OUTPUT="$BUILD_DIR/${src_base}-kiosk.iso"
|
||||
kind="kiosk"; (( OFFLINE )) && kind="kiosk-offline"
|
||||
OUTPUT="$BUILD_DIR/${src_base/-live-server/-$kind}.iso"
|
||||
[[ "$OUTPUT" != "$BUILD_DIR/$src_base.iso" ]] || OUTPUT="$BUILD_DIR/${src_base}-$kind.iso"
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -244,12 +258,18 @@ git -C "$stage_repo" config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
|
||||
|
||||
install -m 755 "$SCRIPT_DIR/firstboot/kiosk-firstboot" "$WORK/kiosk/firstboot/"
|
||||
install -m 644 "$SCRIPT_DIR/firstboot/kiosk-firstboot.service" "$WORK/kiosk/firstboot/"
|
||||
install -m 755 "$SCRIPT_DIR/firstboot/kiosk-offline-apt" "$WORK/kiosk/firstboot/"
|
||||
cat > "$WORK/kiosk/firstboot/kiosk-firstboot.conf" <<EOF
|
||||
# Read by /usr/local/sbin/kiosk-firstboot. Written by iso/build-iso.sh.
|
||||
# 1 = take every install.sh default and reboot into the kiosk; 0 = interactive.
|
||||
KIOSK_UNATTENDED=$UNATTENDED
|
||||
EOF
|
||||
|
||||
if (( OFFLINE )); then
|
||||
info "Building offline bundle (packages, Node.js, Electron)..."
|
||||
"$SCRIPT_DIR/offline/build-bundle.sh" "$WORK/kiosk/offline" "$SRC_ISO" "$stage_repo" "$BUILD_DIR/offline-cache"
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# autoinstall.yaml
|
||||
################################################################################
|
||||
@@ -305,9 +325,14 @@ interactive=()
|
||||
- install -m 755 /cdrom/kiosk/firstboot/kiosk-firstboot /target/usr/local/sbin/kiosk-firstboot
|
||||
- install -m 644 /cdrom/kiosk/firstboot/kiosk-firstboot.service /target/etc/systemd/system/kiosk-firstboot.service
|
||||
- install -m 644 /cdrom/kiosk/firstboot/kiosk-firstboot.conf /target/etc/kiosk-firstboot.conf
|
||||
- install -m 755 /cdrom/kiosk/firstboot/kiosk-offline-apt /target/usr/local/sbin/kiosk-offline-apt
|
||||
- touch /target/var/lib/kiosk-firstboot/pending
|
||||
- curtin in-target --target=/target -- systemctl enable kiosk-firstboot.service
|
||||
EOF
|
||||
if (( OFFLINE )); then
|
||||
echo " - cp -a /cdrom/kiosk/offline /target/opt/kiosk-offline"
|
||||
echo " - chmod -R u+w,a+rX /target/opt/kiosk-offline"
|
||||
fi
|
||||
} > "$WORK/autoinstall.yaml"
|
||||
|
||||
################################################################################
|
||||
@@ -345,6 +370,7 @@ echo
|
||||
echo "Installer asks for : ${interactive[*]:-nothing}$( (( NO_CONFIRM )) || echo " (plus a 'Continue with autoinstall?' confirmation)")"
|
||||
echo "Admin user : ${ADMIN_USER:-chosen during install}"
|
||||
echo "First boot : $( (( UNATTENDED )) && echo "unattended install.sh, then reboots into the kiosk" || echo "interactive install.sh on the console")"
|
||||
echo "Offline bundle : $( (( OFFLINE )) && echo "yes - installs with no internet (used after 90s offline)" || echo "no - first boot needs internet (add --offline to bundle everything)")"
|
||||
echo
|
||||
echo "Write it to a USB stick (replace /dev/sdX - this erases it):"
|
||||
echo " sudo dd if='$OUTPUT' of=/dev/sdX bs=4M status=progress oflag=sync"
|
||||
|
||||
Reference in New Issue
Block a user