From 09778b82462561f6ac8530a71e8db997c26af51f Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Sat, 14 Sep 2024 09:45:53 +1000 Subject: [PATCH 1/1] initial snapshot --- build-installer.sh | 340 +++++++++++++++++++++++++++++++++++ initrd-init | 24 +++ installer-packages.list | 119 ++++++++++++ pool-packages-installer.list | 113 ++++++++++++ vm.sh | 24 +++ 5 files changed, 620 insertions(+) create mode 100755 build-installer.sh create mode 100755 initrd-init create mode 100644 installer-packages.list create mode 100644 pool-packages-installer.list create mode 100755 vm.sh diff --git a/build-installer.sh b/build-installer.sh new file mode 100755 index 0000000..f73f059 --- /dev/null +++ b/build-installer.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# +# This script prepares a Devuan installer 'application' as a root +# filesystem packed up as an initrd. + +export http_proxy=http://10.10.10.100:3142 + +: ${LINUX:=linux-image-6.1.0-25-arm64} + +: ${DISTNAME:=daedalus} +: ${DISTVERS:=5.1.0} +: ${TARGET_ARCH:=arm64} +: ${SOURCE_SERVER:=http://deb.devuan.org/merged} +: ${SECTIONS:="main non-free-firmware main/debian-installer"} +: ${BUILD:=build} +: ${SOURCES:=$BUILD/sources} +: ${MEDIA:=$BUILD/media} +: ${INITRD:=$BUILD/initrd} +: ${UDEBSDIR:=$INITRD/udebs} +: ${UDEBSLIST:=$(pwd)/installer-packages.list} + +mkdir -p $SOURCES $MEDIA/{pool,dists} $INITRD + +# Declare global tables: +# DEBURL is a mapping: package => download source path +# DEBDIR is a mapping: package => download target dir +# PKGS is a subset of DEBURL with only packages to download +typeset -A DEBURL DEBDIR PKGS + +# Helper function to print a message to stderr and exit(1). This is +# used as bailout when something seems badly wrong. +die() { echo "$*" >&1 ; exit 1 ; } + +# Helper function to reduce a Pacakges file into a series of mappings +# of the form "package=filename" +deb_url_map() { + sed '/Package:/{s/[^ ]* //;h;d};/Filename:/!d;s/[^ ]* /=/;H;x;s/\n//' $1 +} + +# Helper function that resolves alternative dependency to preferred +# choice, which is one already selected (in PKGS) or else the first of +# options. +check_depends() { + local P + for P in $@ ; do [ -n "${PKGS[$P]}" ] && return 0 ; done + echo "$1" +} + +# Helper function that enumerates all dependent and recommended +# packages of a given package. Uses check_depends to handle +# alternative dependencies +depends() { + local D + sed '/^Package: '$1'$/,/^$/!d;/^\(Depends\|Pre-Depends\|Recommends\):/!d;s/^[^:]*: //;s/([^)]*)//g' $SOURCES/*-Packages | tr , '\012' | \ + while read D ; do check_depends ${D//\|/ } ; done +} + +# Helper function that expands a given package recursively into all +# its depends and recommends and installs them all in PKGS. +expand_depends() { + local F P + for P in $(depends $1) ; do + F="${DEBURL[$P]}" + [ -z "$F" ] && continue + [ -z "${PKGS["$P"]}" ] || continue + PKGS["$P"]="$F" + expand_depends $P + done +} + +# Helper function to download package $1 and all its dependencies +# +download() { + local URI="${DEBURL["$1"]}" + [ -z "$URI" ] && return 1 # Just ignore missing packages + local F="${DEBDIR["$1"]}/${URI##*/}" + [ -f "$F" ] && return 0 # alread y downloaded + PKGS["$1"]="$URI" + local URL="$SOURCE_SERVER/$URI" + mkdir -p "${F%/*}" + for I in {1..5} ; do + wget -O $F -nv "$URL" && break + echo "err $I: $URL" >&2 + rm $F + done + if [ -f "$F" ] ; then + [ -n "$2" ] && cp "$F" "$2/${F##*/}" + for D in $(depends $1) ; do download $D $2 ; done + return 0 + fi + echo "** download error for package $1" >&2 + return 1; +} + +# Helper function to enumerate pool packages +pool_packages() { + local T SRC=$SOURCES/non-free-firmware-Packages + { + # This step prepares the list of all packages of required, + # important and standard priority + for T in required important standard ; do + sed '/^Package:/{s/[^ ]* //;h;d};/^Priority: '$T'$/!d;x' \ + $SOURCES/*-Packages + done + + # This step prepares the list of all packages of + # non-free-firmware + if [ -r $SRC ] ; then + sed '/^Package:/!d;s/[^ ]* //' $SRC + fi + + # This step includes additional packages from files + # pool-packages*.list + sed '/#/d;/^$/d' pool-packages*.list + } | sort -u +} + +############################################################ + +#===== Step 1: Setup "The Sources". +# +# This which means to download Packages files for the $DISTNAME, +# $SECTIONS and $TARGET_ARCH concerned into the $SOURCES directory. + +for S in $SECTIONS ; do + BASE=$SOURCE_SERVER/dists/$DISTNAME/$S/binary-$TARGET_ARCH/Packages + INTO=$SOURCES/${S/\//_}-Packages + [ -f $INTO ] && continue + for E in .xz .gz "" ; do + if wget -nv -O $INTO$E $BASE$E ; then + case "$E" in + .xz) unxz $INTO$E ;; + .gz) gunzip $INTO$E ;; + esac + break; + else + rm -f $INTO$E + fi + done + [ -f $INTO ] || die "Cannot get $BASE" +done + +#==== Step 2: Prepare DEBURL and DEBDIR from the Packages files as +# mappings form package name to download filename and pool section +# respectively + +for S in $SECTIONS ; do + for M in $(deb_url_map "$SOURCES/${S/\//_}-Packages") ; do + echo "$M" >&2 + P="${M%%=*}" + F="${M#*=}" + DEBURL["$P"]="$F" + DEBDIR["$P"]="$MEDIA/pool/$S" + done +done + +#==== Step 3: load up packages to be unpacked for the initrd. This are +# packages enumerated in $UDEBSLIST, expanded for depends and +# recommends. + +mkdir -p $UDEBSDIR +export KERNELVERSION="${LINUX#linux-image-}" +for P in $(envsubst '${KERNELVERSION}' < $UDEBSLIST | sed '/#/d;/^$/d') ; do + download $P $UDEBSDIR +done + +typeset -A INST + +# Helper function that resolves alternative dependency to preferred +# choice, which is one already selected (in PKGS) or else the first of +# options. +check_installed_depends() { + local P + for P in $@ ; do [ -n "${INST[$P]}" ] && return 0 ; done + for P in $@ ; do [ -n "${PKGS[$P]}" ] && echo $P && return 0 ; done +} + +# Helper function that enumerates all dependent and recommended +# packages of a given package. Uses check_depends to handle +# alternative dependencies +install_after() { + local D + sed '/^Package: '$1'$/,/^$/!d;/^\(Depends\|Pre-Depends\|Recommends\):/!d;s/^[^:]*: //;s/([^)]*)//g' $SOURCES/*-Packages | tr , '\012' | \ + while read D ; do check_installed_depends ${D//\|/ } ; done +} + +# Does $1 occur in $2... +mentioned() { + local X="${@:2}" + [ -n "$X" ] && [ -z "${X##*$1*}" ] +} + +# Helper function to enumerate package dependencies in install order +install_order() { + local ORDER=( ${@:1} ) BEFORE=( $(install_after $1) ) + for D in ${BEFORE[@]} ; do + mentioned $D ${@:1} && continue + install_order $D ${BEFORE[@]} $1 ${@:1} + done + echo $1 +} + +# Prepare for unpacking +mkdir -p $INITRD/var/log $INITRD/var/lib/dpkg + +# Set up silly-links +for D in bin sbin lib lib64 ; do + mkdir -p $INITRD/usr/$D + ln -sTf usr/$D $INITRD/$D +done + +echo "######## Installing installer ######### ${#PKGS[@]}" >&2 +# Use busybox-static rather than busybox-udeb +download busybox-static $UDEBSDIR +rm $UDEBSDIR/busybox-udeb_* + +mydpkg() { + fakechroot fakeroot dpkg --force-architecture \ + --admindir=$INITRD/var/lib/dpkg --log=$INITRD/var/log/dpkg.log \ + --root=$INITRD $@ +} + +mydpkg --unpack $UDEBSDIR/busybox-static_*.deb +$INITRD/bin/busybox --list | while read B ; do + case "$B" in + linuxrc|busybox) : ;; + acpid|adjtimex|arp|devmem|freeramdisk|ipneigh|klogd| \ + loadkmap|logread|mdev|run-init|syslogd|tunctl|uevent|vconfig| \ + watchdog|arping|brctl|crond|fsfreeze|i2cdetect|i2cdump| \ + i2cget|i2cset|i2ctransfer|loadfont|mim|partprobe| \ + rdate|telnetd|ubirename|udhcpd) + ln -s ../bin/busybox $INITRD/sbin/$B + ;; + *) + ln -s busybox $INITRD/bin/$B + ;; + esac +done + +echo "# Patch to pretend debian-installer is installed" >&2 +STATUS=$INITRD/var/lib/dpkg/status +if ! grep -q 'Package: debian-installer' ${STATUS} ; then + # Patch ${STATUS} file to pretend debian-installer is installed + VERSION="$(date +"%Y%m%d.%H%M%S-installer")" + cat <> ${STATUS} +Package: debian-installer +Status: install ok installed +Maintainer: $TARGET_ARCH installer +Architecture: $TARGET_ARCH +Version: $VERSION +Description: devuan installation image + +Package: busybox-udeb +Status: install ok installed +Maintainer: $TARGET_ARCH installer +Architecture: $TARGET_ARCH +Version: $VERSION +Description: not actually, but busybox-static is installed + +EOF +fi + +mydpkg --force-overwrite --path-include="$UDEBSDIR/*.deb" \ + --unpack $UDEBSDIR/*.udeb + +# Configure in good order +configured() { + local F="$INITRD/var/lib/dpkg/status" + local X="$(sed '/Package: '$1'$/,/^$/!d;/^Status:/!d' $F)" + [ -z "${X#*installed}" ] +} + +for DEB in $UDEBSDIR/*.udeb ; do + F="${DEB##*/}" + P="${F%%_*}" + for D in $(install_order $P) ; do + configured $D && continue + mydpkg -E --path-include="$UDEBSDIR/*.deb" --configure $D + done +done + +# 3f This is set up for choose-mirror and console-setup +echo ${DISTNAME} > $INITRD/etc/default-release +mkdir $INITRD/etc/console-setup +mkdir -p $INITRD/cdrom + +# 3g Install "initrd-init" as the initrd /init +cp initrd-init $INITRD/init + +#==== Step 4. Set up a package pool +# +# This will populate $MEDIA/pool/* with deb files and $MEDIA/dists +# with Packages.xz to describe them. First PKGS is extended with +# pool_packages, + +# Extend PKGS table with pool packages; +for P in $(pool_packages) ; do + F="${DEBURL[$P]}" + [ -z "$F" ] || PKGS["$P"]="$F" +done + +# Expand the PKGS table with depends and recommends; +echo -n "*** computing dependencies" >&2 +for P in ${!PKGS[@]} ; do expand_depends "$P" ; done +echo + +# Download the PKGS table packages into their pool sections; +for P in ${!PKGS[@]} ; do download "$P" ; done + +# Prepare the distribution indexes for the various sections. +for S in $SECTIONS ; do + P="dists/$DISTNAME/$S/binary-$TARGET_ARCH/Packages" + mkdir -p "$MEDIA/${P%/*}" + ( cd $MEDIA ; dpkg-scanpackages -t '*deb' "pool/$S" > $P ) +done + +apt-ftparchive \ + -o APT::FTPArchive::Release::Date="$(date -R)" \ + -o APT::FTPArchive::Release::Label="DEVUANMEDIA" \ + -o APT::FTPArchive::Release::Origin="Devuan" \ + -o APT::FTPArchive::Release::Suite="stable" \ + -o APT::FTPArchive::Release::Version="$DISTVERS" \ + -o APT::FTPArchive::Release::Codename="$DISTNAME" \ + -o APT::FTPArchive::Release::Architectures="$TARGET_ARCH" \ + -o APT::FTPArchive::Release::Components="$SECTIONS" \ + release $MEDIA > $MEDIA/dists/$DISTNAME/Release +ln -s $DISTNAME $MEDIA/dists/stable + +# Finally prepare a squashfs of $MEDIA into $INITRD +fakeroot mksquashfs $MEDIA $INITRD/pool.squashfs + +#==== Step 5: Pack up the initrd + +# Pack up as initrd.gz and grab vmlinuz +find $INITRD -not -name udebs -printf '%P\n' | \ + fakeroot cpio -o -H newc -D $INITRD | gzip > initrd.gz +cp $INITRD/boot/vmlinuz . + +exit 0 + diff --git a/initrd-init b/initrd-init new file mode 100755 index 0000000..ee2120b --- /dev/null +++ b/initrd-init @@ -0,0 +1,24 @@ +#!/bin/sh +# +echo INITIALIZING >&2 +mkdir -p /proc /dev /sys /tmp /run +mount -t proc proc /proc +mount -t devtmpfs devtmpfs /dev +mount -t sysfs sysfs /sys + +mkdir -p /dev/pts +mount -t devpts devpts /dev/pts + +depmod + +echo NOW WE ARE HERE >&2 +/lib/debian-installer/start-udev + +modprobe loop +modprobe squashfs +losetup -f /pool.squashfs +mount /dev/loop0 /cdrom + +exec /bin/busybox init < /dev/console > /dev/console 2>&1 +/bin/sh +sleep 5 diff --git a/installer-packages.list b/installer-packages.list new file mode 100644 index 0000000..5037f50 --- /dev/null +++ b/installer-packages.list @@ -0,0 +1,119 @@ +# This is a list of packages that should be unpacked for the installer +# Lines with # are ignored. Use envsubst with KERNELVERSION defined +# +kernel-image-${KERNELVERSION}-di +acpi-modules-${KERNELVERSION}-di +ata-modules-${KERNELVERSION}-di +btrfs-modules-${KERNELVERSION}-di +cdrom-core-modules-${KERNELVERSION}-di +compress-modules-${KERNELVERSION}-di +crc-modules-${KERNELVERSION}-di +crypto-dm-modules-${KERNELVERSION}-di +crypto-modules-${KERNELVERSION}-di +efi-modules-${KERNELVERSION}-di +event-modules-${KERNELVERSION}-di +ext4-modules-${KERNELVERSION}-di +f2fs-modules-${KERNELVERSION}-di +fat-modules-${KERNELVERSION}-di +fb-modules-${KERNELVERSION}-di +firewire-core-modules-${KERNELVERSION}-di +fuse-modules-${KERNELVERSION}-di +i2c-modules-${KERNELVERSION}-di +input-modules-${KERNELVERSION}-di +isofs-modules-${KERNELVERSION}-di +jfs-modules-${KERNELVERSION}-di +loop-modules-${KERNELVERSION}-di +md-modules-${KERNELVERSION}-di +mmc-core-modules-${KERNELVERSION}-di +mmc-modules-${KERNELVERSION}-di +mouse-modules-${KERNELVERSION}-di +mtd-core-modules-${KERNELVERSION}-di +multipath-modules-${KERNELVERSION}-di +nbd-modules-${KERNELVERSION}-di +nic-modules-${KERNELVERSION}-di +nic-pcmcia-modules-${KERNELVERSION}-di +nic-shared-modules-${KERNELVERSION}-di +nic-usb-modules-${KERNELVERSION}-di +nic-wireless-modules-${KERNELVERSION}-di +pata-modules-${KERNELVERSION}-di +pcmcia-modules-${KERNELVERSION}-di +pcmcia-storage-modules-${KERNELVERSION}-di +ppp-modules-${KERNELVERSION}-di +sata-modules-${KERNELVERSION}-di +scsi-core-modules-${KERNELVERSION}-di +scsi-modules-${KERNELVERSION}-di +scsi-nic-modules-${KERNELVERSION}-di +serial-modules-${KERNELVERSION}-di +sound-modules-${KERNELVERSION}-di +speakup-modules-${KERNELVERSION}-di +squashfs-modules-${KERNELVERSION}-di +udf-modules-${KERNELVERSION}-di +uinput-modules-${KERNELVERSION}-di +usb-modules-${KERNELVERSION}-di +usb-serial-modules-${KERNELVERSION}-di +usb-storage-modules-${KERNELVERSION}-di +xfs-modules-${KERNELVERSION}-di +apt-cdrom-setup +apt-mirror-setup +apt-setup-udeb +base-installer +bogl-bterm-udeb +bootstrap-base +brltty-udeb +ca-certificates-udeb +cdebconf +cdebconf-newt-entropy +cdebconf-newt-terminal +cdebconf-newt-udeb +cdebconf-priority +cdebconf-text-entropy +cdebconf-text-udeb +cdrom-checker +cdrom-detect +choose-init +console-setup-pc-ekmap +console-setup-udeb +console-setup-linux-fonts-udeb +di-utils-exit-installer +di-utils-reboot +di-utils-shell +eject-udeb +env-preseed +espeakup-udeb +f2fs-tools-udeb +fdisk-udeb +file-preseed +finish-install +gpgv-udeb +haveged-udeb +initrd-preseed +installation-locale +kbd-chooser +kmod-udeb +libc-bin +libc6-udeb +libfribidi0-udeb +libkmod2 +libpcre3-udeb +libelogind0 +libtinfo6-udeb +lilo-installer +load-cdrom +localechooser +lowmemcheck +main-menu +mbr-udeb +mountmedia +nano-udeb +netcfg +nobootloader +openssh-client-udeb +open-iscsi-udeb +pcmciautils-udeb +pkgsel +rescue-mode +rfkill +save-logs +screen-udeb +tzsetup-udeb +wget-udeb diff --git a/pool-packages-installer.list b/pool-packages-installer.list new file mode 100644 index 0000000..9f50a43 --- /dev/null +++ b/pool-packages-installer.list @@ -0,0 +1,113 @@ +####### Selected Installer-Menu packages +# with additions of undeclared dependencies further below +apt-setup-udeb +bootstrap-base +brltty-udeb +cdebconf-priority +cdrom-checker +cdrom-detect +choose-init +clock-setup +console-setup-udeb +di-utils-exit-installer +di-utils-reboot +di-utils-shell +disk-detect +driver-injection-disk-detect +eject-udeb +espeakup-udeb +ethdetect +fdisk-udeb +file-preseed +finish-install +grub-installer +iso-scan +kbd-chooser +lilo-installer +load-cdrom +load-media +localechooser +lowmem +lvmcfg +mbr-udeb +mdcfg +netcfg +netcfg-static +network-console +network-preseed +nobootloader +openssh-client-udeb +parted-udeb +partman-auto +partman-auto-crypto +partman-auto-lvm +partman-auto-raid +partman-base +partman-base +partman-basicfilesystems +partman-basicmethods +partman-btrfs +partman-crypto +partman-crypto-dm +partman-efi +partman-ext3 +partman-iscsi +partman-jfs +partman-lvm +partman-md +partman-multipath +partman-nbd +partman-partitioning +partman-target +partman-utils +partman-xfs +pkgsel +rescue-mode +save-logs +user-setup-udeb + +## Undeclared Installer-Menu package dependencies +bash +bcron +bterm-unifont +busybox +busybox-static +cdebconf-gtk-entropy +cdebconf-newt-entropy +cdebconf-text-entropy +cryptsetup +cryptsetup-initramfs +dash +debconf-utils +devuan-keyring +diffutils +findutils +grep +grub-pc +grub-efi +grub-efi-ia32 +gzip +initramfs-tools +installation-locale +isc-dhcp-client-udeb +iw +jfsutils +libc6 +lilo +locales +lvm2 +lvmcfg +lvmcfg-utils +makedev +mawk +mdadm +openrc +os-prober-udeb +rfkill +reportbug +sed +sudo +sysv-rc +tasksel +wireless-tools +wpasupplicant diff --git a/vm.sh b/vm.sh new file mode 100755 index 0000000..923f7f8 --- /dev/null +++ b/vm.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +IMG=disk.raw + +ARGS=( + -M virt -m 4G -cpu cortex-a53 + # boot setup + -kernel vmlinuz + -initrd initrd.gz + -append "console=ttyAMA0 root=/dev/vda1 roottype=ext4" + -serial mon:stdio -echr 0x1c + # graphics setup + -nographic + #-device virtio-gpu-pci + #-vnc :0 + # harddrive setup + -device virtio-blk-pci,drive=hd + -drive if=none,id=hd,file=$IMG,format=raw + # network setup + -device virtio-net-pci,netdev=unet + -netdev vde,sock=/run/vde.ctl,id=unet +) + +qemu-system-aarch64 "${ARGS[@]}" -- 2.39.2