148 lines
6.0 KiB
Bash
Executable File
148 lines
6.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# =====================================================================
|
|
# Puts installation media where build.sh can find it, having checked it.
|
|
#
|
|
# sudo ./fetch.sh ubuntu # download the pinned release
|
|
# sudo ./fetch.sh ubuntu ~/Downloads/x.iso # use one already downloaded
|
|
# sudo ./fetch.sh windows ~/Downloads/x.iso
|
|
#
|
|
# EITHER WAY IT IS CHECKSUMMED
|
|
#
|
|
# A local file is not trusted more than a downloaded one - it is the same
|
|
# 6 GB of installer that becomes the machine every session runs from. For
|
|
# Ubuntu the hash is compared against Canonical's published SHA256SUMS
|
|
# for that series, fetched at the time, rather than a constant pasted in
|
|
# here that goes stale at the next point release and gets deleted.
|
|
#
|
|
# Windows media has no published list to check against, so its hash is
|
|
# only RECORDED. That is a real difference and it is not papered over:
|
|
# the manifest says where the file came from and what it hashed to, and
|
|
# that is all anyone can honestly claim about it.
|
|
#
|
|
# WHY UBUNTU IS NOT FETCHED WITH quickget
|
|
#
|
|
# quickget was adopted for image acquisition because the Windows side -
|
|
# locating an ISO, pairing it with the right virtio-win build - is
|
|
# genuinely fiddly and well solved there. Ubuntu is not that. Acquisition
|
|
# is one download and one checksum, and doing it directly keeps a
|
|
# 2,400-line bash dependency off the path that builds the image this
|
|
# suite runs on every session.
|
|
# =====================================================================
|
|
set -euo pipefail
|
|
cd "$(dirname "$(readlink -f "$0")")"
|
|
|
|
ISO_DIR=/var/lib/owuivm/iso
|
|
|
|
[ "$(id -u)" -eq 0 ] || { echo "run as root" >&2; exit 1; }
|
|
install -d -o owuivmadm -g owuivmadm -m 0755 "$ISO_DIR"
|
|
|
|
# The series to check against, and the release to download when no local
|
|
# file is given. Bump both together.
|
|
UBUNTU_SERIES="26.04"
|
|
UBUNTU_ISO="ubuntu-26.04.1-desktop-amd64.iso"
|
|
UBUNTU_BASE="https://releases.ubuntu.com/${UBUNTU_SERIES}"
|
|
|
|
verify_against_canonical() { # verify_against_canonical <path> <basename>
|
|
local path="$1" name="$2" want got
|
|
echo "==> checking $name against Canonical's SHA256SUMS"
|
|
want=$(curl -fsSL "$UBUNTU_BASE/SHA256SUMS" | awk -v f="*$name" '$2==f{print $1}')
|
|
[ -n "$want" ] || {
|
|
echo "$name is not in the published list for $UBUNTU_SERIES." >&2
|
|
echo "Either it is from another series, or the name has been changed." >&2
|
|
exit 1
|
|
}
|
|
got=$(sha256sum "$path" | awk '{print $1}')
|
|
[ "$want" = "$got" ] || {
|
|
echo "CHECKSUM MISMATCH - refusing to use this file." >&2
|
|
echo " want $want" >&2
|
|
echo " got $got" >&2
|
|
exit 1
|
|
}
|
|
echo " ok $got"
|
|
printf '%s %s verified against %s/SHA256SUMS\n' "$name" "$got" "$UBUNTU_BASE" \
|
|
> "$ISO_DIR/ubuntu.manifest"
|
|
}
|
|
|
|
fetch_ubuntu() {
|
|
local supplied="${1:-}"
|
|
if [ -n "$supplied" ]; then
|
|
[ -f "$supplied" ] || { echo "no such file: $supplied" >&2; exit 1; }
|
|
local name; name=$(basename "$supplied")
|
|
verify_against_canonical "$supplied" "$name"
|
|
# Copied rather than symlinked: the source is in somebody's Downloads
|
|
# folder, and a base image build that fails halfway through because
|
|
# the ISO was tidied away is a bad afternoon.
|
|
echo "==> copying into $ISO_DIR"
|
|
install -o owuivmadm -g owuivmadm -m 0644 "$supplied" "$ISO_DIR/$name"
|
|
else
|
|
local dest="$ISO_DIR/$UBUNTU_ISO"
|
|
if [ -f "$dest" ]; then
|
|
echo "already present: $dest"
|
|
else
|
|
echo "==> downloading $UBUNTU_ISO"
|
|
curl -fL --retry 3 --continue-at - -o "$dest.part" "$UBUNTU_BASE/$UBUNTU_ISO"
|
|
mv -f "$dest.part" "$dest"
|
|
chown owuivmadm:owuivmadm "$dest"
|
|
fi
|
|
verify_against_canonical "$dest" "$UBUNTU_ISO"
|
|
fi
|
|
echo
|
|
cat "$ISO_DIR/ubuntu.manifest"
|
|
}
|
|
|
|
# The virtio driver disk. Windows setup cannot see a virtio-blk disk
|
|
# without it and will tell you there are no drives to install to, which
|
|
# reads like a broken VM rather than a missing driver. Fetched from the
|
|
# same place every Windows-on-KVM guide uses; it is not signed by anyone
|
|
# whose signature we can check, so the hash is recorded rather than
|
|
# verified - exactly like the Windows media itself.
|
|
VIRTIO_URL="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso"
|
|
|
|
fetch_virtio() {
|
|
local dest="$ISO_DIR/virtio-win.iso"
|
|
if [ -f "$dest" ]; then
|
|
echo "already present: $dest"
|
|
else
|
|
echo "==> downloading virtio-win.iso"
|
|
curl -fL --retry 3 --continue-at - -o "$dest.part" "$VIRTIO_URL"
|
|
mv -f "$dest.part" "$dest"
|
|
chown owuivmadm:owuivmadm "$dest"; chmod 0644 "$dest"
|
|
fi
|
|
printf 'virtio-win.iso %s recorded only - from %s\n' \
|
|
"$(sha256sum "$dest" | awk '{print $1}')" "$VIRTIO_URL" > "$ISO_DIR/virtio.manifest"
|
|
cat "$ISO_DIR/virtio.manifest"
|
|
}
|
|
|
|
fetch_windows() {
|
|
local supplied="${1:-}"
|
|
[ -n "$supplied" ] || { echo "Windows media must be supplied: $0 windows /path/to.iso" >&2; exit 2; }
|
|
[ -f "$supplied" ] || { echo "no such file: $supplied" >&2; exit 1; }
|
|
local name got
|
|
name=$(basename "$supplied")
|
|
# The maintenance boot picks Windows media by name, so a file that does
|
|
# not look like Windows media would either be ignored or - worse - the
|
|
# Ubuntu ISO would be picked instead. Checked here, once, where it can
|
|
# still be fixed by renaming rather than debugged from a boot failure.
|
|
case "$name" in
|
|
[Ww]in*.iso|*[Ww]indows*.iso) ;;
|
|
*) echo "refusing '$name': Windows media must have a name starting with Win or containing Windows," >&2
|
|
echo "because that is how the maintenance boot tells it apart from the Ubuntu ISO." >&2
|
|
exit 1 ;;
|
|
esac
|
|
got=$(sha256sum "$supplied" | awk '{print $1}')
|
|
install -o owuivmadm -g owuivmadm -m 0644 "$supplied" "$ISO_DIR/$name"
|
|
# RECORDED, not verified. See the header.
|
|
printf '%s %s recorded only - no published checksum to compare against\n' "$name" "$got" \
|
|
> "$ISO_DIR/windows.manifest"
|
|
cat "$ISO_DIR/windows.manifest"
|
|
echo
|
|
fetch_virtio
|
|
}
|
|
|
|
case "${1:-}" in
|
|
ubuntu) fetch_ubuntu "${2:-}" ;;
|
|
windows) fetch_windows "${2:-}" ;;
|
|
virtio) fetch_virtio ;;
|
|
*) echo "usage: $0 {ubuntu|windows|virtio} [/path/to/local.iso]" >&2; exit 2 ;;
|
|
esac
|