Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

# Use the official Void Linux container
FROM ghcr.io/void-linux/void-glibc-full
LABEL org.opencontainers.image.source=https://github.com/midzelis/zquickinit

ARG XBPS_REPOS="https://repo-fastly.voidlinux.org/current https://repo-fastly.voidlinux.org/current/nonfree"

Expand Down
108 changes: 82 additions & 26 deletions zquickinit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,35 @@ SRC_ROOT=${DIR}
ZBM_ROOT=${SRC_ROOT}/../zfsbootmenu
RECIPES_ROOT=${RECIPES_ROOT:-${SRC_ROOT}/recipes}

RECIPE_BUILDER="ghcr.io/midzelis/zquickinit"
ZQUICKEFI_URL="https://github.com/midzelis/zquickinit/releases/latest"
# if empty, use latest release tag
ZBM_TAG=
RECIPE_BUILDER="${RECIPE_BUILDER:-ghcr.io/midzelis/zquickinit}"
ZQUICKINIT_REPO="${ZQUICKINIT_REPO:-https://github.com/midzelis/zquickinit}"
ZQUICKEFI_URL="${ZQUICKEFI_URL:-${ZQUICKINIT_REPO}/releases/latest}"

# provide default stable, latest ZBM_TAG if not specified
ZBM_TAG="${ZBM_TAG:-v3.0.1}"
# if empty, then unset to get latest release
if [[ -z "$ZBM_TAG" ]]; then
ZBM_TAG=""
fi

# if specified, takes precedence over ZBM_TAG
ZBM_COMMIT_HASH=db78c980f40937f3b4de8d85e7430f6553a39972
ZBM_COMMIT_HASH="${ZBM_COMMIT_HASH:-}"
# if ZBM_COMMIT_HASH is specified, unset ZBM_TAG
if [[ -n "$ZBM_COMMIT_HASH" ]]; then
ZBM_TAG=""
fi

INPUT=/input
OUTPUT=/output
ADD_LOADER=
MKINIT_VERBOSE=
KERNEL_BOOT=
ENGINE=
OBJCOPY=
DU=
FIND=
YG=
STAT=
NOASK=0
DEBUG=0
ENTER=0
Expand Down Expand Up @@ -101,10 +115,10 @@ check() {
fi
fi
if [[ $1 == docker || $1 == podman ]]; then
if command -v docker &>/dev/null; then
if [ -z "$ENGINE" ] && command -v docker &>/dev/null; then
ENGINE=docker
return 0
elif command -v podman &>/dev/null; then
elif [ -z "$ENGINE" ] && command -v podman &>/dev/null; then
ENGINE=podman
return 0
fi
Expand Down Expand Up @@ -142,17 +156,6 @@ check() {
OBJCOPY=objcopy
fi
fi
if ! command -v "$1" &>/dev/null; then
echo "$1 not found. usually part of the $2 package"
if [[ $1 == "gum" && -f "/etc/debian_version" ]]; then
echo "To install, try:"
echo 'sudo mkdir -p /etc/apt/keyrings'
echo 'curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg'
echo 'echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list'
echo 'sudo apt update && sudo apt install gum'
fi
exit 1
fi
if [[ $1 == find ]] && [[ -z "${FIND}" ]]; then
if command -v gfind &>/dev/null; then
FIND="gfind"
Expand All @@ -168,6 +171,47 @@ check() {
exit 1
fi
fi
if [[ $1 == du ]] && [[ -z "${DU}" ]]; then
if command -v gdu &>/dev/null; then
DU="gdu"
else
DU="du"
fi
if [[ ! "$(${DU} --version 2>&1 | head -n1)" == *GNU* ]]; then
echo "du must be GNU flavored. Update or install coreutils package. "
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "On MacOS, use brew to install coreutils"
echo "Note: brew uses /usr/local/bin on Intel, and /opt/homebrew/bin on Apple"
fi
exit 1
fi
fi
if [[ $1 == stat ]] && [[ -z "${STAT}" ]]; then
if command -v gstat &>/dev/null; then
STAT="gstat"
else
STAT="stat"
fi
if [[ ! "$(${STAT} --version 2>&1 | head -n2)" =~ (GNU|BusyBox) ]]; then
echo "stat must be GNU or BusyBox flavored. Update or install coreutils package."
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "On MacOS, use brew to install coreutils"
echo "Note: brew uses /usr/local/bin on Intel, and /opt/homebrew/bin on Apple"
fi
exit 1
fi
fi
if ! command -v "$1" &>/dev/null; then
echo "$1 not found. usually part of the $2 package"
if [[ $1 == "gum" && -f "/etc/debian_version" ]]; then
echo "To install, try:"
echo 'sudo mkdir -p /etc/apt/keyrings'
echo 'curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg'
echo 'echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list'
echo 'sudo apt update && sudo apt install gum'
fi
exit 1
fi
}

# This will build the main ZquickInit Builder OCI image
Expand Down Expand Up @@ -197,6 +241,7 @@ builder() {
echo
cmd=("$ENGINE" build .
-t "$RECIPE_BUILDER"
--label org.opencontainers.image.source="${ZQUICKINIT_REPO}"
--build-arg KERNELS=linux6.6
--build-arg "PACKAGES=${packages[*]}"
--build-arg ZBM_COMMIT_HASH="${ZBM_COMMIT_HASH}"
Expand Down Expand Up @@ -225,6 +270,7 @@ tailscale() {
make_zquick_initramfs() {
check gum gum
check mkinitcpio mkinitcpio
check stat stat

gum style --bold --border double --align center \
--width 50 --margin "1 2" --padding "0 2" "Welcome to ZQuickInit make initramfs"
Expand All @@ -234,13 +280,13 @@ make_zquick_initramfs() {
local hash
echo "Downloading zquickinit"
rm -rf "${INPUT}"
git clone --quiet --depth 1 https://github.com/midzelis/zquickinit.git "${INPUT}"
git clone --quiet --depth 1 "${ZQUICKINIT_REPO}" "${INPUT}"
hash=$(cat /etc/zquickinit-commit-hash || echo '')
if [[ -n "${hash}" ]]; then
(cd "${INPUT}" && git fetch --depth 1 origin "$hash" && git checkout FETCH_HEAD)
fi
fi
[[ -x /etc/zquickinit-commit-hash ]] && (cd "${INPUT}" && git config --global --add safe.directory "${INPUT}" && /etc/zquickinit-commit-hash && git rev-parse HEAD >/etc/zquickinit-commit-hash && echo "ZQuickInit (https://github.com/midzelis/zquickinit) commit hash: $(git rev-parse --short HEAD) ($(git rev-parse HEAD))")
[[ -x /etc/zquickinit-commit-hash ]] && (cd "${INPUT}" && git config --global --add safe.directory "${INPUT}" && /etc/zquickinit-commit-hash && git rev-parse HEAD >/etc/zquickinit-commit-hash && echo "ZQuickInit (${ZQUICKINIT_REPO}) commit hash: $(git rev-parse --short HEAD) ($(git rev-parse HEAD))")

if [[ ! -f "${ZBM}/bin/generate-zbm" ]]; then
echo "Downloading latest zfsbootmenu"
Expand Down Expand Up @@ -576,9 +622,9 @@ make_zquick_initramfs() {
)
chmod o+rw -R "${OUTPUT}"/*
chmod g+rw -R "${OUTPUT}"/*
env LC_ALL=en_US.UTF-8 printf "Kernel size: \t\t%'.0f bytes\n" "$(stat -c '%s' "${OUTPUT}/zquickinit-$build_time.vmlinuz-$kernel")"
env LC_ALL=en_US.UTF-8 printf "initramfs size: \t%'.0f bytes\n" "$(stat -c '%s' "$output_img")"
env LC_ALL=en_US.UTF-8 printf "EFI size: \t\t%'.0f bytes\n" "$(stat -c '%s' "$output_uki")"
env LC_ALL=en_US.UTF-8 printf "Kernel size: \t\t%'.0f bytes\n" "$(${STAT} -c '%s' "${OUTPUT}/zquickinit-$build_time.vmlinuz-$kernel")"
env LC_ALL=en_US.UTF-8 printf "initramfs size: \t%'.0f bytes\n" "$(${STAT} -c '%s' "$output_img")"
env LC_ALL=en_US.UTF-8 printf "EFI size: \t\t%'.0f bytes\n" "$(${STAT} -c '%s' "$output_uki")"
find "${OUTPUT}" -name 'zquickinit*.img' | sort -r | tail -n +4 | xargs -r rm
find "${OUTPUT}" -name 'zquickinit*.efi' | sort -r | tail -n +4 | xargs -r rm
find "${OUTPUT}" -name 'zquickinit*.vmlinuz-*' | sort -r | tail -n +4 | xargs -r rm
Expand Down Expand Up @@ -631,7 +677,7 @@ getefi() {
echo "No image found, finding latest release..."
local version='' download=''
version=$(curl --silent -qI "${ZQUICKEFI_URL}" | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}')
download="https://github.com/midzelis/zquickinit/releases/download/$version/zquickinit.efi"
download="${ZQUICKINIT_REPO}/releases/download/$version/zquickinit.efi"
source="${tmp}/zquickinit-${version}.efi"
echo "Downloading from ${download} to ${source}..."
curl -o "$source" --progress-bar -L "${download}"
Expand Down Expand Up @@ -736,6 +782,7 @@ inject() {
check bsdtar "libarchive-tools"
check objcopy binutils
check truncate coreutils
check stat coreutils
check find findutils

echo "Secrets were injected, appending '_injected' to name"
Expand All @@ -753,7 +800,7 @@ inject() {
# To append an additional initrd segment, the new archive must aligned to a
# 4-byte boundary: https://unix.stackexchange.com/a/737219

initrd_size=$(stat -c '%s' "${initrd}")
initrd_size=$(${STAT} -c '%s' "${initrd}")
initrd_size=$(((initrd_size + 3) / 4 * 4))
truncate -s "${initrd_size}" "${initrd}"

Expand Down Expand Up @@ -829,6 +876,7 @@ iso() {
check xorriso xorriso
check truncate coreutils
check find findutils
check du coreutils

local target=${1:-zquickinit.iso}
local source=${2:-}
Expand All @@ -844,7 +892,7 @@ iso() {
local isoroot="${tmp}/iso"
mkdir -p "${isoroot}"
local size
read -ra size <<<"$(du --apparent-size --block-size=1M "$source")"
read -ra size <<<"$(${DU} --apparent-size --block-size=1M "$source")"
local padded=$((size[0] + 12))
local part_img="${tmp}/efs_partition.img"
rm -rf "${part_img}"
Expand Down Expand Up @@ -878,6 +926,7 @@ playground() {
check truncate coreutils
check qemu-system-x86_64 qemu
check find findutils
check nproc coreutils

# shellcheck disable=SC2155
local tmp=$(tmpdir)
Expand Down Expand Up @@ -1101,6 +1150,12 @@ if [[ $(type -t "$command") == function ]]; then
shift
fi
;;
--engine)
if [[ -n ${2:-} ]]; then
ENGINE=$2
shift
fi
;;
--no-container)
NOCONTAINER=1
;;
Expand Down Expand Up @@ -1188,6 +1243,7 @@ else
echo " --no-container Do not use containers to build initramfs"
echo " --release Do not add QEMU debug, or any secrets"
echo " --secrets <dir> Use this folder for secrets."
echo " --engine <docker|podman> Override automatic detection to use specific engine."
echo " -d,--debug Advanced: Turn on tracing"
echo " -e,--enter Advanced: Do not build an image. Execute bash and"
echo " enter the builder image."
Expand Down