root/build-tools/patch-iso-debian
Luis Sampaio ddd59e4d7b patch-iso script for Debian
Utility for adding patch metadata to the iso.

Debian patches are sequential and uses ostree
so any patch will produce an updated iso, this
utility injects the patch metadata into the iso.

During install the kickstart will copy the metadata
into the right location and the sw-patch query
command will output the correct patch level.

Test:
Pass: build iso and patch
Pass: patch iso
Pass: install iso (with modified kickstart)
Pass: sw-patch query returns metadata information

Story: 2009969
Task: 46467
Signed-off-by: Luis Sampaio <luis.sampaio@windriver.com>
Change-Id: I455a72c4c2140ec3a7426ba78976123c601984f3
2022-10-06 15:06:07 -07:00

263 lines
6.2 KiB
Bash

#!/bin/bash
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# Utility for adding patch metadata to the iso
# Debian patches are sequential and uses ostree
# so any patch will produce an updated iso, this
# utility injects the patch metadata into the iso.
# During install the kickstart will copy the metadata
# into the right location and the sw-patch query
# command will output the correct patch level
#
source "$(dirname $0)/image-utils.sh"
if [ -z "${STX_BUILD_HOME}" ]; then
echo "Required environment variable STX_BUILD_HOME is not set"
exit 1
fi
REPO_ROOT="${STX_BUILD_HOME}"/repo
DEPLOY_DIR="${STX_BUILD_HOME}/localdisk/deploy"
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 filename.iso> -o <output filename.iso> [ -u ] <patch> ..."
echo " -i <file>: Specify input ISO file"
echo " -o <file>: Specify output ISO file"
echo " -p <file>: Patch file"
echo ""
}
function extract_metada() {
local patchesdir=${BUILDDIR}/patches
local patchfile=$1
local patchid=$(basename $patchfile .patch)
local ostree_ref=$(cat ${BUILDDIR}/ostree_repo/refs/heads/starlingx)
# Extract it
tar xf ${patchfile} -O metadata.tar | tar x -O > ${patchesdir}/${patchid}-metadata.xml
if [ $? -ne 0 ]; then
echo "Failed to extract metadata from ${patchfile}"
exit 1
fi
# Verify if ostree_repo ref matches the metadata.xml
xml_base=$(xmllint --xpath "string(//contents/ostree/base/commit)" ${patchesdir}/${patchid}-metadata.xml)
if [ "$xml_base" != "$ostree_ref" ]; then
echo "Error, ostree head ref and patch xml base commit does not match."
echo "ostree head: ${ostree_ref}"
echo "patch base: ${xml_base}"
exit 1
fi
}
declare INPUT_ISO=
declare OUTPUT_ISO=
declare ORIG_PWD=$PWD
declare DO_UPGRADES=1
while getopts "i:o:p:" opt; do
case $opt in
i)
INPUT_ISO=$OPTARG
;;
o)
OUTPUT_ISO=$OPTARG
;;
p)
PATCH_FILE=$OPTARG
;;
*)
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
if [ ! -f ${PATCH_FILE} ]; then
echo "Patch file dos not exists: ${PATCH_FILE}"
exit 1
fi
if [[ ! ${PATCH_FILE} =~ \.patch$ ]]; then
echo "Specified file ${PATCH_FILE} does not have .patch extension"
exit 1
fi
shift $((OPTIND-1))
declare MNTDIR=
declare BUILDDIR=
function check_requirements {
local -a required_utils=(
rsync
mkisofs
isohybrid
implantisomd5
ostree
xmllint
)
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
chmod -R +w $BUILDDIR
\rm -rf $BUILDDIR
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
# Fix for permission denied if not running as root
chmod +w ${BUILDDIR}
chmod -R +w ${BUILDDIR}/isolinux
# Extract patch xml
mkdir ${BUILDDIR}/patches
extract_metada $PATCH_FILE
# Repack the ISO
mkisofs -o "${OUTPUT_ISO}" \
-A 'instboot' -V 'instboot' \
-quiet -U -J -joliet-long -r -iso-level 2 \
-b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot \
-boot-load-size 4 -boot-info-table \
-eltorito-alt-boot \
-e efi.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 ${STX_BUILD_HOME}/repo/cgcs-root/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}"