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"
+}