diff options
Diffstat (limited to 'meta/classes-recipe/image.bbclass')
-rw-r--r-- | meta/classes-recipe/image.bbclass | 109 |
1 files changed, 84 insertions, 25 deletions
diff --git a/meta/classes-recipe/image.bbclass b/meta/classes-recipe/image.bbclass index e387645503..834ae03f3c 100644 --- a/meta/classes-recipe/image.bbclass +++ b/meta/classes-recipe/image.bbclass @@ -14,18 +14,19 @@ ROOTFS_BOOTSTRAP_INSTALL = "run-postinsts" IMGCLASSES = "rootfs_${IMAGE_PKGTYPE} image_types ${IMAGE_CLASSES}" # Only Linux SDKs support populate_sdk_ext, fall back to populate_sdk_base # in the non-Linux SDK_OS case, such as mingw32 -IMGCLASSES += "${@['populate_sdk_base', 'populate_sdk_ext']['linux' in d.getVar("SDK_OS")]}" +inherit populate_sdk_base +IMGCLASSES += "${@['', 'populate_sdk_ext']['linux' in d.getVar("SDK_OS")]}" IMGCLASSES += "${@bb.utils.contains_any('IMAGE_FSTYPES', 'live iso hddimg', 'image-live', '', d)}" IMGCLASSES += "${@bb.utils.contains('IMAGE_FSTYPES', 'container', 'image-container', '', d)}" IMGCLASSES += "image_types_wic" IMGCLASSES += "rootfs-postcommands" IMGCLASSES += "image-postinst-intercepts" IMGCLASSES += "overlayfs-etc" -inherit ${IMGCLASSES} +inherit_defer ${IMGCLASSES} TOOLCHAIN_TARGET_TASK += "${PACKAGE_INSTALL}" TOOLCHAIN_TARGET_TASK_ATTEMPTONLY += "${PACKAGE_INSTALL_ATTEMPTONLY}" -POPULATE_SDK_POST_TARGET_COMMAND += "rootfs_sysroot_relativelinks; " +POPULATE_SDK_POST_TARGET_COMMAND += "rootfs_sysroot_relativelinks" LICENSE ?= "MIT" PACKAGES = "" @@ -87,6 +88,11 @@ PACKAGE_INSTALL_ATTEMPTONLY ?= "${FEATURE_INSTALL_OPTIONAL}" IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-image-complete" +IMGMANIFESTDIR = "${WORKDIR}/image-task-manifest" + +IMAGE_OUTPUT_MANIFEST_DIR = "${WORKDIR}/deploy-image-output-manifest" +IMAGE_OUTPUT_MANIFEST = "${IMAGE_OUTPUT_MANIFEST_DIR}/manifest.json" + # Images are generally built explicitly, do not need to be part of world. EXCLUDE_FROM_WORLD = "1" @@ -96,6 +102,7 @@ USE_DEPMOD ?= "1" PID = "${@os.getpid()}" PACKAGE_ARCH = "${MACHINE_ARCH}" +SSTATE_ARCHS_TUNEPKG = "${@all_multilib_tune_values(d, 'TUNE_PKGARCH')}" LDCONFIGDEPEND ?= "ldconfig-native:do_populate_sysroot" LDCONFIGDEPEND:libc-musl = "" @@ -120,8 +127,7 @@ def rootfs_command_variables(d): python () { variables = rootfs_command_variables(d) for var in variables: - if d.getVar(var, False): - d.setVarFlag(var, 'func', '1') + d.setVarFlag(var, 'vardeps', d.getVar(var)) } def rootfs_variables(d): @@ -182,8 +188,7 @@ python () { IMAGE_POSTPROCESS_COMMAND ?= "" -# some default locales -IMAGE_LINGUAS ?= "de-de fr-fr en-gb" +IMAGE_LINGUAS ??= "" LINGUAS_INSTALL ?= "${@" ".join(map(lambda s: "locale-base-%s" % s, d.getVar('IMAGE_LINGUAS').split()))}" @@ -203,6 +208,7 @@ fakeroot python do_rootfs () { from oe.rootfs import create_rootfs from oe.manifest import create_manifest import logging + import oe.packagedata logger = d.getVar('BB_TASK_LOGGER', False) if logger: @@ -247,9 +253,9 @@ fakeroot python do_rootfs () { # otherwise, the multilib renaming could step in and squash any fixups that # may have occurred. pn = d.getVar('PN') - runtime_mapping_rename("PACKAGE_INSTALL", pn, d) - runtime_mapping_rename("PACKAGE_INSTALL_ATTEMPTONLY", pn, d) - runtime_mapping_rename("BAD_RECOMMENDATIONS", pn, d) + oe.packagedata.runtime_mapping_rename("PACKAGE_INSTALL", pn, d) + oe.packagedata.runtime_mapping_rename("PACKAGE_INSTALL_ATTEMPTONLY", pn, d) + oe.packagedata.runtime_mapping_rename("BAD_RECOMMENDATIONS", pn, d) # Generate the initial manifest create_manifest(d) @@ -276,14 +282,28 @@ fakeroot python do_image () { execute_pre_post_process(d, pre_process_cmds) } do_image[dirs] = "${TOPDIR}" +do_image[cleandirs] += "${IMGMANIFESTDIR}" addtask do_image after do_rootfs fakeroot python do_image_complete () { from oe.utils import execute_pre_post_process + from pathlib import Path + import json post_process_cmds = d.getVar("IMAGE_POSTPROCESS_COMMAND") execute_pre_post_process(d, post_process_cmds) + + image_manifest_dir = Path(d.getVar('IMGMANIFESTDIR')) + + data = [] + + for manifest_path in image_manifest_dir.glob("*.json"): + with manifest_path.open("r") as f: + data.extend(json.load(f)) + + with open(d.getVar("IMAGE_OUTPUT_MANIFEST"), "w") as f: + json.dump(data, f) } do_image_complete[dirs] = "${TOPDIR}" SSTATETASKS += "do_image_complete" @@ -291,6 +311,8 @@ SSTATE_SKIP_CREATION:task-image-complete = '1' do_image_complete[sstate-inputdirs] = "${IMGDEPLOYDIR}" do_image_complete[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}" do_image_complete[stamp-extra-info] = "${MACHINE_ARCH}" +do_image_complete[sstate-plaindirs] += "${IMAGE_OUTPUT_MANIFEST_DIR}" +do_image_complete[dirs] += "${IMAGE_OUTPUT_MANIFEST_DIR}" addtask do_image_complete after do_image before do_build python do_image_complete_setscene () { sstate_setscene(d) @@ -307,23 +329,24 @@ addtask do_image_complete_setscene # # The functions should use ${IMAGE_ROOTFS} to find the unpacked rootfs # directory, which if QA passes will be the basis for the images. +# +# The functions should use oe.utils.ImageQAFailed(description, name) to raise +# errors. The name must be listed in ERROR_QA or WARN_QA to prompt. fakeroot python do_image_qa () { from oe.utils import ImageQAFailed qa_cmds = (d.getVar('IMAGE_QA_COMMANDS') or '').split() - qamsg = "" for cmd in qa_cmds: try: bb.build.exec_func(cmd, d) except oe.utils.ImageQAFailed as e: - qamsg = qamsg + '\tImage QA function %s failed: %s\n' % (e.name, e.description) + qamsg = 'Image QA function %s failed: %s\n' % (e.name, e.description) + oe.qa.handle_error(e.name, qamsg, d) except Exception as e: - qamsg = qamsg + '\tImage QA function %s failed\n' % cmd + qamsg = qamsg + '\tImage QA function %s failed: %s\n' % (cmd, e) - if qamsg: - imgname = d.getVar('IMAGE_NAME') - bb.fatal("QA errors found whilst validating image: %s\n%s" % (imgname, qamsg)) + oe.qa.exit_if_errors(d) } addtask do_image_qa after do_rootfs before do_image @@ -446,7 +469,7 @@ python () { localdata.delVar('DATE') localdata.delVar('TMPDIR') localdata.delVar('IMAGE_VERSION_SUFFIX') - vardepsexclude = (d.getVarFlag('IMAGE_CMD:' + realt, 'vardepsexclude', True) or '').split() + vardepsexclude = (d.getVarFlag('IMAGE_CMD:' + realt, 'vardepsexclude') or '').split() for dep in vardepsexclude: localdata.delVar(dep) @@ -480,14 +503,14 @@ python () { if subimage not in subimages: subimages.append(subimage) if type not in alltypes: - rm_tmp_images.add(localdata.expand("${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}")) + rm_tmp_images.add(localdata.expand("${IMAGE_NAME}.${type}")) for bt in basetypes[t]: gen_conversion_cmds(bt) localdata.setVar('type', realt) if t not in alltypes: - rm_tmp_images.add(localdata.expand("${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}")) + rm_tmp_images.add(localdata.expand("${IMAGE_NAME}.${type}")) else: subimages.append(realt) @@ -506,12 +529,14 @@ python () { d.setVar(task, '\n'.join(cmds)) d.setVarFlag(task, 'func', '1') d.setVarFlag(task, 'fakeroot', '1') + d.setVarFlag(task, 'imagetype', t) d.appendVarFlag(task, 'prefuncs', ' ' + debug + ' set_image_size') d.prependVarFlag(task, 'postfuncs', 'create_symlinks ') d.appendVarFlag(task, 'subimages', ' ' + ' '.join(subimages)) d.appendVarFlag(task, 'vardeps', ' ' + ' '.join(vardeps)) d.appendVarFlag(task, 'vardepsexclude', ' DATETIME DATE ' + ' '.join(vardepsexclude)) + d.appendVarFlag(task, 'postfuncs', ' write_image_output_manifest') bb.debug(2, "Adding task %s before %s, after %s" % (task, 'do_image_complete', after)) bb.build.addtask(task, 'do_image_complete', after, d) @@ -594,13 +619,12 @@ python create_symlinks() { manifest_name = d.getVar('IMAGE_MANIFEST') taskname = d.getVar("BB_CURRENTTASK") subimages = (d.getVarFlag("do_" + taskname, 'subimages', False) or "").split() - imgsuffix = d.getVarFlag("do_" + taskname, 'imgsuffix') or d.expand("${IMAGE_NAME_SUFFIX}.") if not link_name: return for type in subimages: dst = os.path.join(deploy_dir, link_name + "." + type) - src = img_name + imgsuffix + type + src = img_name + "." + type if os.path.exists(os.path.join(deploy_dir, src)): bb.note("Creating symlink: %s -> %s" % (dst, src)) if os.path.islink(dst): @@ -610,7 +634,42 @@ python create_symlinks() { bb.note("Skipping symlink, source does not exist: %s -> %s" % (dst, src)) } -MULTILIBRE_ALLOW_REP =. "${base_bindir}|${base_sbindir}|${bindir}|${sbindir}|${libexecdir}|${sysconfdir}|${nonarch_base_libdir}/udev|/lib/modules/[^/]*/modules.*|" +python write_image_output_manifest() { + import json + from pathlib import Path + + taskname = d.getVar("BB_CURRENTTASK") + image_deploy_dir = Path(d.getVar('IMGDEPLOYDIR')) + image_manifest_dir = Path(d.getVar('IMGMANIFESTDIR')) + manifest_path = image_manifest_dir / ("do_" + d.getVar("BB_CURRENTTASK") + ".json") + + image_name = d.getVar("IMAGE_NAME") + image_basename = d.getVar("IMAGE_BASENAME") + machine = d.getVar("MACHINE") + + subimages = (d.getVarFlag("do_" + taskname, 'subimages', False) or "").split() + imagetype = d.getVarFlag("do_" + taskname, 'imagetype', False) + + data = { + "taskname": taskname, + "imagetype": imagetype, + "images": [] + } + + for type in subimages: + image_filename = image_name + "." + type + image_path = image_deploy_dir / image_filename + if not image_path.exists(): + continue + data["images"].append({ + "filename": image_filename, + }) + + with manifest_path.open("w") as f: + json.dump([data], f) +} + +MULTILIBRE_ALLOW_REP += "${base_bindir} ${base_sbindir} ${bindir} ${sbindir} ${libexecdir} ${sysconfdir} ${nonarch_base_libdir}/udev /lib/modules/[^/]*/modules.*" MULTILIB_CHECK_FILE = "${WORKDIR}/multilib_check.py" MULTILIB_TEMP_ROOTFS = "${WORKDIR}/multilib" @@ -658,8 +717,8 @@ create_merged_usr_symlinks_sdk() { create_merged_usr_symlinks ${SDK_OUTPUT}${SDKTARGETSYSROOT} } -ROOTFS_PREPROCESS_COMMAND += "${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', 'create_merged_usr_symlinks_rootfs; ', '',d)}" -POPULATE_SDK_PRE_TARGET_COMMAND += "${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', 'create_merged_usr_symlinks_sdk; ', '',d)}" +ROOTFS_PREPROCESS_COMMAND += "${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', 'create_merged_usr_symlinks_rootfs', '',d)}" +POPULATE_SDK_PRE_TARGET_COMMAND += "${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', 'create_merged_usr_symlinks_sdk', '',d)}" reproducible_final_image_task () { if [ "$REPRODUCIBLE_TIMESTAMP_ROOTFS" = "" ]; then @@ -679,6 +738,6 @@ systemd_preset_all () { fi } -IMAGE_PREPROCESS_COMMAND:append = " ${@ 'systemd_preset_all;' if bb.utils.contains('DISTRO_FEATURES', 'systemd', True, False, d) and not bb.utils.contains('IMAGE_FEATURES', 'stateless-rootfs', True, False, d) else ''} reproducible_final_image_task; " +IMAGE_PREPROCESS_COMMAND:append = " ${@ 'systemd_preset_all' if bb.utils.contains('DISTRO_FEATURES', 'systemd', True, False, d) and not bb.utils.contains('IMAGE_FEATURES', 'stateless-rootfs', True, False, d) else ''} reproducible_final_image_task " CVE_PRODUCT = "" |