Skip to content

Commit

Permalink
Merge pull request #37 from sysrich/systemdrepartcore
Browse files Browse the repository at this point in the history
Introduce systemd-repart core functionality, use it for encryption, and introduce encryption module relying on it
  • Loading branch information
sysrich authored Jul 24, 2024
2 parents c046425 + 8b56db0 commit a17b5aa
Show file tree
Hide file tree
Showing 7 changed files with 432 additions and 96 deletions.
9 changes: 5 additions & 4 deletions usr/bin/tik
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ cleanup() {
zenity --timeout 5 --info --no-wrap --text="<b>Test Succeeded:</b>\n\nHave a nice day!"
elif [ "${retval}" == "0" ]; then
zenity --timeout 5 --info --no-wrap --title="Installation Complete!" --text="${TIK_OS_NAME} has been installed.\n\n<b>System is rebooting</b>"
systemctl reboot
prun systemctl reboot --force
else
zenity --error --no-wrap --title="Installation Failed" --text="Please file a bug report at <tt>${TIK_BUG_URL}</tt>\n\nPlease include the <tt>tik.log</tt> file\nIt can be found on the IGNITION partition on this USB Stick\n\n<b>System is shutting down</b>"
cp -a ${tik_log} /ignition
systemctl poweroff
prun systemctl poweroff --force
fi
}
trap cleanup EXIT
Expand All @@ -55,9 +55,10 @@ load_modules "pre" "custom"
get_disk
get_img
dump_image "${TIK_INSTALL_IMAGE}" "${TIK_INSTALL_DEVICE}"
reread_partitiontable

load_modules "post"
load_modules "post" "custom"

set_boot_target

wipe_keyfile
set_boot_target
148 changes: 123 additions & 25 deletions usr/lib/tik/lib/tik-functions
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,28 @@ probe_partitions() {
prun /usr/bin/mkdir -p ${probe_dir}/mnt
probedpart=""
for part in $(lsblk ${device} -p -n -r -o ID-LINK,FSTYPE|tr -s ' ' ";"|grep ";${filesystem_type}"|cut -d\; -f1); do
# Fallback to unix device in order to fix issue with USB devices
prun /usr/bin/mount ${mountops} "$(/usr/bin/readlink -f "/dev/disk/by-id/${part}")" "${probe_dir}/mnt"
# Check if ${filematch} exists
if [ -f ${probe_dir}/mnt/${filematch} ]; then
# Fallback to unix device in order to fix issue USB devices
if [ -z ${filematch} ]; then
log "[probe_partitions] no file match required"
# Fallback to unix device in order to fix issue with USB devices
probedpart="$(/usr/bin/readlink -f "/dev/disk/by-id/""${part}")"
log "[probe_partitions] /dev/disk/by-id/${part} found"
if grep -q 'PRETTY_NAME="openSUSE MicroOS"' ${probe_dir}/mnt/${filematch} && [ -f ${probe_dir}/mnt/usr/bin/gnome-shell ]; then
# Found legacy Aeon, activate easter egg
log "Legacy Aeon Install FOUND"
legacy_aeon=1
log "[probe_partitions] Partition ${probedpart} found"
else # Check if ${filematch} exists
# Fallback to unix device in order to fix issue with USB devices
part="$(/usr/bin/readlink -f "/dev/disk/by-id/""${part}")"
prun /usr/bin/mount ${mountops} ${part} "${probe_dir}/mnt"
if [ -f ${probe_dir}/mnt/${filematch} ]; then
log "[probe_partitions] File ${filematch} found"
# Fallback to unix device in order to fix issue with USB devices
probedpart="${part}"
log "[probe_partitions] Partition ${probedpart} found"
if grep -q 'PRETTY_NAME="openSUSE MicroOS"' ${probe_dir}/mnt/${filematch} && [ -f ${probe_dir}/mnt/usr/bin/gnome-shell ]; then
# Found legacy Aeon, activate easter egg
log "Legacy Aeon Install FOUND"
legacy_aeon=1
fi
fi
prun-opt /usr/bin/umount ${probe_dir}/mnt
fi
prun-opt /usr/bin/umount ${probe_dir}/mnt
done
prun /usr/bin/rmdir ${probe_dir}/mnt
}
Expand Down Expand Up @@ -261,15 +269,17 @@ get_img() {
local img_item
local img_list
local img_array
local file_type
# Images are assumed to be named to the following standard
# $ProductName.$Version.raw.xz
# $ProductName.$Version.raw.xz for block devices
# $ProductName.$Version.raw for systemd-repart images
# Any extraneous fields may confuse tik's detection, selection and presentation of the image to the user
for img_meta in $(
eval cd $TIK_IMG_DIR && (stat --printf="%n\t%s\n" *.raw.xz | tr ' ' ":")
);do
img_filename="$(echo $img_meta | cut -f1 -d:)"
img_size="$(echo $img_meta | cut -f2 -d:)"
list_items="${list_items} ${img_filename} ${img_size}"
for file_type in '*.raw.xz' '*.raw';do
for img_meta in $(cd $TIK_IMG_DIR && (stat --printf="%n\t%s\n" ${file_type} | tr ' ' ":"));do
img_filename="$(echo $img_meta | cut -f1 -d:)"
img_size="$(echo $img_meta | cut -f2 -d:)"
list_items="${list_items} ${img_filename} ${img_size}"
done
done
if [ -n "${TIK_INSTALL_IMAGE}" ];then
# install image overwritten by config.
Expand All @@ -294,8 +304,7 @@ get_img() {
log "${message}"
fi
if [ -z "${list_items}" ];then
local no_image_text="No images(s) for installation found"
error "${no_image_text}"
TIK_INSTALL_IMAGE='TIK_SELFDEPLOY'
fi
img_list=${list_items}
if [ -n "${img_list}" ];then
Expand All @@ -313,34 +322,123 @@ get_img() {
TIK_INSTALL_IMAGE="${img_array[0]}"
else
# manually select from storage list
d --list --column=Disk --column=Size --title="Select A Image" --text="Select the operating system image to install.\n" ${list_items}
d --list --column=Image --column=Size --title="Select A Image" --text="Select the operating system image to install.\n" ${list_items}
TIK_INSTALL_IMAGE="$result"
fi
fi
}

reread_partitiontable() {
# We've just done a lot to $TIK_INSTALL_DEVICE and it's probably a good idea to make sure the partition table is clearly read so tools like dracut dont get confused.
log "[reread_partitiontable] Re-reading partition table"
prun /usr/sbin/blockdev --rereadpt ${TIK_INSTALL_DEVICE}
}

create_keyfile() {
# Even if there's no partitions using encryption, systemd-repart will need a key-file defined for the --key-file parameter.
tik_keyfile=/tmp/tikkeyfile
log "[create_keyfile] Creating keyfile ${tik_keyfile}"
prun /usr/bin/dd bs=512 count=4 if=/dev/urandom of=${tik_keyfile} iflag=fullblock
prun /usr/bin/chmod 400 ${tik_keyfile}
}

wipe_keyfile() {
# We made a keyfile and need to clean it up at the end of the installation, possibly wiping it from the newly installed device
log "[wipe_keyfile] Deleting keyfile ${tik_keyfile}"
probe_partitions ${TIK_INSTALL_DEVICE} "crypto_LUKS"
if [ -n "${probedpart}" ]; then
# Assumes Slot 0 is always by the key-file at enrolment
prun /usr/bin/systemd-cryptenroll --unlock-key-file=${tik_keyfile} --wipe-slot=0 ${probedpart}
fi
# We're done with the key-file, so remove it
prun /usr/bin/rm ${tik_keyfile}
}

dump_image() {
local image_source_files=$1
local image_target=$2
local image_source

d --question --no-wrap --title="Begin Installation?" --text="Once the installation begins the changes to the selected disk are irreversible.\n\n<b>Proceeding will fully erase the disk.</b>\n\nContinue with installation?"

case "${image_source_files}" in
*.raw.xz)
dump_image_dd ${image_source_files} ${image_target}
;;
*.raw)
dump_image_repart_image ${image_source_files} ${image_target}
;;
TIK_SELFDEPLOY)
dump_image_repart_self ${image_target}
;;
*)
error "invalid image type provided"
esac
}

dump_image_dd() {
local image_source_files=$1
local image_target=$2
log "[dump_image_dd] deploying ${TIK_IMG_DIR}/${image_source_files}"
(xzcat ${TIK_IMG_DIR}/${image_source_files} | pv -f -F "# %b copied in %t %r" | prun /usr/bin/dd of=${image_target} bs=64k) 2>&1 | d --progress --title="Installing ${TIK_OS_NAME}" --pulsate --auto-close --no-cancel --width=400
prun /usr/bin/sync | d --progress --title="Syncing" --pulsate --auto-close --no-cancel --width=400
}

dump_image_repart_image() {
local image_source_files=$1
local image_target=$2
local success=0
local max_attempts=5
local attempt_num=1
create_keyfile
log "[dump_image_repart_image] deploying ${TIK_IMG_DIR}/${image_source_files}"
# systemd-repart doesn't always parse the contents of the image perfectly first time, so retry a few times before declaring it a failure
while [ ${success} = 0 ] && [ ${attempt_num} -lt ${max_attempts} ]; do
prun-opt systemd-repart --no-pager --pretty=0 --empty=force --dry-run=no --key-file=${tik_keyfile} --image=${TIK_IMG_DIR}/${image_source_files} --image-policy=root=unprotected ${image_target} > >(d --progress --title="Installing ${TIK_OS_NAME}" --text="Deploying OS Image" --pulsate --auto-close --no-cancel --width=400)
if [ ${retval} -eq 0 ]; then
success=1
else
# repart couldn't find a root partition
log "[dump_image_repart_image] systemd-repart attempt $attempt_num failed. Trying again..."
sleep 1
# Increment the attempt counter
attempt_num=$(( attempt_num + 1 ))
fi
done
if [ ${success} = 1 ]; then
log "[dump_image_repart_image] systemd-repart succeeded after $attempt_num attempts"
else
error "systemd-repart failed"
fi
}

dump_image_repart_self() {
local image_target=$1
create_keyfile
log "[dump_image_repart_self] self-deploying"
prun systemd-repart --no-pager --pretty=0 --empty=force --dry-run=no --key-file=${tik_keyfile} ${image_target} > >(d --progress --title="Installing ${TIK_OS_NAME}" --text="Deploying OS Image" --pulsate --auto-close --no-cancel --width=400)
}

set_boot_target() {
local efipartnum
if [ "${debug}" == "1" ]; then
log "[debug] Not setting EFI boot target"
elif [ -n "${efi_already_set}" ]; then
log "[set_boot_target] boot target already set, not setting again"
else
# Cleanup any existing openSUSE boot entries
prun-opt /usr/sbin/efibootmgr -B -L "openSUSE Boot Manager"
prun /usr/sbin/efibootmgr -O
# Currently assuming Aeon-like partition layout and shim name. This function will need extra intelligence to probe partitions for other image layouts
prun /usr/sbin/efibootmgr -c -L "openSUSE Boot Manager" -d ${TIK_INSTALL_DEVICE} -l "\EFI\systemd\shim.efi" -p 2
log "[set_boot_target] searching for ESP partition containing /EFI/systemd/shim.efi on ${TIK_INSTALL_DEVICE}"
probe_partitions ${TIK_INSTALL_DEVICE} "vfat" "/EFI/systemd/shim.efi"
if [ -z "${probedpart}" ]; then
error "esp partition not found"
fi
efipartnum=$(lsblk ${probedpart} -p -n -r -o PARTN)
log "[set_boot_target] found ESP on ${probedpart}, partition number ${efipartnum}"
prun /usr/sbin/efibootmgr -c -L "openSUSE Boot Manager" -d ${TIK_INSTALL_DEVICE} -l "\EFI\systemd\shim.efi" -p ${efipartnum}
# Log to show the resulting eficonfig
log "[efibootmgr] $(prun /usr/sbin/efibootmgr)"
log "[set_boot_target] $(prun /usr/sbin/efibootmgr)"
efi_already_set=1
fi
}

Expand Down
65 changes: 0 additions & 65 deletions usr/lib/tik/modules/post/10-encrypt

This file was deleted.

Loading

0 comments on commit a17b5aa

Please sign in to comment.