Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If target image is a block device, access it directly #22

Merged
merged 2 commits into from
Sep 29, 2023
Merged
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
52 changes: 30 additions & 22 deletions alpine-make-vm-image
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
# --partition.
#
# Arguments:
# <image> Path of disk image to use or create if not exists.
# <image> Path of block device or disk image file to use or create
# if it does not exist.
#
# <script> Path of script to execute after installing base system in
# the mounted image and before umounting it.
Expand Down Expand Up @@ -48,10 +49,12 @@
# -P --partition (PARTITION) Create GUID Partition Table (GPT) with a single partition.
# GPT is always created if --boot-mode is UEFI.
#
# -f --image-format IMAGE_FORMAT Format of the disk image (see qemu-img --help).
# -f --image-format IMAGE_FORMAT Format of the disk image (see qemu-img --help). Not
# applicable if the target image is a block device.
#
# -s --image-size IMAGE_SIZE Size of the disk image to create in bytes or with suffix
# (e.g. 1G, 1024M). Default is 2G.
# (e.g. 1G, 1024M). Default is 2G. Not applicable if the
# target image is a block device.
#
# -i --initfs-features INITFS_FEATURES List of additional mkinitfs features (basically modules)
# to be included in initramfs (see mkinitfs -L). "base" and
Expand Down Expand Up @@ -170,12 +173,12 @@ cleanup() {
fi
if [ "$mount_dir" ]; then
umount_recursively "$mount_dir" \
|| die "Failed to unmount $mount_dir; unmount it and disconnect $nbd_dev manually"
|| die "Failed to unmount $mount_dir; unmount it and disconnect $disk_dev manually"
rm -Rf "$mount_dir"
fi
if [ "$nbd_dev" ]; then
qemu-nbd --disconnect "$nbd_dev" \
|| die "Failed to disconnect $nbd_dev; disconnect it manually"
if [ "$disk_dev" ] && ! [ -b "$IMAGE_FILE" ]; then
qemu-nbd --disconnect "$disk_dev" \
|| die "Failed to disconnect $disk_dev; disconnect it manually"
fi
if [ "$INSTALL_HOST_PKGS" = yes ]; then
_apk del $VIRTUAL_PKG
Expand All @@ -190,17 +193,17 @@ _apk() {
attach_image() {
local image="$1"
local format="${2:-}"
local nbd_dev
local disk_dev

nbd_dev=$(get_available_nbd) || {
disk_dev=$(get_available_nbd) || {
modprobe nbd max_part=16
sleep 1
nbd_dev=$(get_available_nbd)
disk_dev=$(get_available_nbd)
} || die 'No available nbd device found!'

qemu-nbd --connect="$nbd_dev" --cache=writeback \
qemu-nbd --connect="$disk_dev" --cache=writeback \
${format:+--format=$format} "$image" \
&& echo "$nbd_dev"
&& echo "$disk_dev"
}

# Prints UUID of filesystem on the specified block device.
Expand All @@ -223,7 +226,7 @@ create_gpt() {
'label: gpt' \
'name=efi,type=U,size=128M,bootable' \
'name=system,type=L' \
| sfdisk "$nbd_dev" ;;
| sfdisk "$disk_dev" ;;
*) die "Invalid mode: $mode" ;;
esac
}
Expand Down Expand Up @@ -505,33 +508,38 @@ if ! command -v "$APK" >/dev/null; then
fi

#-----------------------------------------------------------------------
if [ ! -f "$IMAGE_FILE" ]; then
if [ ! -f "$IMAGE_FILE" ] && [ ! -b "$IMAGE_FILE" ]; then
einfo "Creating $IMAGE_FORMAT image of size $IMAGE_SIZE"
qemu-img create ${IMAGE_FORMAT:+-f $IMAGE_FORMAT} "$IMAGE_FILE" "$IMAGE_SIZE"
fi

#-----------------------------------------------------------------------
einfo "Attaching image $IMAGE_FILE as a NBD device"
if [ -b "$IMAGE_FILE" ]; then
echo "Provided target $IMAGE_FILE is a block device" >&2

nbd_dev=$(attach_image "$IMAGE_FILE" "$IMAGE_FORMAT")
disk_dev="$IMAGE_FILE"
else
einfo "Attaching image $IMAGE_FILE as a NBD device"

disk_dev=$(attach_image "$IMAGE_FILE" "$IMAGE_FORMAT")
fi

#-----------------------------------------------------------------------
if [ "$PARTITION" = yes ] || [ "$BOOT_MODE" = 'UEFI' ]; then
einfo 'Creating GPT partition table'

create_gpt "$nbd_dev" "$BOOT_MODE"
create_gpt "$disk_dev" "$BOOT_MODE"

if [ "$BOOT_MODE" = 'BIOS' ]; then
root_dev="${nbd_dev}p1"
root_dev="${disk_dev}p1"
else
esp_dev="${nbd_dev}p1"
root_dev="${nbd_dev}p2"
esp_dev="${disk_dev}p1"
root_dev="${disk_dev}p2"
fi
# This is needed when running in a container.
settle_dev_node "$root_dev" || die "system didn't create $root_dev node"
else
root_dev="$nbd_dev"
root_dev="$disk_dev"
fi

#-----------------------------------------------------------------------
Expand Down Expand Up @@ -620,7 +628,7 @@ if [ "$BOOT_MODE" = 'BIOS' ]; then
setup_extlinux . "UUID=$root_uuid" "$ROOTFS" "$KERNEL_FLAVOR" "$SERIAL_PORT"

if [ "$PARTITION" = yes ]; then
dd bs=440 count=1 conv=notrunc if=usr/share/syslinux/gptmbr.bin of="$nbd_dev"
dd bs=440 count=1 conv=notrunc if=usr/share/syslinux/gptmbr.bin of="$disk_dev"
sync
fi
fi
Expand Down