466ce2c528
Changes made previously to upversion grub2 in starlingx resulted in some restructuring of the pxe-network-installer package, and corresponding changes in build-iso. These changes were not reflected in patch-iso, however. This update fixes the handling of pxe-network-installer extraction, and includes additional grub2 packages in the patch support. Change-Id: Ib72a44d2d5a39fe41023be8feb83b88e5f39435b Closes-Bug: 1892424 Signed-off-by: Don Penney <don.penney@windriver.com>
428 lines
10 KiB
Bash
Executable File
428 lines
10 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 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}/pxeboot/pxeboot_controller.cfg \
|
|
${BUILDDIR}/pxeboot/pxeboot_smallsystem.cfg \
|
|
${BUILDDIR}/pxeboot/pxeboot_smallsystem_lowlatency.cfg &&
|
|
\cp --preserve=all pxeboot/* ${BUILDDIR}/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 pxeboot/pxelinux.0 pxeboot/menu.c32 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 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 pxeboot/rel-*/installer-bzImage_1.0 \
|
|
${BUILDDIR}/vmlinuz &&
|
|
\cp --preserve=all pxeboot/rel-*/installer-bzImage_1.0 \
|
|
${BUILDDIR}/images/pxeboot/vmlinuz &&
|
|
\cp --preserve=all pxeboot/rel-*/installer-intel-x86-64-initrd_1.0 \
|
|
${BUILDDIR}/initrd.img &&
|
|
\cp --preserve=all 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}/pxeboot/EFI/grubx64.efi &&
|
|
\cp --preserve=all pxeboot/EFI/grubx64.efi ${BUILDDIR}/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}/pxeboot/EFI/$f_base &&
|
|
\cp --preserve=all ${f} ${BUILDDIR}/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}/pxeboot/EFI/$f_base &&
|
|
\cp --preserve=all ${f} ${BUILDDIR}/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}"
|
|
|