Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/bin/bash
ARCH="x86_64"
TARGET="/tmp/alpinefs"
ROOTGZ="/tmp/alpine-rootfs.tar.gz"
MIRROR="http://dl-cdn.alpinelinux.org/alpine"
echoerr() {
printf "%s\n" "$*" >&2;
}
if [[ "$#" == "0" ]]; then
echoerr "Usage: $0 RELEASE [DEVICE]"
echoerr "Omitting DEVICE will set alpine rootfs up, but WILL NOT burn the image"
exit 1
fi
RELEASE=$1
USBDEV=$2
MAJOR_RELEASE=$(echo $RELEASE | awk -F"." '{ print "v"$1"."$2 }')
RELURL="${MIRROR}/${MAJOR_RELEASE}/releases/${ARCH}/alpine-minirootfs-${RELEASE}-${ARCH}.tar.gz"
RELSHA=$(wget --quiet "http://dl-cdn.alpinelinux.org/alpine/${MAJOR_RELEASE}/releases/${ARCH}/alpine-minirootfs-${RELEASE}-${ARCH}.tar.gz.sha256" -O - | awk ' { print $1 } ')
ISOURL="${MIRROR}/${MAJOR_RELEASE}/releases/${ARCH}/alpine-standard-${RELEASE}-${ARCH}.iso"
ISOSHA=$(wget --quiet "http://dl-cdn.alpinelinux.org/alpine/${MAJOR_RELEASE}/releases/${ARCH}/alpine-standard-${RELEASE}-${ARCH}.iso.sha256" -O - | awk '{ print $1 }')
# Check if unpacking is already finished
if [[ ! -f "${TARGET}/unpack-ok" ]]; then
echo "Downloading alpine rootfs"
wget -q --show-progress -c "${RELURL}" -O "${ROOTGZ}"
if [[ "$?" != "0" ]]; then
echoerr "Download failed; aborting"
exit 1
fi
DLRELSHA=$(sha256sum "${ROOTGZ}" | awk '{ print $1 }')
shopt -s nocasematch
if [[ "${RELSHA}" != "${DLRELSHA}" ]]; then
echoerr "SHA256 checksum of rootfs failed; aborting"
exit 1
else
echo "rootfs SHA256 checked out"
fi
shopt -u nocasematch
echo "Unpacking alpine rootfs to ${TARGET}"
if [[ ! -d "${TARGET}" && -f "${TARGET}" ]]; then
echoerr "Target \"${TARGET}\" is not a directory"
exit 1
else
mkdir ${TARGET}
fi
tar xfz "${ROOTGZ}" -C "${TARGET}"
#if [[ "$?" != "0" ]]; then
# echoerr "Unpacking rootfs failed; aborting"
# exit 1
#fi
touch "${TARGET}/unpack-ok"
else
echo "Rootfs already unpacked; continuing..."
fi
if [[ ! -f "${TARGET}/config-ok" ]]; then
echo "Adjusting inittab"
sed '/tty[0-9]:/ s/^/#/' -i "${TARGET}/etc/inittab"
printf 'console::respawn:/sbin/getty 38400 console\n' >> "${TARGET}/etc/inittab"
echo "Adding mirror"
printf '%s/%s/main\n' "${MIRROR}" "${MAJOR_RELEASE}" >| "${TARGET}/etc/apk/repositories"
touch "${TARGET}/config-ok"
fi
echo "Initial configuration finished"
echo "Updating rootfs to the latest version"
systemd-nspawn -D "${TARGET}" /sbin/apk update
systemd-nspawn -D "${TARGET}" /sbin/apk upgrade
echo "Downloading alpine ${ARCH} ISO"
wget -q --show-progress -c "${ISOURL}" -O "${TARGET}/alpine-${ARCH}.iso"
DLISOSHA=$(sha256sum "${TARGET}/alpine-${ARCH}.iso" | awk '{ print $1 }')
shopt -s nocasematch
if [[ "${ISOSHA}" != "${DLISOSHA}" ]]; then
echoerr "SHA256 checksum of rootfs failed; aborting"
exit 1
else
echo "ISO SHA256 checked out"
fi
shopt -u nocasematch
if [[ ! -d "${TARGET}/iso" ]]; then
mkdir "${TARGET}/iso"
fi
echo "Adding required packages"
systemd-nspawn -D "${TARGET}" /sbin/apk add alpine-conf parted syslinux dosfstools e2fsprogs p7zip
echo "Extracting ISO"
if [[ ! -f "${TARGET}/iso-extract-ok" ]]; then
# Do not extract any MBR info, there will be recreated by setup-bootable anyway
systemd-nspawn -D "${TARGET}" /usr/bin/7z x -x!'[BOOT]/*' -o'/iso' "/alpine-${ARCH}.iso"
if [[ "$?" != "0" ]]; then
echoerr "Failed to unzip iso; aborting"
exit 1
else
touch "${TARGET}/iso-extract-ok"
fi
else
echo "ISO is already extracted"
fi
echo "Enabling console output to /dev/ttyS0 for syslinux.cfg"
# Get the APPEND line that has the options
APPENDLINE=$(tail -n1 "${TARGET}/iso/boot/syslinux/syslinux.cfg")
# Split them up into an arry
OPTS=($APPENDLINE)
NEWAPPEND=""
# Reassemble them but drop any existing "console=" parts
for o in "${OPTS[@]}"; do
if [[ ${o} =~ "console=" ]]; then
echo "Ignoring existing console line"
else
NEWAPPEND=$(printf "%s %s" "${NEWAPPEND}" "${o}")
fi
done
# Add the "console=" bit
NEWAPPEND=$(printf "%s console=ttyS0,115200" "${NEWAPPEND}")
# Replace last line in syslinux.cfg with the new one
head -n -1 "${TARGET}/iso/boot/syslinux/syslinux.cfg" >| "${TARGET}/iso/boot/syslinux/syslinux.new.cfg"
mv "${TARGET}/iso/boot/syslinux/syslinux.new.cfg" "${TARGET}/iso/boot/syslinux/syslinux.cfg"
echo "${NEWAPPEND}" | sed -e 's/^[[:space:]]*//' >> "${TARGET}/iso/boot/syslinux/syslinux.cfg"
if [[ "${USBDEV}" != "" ]]; then
if [[ ! -b "${USBDEV}" ]]; then
echoerr "${USBDEV} does not appear to be a block device; aborting"
exit 1
fi
echo "Preparing partitions on ${USBDEV}"
systemd-nspawn --bind ${USBDEV} -D "${TARGET}" /usr/sbin/parted ${USBDEV} --script \
mklabel msdos \
mkpart primary fat32 1MiB 100% \
set 1 boot on
if [[ "$?" != "0" ]]; then
echoerr "Preparting partitions on ${USBDEV} failed; aborting"
fi
echo "Formatting ${USBDEV}1"
systemd-nspawn --bind ""${USBDEV}"" --bind "${USBDEV}1" -D "${TARGET}" /sbin/mkdosfs -F32 "${USBDEV}1"
if [[ "$?" != "0" ]]; then
echoerr "mkdosfs -F32 ${USBDEV}1 failed; aborting"
exit 1
fi
echo "Running /sbin/setup-bootable /iso ${USBDEV}1"
systemd-nspawn --bind ${USBDEV} --bind "${USBDEV}1" -D "${TARGET}" /sbin/setup-bootable /iso "${USBDEV}1"
if [[ "$?" != "0" ]]; then
echoerr "setup-bootable failed; inspect ${USBDEV} manually"
exit 1
fi
else
echoerr "No device provided; nothing more to do"
fi
echo "Script finished!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.