Offline install that lands fully patched: resolve against the ISO's own base
- autoinstall: dead mirror + fallback offline-install, so the installed base is exactly the ISO's; late-commands run offline-apt-install.sh on CIDATA packages/ (local apt repo, one transaction, errors fail the install, log /var/log/offline-apt-install.log); first boot no longer runs dpkg -i; real archive sources written back at the end. - download-packages.sh --iso: unpacks the ISO's default install source into a docker image (pxe-iso-base:<version>) and downloads there: all updates of the base, the explicit list (zip included) and the newest pool packages with their closure; writes Packages + explicit.list and checks the set offline in a fresh base container (--network none). - offline-apt-install.sh: new; also used by that check (--simulate). - build-usb.sh: ships Packages, explicit.list and the script; refuses a set without them. - tests/vm: pxetest-client-nosb (Secure Boot off, e1000e, SATA), one client at a time.
This commit is contained in:
85
scripts/offline-apt-install.sh
Executable file
85
scripts/offline-apt-install.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# offline-apt-install.sh - Install and patch from the offline package set
|
||||
#
|
||||
# Uses DIR (offline-packages/ as built by download-packages.sh: the .debs,
|
||||
# a Packages index and explicit.list) as the ONLY apt source:
|
||||
# 1. every installed package that DIR has a newer version of is upgraded
|
||||
# 2. every package in DIR/explicit.list is installed
|
||||
# in one apt transaction, then checks that nothing is left to upgrade.
|
||||
# The system's own sources.list and lists are not read or changed.
|
||||
#
|
||||
# Any apt failure stops the script with a non-zero exit and apt's message.
|
||||
#
|
||||
# Usage:
|
||||
# offline-apt-install.sh DIR install (as root)
|
||||
# offline-apt-install.sh --simulate DIR resolve only (apt-get -s)
|
||||
#
|
||||
# Runs in the autoinstall late-commands (curtin in-target) and in
|
||||
# download-packages.sh's offline check of the bundle.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SIMULATE=0
|
||||
if [ "${1:-}" = "--simulate" ]; then SIMULATE=1; shift; fi
|
||||
DIR="${1:?usage: $0 [--simulate] DIR}"
|
||||
DIR="$(cd "$DIR" && pwd)"
|
||||
|
||||
for f in Packages explicit.list; do
|
||||
[ -f "$DIR/$f" ] || { echo "offline-apt: ERROR: $DIR/$f missing (rebuild with download-packages.sh)" >&2; exit 1; }
|
||||
done
|
||||
|
||||
WORK=$(mktemp -d)
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
mkdir -p "$WORK/lists/partial" "$WORK/parts"
|
||||
echo "deb [trusted=yes] file:$DIR ./" >"$WORK/sources.list"
|
||||
|
||||
APT=(apt-get
|
||||
-o "Dir::Etc::SourceList=$WORK/sources.list"
|
||||
-o "Dir::Etc::SourceParts=$WORK/parts"
|
||||
-o "Dir::State::Lists=$WORK/lists"
|
||||
-o "APT::Sandbox::User=root"
|
||||
-o "Dpkg::Options::=--force-confdef"
|
||||
-o "Dpkg::Options::=--force-confold")
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
echo "offline-apt: source $DIR ($(find "$DIR" -maxdepth 1 -name '*.deb' | wc -l) debs)"
|
||||
"${APT[@]}" update
|
||||
|
||||
mapfile -t EXPLICIT < <(grep -v '^[[:space:]]*\(#\|$\)' "$DIR/explicit.list")
|
||||
DU=$("${APT[@]}" -s dist-upgrade)
|
||||
if grep -q 'kept back' <<<"$DU"; then
|
||||
echo "offline-apt: ERROR: upgrades kept back (missing dependencies in $DIR):" >&2
|
||||
echo "$DU" >&2
|
||||
exit 1
|
||||
fi
|
||||
mapfile -t UPGRADES < <(awk '/^Inst /{print $2}' <<<"$DU")
|
||||
echo "offline-apt: ${#UPGRADES[@]} upgrades, ${#EXPLICIT[@]} explicit packages"
|
||||
|
||||
if [ "$SIMULATE" -eq 1 ]; then
|
||||
OUT=$("${APT[@]}" -s install "${EXPLICIT[@]}" "${UPGRADES[@]}")
|
||||
echo "offline-apt: simulated: $(grep -c '^Inst ' <<<"$OUT") packages to unpack, $(grep -c '^Conf ' <<<"$OUT") to configure"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
"${APT[@]}" -y install "${EXPLICIT[@]}" "${UPGRADES[@]}"
|
||||
|
||||
AFTER=$("${APT[@]}" -s dist-upgrade)
|
||||
LEFT=$(awk '/^Inst /{print $2}' <<<"$AFTER")
|
||||
if grep -q 'kept back' <<<"$AFTER"; then
|
||||
echo "offline-apt: ERROR: upgrades kept back (missing dependencies in $DIR):" >&2
|
||||
echo "$AFTER" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "$LEFT" ]; then
|
||||
echo "offline-apt: ERROR: still upgradable from $DIR after install:" >&2
|
||||
echo "$LEFT" >&2
|
||||
exit 1
|
||||
fi
|
||||
BROKEN=$(dpkg --audit || true)
|
||||
if [ -n "$BROKEN" ]; then
|
||||
echo "offline-apt: ERROR: dpkg --audit reports:" >&2
|
||||
echo "$BROKEN" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "offline-apt: done, nothing left to upgrade from the offline set"
|
||||
Reference in New Issue
Block a user