initial snapshot
authorRalph Ronnquist <rrq@rrq.au>
Fri, 13 Sep 2024 23:45:53 +0000 (09:45 +1000)
committerRalph Ronnquist <rrq@rrq.au>
Fri, 13 Sep 2024 23:45:53 +0000 (09:45 +1000)
build-installer.sh [new file with mode: 0755]
initrd-init [new file with mode: 0755]
installer-packages.list [new file with mode: 0644]
pool-packages-installer.list [new file with mode: 0644]
vm.sh [new file with mode: 0755]

diff --git a/build-installer.sh b/build-installer.sh
new file mode 100755 (executable)
index 0000000..f73f059
--- /dev/null
@@ -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 <<EOF >> ${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 (executable)
index 0000000..ee2120b
--- /dev/null
@@ -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 (file)
index 0000000..5037f50
--- /dev/null
@@ -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 (file)
index 0000000..9f50a43
--- /dev/null
@@ -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 (executable)
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[@]}"