diff --git a/meta-arm-autonomy/recipes-core/images/arm-autonomy-host-image-minimal.bb b/meta-arm-autonomy/recipes-core/images/arm-autonomy-host-image-minimal.bb index ea5d889a..cce632ff 100644 --- a/meta-arm-autonomy/recipes-core/images/arm-autonomy-host-image-minimal.bb +++ b/meta-arm-autonomy/recipes-core/images/arm-autonomy-host-image-minimal.bb @@ -11,39 +11,6 @@ inherit core-image features_check LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" -# The ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS variable can be used to include in the -# image one or several xenguest images. -# The list must be space separated and each entry must have the following -# format: URL[;params] -# - URL can be the full path to a file or a Yocto compatible SRC_URI url -# - params encompasses two values that can be optionally set: -# - guestname=NAME can be used to specify the name of the guest. If not -# specified the default value is the basename of the file -# (without .xenguest extension). -# - guestcount=NUM can be used to created NUM guests with the same config. -# All guests after the first will have numbers appended to the guestname, -# starting from 2. In the rootfs additional xenguest files will be -# symlinks to the original. -# params should be semicolon seperated, without a space, and can appear in -# any order. -# -# Here are examples of values: -# /home/mydir/myguest.xenguest;guestname=guest1;guestcount=3 -# http://www.url.com/testguest.xenguest -# -# If you are using the output of an other Yocto project, you should use the -# full path syntax instead of the Yocto SRC_URI to be able to use the -# symlink version of your image (as the real file has a new name on each -# build as it includes the date). You must not use SRC_URI type file:// as -# it will try to include the symlink and not the destination file which will -# be detected by the recipe and output an error 'Guest file is a symlink'. -# -# Guests can also be added using a bbapend to this recipe by adding entries -# to SRC_URI with parameter ;guestname=NAME to specify the destination -# guestname. The parameter guestname must be present as it is used to detect -# guests to be added -ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS ??= "" - # Includes minimal set required to start and manage guest. The xen specific # modules are not explicitly included as they are built as part of the kernel # image for performance reasons. It doesn't include all kernel modules to @@ -53,6 +20,7 @@ IMAGE_INSTALL += " \ packagegroup-core-boot \ packagegroup-core-ssh-openssh \ qemu-system-i386 \ + xenguest-extern-guests \ xenguest-manager \ xenguest-network \ " @@ -63,110 +31,5 @@ EXTRA_IMAGEDEPENDS += "xen" # Build xen-devicetree to produce a xen ready devicetree EXTRA_IMAGEDEPENDS += "xen-devicetree" -# Documentation for setting up a multiconfig build can be found in: -# meta-arm-autonomy/documentation/arm-autonomy-multiconfig.md - -# In a multiconfig build this variable will hold a dependency string, which differs based -# on whether the guest has initramfs or not. -# It may have a space seperated list of dependency strings if mulitple guest types are -# configured -MC_DOIMAGE_MCDEPENDS ?= "" -# Example value: mc:host:guest:core-image-minimal:do_image_complete - -# In a multiconfig build the host task 'do_image' has a dependency on multiconfig guest. -# This ensures that the guest image file already exists when it is needed by the host -DO_IMAGE_MCDEPENDS := "${@ '${MC_DOIMAGE_MCDEPENDS}' if d.getVar('BBMULTICONFIG') else ''}" - -# Apply mc dependency. Empty string if multiconfig not enabled -do_image[mcdepends] += "${DO_IMAGE_MCDEPENDS}" - REQUIRED_DISTRO_FEATURES += 'arm-autonomy-host' REQUIRED_DISTRO_FEATURES += 'xen' - -# Configurable guest variables -require conf/xenguest.conf - -python __anonymous() { - import re - guestfile_pattern = re.compile(r"^([^;]+);") - guestname_pattern = re.compile(r";guestname=([^;]+);?") - guestcount_pattern = re.compile(r";guestcount=(\d+);?") - - # Check in ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS for extra guests and add them - # to SRC_URI with xenguest parameter if not set - guestlist = d.getVar('ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS') - if guestlist: - for guest in guestlist.split(): - # If the user just specified a file instead of file://FILE, add - # the file:// prefix - if guest.startswith('/'): - guestname = os.path.basename(guest) - guestfile = guest - guestcount = "1" - f = guestfile_pattern.search(guest) - n = guestname_pattern.search(guest) - c = guestcount_pattern.search(guest) - - if f is not None: - guestfile = f.group(1) - if n is not None: - guestname = n.group(1) - if c is not None: - guestcount = c.group(1) - # in case we have a link we need the destination - guestfile = os.path.realpath(guestfile) - - # make sure the file exist to give a meaningfull error - if not os.path.exists(guestfile): - raise bb.parse.SkipRecipe("ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS entry does not exist: " + guest) - - # In case the file is a symlink make sure we use the destination - d.appendVar('SRC_URI', ' file://' + guestfile + ';guestname=' + guestname + ';guestcount=' + guestcount) - else: - # we have a Yocto URL - try: - _, _, path, _, _, parm = bb.fetch.decodeurl(guest) - # force guestname param in if not already there - if not 'guestname' in parm: - guest += ';guestname=' + os.path.basename(path) - d.appendVar('SRC_URI', ' ' + guest) - except: - raise bb.parse.SkipRecipe("ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS contains an invalid entry: " + guest) -} - -python add_extern_guests () { - # Destination directory on the rootfs - guestdir = d.getVar('IMAGE_ROOTFS') + d.getVar('XENGUEST_MANAGER_GUEST_DIR') - - # Parse SRC_URI for files with ;guestname= parameter - src_uri = d.getVar('SRC_URI') - for entry in src_uri.split(): - _, _, path, _, _, parm = bb.fetch.decodeurl(entry) - if 'guestname' in parm: - if os.path.islink(path): - realpath = os.path.realpath(path) - - if not os.path.exists(realpath): - bb.fatal("ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS link does not resolve: " + path) - - bb.note("Guest file is a symlink:\n " + path + "\nResolved to:\n " + realpath) - path = realpath - - bb.utils.mkdirhier(guestdir) - dstname = parm['guestname'] - # Add file extension if not there - if not dstname.endswith('.xenguest'): - dstname += '.xenguest' - - if not bb.utils.copyfile(path, guestdir + '/' + dstname): - bb.fatal("Fail to copy Guest file " + path) - - if 'guestcount' in parm: - guestcount = int(parm['guestcount']) + 1 - - for i in range(2, guestcount): - os.symlink('./' + dstname, guestdir + '/' + dstname.replace('.xenguest', str(i) + '.xenguest')) -} - -IMAGE_PREPROCESS_COMMAND += "add_extern_guests; " - diff --git a/meta-arm-autonomy/recipes-extended/xenguest/xenguest-extern-guests.bb b/meta-arm-autonomy/recipes-extended/xenguest/xenguest-extern-guests.bb new file mode 100644 index 00000000..9310cbc8 --- /dev/null +++ b/meta-arm-autonomy/recipes-extended/xenguest/xenguest-extern-guests.bb @@ -0,0 +1,118 @@ +# Xenguest Extern Guests +# +# This recipe installs the extern guest files specified in +# ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS into the host image, They are installed +# to the directory XENGUEST_MANAGER_GUEST_DIR +# +# src_uri_parse_var.bbclass is used to parse +# ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS +# +# There are 4 supported formats for ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS +# entries: +# +# - http/https url +# - "https://[url]:[port]/foo.xenguest;md5sum=..." +# +# - file:// absolute local path from root +# - "file:///xenguests/bar.xenguest" +# +# - file:// path relative to FILESEXTRAPATHS +# - "file://relative/baz.xenguest" +# +# - plain absolute local path from root +# - "/xenguests/absolute/xyzzy.xenguest" +# +# It is not recommended to use other yocto URL types, as they may result in +# undefined behaviour. +# +# A semicolon seperated list of install arguments can follow each image path: +# - guestname : the name that will be attached when the image is imported +# (default: [filename, without extension]) +# - guestcount : the number of copies of the guest to install, with +# incrementing numbers appended to the name +# (default: 1) +# +# Any other arguments, for example an md5sum, will be assumed to be fetch +# arguments, and will be kept when the path is added to the SRC_URI +# +# e.g. ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS = "\ +# https://[url]:[port]/base.xenguest;md5sum=[checksum];guestname=http \ +# file:///guests/base.xenguest;guestname=file_abs \ +# file://foo/base.xenguest;guestname=file_rel;guestcount=2 \ +# /guests/foo/bar/base.xenguest;guestname=no_fetcher \ " +# +# Documentation for setting up a multiconfig build can be found in: +# meta-arm-autonomy/documentation/arm-autonomy-multiconfig.md + +DESCRIPTION = "Xenguest Extern Guests" +LICENSE = "MIT" + +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +# Global value of XENGUEST_MANAGER_GUEST_DIR set here +require conf/xenguest.conf + +ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS ??= "" + +# Parse the variable ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS for xenguest files, +# unpack them to SRC_URI_FROM_VAR_UNPACK_DIR and create a manifest file +# containing each of SRC_URI_FROM_VAR_MANIFEST_PARAMS for each entry +inherit set_src_uri_from_var +SRC_URI_FROM_VAR_NAME = "ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS" +SRC_URI_FROM_VAR_MANIFEST_PARAMS= "guestname=[basename] guestcount=1" +SRC_URI_FROM_VAR_UNPACK_DIR = "xenguests" + +# Unnecessary tasks +do_compile[noexec] = "1" +do_configure[noexec] = "1" +do_patch[noexec] = "1" + +# Install guest files to XENGUEST_MANAGER_GUEST_DIR +do_install() { + + local guestfile guestname guestcount + + if [ -f "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/manifest" ]; then + + install -d "${D}${XENGUEST_MANAGER_GUEST_DIR}" + + # Iterate over manifest file containing parameters + while read -r guestfile guestname guestcount _; do + [ -f "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/${guestfile}" ] || + bbfatal "${guestfile} does not exist" + + install -m 644 \ + "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/${guestfile}" \ + "${D}${XENGUEST_MANAGER_GUEST_DIR}/${guestname}.xenguest" + + # Create symlinks for duplicate guests, appending numbers to + # guestname + for i in `seq 2 $guestcount` + do + ln -s -r \ + "${D}${XENGUEST_MANAGER_GUEST_DIR}/${guestname}.xenguest" \ + "${D}${XENGUEST_MANAGER_GUEST_DIR}/${guestname}$i.xenguest" + done + + done < "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/manifest" + fi +} + +do_install[vardeps] += "ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS" + +FILES_${PN} += "${XENGUEST_MANAGER_GUEST_DIR}" + +# In a multiconfig build this variable will hold a dependency string, which +# differs based on whether the guest has initramfs or not. It may have a space +# seperated list of dependency strings if mulitple guest types are configured +MC_DOIMAGE_MCDEPENDS ?= "" +# Example value: mc:host:guest:core-image-minimal:do_merge_xenguestenv + +# In a multiconfig build the host task 'do_image' has a dependency on +# multiconfig guest. This ensures that the guest image file already exists +# when it is needed by the host +DO_IMAGE_MCDEPENDS := "${@ '${MC_DOIMAGE_MCDEPENDS}' \ +if d.getVar('BBMULTICONFIG') else ''}" + +# Apply mc dependency. Empty string if multiconfig not enabled +do_fetch[mcdepends] += "${DO_IMAGE_MCDEPENDS}"