~ajhalili2006/ppa

f817c8c44d04aeb58924cc8efba1b9fd1721c8e2 — Andrei Jiroh Halili 5 months ago 67c23b1
build(alpine/build): :construction_worker: add build scripts for ISO generation from upstream aports

Typical copying from my local copy, although I may check if they're outdated lol.

Signed-off-by: Andrei Jiroh Halili <ajhalili2006@andreijiroh.eu.org>
A alpine/build/bootstrap.sh => alpine/build/bootstrap.sh +154 -0
@@ 0,0 1,154 @@
#!/bin/sh

set -e

TARGET_ARCH="$1"
SUDO_APK=abuild-apk

# optional cross build packages
: ${KERNEL_PKG=linux-firmware linux-lts}

if [ -z "$TARGET_ARCH" ]; then
	program=$(basename $0)
	cat <<EOF
usage: $program TARGET_ARCH

This script creates a local cross-compiler, and uses it to
cross-compile an Alpine Linux base system for new architecture.

Steps for introducing new architecture include:
- adding the compiler triplet and arch type to abuild
- adding the arch type detection to apk-tools
- adjusting build rules for packages that are arch aware:
  gcc, openssl, linux-headers, musl
- create new kernel config for linux-lts

After these steps the initial cross-build can be completed
by running this with the target arch as parameter, e.g.:
	./$program aarch64

The cross-compiler generated by this script is not intended
nor supported for any use other than building the base system
and other packages in the bootstrap path.

EOF
	return 1
fi

# get abuild configurables
[ -e /usr/share/abuild/functions.sh ] || (echo "abuild not found" ; exit 1)
CBUILDROOT="$(CTARGET=$TARGET_ARCH . /usr/share/abuild/functions.sh ; echo $CBUILDROOT)"
. /usr/share/abuild/functions.sh
[ -z "$CBUILD_ARCH" ] && die "abuild is too old (use 2.29.0 or later)"
[ -z "$CBUILDROOT" ] && die "CBUILDROOT not set for $TARGET_ARCH"
export CBUILD

# deduce aports directory
[ -z "$APORTS" ] && APORTS=$(realpath $(dirname $0)/../)
[ -e "$APORTS/main/build-base" ] || die "Unable to deduce aports base checkout"

apkbuildname() {
	local repo="${1%%/*}"
	local pkg="${1##*/}"
	[ "$repo" = "$1" ] && repo="main"
	echo $APORTS/$repo/$pkg/APKBUILD
}

msg() {
	[ -n "$quiet" ] && return 0
	local prompt="$GREEN>>>${NORMAL}"
	local name="${BLUE}bootstrap-${TARGET_ARCH}${NORMAL}"
        printf "${prompt} ${name}: %s\n" "$1" >&2
}

if [ ! -d "$CBUILDROOT" ]; then
	msg "Creating sysroot in $CBUILDROOT"
	mkdir -p "$CBUILDROOT/etc/apk/keys"
	# /etc/apk/keys and ~/.abuild/ can contain files with the same names.
	# if that is the case, cp will abort copying and fail. Then on the next
	# run of the bootstrap script, 1) the keys are not in the sysroot and 
	# 2) the apk database is not initialized the sysroot
	# Thus it's unusable at that point and needs to be deleted manually.
	cp -a /etc/apk/keys/* "$CBUILDROOT/etc/apk/keys"
	cp -a ~/.abuild/*.pub "$CBUILDROOT/etc/apk/keys"
	${SUDO_APK} add --quiet --initdb --arch $TARGET_ARCH --root $CBUILDROOT
fi

msg "Building cross-compiler"

# Build and install cross binutils (--with-sysroot)
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname binutils) abuild -r

if ! CHOST=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname musl) abuild up2date 2>/dev/null; then
	# C-library headers for target
	CHOST=$TARGET_ARCH BOOTSTRAP=nocc APKBUILD=$(apkbuildname musl) abuild -r

	# Minimal cross GCC
	EXTRADEPENDS_HOST="musl-dev" \
	CTARGET=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname gcc) abuild -r

	# Cross build bootstrap C-library for the target
	EXTRADEPENDS_BUILD="gcc-pass2-$TARGET_ARCH" \
	CHOST=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname musl) abuild -r
fi

# Full cross GCC
EXTRADEPENDS_TARGET="musl musl-dev" \
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname gcc) abuild -r

# Cross build-base
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname build-base) abuild -r

msg "Cross building base system"

# Implicit dependencies for early targets
EXTRADEPENDS_TARGET="libgcc libstdc++ musl-dev"

# On a few architectures like riscv64 we need to account for
# gcc requiring -ltomic to be set explicitly if a C[++]11 program
# uses atomics (e.g. #include <atomic>):
# https://github.com/riscv/riscv-gnu-toolchain/issues/183#issuecomment-253721765
# The reason gcc itself is needed is because .so is in that package,
# not in libatomic.
if [ "$TARGET_ARCH" = "riscv64" ]; then
	NEEDS_LIBATOMIC="yes"
fi

for PKG in fortify-headers linux-headers musl libc-dev pkgconf zlib \
	   openssl ca-certificates libmd \
	   gmp mpfr4 mpc1 isl26 libucontext zstd binutils gcc \
	   libbsd busybox make \
	   apk-tools file \
	   libcap openrc alpine-conf alpine-baselayout alpine-keys alpine-base patch build-base \
	   attr acl fakeroot tar \
	   lzip abuild ncurses libedit openssh \
	   libcap-ng util-linux libaio lvm2 popt xz \
	   json-c argon2 cryptsetup kmod lddtree mkinitfs \
	   libffi \
	   brotli libev c-ares cunit nghttp2 libidn2 curl \
	   libssh2 \
	   libxml2 pax-utils llvm14 community/ghc llvm16 rust \
	   $KERNEL_PKG ; do

	if [ "$NEEDS_LIBATOMIC" = "yes" ]; then
		EXTRADEPENDS_BUILD="libatomic gcc-$TARGET_ARCH g++-$TARGET_ARCH"
	fi
	EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET"  EXTRADEPENDS_BUILD="$EXTRADEPENDS_BUILD" \
	CHOST=$TARGET_ARCH BOOTSTRAP=bootimage APKBUILD=$(apkbuildname $PKG) abuild -r

	case "$PKG" in
	fortify-headers | libc-dev)
		# Additional implicit dependencies once built
		EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET $PKG"
		;;
	gcc)
		if [ "$NEEDS_LIBATOMIC" = "yes" ]; then
			EXTRADEPENDS_TARGET="libatomic gcc $EXTRADEPENDS_TARGET"
		fi
		;;
	build-base)
		# After build-base, that alone is sufficient dependency in the target
		EXTRADEPENDS_TARGET="busybox $PKG"
		;;
	esac
done

A alpine/build/genapkovl-dhcp.sh => alpine/build/genapkovl-dhcp.sh +66 -0
@@ 0,0 1,66 @@
#!/bin/sh -e

HOSTNAME="$1"
if [ -z "$HOSTNAME" ]; then
	echo "usage: $0 hostname"
	exit 1
fi

cleanup() {
	rm -rf "$tmp"
}

makefile() {
	OWNER="$1"
	PERMS="$2"
	FILENAME="$3"
	cat > "$FILENAME"
	chown "$OWNER" "$FILENAME"
	chmod "$PERMS" "$FILENAME"
}

rc_add() {
	mkdir -p "$tmp"/etc/runlevels/"$2"
	ln -sf /etc/init.d/"$1" "$tmp"/etc/runlevels/"$2"/"$1"
}

tmp="$(mktemp -d)"
trap cleanup EXIT

mkdir -p "$tmp"/etc
makefile root:root 0644 "$tmp"/etc/hostname <<EOF
$HOSTNAME
EOF

mkdir -p "$tmp"/etc/network
makefile root:root 0644 "$tmp"/etc/network/interfaces <<EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF

mkdir -p "$tmp"/etc/apk
makefile root:root 0644 "$tmp"/etc/apk/world <<EOF
alpine-base
EOF

rc_add devfs sysinit
rc_add dmesg sysinit
rc_add mdev sysinit
rc_add hwdrivers sysinit
rc_add modloop sysinit

rc_add hwclock boot
rc_add modules boot
rc_add sysctl boot
rc_add hostname boot
rc_add bootmisc boot
rc_add syslog boot

rc_add mount-ro shutdown
rc_add killprocs shutdown
rc_add savecache shutdown

tar -c -C "$tmp" etc | gzip -9n > $HOSTNAME.apkovl.tar.gz

A alpine/build/genapkovl-xen.sh => alpine/build/genapkovl-xen.sh +75 -0
@@ 0,0 1,75 @@
#!/bin/sh -e

HOSTNAME="$1"
if [ -z "$HOSTNAME" ]; then
	echo "usage: $0 hostname"
	exit 1
fi

cleanup() {
	rm -rf "$tmp"
}

makefile() {
	OWNER="$1"
	PERMS="$2"
	FILENAME="$3"
	cat > "$FILENAME"
	chown "$OWNER" "$FILENAME"
	chmod "$PERMS" "$FILENAME"
}

rc_add() {
	mkdir -p "$tmp"/etc/runlevels/"$2"
	ln -sf /etc/init.d/"$1" "$tmp"/etc/runlevels/"$2"/"$1"
}

tmp="$(mktemp -d)"
trap cleanup EXIT

mkdir -p "$tmp"/etc
makefile root:root 0644 "$tmp"/etc/hostname <<EOF
$HOSTNAME
EOF

makefile root:root 0644 "$tmp"/etc/modules <<EOF
xen_netback
xen_blkback
xenfs
xen-platform-pci
xen_wdt
tun
EOF

mkdir -p "$tmp"/etc/network
makefile root:root 0644 "$tmp"/etc/network/interfaces <<EOF
auto lo
iface lo inet loopback
EOF

mkdir -p "$tmp"/etc/apk

makefile root:root 0644 "$tmp"/etc/apk/world <<EOF
xen
EOF

rc_add devfs sysinit
rc_add dmesg sysinit
rc_add udev sysinit

rc_add hwclock boot
rc_add modules boot
rc_add sysctl boot
rc_add hostname boot
rc_add bootmisc boot
rc_add syslog boot

rc_add udev-postmount default
rc_add xenstored default
rc_add xenconsoled default

rc_add mount-ro shutdown
rc_add killprocs shutdown
rc_add savecache shutdown

tar -c -C "$tmp" etc | gzip -9n > $HOSTNAME.apkovl.tar.gz

A alpine/build/genrootfs.sh => alpine/build/genrootfs.sh +58 -0
@@ 0,0 1,58 @@
#!/bin/sh -e

cleanup() {
	rm -rf "$tmp"
}

tmp="$(mktemp -d)"
trap cleanup EXIT
chmod 0755 "$tmp"

arch="$(apk --print-arch)"
repositories_file=/etc/apk/repositories
keys_dir=/etc/apk/keys

while getopts "a:r:k:o:" opt; do
	case $opt in
	a) arch="$OPTARG";;
	r) repositories_file="$OPTARG";;
	k) keys_dir="$OPTARG";;
	o) outfile="$OPTARG";;
	esac
done
shift $(( $OPTIND - 1))

cat "$repositories_file"

if [ -z "$outfile" ]; then
	outfile=$name-$arch.tar.gz
fi

${APK:-apk} add --keys-dir "$keys_dir" --no-cache \
	--repositories-file "$repositories_file" \
	--no-script --root "$tmp" --initdb --arch "$arch" \
	"$@"
for link in $("$tmp"/bin/busybox --list-full); do
	[ -e "$tmp"/$link ] || ln -s /bin/busybox "$tmp"/$link
done

${APK:-apk} fetch --keys-dir "$keys_dir" --no-cache \
	--repositories-file "$repositories_file" --root "$tmp" \
	--stdout --quiet alpine-release | tar -zx -C "$tmp" etc/

# make sure root login is disabled
sed -i -e 's/^root::/root:*:/' "$tmp"/etc/shadow

branch=edge
VERSION_ID=$(awk -F= '$1=="VERSION_ID" {print $2}'  "$tmp"/etc/os-release)
case $VERSION_ID in
*_alpha*|*_beta*) branch=edge;;
*.*.*) branch=v${VERSION_ID%.*};;
esac

cat > "$tmp"/etc/apk/repositories <<EOF
https://dl-cdn.alpinelinux.org/alpine/$branch/main
https://dl-cdn.alpinelinux.org/alpine/$branch/community
EOF

tar --numeric-owner --exclude='dev/*' -c -C "$tmp" . | gzip -9n > "$outfile"

A alpine/build/mkimage-yaml.sh => alpine/build/mkimage-yaml.sh +81 -0
@@ 0,0 1,81 @@
#!/bin/sh

progname=$(basename $0)

usage() {
	echo "usage: $progname --checksums <checksums> --arch <arch> FILE..."
}

checksums="sha256 sha512"
while [ $# -gt 0 ]; do
	opt="$1"
	shift
	case "$opt" in
	--checksums) checksums="$1"; shift ;;
	--arch) arch="$1"; shift ;;
	--branch) branch="$1"; shift;;
	--release) release="$1"; shift;;
	--flavor) flavor="$1"; shift;;
	--title) title="$1"; shift;;
	--desc) desc="$1"; shift;;
	--) break ;;
	-*) usage; exit 1;;
	esac
done

set -- $opt "$@"

if [ -z "$branch" ]; then
	case "$release" in
	*.*.*_alpha*|*.*.*_beta*) branch=edge;;
	*.*.*) branch=${release%.*}; branch="v${branch#v}";;
	*)
		git_branch="$(git rev-parse --abbrev-ref HEAD)"
		case "$git_branch" in
		*-stable) branch=${git_branch%-stable};;
		*) branch=edge;;
		esac
		;;
	esac
fi
releasedir="$branch/releases/$arch"

[ -n "$arch" ] || arch=$(apk --print-arch)


for image; do
	filepath="$releasedir/${image##*/}"
	datetime="$(stat -c "%y" $image)"
	size="$(stat -c "%s" $image)"
	date=${datetime%% *}
	time=${datetime#* }
	time=${time%.*}
	file=${filepath##*/}
	flavor=${file%-${release}-${arch}.*}
	desc=$(echo "$desc" | sed -E 's/^\s*/    /')

	cat <<-EOF
	-
	  title: "$title"
	  desc: |
	$desc
	  branch: $branch
	  arch: $arch
	  version: $release
	  flavor: $flavor
	  file: $file
	  iso: $file
	  date: $date
	  time: $time
	  size: $size
EOF
	# generate checksums if missing
	for hash in ${checksums}; do
		if ! [ -f "$image.$hash" ]; then
			${hash}sum $image | sed 's: .*/:  :' > $image.$hash
		fi
		echo "  $hash: $(cut -d' ' -f1 $image.$hash)"
	done


done

A alpine/build/mkimage.sh => alpine/build/mkimage.sh +321 -0
@@ 0,0 1,321 @@
#!/bin/sh

# apk add \
#	abuild apk-tools alpine-conf busybox fakeroot syslinux xorriso cmd:mksquashfs
#	(for efi:) mtools grub-efi

# FIXME: clean workdir out of unneeded sections
# FIXME: --release: cp/mv images to REPODIR/$ARCH/releases/
# FIXME: --update-latest: rewrite latest-releases.yaml with this build

set -e

# get abuild configurables
[ -e /usr/share/abuild/functions.sh ] || (echo "abuild not found" ; exit 1)
. /usr/share/abuild/functions.sh

scriptdir="$(dirname "$0")"
git=$(command -v git) || git=true

# deduce aports directory
[ -n "$APORTS" ] || APORTS=$(realpath "$scriptdir/../")
[ -e "$APORTS/main/build-base" ] || die "Unable to deduce aports base checkout"

# echo '-dirty' if git is not clean
git_dirty() {
	[ $($git status -s -- "$scriptdir" | wc -l) -ne 0 ] && echo "-dirty"
}

# echo last commit hash id
git_last_commit() {
	$git log --format=oneline -n 1 -- "$scriptdir" | awk '{print $1}'
}

# date of last commit
git_last_commit_epoch() {
	$git log -1 --format=%cd --date=unix "$1" -- "$scriptdir"
}

set_source_date() {
	# dont error out if we're not in git
	if ! $git rev-parse --show-toplevel >/dev/null 2>&1; then
		git=true
	fi
	# set time stamp for reproducible builds
	if [ -z "$ABUILD_LAST_COMMIT" ]; then
		export ABUILD_LAST_COMMIT="$(git_last_commit)$(git_dirty)"
	fi
	if [ -z "$SOURCE_DATE_EPOCH" ] && [ "${ABUILD_LAST_COMMIT%-dirty}" = "$ABUILD_LAST_COMMIT" ]; then
		SOURCE_DATE_EPOCH=$(git_last_commit_epoch "$ABUILD_LAST_COMMIT")
	fi
	if [ -z "$SOURCE_DATE_EPOCH" ]; then
		SOURCE_DATE_EPOCH=$(date -u "+%s")
	fi
	export SOURCE_DATE_EPOCH
}

set_source_date

# 
all_sections=""
all_profiles=""
all_checksums="sha256 sha512"
all_arches="aarch64 armhf armv7 riscv64 x86 x86_64"
all_dirs=""
build_date="$(date -u +%y%m%d -d "@$SOURCE_DATE_EPOCH")"
default_arch="$(apk --print-arch)"
_hostkeys=""
_simulate=""
_checksum=""

OUTDIR="$PWD"
RELEASE="${build_date}"


msg() {
	if [ -n "$quiet" ]; then return 0; fi
	local prompt="$GREEN>>>${NORMAL}"
	local name="${BLUE}mkimage${ARCH+-$ARCH}${NORMAL}"
	printf "${prompt} ${name}: %s\n" "$1" >&2
}

list_has() {
	local needle="$1"
	local i
	shift
	for i in $@; do
		[ "$needle" != "$i" ] || return 0
	done
	return 1
}

usage() {
	cat <<EOF

$0	[--tag RELEASE] [--outdir OUTDIR] [--workdir WORKDIR]
		[--arch ARCH] [--profile PROFILE] [--hostkeys] [--simulate]
		[--repository REPO] [--extra-repository REPO] [--yaml FILE]
$0	--help

options:
--arch			Specify which architecture images to build
			(default: $default_arch)
--hostkeys		Copy system apk signing keys to created images
--outdir		Specify directory for the created images
--profile		Specify which profiles to build
--repository		Package repository to use for the image create
--extra-repository	Add repository to search packages from
--simulate		Don't execute commands
--tag			Build images for tag RELEASE
--workdir		Specify temporary working directory (cache)
--yaml

known profiles: $(echo $all_profiles | sort -u)

EOF
}

# helpers
load_plugins() {
	local f
	[ -e "$1" ] || return 0
	for f in "$1"/mkimg.*.sh; do
		[ -e "$f" ] || return 0
		break
	done
	all_profiles="$all_profiles $(sed -n -e 's/^profile_\(.*\)() {$/\1/p' $1/mkimg.*.sh)"
	all_sections="$all_sections $(sed -n -e 's/^section_\(.*\)() {$/\1/p' $1/mkimg.*.sh)"
	for f in "$1"/mkimg.*.sh; do
		. $f
	done
}

checksum() {
	sha1sum | cut -f 1 -d ' '
}

build_section() {
	local section="$1"
	local args="$@"
	local _dir="${args//[^a-zA-Z0-9]/_}"
	shift
	local args="$@"

	if [ -z "$_dir" ]; then
		_fail="yes"
		return 1
	fi

	if [ ! -e "$WORKDIR/${_dir}" ]; then
		DESTDIR="$WORKDIR/${_dir}.work"
		msg "--> $section $args"
		if [ -z "$_simulate" ]; then
			rm -rf "$DESTDIR"
			mkdir -p "$DESTDIR"
			if build_${section} "$@"; then
				mv "$DESTDIR" "$WORKDIR/${_dir}"
				_dirty="yes"
			else
				rm -rf "$DESTDIR"
				_fail="yes"
				return 1
			fi
		fi
	fi
	unset DESTDIR
	all_dirs="$all_dirs $_dir"
	_my_sections="$_my_sections $_dir"
}

build_profile() {
	local _id _dir _spec
	_my_sections=""
	_dirty="no"
	_fail="no"

	profile_$PROFILE
	list_has $ARCH $arch || return 0

	msg "Building $PROFILE"

	# Collect list of needed sections, and make sure they are built
	for SECTION in $all_sections; do
		section_$SECTION || return 1
	done
	[ "$_fail" = "no" ] || return 1

	# Defaults
	[ -n "$image_name" ] || image_name="alpine-${PROFILE}"
	[ -n "$output_filename" ] || output_filename="${image_name}-${RELEASE}-${ARCH}.${image_ext}"
	local output_file="${OUTDIR:-.}/$output_filename"

	# Construct final image
	local _imgid=$(echo -n $_my_sections | sort | checksum)
	DESTDIR=$WORKDIR/image-$_imgid-$ARCH-$PROFILE
	if [ "$_dirty" = "yes" -o ! -e "$DESTDIR" ]; then
		msg "Creating $output_filename"
		if [ -z "$_simulate" ]; then
			# Merge sections
			rm -rf "$DESTDIR"
			mkdir -p "$DESTDIR"
			for _dir in $_my_sections; do
				for _fn in $WORKDIR/$_dir/*; do
					[ ! -e "$_fn" ] || cp -Lrs $_fn $DESTDIR/
				done
			done
			echo "${image_name}-${RELEASE} ${build_date}" > "$DESTDIR"/.alpine-release
		fi
	fi

	if [ "$_dirty" = "yes" -o ! -e "$output_file" ]; then
		# Create image
		[ -n "$output_format" ] || output_format="${image_ext//[:\.]/}"
		create_image_${output_format} || { _fail="yes"; false; }

		if [ "$_checksum" = "yes" ]; then
			for _c in $all_checksums; do
				echo "$(${_c}sum "$output_file" | cut -d' '  -f1)  ${output_filename}" > "${output_file}.${_c}"
			done
		fi
	fi
	if [ -n "$_yaml_out" ]; then
		$mkimage_yaml --release $RELEASE \
			--title "$title" \
			--desc "$desc" \
			"$output_file" >> "$_yaml_out"
	fi
}

# load plugins
load_plugins "$scriptdir"
[ -z "$HOME" ] || load_plugins "$HOME/.mkimage"

mkimage_yaml="$(dirname $0)"/mkimage-yaml.sh

# parse parameters
while [ $# -gt 0 ]; do
	opt="$1"
	shift
	case "$opt" in
	--repository)
		if [ -z "$REPOS" ]; then
			REPOS="$1"
		else
			REPOS=$(printf '%s\n%s' "$REPOS" "$1");
		fi
		shift ;;
	--extra-repository) EXTRAREPOS="$EXTRAREPOS $1"; shift ;;
	--workdir) WORKDIR="$1"; shift ;;
	--outdir) OUTDIR="$1"; shift ;;
	--tag) RELEASE="$1"; shift ;;
	--arch) req_arch="$1"; shift ;;
	--profile) req_profiles="$1"; shift ;;
	--hostkeys) _hostkeys="--hostkeys";;
	--simulate) _simulate="yes";;
	--checksum) _checksum="yes";;
	--yaml) _yaml="yes";;
	--help) usage; exit 0;;
	--) break ;;
	-*) usage; exit 1;;
	esac
done

if [ -z "$RELEASE" ]; then
	if git describe --exact-match >/dev/null 2>&1; then
		RELEASE=$(git describe --always)
		RELEASE=${RELEASE#v}
	else
		RELEASE="${build_date}"
	fi
fi

if [ -z "$REPOS" ]; then
  echo "Must provide --repository"
  exit 2
fi

# setup defaults
if [ -z "$WORKDIR" ]; then
	WORKDIR="$(mktemp -d -t mkimage.XXXXXX)"
	trap 'rm -rf $WORKDIR' INT EXIT
fi
req_profiles=${req_profiles:-${all_profiles}}
req_arch=${req_arch:-${default_arch}}
[ "$req_arch" != "all" ] || req_arch="${all_arch}"
[ "$req_profiles" != "all" ] || req_profiles="${all_profiles}"

mkdir -p "$OUTDIR"

# get abuild pubkey used to sign the apkindex
# we need inject this to the initramfs or we will not be able to use the
# boot repository
if [ -z "$_hostkeys" ]; then
	_pub=${PACKAGER_PRIVKEY:+${PACKAGER_PRIVKEY}.pub}
	_abuild_pubkey="${PACKAGER_PUBKEY:-$_pub}"
fi

# create images
for ARCH in $req_arch; do
	APKROOT="$WORKDIR/apkroot-$ARCH"
	if [ ! -e "$APKROOT" ]; then
		# create root for caching packages
		mkdir -p "$APKROOT/etc/apk/cache"
		cp -Pr /etc/apk/keys "$APKROOT/etc/apk/"
		apk --arch "$ARCH" --root "$APKROOT" add --initdb

		echo "$REPOS" > "$APKROOT/etc/apk/repositories"
		for repo in $EXTRAREPOS; do
			echo "$repo" >> "$APKROOT/etc/apk/repositories"
		done
	fi
	apk update --root "$APKROOT"

	if [ "$_yaml" = "yes" ]; then
		_yaml_out=${OUTDIR:-.}/latest-releases.yaml
		echo "---" > "$_yaml_out"
	fi
	for PROFILE in $req_profiles; do
		(build_profile) || exit 1
	done
done
echo "Images generated in $OUTDIR"

A alpine/build/mkimg.arm.sh => alpine/build/mkimg.arm.sh +151 -0
@@ 0,0 1,151 @@
build_rpi_blobs() {
	for i in raspberrypi-bootloader-common raspberrypi-bootloader; do
		apk fetch --quiet --stdout "$i" | tar -C "${DESTDIR}" -zx --strip=1 boot/ || return 1
	done
}

rpi_gen_cmdline() {
	echo "modules=loop,squashfs,sd-mod,usb-storage quiet ${kernel_cmdline}"
}

rpi_gen_config() {
	cat <<-EOF
	# do not modify this file as it will be overwritten on upgrade.
	# create and/or modify usercfg.txt instead.
	# https://www.raspberrypi.com/documentation/computers/config_txt.html
	EOF
	case "$ARCH" in
	armhf)
		cat <<-EOF
		[pi0]
		kernel=boot/vmlinuz-rpi
		initramfs boot/initramfs-rpi
		[pi0w]
		kernel=boot/vmlinuz-rpi
		initramfs boot/initramfs-rpi
		[pi1]
		kernel=boot/vmlinuz-rpi
		initramfs boot/initramfs-rpi
		[pi02]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[pi2]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[pi3]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[pi3+]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[all]
		include usercfg.txt
		EOF
	;;
	armv7)
		cat <<-EOF
		[pi02]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[pi2]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[pi3]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[pi3+]
		kernel=boot/vmlinuz-rpi2
		initramfs boot/initramfs-rpi2
		[pi4]
		kernel=boot/vmlinuz-rpi4
		initramfs boot/initramfs-rpi4
		[all]
		include usercfg.txt
		EOF
	;;
	aarch64)
		cat <<-EOF
		[pi02]
		kernel=boot/vmlinuz-rpi
		initramfs boot/initramfs-rpi
		[pi3]
		kernel=boot/vmlinuz-rpi
		initramfs boot/initramfs-rpi
		[pi3+]
		kernel=boot/vmlinuz-rpi
		initramfs boot/initramfs-rpi
		[pi4]
		enable_gic=1
		kernel=boot/vmlinuz-rpi4
		initramfs boot/initramfs-rpi4
		[all]
		arm_64bit=1
		include usercfg.txt
		EOF
	;;
	esac
}

build_rpi_config() {
	rpi_gen_cmdline > "${DESTDIR}"/cmdline.txt
	rpi_gen_config > "${DESTDIR}"/config.txt
}

section_rpi_config() {
	[ "$hostname" = "rpi" ] || return 0
	build_section rpi_config $( (rpi_gen_cmdline ; rpi_gen_config) | checksum )
	build_section rpi_blobs
}

profile_rpi() {
	profile_base
	title="Raspberry Pi"
	desc="Includes Raspberry Pi kernel.
		Designed for RPI 1, 2, 3 and 4.
		And much more..."
	image_ext="tar.gz"
	arch="aarch64 armhf armv7"
	kernel_flavors="rpi"
	case "$ARCH" in
		aarch64) kernel_flavors="rpi rpi4";;
		armhf) kernel_flavors="rpi rpi2";;
		armv7) kernel_flavors="rpi2 rpi4";;
	esac
	kernel_cmdline="console=tty1"
	initfs_features="base squashfs mmc usb kms dhcp https"
	hostname="rpi"
	grub_mod=
}

build_uboot() {
	set -x
	# FIXME: Fix apk-tools to extract packages directly
	local pkg pkgs="$(apk fetch  --simulate --root "$APKROOT" --recursive u-boot-all | sed -ne "s/^Downloading \(.*\)\-[0-9].*$/\1/p")"
	for pkg in $pkgs; do
		[ "$pkg" = "u-boot-all" ] || apk fetch --root "$APKROOT" --stdout $pkg | tar -C "$DESTDIR" -xz usr
	done
	mkdir -p "$DESTDIR"/u-boot
	mv "$DESTDIR"/usr/sbin/update-u-boot "$DESTDIR"/usr/share/u-boot/* "$DESTDIR"/u-boot
	rm -rf "$DESTDIR"/usr
}

section_uboot() {
	[ -n "$uboot_install" ] || return 0
	build_section uboot $ARCH $(apk fetch --root "$APKROOT" --simulate --recursive u-boot-all | sort | checksum)
}

profile_uboot() {
	profile_base
	title="Generic ARM"
	desc="Has default ARM kernel.
		Includes the uboot bootloader.
		Supports armv7 and aarch64."
	image_ext="tar.gz"
	arch="aarch64 armv7"
	kernel_flavors="lts"
	kernel_addons="xtables-addons"
	initfs_features="base bootchart ext4 kms mmc nvme raid scsi squashfs usb"
	apkovl="genapkovl-dhcp.sh"
	hostname="alpine"
	uboot_install="yes"
}

A alpine/build/mkimg.base.sh => alpine/build/mkimg.base.sh +333 -0
@@ 0,0 1,333 @@
build_kernel() {
	local _flavor="$2" _modloopsign= _add
	shift 3
	local _pkgs="$@"
	[ "$modloop_sign" = "yes" ] && _modloopsign="--modloopsign"
	update-kernel \
		$_hostkeys \
		${_abuild_pubkey:+--apk-pubkey $_abuild_pubkey} \
		$_modloopsign \
		--media \
		--flavor "$_flavor" \
		--arch "$ARCH" \
		--package "$_pkgs" \
		--feature "$initfs_features" \
		--modloopfw "$modloopfw" \
		--repositories-file "$APKROOT/etc/apk/repositories" \
		"$DESTDIR" \
		|| return 1
    if [ -n "$boot_addons" ]; then
        for _add in $boot_addons; do
           apk fetch --quiet --stdout $_add | tar -C "${DESTDIR}" -zx boot/
        done
    fi
}

section_kernels() {
	local _f _a _pkgs
	for _f in $kernel_flavors; do
		_pkgs="linux-$_f linux-firmware wireless-regdb $modloop_addons"
		for _a in $kernel_addons; do
			_pkgs="$_pkgs $_a-$_f"
		done
		local id=$( (echo "$initfs_features::$_hostkeys" ; apk fetch --root "$APKROOT" --simulate alpine-base $_pkgs | sort) | checksum)
		build_section kernel $ARCH $_f $id $_pkgs
	done
}

build_apks() {
	local _apksdir="$DESTDIR/apks"
	local _archdir="$_apksdir/$ARCH"
	mkdir -p "$_archdir"

	apk fetch --root "$APKROOT" --link --recursive --output "$_archdir" $apks
	if ! ls "$_archdir"/*.apk >& /dev/null; then
		return 1
	fi

	apk index \
		--description "$RELEASE" \
		--rewrite-arch "$ARCH" \
		--index "$_archdir"/APKINDEX.tar.gz \
		--output "$_archdir"/APKINDEX.tar.gz \
		"$_archdir"/*.apk
	abuild-sign "$_archdir"/APKINDEX.tar.gz
	touch "$_apksdir/.boot_repository"
}

section_apks() {
	[ -n "$apks" ] || return 0
	build_section apks $ARCH $(apk fetch --root "$APKROOT" --simulate --recursive $apks | sort | checksum)
}

build_apkovl() {
	local _host="$1" _script=
	msg "Generating $_host.apkovl.tar.gz"
	for _script in "$PWD"/"$apkovl" $HOME/.mkimage/$apkovl \
		$(readlink -f "$scriptdir/$apkovl"); do

		if [ -f "$_script" ]; then
			break
		fi
	done
	[ -n "$_script" ] || die "could not find $apkovl"
	(cd "$DESTDIR"; fakeroot "$_script" "$_host")
}

section_apkovl() {
	[ -n "$apkovl" -a -n "$hostname" ] || return 0
	build_section apkovl $hostname $(checksum < "$apkovl")
}

build_syslinux() {
	local _fn
	mkdir -p "$DESTDIR"/boot/syslinux
	apk fetch --root "$APKROOT" --stdout syslinux | tar -C "$DESTDIR" -xz usr/share/syslinux
	for _fn in isohdpfx.bin isolinux.bin ldlinux.c32 libutil.c32 libcom32.c32 mboot.c32; do
		mv "$DESTDIR"/usr/share/syslinux/$_fn "$DESTDIR"/boot/syslinux/$_fn || return 1
	done
	rm -rf "$DESTDIR"/usr
}

section_syslinux() {
	[ "$ARCH" = x86 -o "$ARCH" = x86_64 ] || return 0
	[ "$output_format" = "iso" ] || return 0
	build_section syslinux $(apk fetch --root "$APKROOT" --simulate syslinux | sort | checksum)
}

syslinux_gen_config() {
	[ -z "$syslinux_serial" ] || echo "SERIAL $syslinux_serial"
	echo "TIMEOUT ${syslinux_timeout:-10}"
	echo "PROMPT ${syslinux_prompt:-1}"
	echo "DEFAULT ${kernel_flavors%% *}"

	local _f _p _initrd
	for _f in $kernel_flavors; do
		if [ -z "${xen_params+set}" ]; then
			_initrd="/boot/initramfs-$_f"
			if [ -n "$initrd_ucode" ]; then
				for _p in $initrd_ucode; do
					_initrd="$_p,$_initrd"
				done
			fi

			cat <<- EOF

			LABEL $_f
				MENU LABEL Linux $_f
				KERNEL /boot/vmlinuz-$_f
				INITRD $_initrd
				FDTDIR /boot/dtbs-$_f
				APPEND $initfs_cmdline $kernel_cmdline
			EOF
		else
			cat <<- EOF

			LABEL $_f
				MENU LABEL Xen/Linux $_f
				KERNEL /boot/syslinux/mboot.c32
				APPEND /boot/xen.gz ${xen_params} --- /boot/vmlinuz-$_f $initfs_cmdline $kernel_cmdline --- /boot/initramfs-$_f
			EOF
		fi
	done
}

grub_gen_config() {
	local _f _p _initrd
	echo "set timeout=1"
	for _f in $kernel_flavors; do
		if [ -z "${xen_params+set}" ]; then
			_initrd="/boot/initramfs-$_f"
			if [ -n "$initrd_ucode" ]; then
				for _p in $initrd_ucode; do
					_initrd="$_p $_initrd"
				done
			fi

			cat <<- EOF

			menuentry "Linux $_f" {
				linux	/boot/vmlinuz-$_f $initfs_cmdline $kernel_cmdline
				initrd	$_initrd
			}
			EOF
		else
			cat <<- EOF

			menuentry "Xen/Linux $_f" {
				multiboot2	/boot/xen.gz ${xen_params}
				module2		/boot/vmlinuz-$_f $initfs_cmdline $kernel_cmdline
				module2		/boot/initramfs-$_f
			}
			EOF
		fi
	done
}

build_syslinux_cfg() {
	local syslinux_cfg="$1"
	mkdir -p "${DESTDIR}/$(dirname $syslinux_cfg)"
	syslinux_gen_config > "${DESTDIR}"/$syslinux_cfg
}

section_syslinux_cfg() {
	syslinux_cfg=""
	if [ "$ARCH" = x86 -o "$ARCH" = x86_64 ]; then
		[ ! "$output_format" = "iso" ] || syslinux_cfg="boot/syslinux/syslinux.cfg"
	fi
	[ ! -n "$uboot_install" ] || syslinux_cfg="extlinux/extlinux.conf"
	[ -n "$syslinux_cfg" ] || return 0
	build_section syslinux_cfg $syslinux_cfg $(syslinux_gen_config | checksum)
}

build_grub_cfg() {
	local grub_cfg="$1"
	mkdir -p "${DESTDIR}/$(dirname $grub_cfg)"
	grub_gen_config > "${DESTDIR}"/$grub_cfg
}

grub_gen_earlyconf() {
	cat <<- EOF
	search --no-floppy --set=root --label "alpine-${profile_abbrev:-$PROFILE} $RELEASE $ARCH"
	set prefix=(\$root)/boot/grub
	EOF
}

build_grub_efi() {
	local _format="$1"
	local _efi="$2"

	# Prepare grub-efi bootloader
	mkdir -p "$DESTDIR/efi/boot"
	grub_gen_earlyconf > "$WORKDIR/grub_early.$3.cfg"
	grub-mkimage \
		--config="$WORKDIR/grub_early.$3.cfg" \
		--prefix="/boot/grub" \
		--output="$DESTDIR/efi/boot/$_efi" \
		--format="$_format" \
		--compression="xz" \
		$grub_mod
}

section_grubieee1275() {
	[ "$ARCH" = ppc64le ] || return 0
	[ "$output_format" = "iso" ] || return 0
	kernel_cmdline="$kernel_cmdline console=hvc0"

	build_section grub_cfg boot/grub/grub.cfg $(grub_gen_config | checksum)
}

section_grub_efi() {
	[ -n "$grub_mod" ] || return 0
	local _format _efi
	case "$ARCH" in
	aarch64)_format="arm64-efi";  _efi="bootaa64.efi" ;;
	arm*)	_format="arm-efi";    _efi="bootarm.efi"  ;;
	x86)	_format="i386-efi";   _efi="bootia32.efi" ;;
	x86_64) _format="x86_64-efi"; _efi="bootx64.efi"  ;;
	riscv64) _format="riscv64-efi"; _efi="bootriscv64.efi"  ;;
	*)	return 0 ;;
	esac

	build_section grub_cfg boot/grub/grub.cfg $(grub_gen_config | checksum)
	build_section grub_efi $_format $_efi $(grub_gen_earlyconf | checksum)
}

create_image_iso() {
	local ISO="${OUTDIR}/${output_filename}"
	local _isolinux
	local _efiboot

	if [ -e "${DESTDIR}/boot/syslinux/isolinux.bin" ]; then
		# isolinux enabled
		_isolinux="
			-isohybrid-mbr ${DESTDIR}/boot/syslinux/isohdpfx.bin
			-eltorito-boot boot/syslinux/isolinux.bin
			-eltorito-catalog boot/syslinux/boot.cat
			-no-emul-boot
			-boot-load-size 4
			-boot-info-table
			"
	fi
	if [ -e "${DESTDIR}/efi" -a -e "${DESTDIR}/boot/grub" ]; then
		# Create the EFI boot partition image
		mformat -i ${DESTDIR}/boot/grub/efi.img -C -f 1440 -N 0 ::
		mcopy -i ${DESTDIR}/boot/grub/efi.img -s ${DESTDIR}/efi ::
		touch -md "@${SOURCE_DATE_EPOCH}" ${DESTDIR}/boot/grub/efi.img

		# Enable EFI boot
		if [ -z "$_isolinux" ]; then
			# efi boot only
			_efiboot="
				-efi-boot-part
				--efi-boot-image
				-e boot/grub/efi.img
				-no-emul-boot
				"
		else
			# hybrid isolinux+efi boot
			_efiboot="
				-eltorito-alt-boot
				-e boot/grub/efi.img
				-no-emul-boot
				-isohybrid-gpt-basdat
				"
		fi
	fi

	if [ "$ARCH" = ppc64le ]; then
		grub-mkrescue --output ${ISO} ${DESTDIR} -follow-links \
			-sysid LINUX \
			-volid "alpine-${profile_abbrev:-$PROFILE} $RELEASE $ARCH"
	else
		if [ "$ARCH" = s390x ]; then
			printf %s "$initfs_cmdline $kernel_cmdline " > ${WORKDIR}/parmfile
			for _f in $kernel_flavors; do
				mk-s390-cdboot -p ${WORKDIR}/parmfile \
					-i ${DESTDIR}/boot/vmlinuz-$_f \
					-r ${DESTDIR}/boot/initramfs-$_f \
					-o ${DESTDIR}/boot/merged.img
			done
			iso_opts="$iso_opts -no-emul-boot -eltorito-boot boot/merged.img"
		fi
		xorrisofs \
			-quiet \
			-output ${ISO} \
			-full-iso9660-filenames \
			-joliet \
			-rational-rock \
			-sysid LINUX \
			-volid "alpine-${profile_abbrev:-$PROFILE} $RELEASE $ARCH" \
			$_isolinux \
			$_efiboot \
			-follow-links \
			${iso_opts} \
			${DESTDIR}
	fi
}

create_image_targz() {
	tar -C "${DESTDIR}" \
		--mtime="@${SOURCE_DATE_EPOCH}" \
		--owner=0 --group=0 --numeric-owner \
		-chzf "${OUTDIR}/${output_filename}" .
}

profile_base() {
	kernel_flavors="lts"
	initfs_cmdline="modules=loop,squashfs,sd-mod,usb-storage quiet"
	initfs_features="ata base bootchart cdrom ext4 mmc nvme raid scsi squashfs usb virtio"
	modloop_sign=yes
	grub_mod="all_video disk part_gpt part_msdos linux normal configfile search search_label efi_gop fat iso9660 cat echo ls test true help gzio"
	case "$ARCH" in
		x86*) grub_mod="$grub_mod multiboot2 efi_uga";;
	esac
	case "$ARCH" in
		x86_64) initfs_features="$initfs_features nfit";;
	esac
	apks="alpine-base busybox chrony dhcpcd doas e2fsprogs
		kbd-bkeymaps network-extras openntpd openssl openssh
		tzdata wget tiny-cloud-alpine"
	apkovl=
	hostname="alpine"
}

A alpine/build/mkimg.minirootfs.sh => alpine/build/mkimg.minirootfs.sh +25 -0
@@ 0,0 1,25 @@
section_minirootfs() {
	return 0
}

create_image_rootfs() {
	local _script=$(readlink -f "$scriptdir/genrootfs.sh")
	local output_file="$(readlink -f ${OUTDIR:-.})/$output_filename"

	(cd "$OUTDIR"; fakeroot "$_script" -k "$APKROOT"/etc/apk/keys \
		-r "$APKROOT"/etc/apk/repositories \
		-o "$output_file" \
		-a $ARCH \
		$rootfs_apks)
}

profile_minirootfs() {
	title="Mini root filesystem"
	desc="Minimal root filesystem.
		For use in containers
		and minimal chroots."
	image_ext=tar.gz
	output_format=rootfs
	arch="x86 x86_64 armhf armv7 aarch64 ppc64le s390x mips64 riscv64"
	rootfs_apks="busybox alpine-baselayout alpine-keys apk-tools libc-utils"
}

A alpine/build/mkimg.netboot.sh => alpine/build/mkimg.netboot.sh +32 -0
@@ 0,0 1,32 @@
create_image_netboot() {
	rm -rf "${OUTDIR}"/netboot-$RELEASE "${OUTDIR}"/netboot
	cp -aL "${DESTDIR}"/boot "${OUTDIR}"/netboot-$RELEASE
	ln -s netboot-$RELEASE "${OUTDIR}"/netboot
	# let webserver read initramfs
	chmod a+r "${OUTDIR}"/netboot-$RELEASE/*
	tar -C "${DESTDIR}" -chzf ${OUTDIR}/${output_filename} boot/
}

profile_netboot() {
	title="Netboot"
	desc="Kernel, initramfs and modloop for
		netboot.
		"
	arch="aarch64 armhf armv7 ppc64le x86 x86_64 s390x"
	case "$ARCH" in
		aarch64) kernel_flavors="lts rpi rpi4 virt";;
		armhf) kernel_flavors="rpi rpi2";;
		armv7) kernel_flavors="lts rpi rpi2";;
		x86_64) kernel_flavors="lts virt";;
		*) kernel_flavors="lts";;
	esac
	case "$ARCH" in
		s390x) initfs_features="base network squashfs usb dasd_mod qeth zfcp";;
		*) initfs_features="base network squashfs usb virtio"
	esac
	modloop_sign=yes
	apks=""
	output_format="netboot"
	image_ext="tar.gz"
}


A alpine/build/mkimg.standard.sh => alpine/build/mkimg.standard.sh +91 -0
@@ 0,0 1,91 @@
profile_standard() {
	title="Standard"
	desc="Alpine as it was intended.
		Just enough to get you started.
		Network connection is required."
	profile_base
	profile_abbrev="std"
	image_ext="iso"
	arch="aarch64 armv7 x86 x86_64 ppc64le riscv64 s390x"
	output_format="iso"
	kernel_addons="xtables-addons"
	case "$ARCH" in
	s390x)
		apks="$apks s390-tools"
		initfs_features="$initfs_features dasd_mod qeth zfcp"
		initfs_cmdline="modules=loop,squashfs,dasd_mod,qeth,zfcp quiet"
		;;
	ppc64le)
		initfs_cmdline="modules=loop,squashfs,sd-mod,usb-storage,ibmvscsi quiet"
		;;
	riscv64)
		kernel_flavors="edge"
		kernel_cmdline="console=tty0 console=ttyS0,115200 console=ttySIF0,115200"
		kernel_addons=
		;;
	esac
	apks="$apks iw wpa_supplicant"
}

profile_extended() {
	profile_standard
	profile_abbrev="ext"
	title="Extended"
	desc="Most common used packages included.
		Suitable for routers and servers.
		Runs from RAM.
		Includes AMD and Intel microcode updates."
	arch="x86 x86_64"
	kernel_addons="xtables-addons zfs"
	boot_addons="amd-ucode intel-ucode"
	initrd_ucode="/boot/amd-ucode.img /boot/intel-ucode.img"
	apks="$apks
		coreutils ethtool hwids doas
		logrotate lsof lm_sensors lxc lxc-templates nano
		pciutils strace tmux
		usbutils v86d vim xtables-addons curl

		acct arpon arpwatch awall bridge-utils bwm-ng
		ca-certificates conntrack-tools cutter cyrus-sasl dhcp
		dhcpcd dhcrelay dnsmasq fping fprobe htop
		igmpproxy ip6tables iproute2 iproute2-qos
		iptables iputils nftables iw kea ldns-tools links
		ncurses-terminfo net-snmp net-snmp-tools nrpe nsd
		opennhrp openvpn pingu ppp quagga
		quagga-nhrp rng-tools sntpc socat ssmtp strongswan
		sysklogd tcpdump tinyproxy unbound
		wireguard-tools wireless-tools wpa_supplicant zonenotify

		btrfs-progs cksfv dosfstools cryptsetup
		e2fsprogs e2fsprogs-extra efibootmgr f2fs-tools
		grub-bios grub-efi lvm2 lz4 mdadm mkinitfs mtools nfs-utils
		parted rsync sfdisk syslinux util-linux xfsprogs zstd zfs
		"

	local _k _a
	for _k in $kernel_flavors; do
		apks="$apks linux-$_k"
		for _a in $kernel_addons; do
			apks="$apks $_a-$_k"
		done
	done
	apks="$apks linux-firmware linux-firmware-none"
}

profile_virt() {
	profile_standard
	profile_abbrev="virt"
	title="Virtual"
	desc="Similar to standard.
		Slimmed down kernel.
		Optimized for virtual systems."
	arch="aarch64 armv7 x86 x86_64"
	kernel_addons=
	kernel_flavors="virt"
	case "$ARCH" in
		arm*|aarch64)
			kernel_cmdline="console=tty0 console=ttyAMA0"
			;;
	esac
	syslinux_serial="0 115200"
}

A alpine/build/mkimg.xen.sh => alpine/build/mkimg.xen.sh +20 -0
@@ 0,0 1,20 @@
build_xen() {
	apk fetch --root "$APKROOT" --stdout xen-hypervisor | tar -C "$DESTDIR" -xz boot
}

section_xen() {
	[ -n "${xen_params+set}" ] || return 0
	build_section xen $ARCH $(apk fetch --root "$APKROOT" --simulate xen-hypervisor | checksum)
}

profile_xen() {
	profile_standard
	profile_abbrev="xen"
	title="Xen"
	desc="Built-in support for Xen Hypervisor.
		Includes packages targetted at Xen usage.
		Use for Xen Dom0."
	arch="x86_64"
	xen_params=""
	apks="$apks ethtool lvm2 mdadm multipath-tools rng-tools sfdisk xen xen-bridge syslinux"
}