Skip to content
Draft
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
75 changes: 56 additions & 19 deletions live-build/config/hooks/vm-artifacts/90-raw-disk-image.binary
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ internal-buildserver)
RAW_DISK_SIZE_GB=512
;;
internal-*)
RAW_DISK_SIZE_GB=70
RAW_DISK_SIZE_GB=48
;;
*)
die "Invalid variant specified: '$APPLIANCE_VARIANT'"
Expand All @@ -89,24 +89,23 @@ truncate -s "${RAW_DISK_SIZE_GB}G" "$ARTIFACT_NAME.img"
sgdisk --zap-all "$ARTIFACT_NAME.img"

#
# Here we're creating the boot partition. When installing grub, this
# partition will be used and automatically detected by "grub-install"
# based on the partitions typecode. This partition is required since we're
# partitioning using GPT; if we used MBR, an explicit boot partition
# wouldn't be required. Also we leave the first 1MB unallocated since
# some clouds (i.e. Azure) may require space for their own internal
# purposes.
# Here we're creating the boot partition. A 250MB EFI boot partition should
# be sufficient to store 5 initrd and vmlinuz versions (if necessary). GRUB
# files are ~11MB, initrd and vmlinuz are ~40MB, and all boot loaders EFI
# directory are under 500K.
#
sgdisk "$ARTIFACT_NAME.img" \
--set-alignment=1 --new=2:1m:+1m --typecode=2:EF02

# Also we leave the first 1MB unallocated since some clouds (i.e. Azure) may
# require space for their own internal purposes.
#
sgdisk "$ARTIFACT_NAME.img" --set-alignment=1 \
--new=1:1m:+250m --typecode=1:EF00 -c:1:"EFI Boot"
#
# Now we create the partition that we'll use for the zpool that will be
# used for the root pool. We use a generic typecode for this partition
# that simply maps to "Linux filesystem". The typecode here is simply
# cosmetic, as there's nothing that relies on it being set.
#
sgdisk "$ARTIFACT_NAME.img" --new=1:: --typecode=1:8300
sgdisk "$ARTIFACT_NAME.img" --new=2:: --typecode=2:8300

#
# This is done simply for debugging and/or diagnostic purposes. When
Expand Down Expand Up @@ -147,7 +146,7 @@ zpool create -d \
-O compression=on \
-R "$DIRECTORY" \
-t "$FSNAME" \
rpool "/dev/mapper/${LOOPNAME}p1"
rpool "/dev/mapper/${LOOPNAME}p2"

zfs create \
-o canmount=off \
Expand Down Expand Up @@ -293,6 +292,10 @@ mount -t zfs "$FSNAME/ROOT/$FSNAME/vartmp" "$DIRECTORY/var/tmp"
mkdir -p "/var/crash"
mount -t zfs "$FSNAME/crashdump" "/var/crash"

# Make the vfat partition and get its FSID
mkfs.vfat -F32 /dev/mapper/${LOOPNAME}p1
efi_part_fsid=`blkid -s UUID -o value /dev/mapper/${LOOPNAME}p1`

#
# Populate the root filesystem with the contents of the "binary" directory
# that (we assume) was previously generated by live-build.
Expand All @@ -318,6 +321,7 @@ cat <<-EOF >"$DIRECTORY/etc/fstab"
rpool/ROOT/$FSNAME/tmp /tmp zfs defaults,nosuid,nodev,exec,x-systemd.before=zfs-import-cache.service 0 0
rpool/ROOT/$FSNAME/vartmp /var/tmp zfs defaults,nosuid,nodev,exec,x-systemd.before=zfs-import-cache.service 0 0
rpool/crashdump /var/crash zfs defaults,x-systemd.before=zfs-import-cache.service,x-systemd.before=kdump-tools.service 0 0
UUID=${efi_part_fsid} /boot/efi vfat defaults 0 0
EOF

#
Expand All @@ -343,13 +347,46 @@ for dir in /dev /proc /sys; do
done

#
# We need to use the dedicated grub dataset when running "grub-install"
# and "grub-mkconfig", so we need to mount this dataset first.
# Mount /boot/efi and do grub and bootctl install
#
chroot "$DIRECTORY" mount -t zfs "$FSNAME/grub" /mnt
chroot "$DIRECTORY" grub-install --root-directory=/mnt "/dev/$LOOPNAME"
chroot "$DIRECTORY" grub-mkconfig -o /mnt/boot/grub/grub.cfg
chroot "$DIRECTORY" umount /mnt
EFI_DIR="/mnt/boot/efi"
chroot "$DIRECTORY" mkdir -p $EFI_DIR
chroot "$DIRECTORY" mount /dev/mapper/${LOOPNAME}p1 $EFI_DIR

# Copy the latest kernel into EFI boot directory
chroot "$DIRECTORY" cp /boot/initrd.img $EFI_DIR
chroot "$DIRECTORY" cp /boot/vmlinuz $EFI_DIR
chroot "$DIRECTORY" bootctl --esp-path=$EFI_DIR install --no-variables

# Use GRUB_CMDLINE_LINUX_DEFAULT boot options
source $DIRECTORY/etc/default/grub.d/override.cfg
cat <<-EOF >"${DIRECTORY}/${EFI_DIR}/loader/entries/delphix.conf"
title Delphix Engine
linux /vmlinuz
initrd /initrd.img
options root=ZFS=rpool/ROOT/${FSNAME}/root ro $GRUB_CMDLINE_LINUX_DEFAULT
EOF

# Single user mode. Need the console options from GRUB
console_options=$(awk -F'"' '/console=tty/ {print $2}' $DIRECTORY/etc/default/grub.d/override.cfg)
cat <<-EOF >"${DIRECTORY}/${EFI_DIR}/loader/entries/delphix-single.conf"
title Delphix Engine Single User mode
linux /vmlinuz
initrd /initrd.img
options root=ZFS=rpool/ROOT/${FSNAME}/root ro single ${console_options} nomodeset dis_ucode_ldr
EOF

# Set loader configurations
cat <<-EOF >"${DIRECTORY}/${EFI_DIR}/loader/loader.conf"
timeout 10
console-mode max
default delphix.conf
editor yes
auto-entries yes
auto-firmware yes
EOF

chroot "$DIRECTORY" umount $EFI_DIR

for dir in /dev /proc /sys; do
retry 5 10 umount -R "${DIRECTORY}${dir}"
Expand Down
3 changes: 2 additions & 1 deletion live-build/config/hooks/vm-artifacts/template.ovf
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@
</Item>
<vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" vmw:value="true"/>
<vmw:Config ovf:required="false" vmw:key="cpuHotRemoveEnabled" vmw:value="false"/>
<vmw:Config ovf:required="false" vmw:key="firmware" vmw:value="bios"/>
<vmw:Config ovf:required="false" vmw:key="firmware" vmw:value="efi"/>
<vmw:Config ovf:required="false" vmw:key="bootOptions.efiSecureBootEnabled" vmw:value="false"/>
<vmw:Config ovf:required="false" vmw:key="virtualICH7MPresent" vmw:value="false"/>
<vmw:Config ovf:required="false" vmw:key="virtualSMCPresent" vmw:value="false"/>
<vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" vmw:value="true"/>
Expand Down
7 changes: 6 additions & 1 deletion upgrade/upgrade-scripts/common.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright 2018 Delphix
# Copyright 2018, 2025 Delphix
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,7 @@
UPDATE_DIR="/var/dlpx-update"
LOG_DIRECTORY="/var/tmp/delphix-upgrade"
HOTFIX_PATH="/etc/hotfix"
EFI_DIR="/boot/efi"

#
# The virtualization service uses a different umask than the default. Thus to
Expand Down Expand Up @@ -376,6 +377,10 @@ function verify_upgrade_not_in_progress() {
[[ -z "$UPGRADE_TYPE" ]] || die "upgrade currently in-progress"
}

function is_bootmode_uefi() {
[ -d /sys/firmware/efi/efivars ] && return 0 || return 1
}

function mask_service() {
local svc="$1"
local container="$2"
Expand Down
118 changes: 77 additions & 41 deletions upgrade/upgrade-scripts/rootfs-container
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright 2019 Delphix
# Copyright 2019, 2025 Delphix
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -102,6 +102,28 @@ function get_bootloader_devices() {
done
}

function update_systemd_boot_entries() {
cp "${EFI_DIR}/loader/entries/delphix.conf" "${EFI_DIR}/loader/entries/delphix.conf.bak"
cp "${EFI_DIR}/loader/entries/delphix-single.conf" "${EFI_DIR}/loader/entries/delphix-single.conf.bak"

# Update default and single user entries
source /etc/default/grub.d/override.cfg
cat <<-EOF >"${EFI_DIR}/loader/entries/delphix.conf"
title Delphix Engine
linux /vmlinuz
initrd /initrd.img
options root=ZFS=rpool/ROOT/${CONTAINER}/root ro $GRUB_CMDLINE_LINUX_DEFAULT
EOF

# Single user entry
cat <<-EOF >"${EFI_DIR}/loader/entries/delphix-single.conf"
title Delphix Engine Single User mode
linux /vmlinuz
initrd /initrd.img
options root=ZFS=rpool/ROOT/${CONTAINER}/root ro single nomodeset dis_ucode_ldr
EOF
}

function set_bootfs_not_mounted_cleanup() {
umount "/var/lib/machines/$CONTAINER/mnt" ||
warn "'umount' of '/var/lib/machines/$CONTAINER/mnt' failed"
Expand Down Expand Up @@ -147,30 +169,37 @@ function set_bootfs_not_mounted() {

PLATFORM=$(get-appliance-platform)

for dev in $(get_bootloader_devices); do
[[ -e "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not found"

[[ -b "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not block device"

opts="--root-directory=/mnt"

if [[ "$PLATFORM" == "esx" ]] || [[ "$PLATFORM" == "oci" ]]; then
opts+=" --debug-image=all"
opts+=" -v"
fi
# If using EFI firmware, update boot entries, vmlinuz, initrd, and bootloader
if is_bootmode_uefi; then
update_systemd_boot_entries
cp "/var/lib/machines/${CONTAINER}/boot/initrd.img" "$EFI_DIR"
cp "/var/lib/machines/${CONTAINER}/boot/vmlinuz" "$EFI_DIR"
chroot "/var/lib/machines/$CONTAINER" bootctl update
else
for dev in $(get_bootloader_devices); do
[[ -e "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not found"

[[ -b "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not block device"

opts="--root-directory=/mnt"

if [[ "$PLATFORM" == "esx" ]] || [[ "$PLATFORM" == "oci" ]]; then
opts+=" --debug-image=all"
opts+=" -v"
fi

# shellcheck disable=SC2086
chroot "/var/lib/machines/$CONTAINER" \
grub-install $opts "/dev/$dev" ||
die "'grub-install' for '$dev' failed in '$CONTAINER'"
done

# shellcheck disable=SC2086
chroot "/var/lib/machines/$CONTAINER" \
grub-install $opts "/dev/$dev" ||
die "'grub-install' for '$dev' failed in '$CONTAINER'"
done

chroot "/var/lib/machines/$CONTAINER" \
grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
die "'grub-mkconfig' failed in '$CONTAINER'"

grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
die "'grub-mkconfig' failed in '$CONTAINER'"
fi
set_bootfs_not_mounted_cleanup
trap - EXIT

Expand Down Expand Up @@ -211,28 +240,35 @@ function set_bootfs_mounted() {

PLATFORM=$(get-appliance-platform)

for dev in $(get_bootloader_devices); do
[[ -e "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not found"
# If using EFI firmware, update boot entries, vmlinuz, initrd, and bootloader
if is_bootmode_uefi; then
update_systemd_boot_entries
cp /boot/initrd.img "$EFI_DIR"
cp /boot/vmlinuz "$EFI_DIR"
bootctl update
else
for dev in $(get_bootloader_devices); do
[[ -e "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not found"

[[ -b "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not block device"
[[ -b "/dev/$dev" ]] ||
die "bootloader device '/dev/$dev' not block device"

opts="--root-directory=/mnt"
opts="--root-directory=/mnt"

if [[ "$PLATFORM" == "esx" ]] || [[ "$PLATFORM" == "oci" ]]; then
opts+=" --debug-image=all"
opts+=" -v"
fi

# shellcheck disable=SC2086
grub-install $opts "/dev/$dev" ||
die "'grub-install' for '$dev' failed in '$CONTAINER'"
done
if [[ "$PLATFORM" == "esx" ]] || [[ "$PLATFORM" == "oci" ]]; then
opts+=" --debug-image=all"
opts+=" -v"
fi

grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
die "'grub-mkconfig' failed in '$CONTAINER'"
# shellcheck disable=SC2086
grub-install $opts "/dev/$dev" ||
die "'grub-install' for '$dev' failed in '$CONTAINER'"
done

grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
die "'grub-mkconfig' failed in '$CONTAINER'"
fi
set_bootfs_mounted_cleanup
trap - EXIT
}
Expand Down Expand Up @@ -367,7 +403,7 @@ set-bootfs)
# We only have a single bootloader on any given appliance, so we
# need to ensure that only a single process is attempting to
# update the bootloader at any given time. The locking done here
# is to help prevent accidential corruption of the bootloader,
# is to help prevent accidental corruption of the bootloader,
# by ensuring only a single invocation of this script can set
# the boot filesystem at any given time.
#
Expand Down