kiwi-build: Update to mimic production builds more closely

Production builds in Fedora have a couple extra features:

* ISOs have custom overrides to set the correct volume/app IDs
* Image filenames are structured to follow roughly NVRA format

Now we support these features with extra helper scripts. If a
"image release" value is passed in, then we fully mimic the
production image build process.

This will be particularly useful for making respins of Fedora images
with updates applied.
This commit is contained in:
Neal Gompa
2024-11-16 20:18:31 -05:00
parent 400c842f0a
commit 2c5cf67014
5 changed files with 159 additions and 7 deletions
+1
View File
@@ -1 +1,2 @@
outdir-build/
outdir/
+25 -5
View File
@@ -6,27 +6,30 @@
set -eu -o pipefail
kiwibuildsh="$(basename "$0")"
kiwibuild_scriptdir="$(dirname "$0")"
usage() {
echo >&2 "usage: $kiwibuildsh [--kiwi-description-dir=DIR] [--kiwi-file=FILE] [--isolated] --output-dir=DIR --image-type=TYPE --image-profile=PROFILE [--debug]"
echo >&2 " eg: $kiwibuildsh --kiwi-description-dir=/var/tmp/desc --kiwi-file=config.kiwi --output-dir=/var/tmp/work --image-type=oem --image-profile=Cloud-Base-Generic --debug"
echo >&2 "usage: $kiwibuildsh [--kiwi-description-dir=DIR] [--kiwi-file=FILE] [--isolated] --output-dir=DIR --image-type=TYPE --image-profile=PROFILE [--image-release=RELEASEID] [--debug]"
echo >&2 " eg: $kiwibuildsh --kiwi-description-dir=/var/tmp/desc --kiwi-file=config.kiwi --output-dir=/var/tmp/work --image-type=oem --image-profile=Cloud-Base-Generic --image-release=0 --debug"
echo >&2 " eg: $kiwibuildsh --output-dir=/var/tmp/work --image-type=oem --image-profile=Cloud-Base-Generic"
echo >&2 " eg: $kiwibuildsh --isolated --output-dir=/var/tmp/work --image-type=oem --image-profile=Cloud-Base-Generic"
exit 255
}
optTemp=$(getopt --options '+k:,f:,i,o:,t:,p:,d,h' --longoptions 'kiwi-description-dir:,kiwi-file:,isolated,output-dir:,image-type:,image-profile:,debug,help' --name "$kiwibuildsh" -- "$@")
optTemp=$(getopt --options '+k:,f:,i,o:,t:,p:,r:,d,h' --longoptions 'kiwi-description-dir:,kiwi-file:,isolated,output-dir:,image-type:,image-profile:,image-release:,debug,help' --name "$kiwibuildsh" -- "$@")
eval set -- "$optTemp"
unset optTemp
output_dir=
image_type=
image_profile=
image_release=
debug=
kiwi_isolated=
# For compatibility with older scripts where these did not exist
kiwi_description_dir="./"
kiwi_file="Fedora.kiwi"
kiwibuild_extra_args=
while true; do
case "$1" in
@@ -36,6 +39,7 @@ while true; do
-o|--output-dir) output_dir="$2" ; shift 2 ;;
-t|--image-type) image_type="$2" ; shift 2 ;;
-p|--image-profile) image_profile="$2" ; shift 2 ;;
-r|--image-release) image_release="$2" ; shift 2 ;;
-d|--debug) debug="--debug" ; shift ;;
-h|--help) usage ;;
--) shift ; break ;;
@@ -47,6 +51,19 @@ if [ -z "$output_dir" ] || [ -z "$image_type" ] || [ -z "$image_profile" ] || [
usage
fi
# Set the bundle format after we know the profile
kiwi_bundle_format=$("${kiwibuild_scriptdir}/scripts/fedora-kiwi-bundle-format-generator" "${kiwi_file}" "${image_profile}")
if [ "$image_type" = "iso" ]; then
# Add parameters for embedded ISO IDs
kiwibuild_extra_args=$("${kiwibuild_scriptdir}/scripts/fedora-live-iso-label-generator" "${kiwi_file}" "${image_profile}" --output-kiwi-args)
fi
if [ "$image_type" = "oci" ]; then
# Extend for OCI images
kiwi_bundle_format="${kiwi_bundle_format}.%T"
fi
if [ ! ${kiwi_isolated} ] && [ -e "/sys/fs/selinux/enforce" ]; then
# Disable SELinux enforcement during the image build if it's enforcing
selinux_enforcing="$(cat /sys/fs/selinux/enforce)"
@@ -57,9 +74,9 @@ fi
set +e
if [ ! ${kiwi_isolated} ]; then
kiwi-ng ${debug} --type="${image_type}" --profile="${image_profile}" --kiwi-file="${kiwi_file}" --color-output system build --description "${kiwi_description_dir}" --target-dir "${output_dir}"
kiwi-ng ${debug} --type="${image_type}" --profile="${image_profile}" --kiwi-file="${kiwi_file}" --color-output system build --description "${kiwi_description_dir}" --target-dir "${output_dir}-build" ${kiwibuild_extra_args}
else
kiwi-ng ${debug} --type="${image_type}" --profile="${image_profile}" --kiwi-file="${kiwi_file}" --color-output system boxbuild --box universal --sshfs-sharing -- --description "${kiwi_description_dir}" --target-dir "${output_dir}"
kiwi-ng ${debug} --type="${image_type}" --profile="${image_profile}" --kiwi-file="${kiwi_file}" --color-output system boxbuild --box universal --sshfs-sharing -- --description "${kiwi_description_dir}" --target-dir "${output_dir}-build" ${kiwibuild_extra_args}
fi
kiwi_status=$?
set -e
@@ -71,4 +88,7 @@ if [ ! ${kiwi_isolated} ] && [ -e "/sys/fs/selinux/enforce" ]; then
fi
fi
if [ "${kiwi_status}" = "0" ] && [ -n "$image_release" ]; then
kiwi-ng ${debug} result bundle --bundle-format="${kiwi_bundle_format}" --target-dir "${output_dir}-build" --bundle-dir "${output_dir}" --id="${image_release}"
fi
exit $kiwi_status
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env python3
# Simple tool to generate bundle formats for kiwi image builds
# Author: Neal Gompa <ngompa@fedoraproject.org>
# SPDX-3.0-License-Identifier: GPL-3.0-or-later
# SPDX-2.0-License-Identifier: GPL-3.0+
from argparse import ArgumentParser
from pathlib import Path
import xml.etree.ElementTree as ET
parser = ArgumentParser(description="Generator of ISO labels for Fedora live media builds")
parser.add_argument("kiwi_file", type=Path, default="Fedora.kiwi", help="kiwi description file")
parser.add_argument("image_profile", type=str, help="kiwi image profile")
parser.add_argument("--oci-variant", "-o", action="store_true", help="generate oci variant")
args = parser.parse_args()
xml_tree = ET.parse(args.kiwi_file)
image_root = xml_tree.getroot()
image_basename = image_root.attrib["name"]
image_profile = args.image_profile
image_bundle_format = f"{image_basename}-{image_profile}-%v.%I.%A"
if args.oci_variant:
print(f"{image_bundle_format}.%T")
else:
print(image_bundle_format)
+101
View File
@@ -0,0 +1,101 @@
#!/usr/bin/env python3
# Simple tool to generate volume IDs and application IDs for ISOs for kiwi image builds
# Author: Neal Gompa <ngompa@fedoraproject.org>
# SPDX-3.0-License-Identifier: GPL-3.0-or-later
# SPDX-2.0-License-Identifier: GPL-3.0+
# Used to map kiwi profiles to application IDs (which may also
# may be used for connecting to volume ID substitutions).
profile_to_application_id = {
"KDE-Desktop": "KDE_Desktop",
"KDE-Mobile": "KDE_Mobile",
}
# Used by Pungi to replace "Cloud" with "C" (etc.) in ISO volume IDs.
# There is a hard 32-character limit on ISO volume IDs, so we use
# these to try and produce short enough but legible IDs. Note this is
# duplicated in Koji for live images, as livemedia-creator does not
# allow Pungi to tell it what volume ID to use. Note:
# https://fedoraproject.org/wiki/User:Adamwill/Draft_fedora_image_naming_policy
# "-Workstation-" is a temporary workaround. See
# https://pagure.io/pungi-fedora/pull-request/525
# Replace "Cloud" with "C" in volume id etc.
# WARNING: This list *MUST* remain in sync with pungi-fedora!
# https://pagure.io/pungi-fedora/blob/main/f/general.conf
volume_id_substitutions = {
"Beta": "B",
"Rawhide": "rawh",
"Astronomy_KDE": "AstK",
"Silverblue": "SB",
"Kinoite": "Knt",
"Cinnamon": "Cinn",
"Cloud": "C",
"Comp_Neuro": "CNr",
"Design_suite": "Dsgn",
"Electronic_Lab": "Elec",
"Everything": "E",
"Games": "Game",
"Images": "img",
"Jam_KDE": "Jam",
"KDE_Desktop": "KDE",
"KDE_Mobile": "KDEM",
"MATE_Compiz": "MATE",
"MiracleWM": "MirWM",
"Onyx": "Onyx",
# Note https://pagure.io/pungi-fedora/issue/533
"Python-Classroom": "Clss",
"Python_Classroom": "Clss",
"Robotics": "Robo",
"Scientific_KDE": "SciK",
"Security": "Sec",
"Sericea": "Src",
"Server": "S",
"-Workstation-": "-WS-",
}
from argparse import ArgumentParser
from pathlib import Path
import xml.etree.ElementTree as ET
parser = ArgumentParser(description="Generator of ISO labels for Fedora live media builds")
parser.add_argument("kiwi_file", type=Path, default="Fedora.kiwi", help="kiwi description file")
parser.add_argument("image_profile", type=str, help="kiwi image profile")
parser.add_argument("--output-kiwi-args", "-k", action="store_true", help="generate kiwi args instead of csv")
args = parser.parse_args()
xml_tree = ET.parse(args.kiwi_file)
image_root = xml_tree.getroot()
image_basename = image_root.attrib["name"]
image_version = image_root.find("preferences/version").text
image_volid_version = image_version
if image_volid_version == "Rawhide":
image_volid_version = "rawh"
image_profile = args.image_profile
if image_profile.endswith("-Live"):
image_profile_baseprefix = image_profile[:-5]
else:
image_profile_baseprefix = image_profile
image_profile_variant_appid_prefix = image_profile_baseprefix
if image_profile_baseprefix in profile_to_application_id.keys():
image_profile_variant_appid_prefix = profile_to_application_id[image_profile_baseprefix]
image_profile_variant_volid_prefix = volume_id_substitutions[image_profile_variant_appid_prefix]
image_appid = f"{image_basename}-{image_profile_variant_appid_prefix}-Live-{image_version}"
image_volid = f"{image_basename}-{image_profile_variant_volid_prefix}-Live-{image_volid_version}"
if args.output_kiwi_args:
print(f"--set-type-attr=application_id={image_appid} --set-type-attr=volid={image_volid}")
else:
print(f"application_id,{image_appid},volid,{image_volid}")
+1 -2
View File
@@ -9,6 +9,5 @@ require:
framework: shell
path: /
test: |
./kiwi-build --debug --image-type="$image_type" --image-profile="$image_profile" --kiwi-description-dir="${TMT_TREE}" --kiwi-file="$kiwi_file" --output-dir="${TMT_TEST_DATA}"
rm -rf "${TMT_TEST_DATA}/build/image-root"
./kiwi-build --debug --image-type="$image_type" --image-profile="$image_profile" --kiwi-description-dir="${TMT_TREE}" --kiwi-file="$kiwi_file" --output-dir="${TMT_TEST_DATA}" --image-release="$(date --utc +'%Y%m%d.%H%M')"
duration: 60m