1a9872ca9d
Commit c8c75e81b5
("relocate /pxeboot to /var/pxeboot", 2021-12-15)
inadvertently introduced a few bugs to patch-iso that prevent successful
execution of this script when a patch with pxe-network-installer is
attempted to be used. This is necessary, for example, to be able to
patch kernel and initial RAM file system images in an ISO image.
Here is an example for the error messages:
+ cp --preserve=all pxeboot/pxelinux.0 pxeboot/menu.c32 \
pxeboot/chain.c32 .../patchiso_build_XXXXXX/var/pxeboot/
cp: target '.../patchiso_build_XXXXXX/var/pxeboot/' \
is not a directory
This commit fixes the paths used by patch-iso so that such errors are
not encountered.
Verification:
- patch-iso is successfully executed against a patch file that includes
a newer pxe-network-installer package.
Closes-Bug: 1968566
Change-Id: I4606d062b45ed03b64f514131d3d6e27434e7675
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
428 lines
11 KiB
Bash
Executable File
428 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Copyright (c) 2018-2020 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Utility for adding patches to an unpatched ISO
|
|
#
|
|
|
|
source "$(dirname $0)/image-utils.sh"
|
|
|
|
if [ -z "${MY_REPO}" ]; then
|
|
echo "Required environment variable MY_REPO is not set"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "${MY_WORKSPACE}" ]; then
|
|
echo "Required environment variable MY_WORKSPACE is not set"
|
|
exit 1
|
|
fi
|
|
|
|
STX_DIR=${MY_REPO}/stx
|
|
SETUP_PATCH_REPO=${STX_DIR}/update/extras/scripts/setup_patch_repo.sh
|
|
if [ ! -x ${SETUP_PATCH_REPO} ]; then
|
|
echo "Cannot find or execute ${SETUP_PATCH_REPO}"
|
|
exit 1
|
|
fi
|
|
|
|
# Create temp dir if necessary
|
|
export TMPDIR="$MY_WORKSPACE/tmp"
|
|
mkdir -p $TMPDIR
|
|
|
|
REPO_UPGRADES_DIR=${STX_DIR}/metal/bsp-files/upgrades
|
|
RELEASE_INFO="$(get_release_info)"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "ERROR: failed to find a release info file."
|
|
exit 1
|
|
fi
|
|
|
|
PLATFORM_RELEASE=$(source $RELEASE_INFO && echo $PLATFORM_RELEASE)
|
|
|
|
function usage() {
|
|
echo ""
|
|
echo "Usage: "
|
|
echo " $(basename $0) -i <input bootimage.iso> -o <output bootimage.iso> [ -u ] <patch> ..."
|
|
echo " -i <file>: Specify input ISO file"
|
|
echo " -o <file>: Specify output ISO file"
|
|
echo " -u : Update with upgrades files from ${REPO_UPGRADES_DIR}"
|
|
echo ""
|
|
}
|
|
|
|
function extract_pkg_from_patch_repo() {
|
|
local repodir=${BUILDDIR}/patches
|
|
local pkgname=$1
|
|
local pkgfile=$(repoquery --disablerepo=* --repofrompath local,${repodir} --enablerepo=local --location -q ${pkgname})
|
|
if [ -z "${pkgfile}" ]; then
|
|
return 1
|
|
fi
|
|
|
|
rpm2cpio ${pkgfile/file://} | cpio -idmv
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed to extract $pkgname files from ${pkgfile/file://}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
declare INPUT_ISO=
|
|
declare OUTPUT_ISO=
|
|
declare ORIG_PWD=$PWD
|
|
declare DO_UPGRADES=1
|
|
|
|
while getopts "i:o:u" opt; do
|
|
case $opt in
|
|
i)
|
|
INPUT_ISO=$OPTARG
|
|
;;
|
|
o)
|
|
OUTPUT_ISO=$OPTARG
|
|
;;
|
|
u)
|
|
DO_UPGRADES=0
|
|
;;
|
|
*)
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$INPUT_ISO" -o -z "$OUTPUT_ISO" ]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f ${INPUT_ISO} ]; then
|
|
echo "Input file does not exist: ${INPUT_ISO}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -f ${OUTPUT_ISO} ]; then
|
|
echo "Output file already exists: ${OUTPUT_ISO}"
|
|
exit 1
|
|
fi
|
|
|
|
shift $((OPTIND-1))
|
|
|
|
if [ $# -le 0 ]; then
|
|
usage
|
|
exit
|
|
fi
|
|
|
|
for pf in $@; do
|
|
if [ ! -f $pf ]; then
|
|
echo "Patch file $pf does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! $pf =~ \.patch$ ]]; then
|
|
echo "Specified file $pf does not have .patch extension"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
declare MNTDIR=
|
|
declare BUILDDIR=
|
|
declare WORKDIR=
|
|
|
|
function check_requirements {
|
|
local -a required_utils=(
|
|
rsync
|
|
mkisofs
|
|
isohybrid
|
|
implantisomd5
|
|
)
|
|
if [ $UID -ne 0 ]; then
|
|
# If running as non-root user, additional utils are required
|
|
required_utils+=(
|
|
guestmount
|
|
guestunmount
|
|
)
|
|
fi
|
|
|
|
local -i missing=0
|
|
|
|
for req in ${required_utils[@]}; do
|
|
which ${req} >&/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Unable to find required utility: ${req}" >&2
|
|
let missing++
|
|
fi
|
|
done
|
|
|
|
if [ ${missing} -gt 0 ]; then
|
|
echo "One or more required utilities are missing. Aborting..." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function mount_iso {
|
|
if [ $UID -eq 0 ]; then
|
|
# Mount the ISO
|
|
mount -o loop ${INPUT_ISO} ${MNTDIR}
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed to mount ${INPUT_ISO}" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
# As non-root user, mount the ISO using guestmount
|
|
guestmount -a ${INPUT_ISO} -m /dev/sda1 --ro ${MNTDIR}
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
# Add a retry
|
|
echo "Call to guestmount failed with rc=$rc. Retrying once..."
|
|
|
|
guestmount -a ${INPUT_ISO} -m /dev/sda1 --ro ${MNTDIR}
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
echo "Call to guestmount failed with rc=$rc. Aborting..."
|
|
exit $rc
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function unmount_iso {
|
|
if [ $UID -eq 0 ]; then
|
|
umount ${MNTDIR}
|
|
else
|
|
guestunmount ${MNTDIR}
|
|
fi
|
|
rmdir ${MNTDIR}
|
|
}
|
|
|
|
function cleanup() {
|
|
if [ -n "$MNTDIR" -a -d "$MNTDIR" ]; then
|
|
unmount_iso
|
|
fi
|
|
|
|
if [ -n "$BUILDDIR" -a -d "$BUILDDIR" ]; then
|
|
\rm -rf $BUILDDIR
|
|
fi
|
|
|
|
if [ -n "$WORKDIR" -a -d "$WORKDIR" ]; then
|
|
\rm -rf $WORKDIR
|
|
fi
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
MNTDIR=$(mktemp -d -p $PWD patchiso_mnt_XXXXXX)
|
|
if [ -z "${MNTDIR}" -o ! -d ${MNTDIR} ]; then
|
|
echo "Failed to create mntdir. Aborting..."
|
|
exit $rc
|
|
fi
|
|
|
|
BUILDDIR=$(mktemp -d -p $PWD patchiso_build_XXXXXX)
|
|
if [ -z "${BUILDDIR}" -o ! -d ${BUILDDIR} ]; then
|
|
echo "Failed to create builddir. Aborting..."
|
|
exit $rc
|
|
fi
|
|
|
|
# Mount the ISO
|
|
mount_iso
|
|
|
|
rsync -a ${MNTDIR}/ ${BUILDDIR}/
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
echo "Call to rsync ISO content. Aborting..."
|
|
exit $rc
|
|
fi
|
|
|
|
unmount_iso
|
|
|
|
# Setup the patch repo
|
|
${SETUP_PATCH_REPO} -o ${BUILDDIR}/patches $@
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
echo "Call to $(basename ${SETUP_PATCH_REPO}) failed with rc=$rc. Aborting..."
|
|
exit $rc
|
|
fi
|
|
|
|
# Look for components that need modification
|
|
#extract_pkg_from_patch_repo
|
|
WORKDIR=$(mktemp -d -p $PWD patchiso_work_XXXXXX)
|
|
if [ -z "${WORKDIR}" -o ! -d ${WORKDIR} ]; then
|
|
echo "Failed to create workdir. Aborting..."
|
|
exit $rc
|
|
fi
|
|
|
|
\cd ${WORKDIR}
|
|
\mkdir extract
|
|
\cd extract
|
|
|
|
# Changes to copied files here must also be reflected in build-iso
|
|
|
|
extract_pkg_from_patch_repo platform-kickstarts
|
|
if [ $? -eq 0 ]; then
|
|
# Replace files
|
|
\rm -f ${BUILDDIR}/*ks.cfg &&
|
|
\cp --preserve=all var/www/pages/feed/rel-*/*.cfg ${BUILDDIR}/ &&
|
|
\cp --preserve=all ${BUILDDIR}/controller_ks.cfg ${BUILDDIR}/ks.cfg
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed to copy extracted kickstarts"
|
|
exit 1
|
|
fi
|
|
fi
|
|
\cd ${WORKDIR}
|
|
\rm -rf extract
|
|
|
|
\mkdir extract
|
|
\cd extract
|
|
extract_pkg_from_patch_repo platform-kickstarts-pxeboot
|
|
if [ $? -eq 0 ]; then
|
|
# Replace files
|
|
\rm -f ${BUILDDIR}/var/pxeboot/pxeboot_controller.cfg \
|
|
${BUILDDIR}/var/pxeboot/pxeboot_smallsystem.cfg \
|
|
${BUILDDIR}/var/pxeboot/pxeboot_smallsystem_lowlatency.cfg &&
|
|
\cp --preserve=all pxeboot/* ${BUILDDIR}/var/pxeboot/
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed to copy extracted pxeboot kickstarts"
|
|
exit 1
|
|
fi
|
|
fi
|
|
\cd ${WORKDIR}
|
|
\rm -rf extract
|
|
|
|
\mkdir extract
|
|
\cd extract
|
|
extract_pkg_from_patch_repo pxe-network-installer
|
|
if [ $? -eq 0 ]; then
|
|
# Replace files
|
|
\rm -f ${BUILDDIR}/pxeboot/pxelinux.0 \
|
|
${BUILDDIR}/pxeboot/menu.c32 \
|
|
${BUILDDIR}/pxeboot/chain.c32 &&
|
|
\cp --preserve=all var/pxeboot/pxelinux.0 var/pxeboot/menu.c32 var/pxeboot/chain.c32 ${BUILDDIR}/pxeboot/
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not copy all files from installer"
|
|
exit 1
|
|
fi
|
|
|
|
\rm -f ${BUILDDIR}/LiveOS/squashfs.img &&
|
|
\cp --preserve=all var/www/pages/feed/rel-*/LiveOS/squashfs.img ${BUILDDIR}/LiveOS/
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not copy squashfs from LiveOS"
|
|
exit 1
|
|
fi
|
|
|
|
# Replace vmlinuz and initrd.img with our own pre-built ones
|
|
\rm -f \
|
|
${BUILDDIR}/vmlinuz \
|
|
${BUILDDIR}/images/pxeboot/vmlinuz \
|
|
${BUILDDIR}/initrd.img \
|
|
${BUILDDIR}/images/pxeboot/initrd.img &&
|
|
\cp --preserve=all var/pxeboot/rel-*/installer-bzImage_1.0 \
|
|
${BUILDDIR}/vmlinuz &&
|
|
\cp --preserve=all var/pxeboot/rel-*/installer-bzImage_1.0 \
|
|
${BUILDDIR}/images/pxeboot/vmlinuz &&
|
|
\cp --preserve=all var/pxeboot/rel-*/installer-intel-x86-64-initrd_1.0 \
|
|
${BUILDDIR}/initrd.img &&
|
|
\cp --preserve=all var/pxeboot/rel-*/installer-intel-x86-64-initrd_1.0 \
|
|
${BUILDDIR}/images/pxeboot/initrd.img
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to copy installer images"
|
|
exit 1
|
|
fi
|
|
fi
|
|
\cd ${WORKDIR}
|
|
\rm -rf extract
|
|
|
|
\mkdir extract
|
|
\cd extract
|
|
extract_pkg_from_patch_repo grub2-efi-x64-pxeboot
|
|
if [ $? -eq 0 ]; then
|
|
# Replace files
|
|
\rm -f ${BUILDDIR}/var/pxeboot/EFI/grubx64.efi &&
|
|
\cp --preserve=all pxeboot/EFI/grubx64.efi ${BUILDDIR}/var/pxeboot/EFI/
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to copy grub2-efi-x64-pxeboot files"
|
|
exit 1
|
|
fi
|
|
fi
|
|
\cd ${WORKDIR}
|
|
\rm -rf extract
|
|
|
|
\mkdir extract
|
|
\cd extract
|
|
extract_pkg_from_patch_repo grub2-common
|
|
if [ $? -eq 0 ]; then
|
|
# Replace files
|
|
for f in usr/lib/grub/x86_64-efi/*; do
|
|
f_base=$(basename $f)
|
|
\rm -f ${BUILDDIR}/var/pxeboot/EFI/$f_base &&
|
|
\cp --preserve=all ${f} ${BUILDDIR}/var/pxeboot/EFI/
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to copy grub2-common files"
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|
|
\cd ${WORKDIR}
|
|
\rm -rf extract
|
|
|
|
\mkdir extract
|
|
\cd extract
|
|
extract_pkg_from_patch_repo grub2-efi-x64-modules
|
|
if [ $? -eq 0 ]; then
|
|
# Replace files
|
|
for f in usr/lib/grub/x86_64-efi/*; do
|
|
f_base=$(basename $f)
|
|
\rm -f ${BUILDDIR}/var/pxeboot/EFI/$f_base &&
|
|
\cp --preserve=all ${f} ${BUILDDIR}/var/pxeboot/EFI/
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to copy grub2-efi-x64-modules files"
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|
|
\cd ${WORKDIR}
|
|
\rm -rf extract
|
|
|
|
\cd ${ORIG_PWD}
|
|
|
|
if [ ${DO_UPGRADES} -eq 0 ]; then
|
|
# Changes to copied files here must also be reflected in build-iso
|
|
|
|
echo "Updating upgrade support files"
|
|
ISO_UPGRADES_DIR="${BUILDDIR}/upgrades"
|
|
\rm -rf ${ISO_UPGRADES_DIR}
|
|
\mkdir ${ISO_UPGRADES_DIR}
|
|
\cp ${REPO_UPGRADES_DIR}/* ${ISO_UPGRADES_DIR}
|
|
sed -i "s/xxxSW_VERSIONxxx/${PLATFORM_RELEASE}/g" ${ISO_UPGRADES_DIR}/metadata.xml
|
|
chmod +x ${ISO_UPGRADES_DIR}/*.sh
|
|
# Write the version out (used in upgrade scripts - this is the same as SW_VERSION)
|
|
echo "VERSION=$PLATFORM_RELEASE" > ${ISO_UPGRADES_DIR}/version
|
|
fi
|
|
|
|
# Rebuild the ISO
|
|
mkisofs -o ${OUTPUT_ISO} \
|
|
-R -D -A 'oe_iso_boot' -V 'oe_iso_boot' \
|
|
-quiet \
|
|
-b isolinux.bin -c boot.cat -no-emul-boot \
|
|
-boot-load-size 4 -boot-info-table \
|
|
-eltorito-alt-boot \
|
|
-e images/efiboot.img \
|
|
-no-emul-boot \
|
|
${BUILDDIR}
|
|
|
|
isohybrid --uefi ${OUTPUT_ISO}
|
|
implantisomd5 ${OUTPUT_ISO}
|
|
|
|
# Sign the .iso with the developer private key
|
|
# Signing with the formal key is only to be done for customer release
|
|
# and is a manual step afterwards, as with the GA ISO
|
|
openssl dgst -sha256 \
|
|
-sign ${MY_REPO}/build-tools/signing/dev-private-key.pem \
|
|
-binary \
|
|
-out ${OUTPUT_ISO/%.iso/.sig} \
|
|
${OUTPUT_ISO}
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
echo "Call to $(basename ${SETUP_PATCH_REPO}) failed with rc=$rc. Aborting..."
|
|
exit $rc
|
|
fi
|
|
|
|
echo "Patched ISO: ${OUTPUT_ISO}"
|
|
|