Experimental standalone alpine aarch64 system with custom packaging, based on techniques developed for https://fruit-testbed.org/
This commit is contained in:
parent
b21660976a
commit
d03d249701
|
@ -0,0 +1,2 @@
|
||||||
|
vmlinuz-virt
|
||||||
|
newroot/
|
|
@ -0,0 +1,29 @@
|
||||||
|
all: run
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f initramfs-syndicate-system
|
||||||
|
|
||||||
|
veryclean: clean
|
||||||
|
rm -f disk.img
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.14
|
||||||
|
|
||||||
|
# vmlinuz-lts:
|
||||||
|
# wget http://dl-cdn.alpinelinux.org/alpine/$(ALPINE_VERSION)/releases/aarch64/netboot/vmlinuz-lts
|
||||||
|
# initramfs-lts:
|
||||||
|
# wget http://dl-cdn.alpinelinux.org/alpine/$(ALPINE_VERSION)/releases/aarch64/netboot/initramfs-lts
|
||||||
|
|
||||||
|
disk.img:
|
||||||
|
qemu-img create -f qcow2 $@ 8G
|
||||||
|
|
||||||
|
initramfs-syndicate-system: pack-image.sh init.sh package-list
|
||||||
|
sudo PACKAGES="$$(cat package-list)" ./pack-image.sh
|
||||||
|
|
||||||
|
# See https://superuser.com/questions/1397991/running-alpine-linux-on-qemu-arm-guests
|
||||||
|
run: initramfs-syndicate-system disk.img
|
||||||
|
qemu-system-aarch64 \
|
||||||
|
-M virt -m 512M -cpu cortex-a57 \
|
||||||
|
-kernel vmlinuz-virt -initrd initramfs-syndicate-system \
|
||||||
|
-netdev user,id=unet,hostfwd=tcp::8022-:22 -device virtio-net-pci,netdev=unet \
|
||||||
|
-hda disk.img \
|
||||||
|
-nographic
|
|
@ -0,0 +1,2 @@
|
||||||
|
syndicate-system-apk-key.rsa
|
||||||
|
syndicate-system-apk-key.rsa.pub
|
|
@ -0,0 +1,106 @@
|
||||||
|
# Originally based on a Makefile from the FRμIT project,
|
||||||
|
# https://fruit-testbed.org/, which is CC Attribution-ShareAlike 4.0
|
||||||
|
# licensed.
|
||||||
|
|
||||||
|
.PHONY: build sign clean
|
||||||
|
|
||||||
|
TARGET = $(shell pwd)/target
|
||||||
|
KEYFILE ?= $(shell pwd)/syndicate-system-apk-key.rsa
|
||||||
|
USER = builder
|
||||||
|
ARCH ?= $(shell apk --print-arch)
|
||||||
|
|
||||||
|
SU_CMD = su $(USER)
|
||||||
|
SU_CMD_PATH_OVERRIDE = PATH=/usr/sbin:/sbin:$$PATH
|
||||||
|
|
||||||
|
PACKAGES = \
|
||||||
|
|
||||||
|
build: $(PACKAGES) sign
|
||||||
|
|
||||||
|
# Packages added:
|
||||||
|
# - alpine-sdk for build support
|
||||||
|
# - shadow for `sg`
|
||||||
|
.prepare:
|
||||||
|
apk update && apk upgrade && apk add alpine-sdk shadow
|
||||||
|
[ -f /etc/apk/keys/$$(basename $(KEYFILE)).pub ] || cp $(KEYFILE).pub /etc/apk/keys/.
|
||||||
|
adduser -s /bin/sh -D $(USER) && \
|
||||||
|
echo "$(USER) ALL=(ALL) ALL" >> /etc/sudoers && \
|
||||||
|
addgroup $(USER) abuild && \
|
||||||
|
chown $(USER):$(USER) . && \
|
||||||
|
chown $(USER):$(USER) -R packages && \
|
||||||
|
mkdir -p /home/$(USER)/.abuild/ && \
|
||||||
|
cp -f $(KEYFILE) /home/$(USER)/.abuild/ && \
|
||||||
|
chmod 0400 /home/$(USER)/.abuild/$$(basename $(KEYFILE)) && \
|
||||||
|
chown $(USER):$(USER) /home/$(USER)/.abuild/$$(basename $(KEYFILE)) && \
|
||||||
|
echo "PACKAGER_PRIVKEY=/home/syndicate-systemdev/.abuild/$$(basename $(KEYFILE))" > /home/$(USER)/.abuild/abuild.conf && \
|
||||||
|
mkdir -p $(TARGET)/packages/$(ARCH) && \
|
||||||
|
chown -R $(USER):$(USER) $(TARGET)
|
||||||
|
addgroup $(shell id -un) abuild
|
||||||
|
mkdir -p /var/cache/distfiles && chmod a+w /var/cache/distfiles
|
||||||
|
touch .prepare
|
||||||
|
|
||||||
|
$(TARGET): .prepare $(PACKAGES)
|
||||||
|
|
||||||
|
%.apk: .prepare
|
||||||
|
@if [ -e packages/$*/APKBUILD ]; then \
|
||||||
|
echo "Building $*..."; \
|
||||||
|
cd packages/$* && sg abuild "abuild -F -P $(TARGET) deps" && $(SU_CMD) -c "$(SU_CMD_PATH_OVERRIDE) abuild -P $(TARGET)"; \
|
||||||
|
else \
|
||||||
|
echo "Fetching $*..."; \
|
||||||
|
apk fetch -o $(TARGET)/packages/$(ARCH) -R $*; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
%.checksum: .prepare
|
||||||
|
cd packages/$* && $(SU_CMD) -c "$(SU_CMD_PATH_OVERRIDE) abuild checksum"
|
||||||
|
|
||||||
|
sign:
|
||||||
|
rm -f $(TARGET)/packages/$(ARCH)/APKINDEX.tar.gz
|
||||||
|
cd $(TARGET)/packages/$(ARCH) && apk index -o APKINDEX.tar.gz --rewrite-arch $(ARCH) *.apk
|
||||||
|
sg abuild "abuild-sign -q -k $(KEYFILE) $(TARGET)/packages/$(ARCH)/APKINDEX.tar.gz"
|
||||||
|
|
||||||
|
tgz:
|
||||||
|
cd $(TARGET)/ && tar cvzf syndicate-system-apks.tar.gz packages
|
||||||
|
|
||||||
|
|
||||||
|
clean.packages:
|
||||||
|
@if [ $$(grep $(USER) /etc/passwd | wc -l) -ne 0 ] && [ -e /usr/bin/abuild ]; then \
|
||||||
|
for package in packages/*; do \
|
||||||
|
if [ -e $$package/APKBUILD ]; then \
|
||||||
|
echo "Cleaning $$package..."; \
|
||||||
|
$(SU_CMD) -c "cd $$package && $(SU_CMD_PATH_OVERRIDE) abuild clean"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean: clean.packages
|
||||||
|
@[ "$$(grep $(USER) /etc/passwd)" = "" ] || deluser $(USER)
|
||||||
|
@[ ! -e /etc/sudoers ] || sed -i 's/^$(USER).*$$//' /etc/sudoers
|
||||||
|
@[ "$$(mount | grep ' on /var/cache/distfiles ')" = "" ] || umount -f /var/cache/distfiles
|
||||||
|
@chown -R $$(id -u -n):$$(id -g -n) .
|
||||||
|
rm -f .prepare
|
||||||
|
|
||||||
|
cleantarget:
|
||||||
|
rm -rf $(TARGET)
|
||||||
|
|
||||||
|
cleancache:
|
||||||
|
@if [ -e /usr/bin/abuild ]; then \
|
||||||
|
for package in packages/*; do \
|
||||||
|
if [ -e $$package/APKBUILD ]; then \
|
||||||
|
echo "Cleaning cache of $$package..."; \
|
||||||
|
cd $$package && sg abuild "abuild -F cleancache"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
fi
|
||||||
|
@rm -rf /var/cache/distfiles/*
|
||||||
|
|
||||||
|
clean.%:
|
||||||
|
@if [ -e packages/$* ]; then \
|
||||||
|
echo "Cleaning $*..."; \
|
||||||
|
cd packages/$* && sg abuild "abuild -F clean" && sg abuild "abuild -F cleancache"; \
|
||||||
|
else \
|
||||||
|
echo "Package $* does not exist"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanapks:
|
||||||
|
rm -f $(TARGET)/syndicate-system-apks.tar.gz
|
||||||
|
|
||||||
|
cleanall: clean cleantarget cleancache cleanapks
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Originally based on build-via-docker.sh from the FRμIT project,
|
||||||
|
# https://fruit-testbed.org/, which is CC Attribution-ShareAlike 4.0
|
||||||
|
# licensed.
|
||||||
|
|
||||||
|
ALPINE_VERSION=${ALPINE_VERSION:-v3.14}
|
||||||
|
DOCKER_ARCH=${DOCKER_ARCH:-aarch64}
|
||||||
|
|
||||||
|
# If you run:
|
||||||
|
# docker run --rm --name squid adricu/alpine-squid
|
||||||
|
# and set DOCKER_SQUID_CONTAINER=squid
|
||||||
|
# then you can avoid repeated downloads of a lot of alpine packages.
|
||||||
|
#
|
||||||
|
DOCKER_SQUID_CONTAINER=${DOCKER_SQUID_CONTAINER:-""}
|
||||||
|
if [ "$DOCKER_SQUID_CONTAINER" = "" ]; then
|
||||||
|
docker_squid_opts=""
|
||||||
|
else
|
||||||
|
docker_squid_opts="--link ${DOCKER_SQUID_CONTAINER}:squid -e http_proxy=http://squid:3128/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
tmpscript=$(mktemp tmpscript.XXXXXXXXXX)
|
||||||
|
trap "rm -f $tmpscript" 0
|
||||||
|
|
||||||
|
cat > $tmpscript <<EOF
|
||||||
|
set -xe
|
||||||
|
apk update
|
||||||
|
apk add make git
|
||||||
|
cd /media/data/syndicate-system/apks
|
||||||
|
rm -f .prepare
|
||||||
|
make $@
|
||||||
|
EOF
|
||||||
|
|
||||||
|
docker run -it --rm -v $(realpath ..):/media/data/syndicate-system \
|
||||||
|
${docker_squid_opts} \
|
||||||
|
multiarch/alpine:${DOCKER_ARCH}-${ALPINE_VERSION} \
|
||||||
|
/bin/sh -c "cd /media/data/syndicate-system/apks && sh $tmpscript"
|
|
@ -0,0 +1,94 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
ROOTDEV=/dev/vda
|
||||||
|
CONSOLE=/dev/ttyAMA0
|
||||||
|
NEWROOT=/mnt
|
||||||
|
|
||||||
|
in_initramfs=true
|
||||||
|
if [ -f /proc/mounts ]
|
||||||
|
then
|
||||||
|
in_initramfs=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $in_initramfs = true ]
|
||||||
|
then
|
||||||
|
echo "Mounting basics."
|
||||||
|
mount -t devtmpfs none /dev
|
||||||
|
mkdir /dev/pts
|
||||||
|
mkdir /dev/shm
|
||||||
|
mount -t devpts none /dev/pts
|
||||||
|
mount -t proc none /proc
|
||||||
|
mount -t sysfs none /sys
|
||||||
|
mount -t tmpfs -o nodev,nosuid,noexec none /dev/shm
|
||||||
|
mount -t tmpfs none /run
|
||||||
|
|
||||||
|
# Docker wants this
|
||||||
|
mount -t cgroup2 none /sys/fs/cgroup
|
||||||
|
|
||||||
|
echo "Loading virtio modules."
|
||||||
|
# The "virt" aarch64 qemu machine needs these to get user networking going
|
||||||
|
modprobe virtio_pci
|
||||||
|
modprobe virtio_net
|
||||||
|
# And this is for the disk
|
||||||
|
modprobe virtio_blk
|
||||||
|
|
||||||
|
echo "Loading btrfs."
|
||||||
|
modprobe btrfs &
|
||||||
|
|
||||||
|
echo "Configuring network."
|
||||||
|
ifconfig lo 127.0.0.1 up
|
||||||
|
ifconfig eth0 up
|
||||||
|
udhcpc -i eth0 &
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
echo "Attempting to mount ${ROOTDEV} on ${NEWROOT} ..."
|
||||||
|
if mount ${ROOTDEV} ${NEWROOT}
|
||||||
|
then
|
||||||
|
echo "Mount successful."
|
||||||
|
else
|
||||||
|
echo "Mount unsuccessful. Building new root."
|
||||||
|
mkfs.btrfs ${ROOTDEV}
|
||||||
|
mount ${ROOTDEV} ${NEWROOT}
|
||||||
|
apk --repositories-file /etc/apk/repositories -U --allow-untrusted \
|
||||||
|
--root ${NEWROOT} --initdb add $(cat /package-list)
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in /etc/apk/repositories /init /package-list /usr/bin/syndicate-server
|
||||||
|
do
|
||||||
|
echo "Updating $f."
|
||||||
|
cp -a $f ${NEWROOT}$f
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Moving mount points."
|
||||||
|
for mp in /dev /proc /sys /run
|
||||||
|
do
|
||||||
|
echo "Moving $mp --> ${NEWROOT}$mp"
|
||||||
|
mount -o move $mp ${NEWROOT}$mp
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Killing leftovers."
|
||||||
|
kill -15 -1
|
||||||
|
sleep 0.2
|
||||||
|
kill -9 -1
|
||||||
|
|
||||||
|
echo "Switching root."
|
||||||
|
exec switch_root -c ${CONSOLE} ${NEWROOT} /init
|
||||||
|
else
|
||||||
|
echo "Initializing with real rootfs."
|
||||||
|
|
||||||
|
echo "Re-configuring network."
|
||||||
|
ifconfig lo 127.0.0.1 up
|
||||||
|
ifconfig eth0 up
|
||||||
|
udhcpc -i eth0
|
||||||
|
|
||||||
|
echo "Ensuring installation of /package-list."
|
||||||
|
apk add $(cat /package-list)
|
||||||
|
fi
|
||||||
|
|
||||||
|
sync
|
||||||
|
|
||||||
|
echo "Dropping to shell."
|
||||||
|
|
||||||
|
# setsid creates a "session", which allows job control to work
|
||||||
|
exec setsid sh -c "exec sh -i <${CONSOLE} >${CONSOLE} 2>&1"
|
|
@ -0,0 +1,111 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Originally loosely based on pack-image.sh from the FRμIT project,
|
||||||
|
# https://fruit-testbed.org/, which is CC Attribution-ShareAlike 4.0
|
||||||
|
# licensed.
|
||||||
|
#
|
||||||
|
# Run this script after the packages are available in
|
||||||
|
# apks/target/packages.
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
INITRAMFS=${INITRAMFS:-initramfs-syndicate-system}
|
||||||
|
NATIVE_COMMANDS=${NATIVE_COMMANDS:-no}
|
||||||
|
DOCKER_ARCH=${DOCKER_ARCH:-aarch64}
|
||||||
|
ALPINE_VERSION=${ALPINE_VERSION:-v3.14}
|
||||||
|
VERSION=${VERSION:-0.1.0}
|
||||||
|
MOUNTPOINT=${MOUNTPOINT:-`pwd`/newroot}
|
||||||
|
|
||||||
|
# docker run --rm --name squid adricu/alpine-squid
|
||||||
|
DOCKER_PROXY_ARGS=${DOCKER_PROXY_ARGS:- --link squid -e http_proxy=http://squid:3128/}
|
||||||
|
|
||||||
|
PACKAGES=${PACKAGES:-}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo "$1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
die_if_empty () {
|
||||||
|
[ ! -z "$2" ] || die "No $1 specified."
|
||||||
|
}
|
||||||
|
|
||||||
|
die_if_empty PACKAGES "$PACKAGES"
|
||||||
|
die_if_empty VERSION "$VERSION"
|
||||||
|
|
||||||
|
invoke_command () {
|
||||||
|
# Shell quoting is a nightmare. Beware spaces.
|
||||||
|
#
|
||||||
|
if [ "$NATIVE_COMMANDS" = "yes" ]
|
||||||
|
then
|
||||||
|
$@
|
||||||
|
else
|
||||||
|
tmpscript=$(mktemp tmpscript.XXXXXXXXXX)
|
||||||
|
echo "$@" > $tmpscript
|
||||||
|
docker run -it --rm -v `pwd`:`pwd` \
|
||||||
|
${DOCKER_PROXY_ARGS} \
|
||||||
|
multiarch/alpine:${DOCKER_ARCH}-${ALPINE_VERSION} \
|
||||||
|
/bin/sh -c "cd `pwd`; sh $tmpscript"
|
||||||
|
rm -f $tmpscript
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
TMP_REPO_FILE=$(mktemp repositories.XXXXXXXXXX)
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
# rm -rf ${MOUNTPOINT} || true
|
||||||
|
rm -f ${TMP_REPO_FILE} || true
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup 0
|
||||||
|
|
||||||
|
cat < /dev/null > ${TMP_REPO_FILE}
|
||||||
|
echo "`pwd`/apks/target/packages" >> ${TMP_REPO_FILE}
|
||||||
|
echo "https://dl-cdn.alpinelinux.org/alpine/${ALPINE_VERSION}/main" >> ${TMP_REPO_FILE}
|
||||||
|
echo "https://dl-cdn.alpinelinux.org/alpine/${ALPINE_VERSION}/community" >> ${TMP_REPO_FILE}
|
||||||
|
|
||||||
|
# Create root file system.
|
||||||
|
#
|
||||||
|
echo "Repositories:"
|
||||||
|
cat ${TMP_REPO_FILE}
|
||||||
|
apkcmd="apk --repositories-file `pwd`/${TMP_REPO_FILE} -U --allow-untrusted"
|
||||||
|
invoke_command ${apkcmd} --root ${MOUNTPOINT} --initdb add ${PACKAGES}
|
||||||
|
# invoke_command ${apkcmd} --no-script --root ${MOUNTPOINT} add mkinitfs
|
||||||
|
|
||||||
|
# Allow root logins on ttyS0 / ttyAMA0
|
||||||
|
#
|
||||||
|
tmpsecuretty=$(mktemp tmpsecuretty.XXXXXXXXXX)
|
||||||
|
cat ${MOUNTPOINT}/etc/securetty | egrep -v '(ttyS0|ttyAMA0)' > $tmpsecuretty
|
||||||
|
echo ttyS0 >> $tmpsecuretty
|
||||||
|
echo ttyAMA0 >> $tmpsecuretty
|
||||||
|
cat $tmpsecuretty > ${MOUNTPOINT}/etc/securetty
|
||||||
|
rm -f $tmpsecuretty
|
||||||
|
|
||||||
|
cat > ${MOUNTPOINT}/etc/os-release <<EOF
|
||||||
|
VERSION=${VERSION}
|
||||||
|
PRETTY_NAME="syndicate-system v${VERSION}"
|
||||||
|
BUILT_TIMESTAMP=$(date +%s)
|
||||||
|
COMMIT=$(git rev-parse HEAD)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cp -a syndicate-server ${MOUNTPOINT}/usr/bin/.
|
||||||
|
|
||||||
|
cat > ${MOUNTPOINT}/etc/apk/repositories <<EOF
|
||||||
|
https://dl-cdn.alpinelinux.org/alpine/${ALPINE_VERSION}/main
|
||||||
|
https://dl-cdn.alpinelinux.org/alpine/${ALPINE_VERSION}/community
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cp package-list ${MOUNTPOINT}/package-list
|
||||||
|
cp init.sh ${MOUNTPOINT}/init
|
||||||
|
chmod a+x ${MOUNTPOINT}/init
|
||||||
|
|
||||||
|
cp -a ${MOUNTPOINT}/boot/vmlinuz-virt .
|
||||||
|
|
||||||
|
(cd ${MOUNTPOINT}; find . -print0 | \
|
||||||
|
cpio --null --create --verbose --format=newc) | \
|
||||||
|
gzip > ${INITRAMFS}
|
||||||
|
|
||||||
|
trap - 0
|
||||||
|
cleanup
|
|
@ -0,0 +1,6 @@
|
||||||
|
alpine-baselayout
|
||||||
|
alpine-keys
|
||||||
|
btrfs-progs
|
||||||
|
linux-virt
|
||||||
|
parted
|
||||||
|
s6
|
Loading…
Reference in New Issue