Skip to content

Commit

Permalink
initial commit of the initrd sdk
Browse files Browse the repository at this point in the history
This commit:
 - Introduces the concept of the initrd SDK in support of disk image building
 - Adds a short README explaining the goal of the initrd SDK
 - Adds the first script to the SDK

Signed-off-by: Adam Rozman <adam.rozman@est.tech>
  • Loading branch information
Rozzii committed Oct 3, 2024
1 parent cf10f81 commit 05995d1
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 0 deletions.
9 changes: 9 additions & 0 deletions jenkins/image_building/initrd_sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Initrd SDK

The Initrd SDK folder contains scripts and documentation to help integrate
features e.g. LUKS and TPM support into the linux "initrd/initfs" of disk
disk images built as part of the Metal3 project.

This directory is just a loose collection of scripts and information that
can be injected at different stages of the image building and would be
eventually executed during the boot process of a machine.
140 changes: 140 additions & 0 deletions jenkins/image_building/initrd_sdk/unlock-mount-luks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/bin/bash

_is_luks(){
# check blkid record of a device and determine if it is luks encrypted
# arguments - any path to device file e.g. /dev/sd*,
# /dev/disk/by-label/<your_label>,by-uuid/<your_id> etc..
local _record _half_type _full_type _device_path
_device_path="$1"
_record="$(blkid "${_device_path}")"
_half_type="${_record##*TYPE=\"}"
_full_type="${_half_type%%\"*}"
printf "TYPE IS %s\n" "${_full_type}"
if [[ "crypto_LUKS" == "${_full_type}" ]]; then
return 0
fi
return 1
}

_get_partition_from_blkid(){
# remove all but the device name of the blkid record
# arguments - any path to deevice file e.g. /dev/sd*,
# /dev/disk/by-label/<yourlabel>,by-uuid/<your_id> etc..
local _record _partition_device_path _partition _uuid _blkid
_partition_device_path="$1"
_record="$(blkid "${_partition_device_path}")"
# take the UUID then, run regular blkid w/o arguments and match the UUID
_record="${_record#*UUID=}"
_uuid="${_record%% *}"

blkid | while read -r _pname _iter_uuid _ _; do
if [[ "${_uuid}" == "${_iter_uuid#*UUID=}" ]]; then
_partition="${_pname%%\:*}"
printf "%s" "${_partition##*/}"
break
fi
done
}

_get_part_prefix_for_device(){
# some block device type will have "p" or "part" partition number
# prefix associated with it, this function return's the partition prefix
# arguments - name of a partition that can be found in /proc/partitions
# and belongs to the device/disk under analysis
local _partition
_partition="$1"
if [[ "${_partition}" =~ nvme|loop|mmcblk ]]; then
if [[ "${_partition}" =~ .*part.* ]]; then
printf "part"
else
printf "p"
fi
fi
}

_count_parts_for_disk(){
# Match how many partitions belong to a given disk based on
# data available in /proc/partitions
# arguments - name of the disk under /dev (not path just name)
local _count _disk
_disk="$1"
# both the disk and the partitions are listed in the /proc/partitions so
# there will be an extra record that has to be accounted for
_count=-1
# read command will also cut up the columns
while read -r _ _ _ _part; do
# if the major device number matches then we have match
if [[ "${_part}" =~ ${_disk} ]]; then
_count=$((_count + 1))
fi
done < "/proc/partitions"
printf "%s" "${_count}"
}

# Start of the execution

# The script has 1 mandatory and 3 optional positional arguments
# Such as:
# - path to the device file of the root partition (mandatory)
# - path to the script that provides the encryption key in plain text format
# - the partition number of the config-drive
# - flag to run in dry run mode (nothig will get created/unlocked/mounted
root_device_path="${1:?}"
key_script="${2:-/etc/tpm2-unseal-key.sh}"
config_drive_part_num="${3:-}"
dry_run="${4:-false}"

printf "INFO: unlock script has been started with the following arguments:\n"
printf "Root device:%s, key script:%s, dry run:%s\n" "${root_device_path}" \
"${key_script}" "${dry_run}"

# create the mount point for the root file system
if [[ "${dry_run}" == "false" ]]; then
mkdir "/realroot"
fi

# different workflows depending on the presence of encryption
# --------------------------------------------------------------------
# nvme, mmc/sd card and loop devices have a partition number prefix
# e.g./dev/nvme0n1 <--> /dev/nvme0n1p1
# --------------------------------------------------------------------
# It is expected that the last partition on the root device is the
# config drive partition thus that is the default logic. In case the user
# specified a value for `config_drive_part_num` the partition count will
# be discarded and the value of `config_drive_part_num` will be used instead.
if [[ $(_is_luks "${root_device_path}") ]]; then
printf "Mounting encrypted %s\n" "${root_device_path}"
if [[ "${dry_run}" == "false" ]]; then
/usr/lib/systemd/systemd-cryptsetup attach realroot \
"${root_device_path}" <("${key_script}") luks
mount "/dev/mapper/realroot" "/realroot"
fi
root_partition="$(_get_partition_from_blkid "${root_device_path}")"
part_prefix="$(_get_part_prefix_for_device "${root_partition}")"
root_device="${root_partition%"${part_prefix}"*}"
part_count="$(_count_parts_for_disk "${root_device}")"
config_drive_common="/dev/${root_device}${part_prefix}"
if [[ -z "${config_drive_part_num}" ]]; then
config_drive_path="${config_drive_common}${part_count}"
else
config_drive_path="${config_drive_common}${config_drive_part_num}"
fi
if [[ $(_is_luks "${config_drive_path}") ]]; then
printf "Unlocking config drive %s\n" "${config_drive_path}"
printf "INFO: config-drive:%s disk:%s part_count:%s " \
"${config_drive_path}" "${root_device}" "${part_count}"
printf "root_partition:%s prefix:%s\n" "${root_partition}" \
"${part_prefix}"
if [[ "${dry_run}" == "false" ]]; then
/usr/lib/systemd/systemd-cryptsetup attach "config-2" \
"${config_drive_path}" <("${key_script}") luks
fi
# At this stage the config drive does not need to be mounted, after
# that it is unlocked cloud-init can identify and mount the config
# drive on its own
fi

else
printf "Mounting NON encrypted volume!!!\n"
mount "${root_device_path}" "/realroot"
fi

0 comments on commit 05995d1

Please sign in to comment.