root/build-tools/patch-iso-debian
Luis Sampaio 7df6ee2987 Create patches dir if does not exist
Due to USM updates the patches dir may be
created during iso creation time so this commit
updates our current prepatch iso to add -p to
the mkdir command.

https://review.opendev.org/c/starlingx/tools/+/892623

Story: 2010676
Task: 48791
Signed-off-by: Luis Sampaio <luis.sampaio@windriver.com>
Change-Id: I4395ae5776df818f8c8c9466d82cb879fb39011a
2023-09-19 15:14:21 -07:00

285 lines
6.9 KiB
Bash
Executable File

#!/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
if [ -z "${MY_REPO}" ]; then
echo "Required environment variable MY_REPO is not set"
exit 1
fi
DEPLOY_DIR="${STX_BUILD_HOME}/localdisk/deploy"
OSTREE_REPO="${DEPLOY_DIR}/ostree_repo"
function usage() {
echo ""
echo "Usage: "
echo " $(basename $0) -i <input filename.iso> -o <output filename.iso> [ -p ] <patch> ..."
echo " -i <file>: Specify input ISO file"
echo " -o <file>: Specify output ISO file"
echo " -p <file>: Patch files. You can call it multiple times."
echo ""
}
function extract_metadata() {
local patchesdir=${BUILDDIR}/patches
local patchfile=$1
local patchid=$(basename $patchfile .patch)
local ostree_log=$(ostree --repo=${BUILDDIR}/ostree_repo log starlingx)
echo "Extracting ${patchfile}"
# 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 top commit from metadata exist in ostree log
xml_base=$(xmllint --xpath "string(//contents/ostree/commit1/commit)" ${patchesdir}/${patchid}-metadata.xml)
if [[ "$ostree_log" != *"$xml_base"* ]]; then
echo "Error, xml base commit does not exist in ostree log."
echo "patch base: ${xml_base}"
echo "ostree log:"
ostree --repo=${BUILDDIR}/ostree_repo log starlingx
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_FILES+=($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
for PATCH in "${PATCH_FILES[@]}";
do
if [ ! -f ${PATCH} ]; then
echo "Patch file dos not exists: ${PATCH}"
exit 1
fi
if [[ ! ${PATCH} =~ \.patch$ ]]; then
echo "Specified file ${PATCH} does not have .patch extension"
exit 1
fi
done
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
}
check_requirements
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
chmod -R +w ${BUILDDIR}/ostree_repo
# Create the directory where metadata will be stored
mkdir -p ${BUILDDIR}/patches
chmod -R +w ${BUILDDIR}/patches
echo "Updating ostree_repo..."
ostree --repo=${BUILDDIR}/ostree_repo pull-local ${OSTREE_REPO} starlingx
ostree --repo=${BUILDDIR}/ostree_repo summary --update
echo "Updated iso ostree commit:"
ostree --repo=${BUILDDIR}/ostree_repo log starlingx
echo "Extracting patch metadata"
for PATCH in "${PATCH_FILES[@]}";
do
extract_metadata $PATCH
done
echo "Packing iso..."
# get the install label
ISO_LABEL=$(grep -ri instiso "${BUILDDIR}"/isolinux/isolinux.cfg | head -1 | xargs -n1 | awk -F= /instiso/'{print $2}')
if [ -z "${ISO_LABEL}" ] ; then
echo "Error: Failed to get iso install label"
fi
echo "ISO Label: ${ISO_LABEL}"
# Repack the ISO
mkisofs -o "${OUTPUT_ISO}" \
-A "${ISO_LABEL}" -V "${ISO_LABEL}" \
-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
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}"