root/build-tools/update-efiboot-image

244 lines
7.1 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright (c) 2016-2017 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# Update the efiboot.img (See https://wiki.archlinux.org/index.php/Remastering_the_Install_ISO)
# We need to mount the image file, make any changes to the filesystem, and unmount.
#
# e.g. udisksctl loop-setup -f efiboot.img --no-user-interaction
# Mapped file efiboot.img as /dev/loop0.
# udisksctl mount -b /dev/loop0
# Mounted /dev/loop0 at /run/media/kbujold/ANACONDA.
#
MY_YUM_CONF=""
# Several commands may need to be executed with sudo if we're not using
# udev. Use a variable to hold the optional "sudo" part
if [ 0${BUILD_ISO_USE_UDEV} -eq 1 ]; then
SUDOPREFIX=""
else
SUDOPREFIX="sudo"
fi
function env_check {
for VAR_TO_CHECK in $@; do
if [ -z "${!VAR_TO_CHECK}" ]; then
echo "Required environment variable is missing: $VAR_TO_CHECK"
exit 1
fi
done
}
env_check MY_REPO MY_WORKSPACE BSP_FILES_PATH
# Cleanup function that will release all mounts and loop devices
function finish {
if [ -z "$LOOP" ] && [ ! -z "$SETUP_RET" ]; then
if [ 0${BUILD_ISO_USE_UDEV} -eq 1 ]; then
LOOP=$(echo $SETUP_RET | awk '{print $5;}' | sed -e 's/\.//g')
else
LOOP=$(echo $SETUP_RET)
fi
fi
if [ ! -z "$LOOP" ]; then
if [ 0${BUILD_ISO_USE_UDEV} -eq 1 ]; then
udisksctl unmount -b $LOOP
else
sudo umount $LOOP
fi
echo $(date) Unmounted $LOOP. $? | tee --append $MOUNT_LOG_FILE
if [ 0${BUILD_ISO_USE_UDEV} -eq 1 ]; then
CLEANUP_RET=$(udisksctl loop-delete -b $LOOP)
else
CLEANUP_RET=$(sudo losetup -d $LOOP)
fi
echo $(date) Released loop device $LOOP. $CLEANUP_RET | tee --append $MOUNT_LOG_FILE
fi
if [ ! -z "$EFI_MOUNT" ] && [ -d "$EFI_MOUNT" ]; then
${SUDOPREFIX} rmdir $EFI_MOUNT
echo $(date) Deleted mount point $EFI_MOUNT | tee --append $MOUNT_LOG_FILE
fi
}
function setup_env_vars {
mkdir -p $MY_WORKSPACE/export/
MY_YUM_CONF=$(create-yum-conf)
if [ $? -ne 0 ]; then
echo "ERROR: create-yum-conf failed"
exit 1
fi
DISTRO_REPO_DIR=$(for d in $(grep baseurl $MY_YUM_CONF | grep file: | awk -F : '{print $2}' | sed 's:///:/:g'); do if [ -d $d/images ]; then echo $d ;fi; done)
if [ ! -d "$DISTRO_REPO_DIR" ] ; then
printf " Error -- could not access $DISTRO_REPO_DIR\n"
exit 1
fi
# where to put stuff (curent dir unless MY_WORKSPACE defined)
OUTPUT_DIR="$PWD/export"
if [ ! -z "$MY_WORKSPACE" ] && [ -d "$MY_WORKSPACE" ] ; then
OUTPUT_DIR="$MY_WORKSPACE/export"
fi
# Directory in which to populate files to be distributed
OUTPUT_DIST_DIR=$OUTPUT_DIR/dist
if [ ! -z "$MY_REPO" ] && [ -d "$MY_REPO" ] ; then
INTERNAL_REPO_ROOT=$MY_REPO
fi
if [ -z "$INTERNAL_REPO_ROOT" ] ; then
if [ ! -z "$MY_REPO_ROOT_DIR" ] && [ -d "$MY_REPO_ROOT_DIR/cgcs-root" ] ; then
INTERNAL_REPO_ROOT=$MY_REPO_ROOT_DIR/cgcs-root
fi
fi
if [ -z "$INTERNAL_REPO_ROOT" ] ; then
if [ -d "$MY_WORKSPACE/std/repo" ] ; then
INTERNAL_REPO_ROOT=$MY_WORKSPACE/std/repo
fi
fi
if [ -z "$INTERNAL_REPO_ROOT" ] ; then
printf " Error -- could not locate cgcs-root repo.\n"
exit 1
fi
}
printf " Calling $0\n"
setup_env_vars
printf " Calling $(basename $0)\n"
mkdir -p $OUTPUT_DIR
if [ $? -ne 0 ]; then
printf " Error: failed to create directory '$OUTPUT_DIR'.\n"
exit 1
fi
MOUNT_LOG_FILE=$OUTPUT_DIR/mounts_used.log
touch $MOUNT_LOG_FILE
if [ $? -ne 0 ]; then
printf " Error: Failed to create log file '$MOUNT_LOG_FILE'.\n"
exit 1
fi
# Register our cleanup function
trap finish EXIT
# Clear old image file
printf " Delete old efiboot.img file\n"
rm -f $OUTPUT_DIR/efiboot.img
yum clean all -c $MY_YUM_CONF
# Copy Vanilla Centos image file
cp -L -u $DISTRO_REPO_DIR/images/efiboot.img $OUTPUT_DIR/
printf " Replacing the efiboot.img grub.cfg file with the Titanium Cloud one\n"
# We can either use udev or sudo to mount loopback device, etc.
# This is controlled via env variable
if [ 0${BUILD_ISO_USE_UDEV} -eq 1 ]; then
SETUP_RET=$(udisksctl loop-setup -f $OUTPUT_DIR/efiboot.img --no-user-interaction)
if [ $? -ne 0 ]; then
printf " Error: failed udev loop-setup command.\n"
exit 1
fi
LOOP=$(echo $SETUP_RET | awk '{print $5;}' | sed -e 's/\.//g')
else
# no udev - use losetup command
# retcode is the lo device used
SETUP_RET=$(sudo losetup --show -f $OUTPUT_DIR/efiboot.img)
if [ -z "$SETUP_RET" ] ; then
printf " Error: failed sudo losetup command.\n"
exit 1
fi
# Save the loop device used into a file
echo $(date) $SETUP_RET >> $MOUNT_LOG_FILE
LOOP=$(echo $SETUP_RET)
if [ -z $LOOP ] ; then
printf " Error: failed losetup command.\n"
exit 1
fi
fi
# Mount the filesystem
if [ 0${BUILD_ISO_USE_UDEV} -eq 1 ]; then
udisksctl mount -b $LOOP
EFI_MOUNT=$(udisksctl info -b $LOOP | grep MountPoints | awk '{print $2;}')
else
EFI_MOUNT=$(sudo mktemp -d -p /mnt -t EFI-noudev.XXXXXX)
sudo mount $LOOP $EFI_MOUNT
fi
if [ -z $EFI_MOUNT ] ; then
printf " Error: failed mount command.\n"
exit 1
fi
# Update the vanilla UEFI Centos grub.cfg with the Titanium Cloud version
${SUDOPREFIX} cp "$BSP_FILES_PATH/grub.cfg" "$EFI_MOUNT/EFI/BOOT/grub.cfg"
# For backward compatibility. Old repo location or new?
CENTOS_REPO=${MY_REPO}/centos-repo
if [ ! -d ${CENTOS_REPO} ]; then
CENTOS_REPO=${MY_REPO}/cgcs-centos-repo
if [ ! -d ${CENTOS_REPO} ]; then
echo "ERROR: directory ${MY_REPO}/centos-repo not found."
exit 1
fi
fi
# Update the grub and shim executables with the Titanium Cloud signed versions
#
# To do this, we extract the RPMS, grab the two executables we need, and replace
# the ones in the current filesystem
TMPDIR=`mktemp -d`
SHIMPKG=`find $MY_WORKSPACE/std/rpmbuild/RPMS ${CENTOS_REPO}/Binary -name 'shim-x64-[0-9]*.x86_64.rpm'`
if [ -z "$SHIMPKG" ]; then
SHIMPKG=`find $MY_WORKSPACE/std/rpmbuild/RPMS ${CENTOS_REPO}/Binary -name 'shim-[0-9]*.x86_64.rpm'`
fi
if [ -z "$SHIMPKG" ]; then
printf " Error -- could not locate shim binary package"
exit 1
fi
GRUBPKG=`find $MY_WORKSPACE/std/rpmbuild/RPMS ${CENTOS_REPO}/Binary -name 'grub2-efi-x64-[0-9]*.x86_64.rpm'`
if [ -z "$GRUBPKG" ]; then
GRUBPKG=`find $MY_WORKSPACE/std/rpmbuild/RPMS ${CENTOS_REPO}/Binary -name 'grub2-efi-[0-9]*.x86_64.rpm'`
fi
if [ -z "$GRUBPKG" ]; then
printf " Error -- could not locate grub binary package"
exit 1
fi
pushd $TMPDIR >/dev/null
rpm2cpio $SHIMPKG | cpio -id --quiet
${SUDOPREFIX} find . -name "shim.efi" | xargs -I '{}' ${SUDOPREFIX} cp '{}' $EFI_MOUNT/EFI/BOOT/BOOTX64.EFI
rm -rf *
rpm2cpio $GRUBPKG | cpio -id --quiet
${SUDOPREFIX} find . -name "grubx64.efi" | xargs -I '{}' ${SUDOPREFIX} cp '{}' $EFI_MOUNT/EFI/BOOT/grubx64.efi
popd >/dev/null
rm -rf $TMPDIR
# Create a directory for Secure Boot certificate
${SUDOPREFIX} mkdir -p $EFI_MOUNT/CERTS
${SUDOPREFIX} cp $INTERNAL_REPO_ROOT/build-tools/certificates/* $EFI_MOUNT/CERTS
exit 0