All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass
@ 2021-03-24 15:32 Nathan Dunne
  2021-03-24 15:32 ` [PATCH 2/3] arm-autonomy/docker: Updated fetcher to use set_src_uri_from_var.bbclass Nathan Dunne
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Nathan Dunne @ 2021-03-24 15:32 UTC (permalink / raw)
  To: meta-arm; +Cc: nd, Nathan Dunne

From: Nathan Dunne <Nathan.Dunne@arm.com>

Introduced set_src_uri_from_var.bbclass to add entries to the
SRC_URI based on a named variable, and generate a manifest
file alongside fetched items containing a number of parameters
for each entry.

Parameters can have an optional default value, or cause an error
if omitted.

Issue-Id: SCM-2225
Signed-off-by: Nathan Dunne <Nathan.Dunne@arm.com>
Change-Id: Ia85b3f4bc3fa666fa7e7aec2d670979ac9348f52
---
 .../classes/set_src_uri_from_var.bbclass      | 224 ++++++++++++++++++
 1 file changed, 224 insertions(+)
 create mode 100644 meta-arm-autonomy/classes/set_src_uri_from_var.bbclass

diff --git a/meta-arm-autonomy/classes/set_src_uri_from_var.bbclass b/meta-arm-autonomy/classes/set_src_uri_from_var.bbclass
new file mode 100644
index 0000000..b2d8aec
--- /dev/null
+++ b/meta-arm-autonomy/classes/set_src_uri_from_var.bbclass
@@ -0,0 +1,224 @@
+# Set SRC_URI from Variable
+
+# This class parses a variable named in SRC_URI_FROM_VAR_NAME for entries that
+# should be added to the SRC_URI
+#
+# There are 4 supported formats for entries:
+#
+# - http/https url
+#   - Note that a checksum (md5sum or sha256sum) must be provided for http(s)
+#
+# - file:// absolute local path from root
+#   - In this case the filename will be added to SRC_URI and the path from '/'
+#   added to FILESEXTRAPATHS
+#
+# - file:// path relative to FILESEXTRAPATHS
+#   - In this case the filename will be added to SRC_URI and the preceding path
+#   added to FILESOVERRIDES, so that the full path to the file will
+#   be available in FILESPATH when it is generated by combining
+#   FILESEXTRAPATHS and FILESOVERRIDES.
+#
+# - plain absolute local path from root
+#   - This will be treated the same as an file:// path from root. Plain paths
+#   must be absolute, and cannot be relative to FILESEXTRAPATHS
+#
+# It is not recommended to use other yocto URL types, as they may result in
+# undefined behaviour.
+#
+# These entries will be added to the SRC_URI so that the yocto fetcher can
+# unpack a copy into ${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}
+#
+#
+# A list of arguments can follow each entry in the input variable, seperated
+# by semi-colons (;). Arguments may be FETCH arguments or MANIFEST arguments.
+#
+# FETCH arguments will be appended to the entry in SRC_URI, for example
+# "downloadfilename" to specify the filename used when storing a
+# downloaded file.
+# Each SRC_URI entry will automatically have the arguments
+# "unpack=0;subdir=${SRC_URI_FROM_VAR_UNPACK_DIR}" added to them, so do not
+# attempt to set these options.
+#
+# MANIFEST arguments are defined in the variable
+# SRC_URI_FROM_VAR_MANIFEST_PARAMS which should be a space seperated list of
+# names, each optionally followed by an equals sign (=) and a default value.
+#
+# The values provided for the manifest arguments will be written to the manifest
+# file in ${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR} as columns, in the same
+# order as they appear in SRC_URI_FROM_VAR_MANIFEST_PARAMS.
+#
+# For entries that do not provide a value for a manifest argument, the default
+# value will be used if possible.
+# If no default is availale, omitting the parameter on any item will cause
+# an error.
+#
+# "[basename]" is a special case default that will set the value to
+# the filename without the path or file extension.
+#
+# e.g.
+# SRC_URI_FROM_VAR_MANIFEST_PARAMS="conname=[basename] contag=local conkeep"
+#
+# Any arguments that follow an entry in SRC_URI_FROM_VAR_NAME, that are not
+# named in SRC_URI_FROM_VAR_MANIFEST_PARAMS are assumed to be FETCH arguments,
+# so are added to the corresponding entry in the SRC_URI.
+
+SRC_URI_FROM_VAR_NAME ??= ""
+SRC_URI_FROM_VAR_MANIFEST_PARAMS ??= ""
+SRC_URI_FROM_VAR_UNPACK_DIR ??= "items"
+
+python __anonymous() {
+
+    parse_var = d.getVar('SRC_URI_FROM_VAR_NAME')
+
+    if not parse_var:
+        return
+
+    parse_var_items = d.getVar(parse_var)
+
+    if parse_var_items:
+        for item in parse_var_items.split(' '):
+            if not item:
+                continue
+
+            if item.startswith('/'):
+                # If not a Yocto URL, must be an absolute path
+                yocto_url = "file://" + item
+            else:
+                # Otherwise assume valid Yocto URL.
+                # Error case is caught later
+                yocto_url = item
+
+            fetcher = host = path = parm = None
+            try:
+                # Attempt to parse a Yocto URL
+                fetcher,host,path,_,_,parm = bb.fetch.decodeurl(yocto_url)
+            except:
+                # Something invalid is in the variable!
+                raise bb.parse.SkipRecipe(parse_var + \
+                                          " contains an invalid entry:\n'" + \
+                                          item + "'")
+
+            # This var is space seperated list of parameter names,
+            # with optional default value following an equals sign
+            # (name=default)
+            item_params_str = d.getVar('SRC_URI_FROM_VAR_MANIFEST_PARAMS')
+
+            # remove directories from path
+            filename = os.path.basename(path)
+
+            if "downloadfilename" in parm:
+                filename = parm["downloadfilename"]
+
+            item_manifest_args = {"filename": filename}
+
+            if item_params_str:
+                # required manifest arguments have been provided
+
+                # If no default is given add "=" for map parsing
+                item_params_list = [ arg + "=" if '=' not in arg
+                                     else arg
+                                     for arg in item_params_str.split(' ')
+                                   ]
+
+                # Generate key value pairs of argument names and
+                # default values
+                item_params_map = dict( (name.strip(), val.strip())
+                                        for name, val in (arg.split('=')
+                                        for arg in item_params_list)
+                                      )
+
+                for argname in item_params_map:
+                    # Iterate over required manifest arguments
+
+                    argvalue = parm.pop(argname, None)
+                    if argvalue:
+                        # a value has been provided for this item
+                        item_manifest_args[argname] = argvalue
+
+                    else:
+                        # No value provided, process default value
+                        default = item_params_map[argname]
+                        if default:
+                            # A default value is provided
+                            if default == "[basename]":
+                                # use the filename without extension
+                                default = os.path.splitext(filename)[0]
+
+                            # store default value in dict
+                            item_manifest_args[argname] = default
+
+                        else:
+                            # No default provided
+                            raise bb.fatal(parse_var + \
+                              " entry is missing a required parameter '" + \
+                              argname + "':\n'" + item + "'")
+
+            # Write value to var flags to ensure data structure is preserved
+            # Each entry of parse_var will have a varflag  where the value
+            # is a dictionary of argument names and values
+            d.setVarFlags(parse_var, {item: item_manifest_args})
+
+            src_uri_entry_suffix = ';'
+
+            # HTTP(S) fetcher must provide a checksum
+            if fetcher.startswith('http') and not \
+            ( 'md5sum' in parm or 'sha256sum' in parm ):
+                # Ensure http/https fetchers get a checksum
+                raise bb.parse.SkipRecipe(parse_var + \
+                                          " entry is missing a checksum:\n'" + \
+                                          item + "'")
+
+            # add remaining fetch parameters including checksum
+            for arg in parm:
+                src_uri_entry_suffix += ";" + arg + "=" + parm[arg]
+
+            # Add default and extra parameters to SRC_URI entry
+            src_uri_entry_suffix += ';unpack=0;subdir=' + \
+                                    d.getVar('SRC_URI_FROM_VAR_UNPACK_DIR')
+
+            if fetcher == 'file':
+                # Prevent local fetcher from re-creating dir structure
+                filedir = os.path.split(path)[0]
+                if filedir.startswith('/'):
+                    # Path is from the root
+                    d.appendVar('FILESEXTRAPATHS', filedir + ':')
+                else:
+                    # Path is relative to FILESEXTRAPATHS
+                    d.appendVar('FILESOVERRIDES', ':' + filedir)
+
+                # Add filename without path to SRC_URI
+                d.appendVar('SRC_URI', ' file://' + \
+                                        filename + src_uri_entry_suffix)
+            else:
+                # Add full entry to SRC_URI
+                d.appendVar('SRC_URI', ' ' + fetcher + \
+                            "://" + host + path + src_uri_entry_suffix)
+}
+
+python generate_manifest() {
+
+    parse_var = d.getVar('SRC_URI_FROM_VAR_NAME')
+
+    if not parse_var:
+        return
+
+    target_dir = os.path.join(d.getVar('WORKDIR'),
+                              d.getVar('SRC_URI_FROM_VAR_UNPACK_DIR'))
+
+    # Write a manifest file containing the parameters so SRC_URI
+    # doesn't need to be parsed by do_install
+    with open (target_dir + "/manifest", 'w') as manifest_file:
+        manifest_args = d.getVarFlags(parse_var)
+
+        parse_var_items = d.getVar(parse_var)
+
+        if parse_var_items:
+            for item in parse_var_items.split():
+
+                manifest_file.write(" ".join(manifest_args[item].values())+"\n")
+
+}
+
+do_unpack[cleandirs] += "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}"
+do_unpack[postfuncs] += "generate_manifest"
+do_unpack[vardeps] += "${SRC_URI_FROM_VAR_NAME}"
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] arm-autonomy/docker: Updated fetcher to use set_src_uri_from_var.bbclass
  2021-03-24 15:32 [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass Nathan Dunne
@ 2021-03-24 15:32 ` Nathan Dunne
  2021-03-24 15:32 ` [PATCH 3/3] arm-autonomy/images: Introduced xenguest-extern-guests recipe Nathan Dunne
  2021-03-26 13:26 ` [meta-arm] [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass Jon Mason
  2 siblings, 0 replies; 4+ messages in thread
From: Nathan Dunne @ 2021-03-24 15:32 UTC (permalink / raw)
  To: meta-arm; +Cc: nd, Nathan Dunne

From: Nathan Dunne <Nathan.Dunne@arm.com>

Use new class to parser CONTAINER_IMAGE_FILES variable and add entries to
the SRC_URI, as well as to generate the manifest.

Issue-Id: SCM-2225
Signed-off-by: Nathan Dunne <Nathan.Dunne@arm.com>
Change-Id: Idd34f564844c725f1b38a20e1e33d9aba6195e43
---
 .../classes/docker_extern_containers.bbclass  | 199 ++++--------------
 1 file changed, 39 insertions(+), 160 deletions(-)

diff --git a/meta-arm-autonomy/classes/docker_extern_containers.bbclass b/meta-arm-autonomy/classes/docker_extern_containers.bbclass
index 7aa1691..363784a 100644
--- a/meta-arm-autonomy/classes/docker_extern_containers.bbclass
+++ b/meta-arm-autonomy/classes/docker_extern_containers.bbclass
@@ -1,39 +1,33 @@
+# Docker Extern Containers
 #
 # This class allows docker image tarballs to be installed in the rootfs
 #
-# The images can be selected using the variable CONTAINER_IMAGE_FILES
-# which should contain a space seperated list of absolute paths or yocto urls
-# for docker images that have been exported using docker export:
+# The images can be selected using the variable CONTAINER_IMAGE_FILES which
+# should contain a space seperated list of absolute paths or yocto urls for
+# docker images that have been exported using docker export:
 # - https://docs.docker.com/engine/reference/commandline/export/
 #
+# src_uri_parse_var.bbclass is used to parse CONTAINER_IMAGE_FILES
+#
 # There are 4 supported formats for CONTAINER_IMAGE_FILES entries:
 #
 # - http/https url
 #   - CONTAINER_IMAGE_FILES = "https://[url]:[port]/alpine.tar;md5sum=..."
-#   - Note that a checksum (md5sum or sha256sum) must be provided for http(s)
 #
 # - file:// absolute local path from root
 #   - CONTAINER_IMAGE_FILES = "file:///containers/alpine2.tar"
-#   - In this case the filename will be added to SRC_URI and the path from '/'
-#     added to FILESEXTRAPATHS
 #
 # - file:// path relative to FILESEXTRAPATHS
 #   - CONTAINER_IMAGE_FILES = "file://foo/alpine3.tar"
 #     FILESEXTRAPATHS .= "/containers:"
-#   - In this case the filename will be added to SRC_URI and the preceding path
-#     added to FILESOVERRIDES, so that the full path to the container file will
-#     be available in FILESPATH when it is generated by combining
-#     FILESEXTRAPATHS and FILESOVERRIDES.
 #
 # - plain absolute local path from root
 #   - CONTAINER_IMAGE_FILES = "/containers/foo/bar/alpine4.tar"
-#   - This will be treated the same as an file:// path from root. Plain paths
-#     must be absolute, and cannot be relative to FILESEXTRAPATHS
 #
 # It is not recommended to use other yocto URL types, as they may result in
 # undefined behaviour.
 #
-# A semicolon seperated list of extra parameters can follow each image path:
+# A semicolon seperated list of install arguments can follow each image path:
 # - conname : the name that will be attached when the image is imported
 #             (default: [filename, without extension])
 # - contag  : the tag that will be attached when the image is imported
@@ -42,13 +36,14 @@
 #             kept once the import has been completed
 #             (default: 0)
 #
-# e.g.
-# CONTAINER_IMAGE_FILES = "\
+# 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.  CONTAINER_IMAGE_FILES = "\
 # https://[url]:[port]/alpine.tar;md5sum=[checksum];conkeep=1 \
 # file:///containers/alpine2.tar;contag=latest;conname=docker2 \
 # file://foo/alpine3.tar \
-# /containers/foo/bar/alpine4.tar;contag=1.0;conkeep=1 \
-# "
+# /containers/foo/bar/alpine4.tar;contag=1.0;conkeep=1 "
 #
 # Resulting Manifest:
 # ARCHIVE     NAME    TAG    KEEP
@@ -58,7 +53,7 @@
 # alpine4.tar alpine4 1.0    1
 #
 # Other configurable variables:
-# CONTAINERS_INSTALL_DIR  : The folder underneath where the docker
+# CONTAINERS_INSTALL_DIR  : The folder underneath ${WORKDIR} where the docker
 #                           images will be stored
 #                           (default: "/usr/share/docker/images")
 # CONTAINERS_MANIFEST     : The name of the manifest file containing image
@@ -71,166 +66,50 @@
 #                           conkeep if no value is provided
 #                           (default: "0")
 #
-# CONTAINERS_SRC_URI_EXTRA_PARAMS : Additional parameters that are added to all
-#                                   container entries in SRC_URI.
-#                                   (default: "")
 
 inherit features_check
+
 REQUIRED_DISTRO_FEATURES = "docker"
 
 RDEPENDS_${PN} = "packagegroup-docker-runtime-minimal"
 
 CONTAINER_IMAGE_FILES ??= ""
-
-CONTAINERS_INSTALL_DIR ?= "${datadir}/docker/images"
-CONTAINERS_MANIFEST ?= "containers.manifest"
-
+CONTAINERS_INSTALL_DIR ??= "${datadir}/docker/images"
+CONTAINERS_MANIFEST ??= "containers.manifest"
 CONTAINERS_TAG_DEFAULT ??= "local"
 CONTAINERS_KEEP_DEFAULT ??= "0"
-CONTAINERS_SRC_URI_EXTRA_PARAMS ?= ""
-
-# Always make sure the tar files are not extracted
-CONTAINERS_SRC_URI_EXTRA_PARAMS_append = ";unpack=0;subdir=containers"
-
-# Parse the CONTAINER_IMAGE_FILES variable and add entries to SRC_URI
-# complete with all parameters. Default values are added if no value
-# is provided
-#
-# The variables FILESEXTRAPATHS and FILESOVERRIDES are use to prevent the
-# fetcher from re-creating the local directory structure underneath
-# ${WORKDIR}/containers, so that all exported images can be found in one
-# directory
-
-python __anonymous() {
-    import re
-
-    # Patterns for identifying parameters
-    containerfile_pattern = re.compile(r"^([^;]+);")
-    containername_pattern = re.compile(r";conname=([^;]+);?")
-    containertag_pattern  = re.compile(r";contag=([^;]+);?")
-    containerkeep_pattern = re.compile(r";conkeep=([10]);?")
-
-    container_files = d.getVar('CONTAINER_IMAGE_FILES')
-
-    # Skip if no container files are provided
-    if not container_files:
-         raise bb.parse.SkipRecipe("CONTAINER_IMAGE_FILES is empty!")
-
-    # Parse each entry of the variable
-    for entry in container_files.split():
-        if entry.startswith('/'):
-            # Simple absolute local filepath specified
-            conname = "local"
-            contag  = d.getVar('CONTAINERS_TAG_DEFAULT')
-            conkeep = d.getVar('CONTAINERS_KEEP_DEFAULT')
-
-            # retrieve parameter values if they are provided
-            f = containerfile_pattern.search(entry)
-            n = containername_pattern.search(entry)
-            t = containertag_pattern.search(entry)
-            k = containerkeep_pattern.search(entry)
-
-            if f:
-                entry = f.group(1)
-            if n:
-                conname = n.group(1)
-            else:
-                # get filename for default conname
-                conname = os.path.splitext(os.path.basename(entry))[0]
-            if t:
-                contag = t.group(1)
-            if k:
-                conkeep = k.group(1)
 
-            entry = os.path.realpath(entry)
-            if not os.path.exists(entry):
-                    raise bb.parse.SkipRecipe("CONTAINER_IMAGE_FILES entry does not exist: \n" + entry)
+inherit set_src_uri_from_var
 
-            filedir, filename = os.path.split(entry)
+SRC_URI_FROM_VAR_NAME = "CONTAINER_IMAGE_FILES"
+# Define installation params
+SRC_URI_FROM_VAR_MANIFEST_PARAMS = "conname=[basename] \
+contag=${CONTAINERS_TAG_DEFAULT} conkeep=${CONTAINERS_KEEP_DEFAULT}"
 
-            d.appendVar('SRC_URI', ' file://' + filename + ';' + \
-                        d.getVar('CONTAINERS_SRC_URI_EXTRA_PARAMS') + \
-                        ';conname=' + conname + \
-                        ';contag=' + contag + \
-                        ';conkeep=' + conkeep \
-                       )
-
-            # Prevent local fetcher from re-creating dir structure
-            d.appendVar('FILESEXTRAPATHS', filedir+':')
-        else:
-            # Yocto url with fetcher prefix
-            type = path = parm = None
-            try:
-                type, _, path, _, _, parm = bb.fetch.decodeurl(entry)
-            except:
-                raise bb.parse.SkipRecipe("CONTAINER_IMAGE_FILES contains an invalid entry: " + entry)
-            src_uri_entry_suffix = ';' + d.getVar('CONTAINERS_SRC_URI_EXTRA_PARAMS')
-
-            # default container name is filename without extension
-            if not 'conname' in parm:
-                conname = os.path.splitext(os.path.basename(path))[0]
-                src_uri_entry_suffix += ';conname=' + conname
-
-            # Set other default values if they are missing
-            if not 'contag' in parm:
-                src_uri_entry_suffix += ';contag=' + d.getVar('CONTAINERS_TAG_DEFAULT')
-            if not 'conkeep' in parm:
-                src_uri_entry_suffix += ';conkeep=' + d.getVar('CONTAINERS_KEEP_DEFAULT')
-
-            # Type specifc operations
-
-            if type.startswith('http'):
-                # Ensure http(s) urls have an md5sum or sha256
-                if not ( 'md5sum' in parm or 'sha256sum' in parm ):
-                     raise bb.parse.SkipRecipe("CONTAINER_IMAGE_FILES entry is missing a checksum, provide either md5sum or sha256sum to resolve:\n" + entry)
-
-            if type == 'file':
-                # Prevent local fetcher from re-creating dir structure
-                filename_params = os.path.split(entry)[1]
-                filedir = os.path.split(path)[0]
-                if filedir.startswith('/'):
-                    # Path is from the root
-                    d.appendVar('FILESEXTRAPATHS', filedir + ':')
-                else:
-                    # Path is relative to FILESEXTRAPATHS
-                    d.appendVar('FILESOVERRIDES', ':' + filedir)
-
-                # Add filename and params to SRC_URI
-                d.appendVar('SRC_URI', ' file://' + filename_params + src_uri_entry_suffix)
-            else:
-                # Add full entry to SRC_URI
-                d.appendVar('SRC_URI', ' ' + entry + src_uri_entry_suffix)
-}
-
-# Create manifest file based on SRC_URI params
-python containers_manifest() {
-    condir = d.getVar('WORKDIR') + "/containers"
-
-    with open (os.path.join(condir, d.getVar('CONTAINERS_MANIFEST')), 'w') as manfile:
-
-        # Parse SRC_URI for files with ;conname= parameter
-        src_uri = d.getVar('SRC_URI')
-        for entry in src_uri.split():
-            _, _, path, _, _, parm = bb.fetch.decodeurl(entry)
-            if 'conname' in parm:
-                dstname = os.path.basename(path)
-                manfile.write(dstname + " " + parm['conname'] + " " + \
-                              parm['contag'] + " " + parm['conkeep'] + '\n'
-                             )
-}
+SRC_URI_FROM_VAR_UNPACK_DIR = "containers"
 
 # Read manifest and install container images
 do_install() {
     local archive name tag keep
-    install -d "${D}${CONTAINERS_INSTALL_DIR}"
-    install -m 644 "${WORKDIR}/containers/${CONTAINERS_MANIFEST}" "${D}${CONTAINERS_INSTALL_DIR}"
 
-    while read -r archive name tag keep _; do
-        [ -f "${WORKDIR}/containers/${archive}" ] || bbfatal "${archive} does not exist"
+    if [ -f "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/manifest" ]; then
 
-        install -m 644 "${WORKDIR}/containers/${archive}" "${D}${CONTAINERS_INSTALL_DIR}"
-    done < "${WORKDIR}/containers/${CONTAINERS_MANIFEST}"
+        install -d "${D}${CONTAINERS_INSTALL_DIR}"
+        install -m 644 \
+            "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/manifest" \
+            "${D}${CONTAINERS_INSTALL_DIR}/${CONTAINERS_MANIFEST}"
+
+        while read -r archive name tag keep _; do
+            [ -f "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/${archive}" ] ||
+                bbfatal "${archive} does not exist"
+
+            install -m 644 \
+                "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}/${archive}" \
+                "${D}${CONTAINERS_INSTALL_DIR}/${archive}"
+        done < "${D}${CONTAINERS_INSTALL_DIR}/${CONTAINERS_MANIFEST}"
+    fi
 }
 
+do_install[vardeps] += "CONTAINER_IMAGE_FILES"
+
 FILES_${PN} += "${CONTAINERS_INSTALL_DIR}"
-do_install[prefuncs]+= "containers_manifest"
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] arm-autonomy/images: Introduced xenguest-extern-guests recipe
  2021-03-24 15:32 [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass Nathan Dunne
  2021-03-24 15:32 ` [PATCH 2/3] arm-autonomy/docker: Updated fetcher to use set_src_uri_from_var.bbclass Nathan Dunne
@ 2021-03-24 15:32 ` Nathan Dunne
  2021-03-26 13:26 ` [meta-arm] [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass Jon Mason
  2 siblings, 0 replies; 4+ messages in thread
From: Nathan Dunne @ 2021-03-24 15:32 UTC (permalink / raw)
  To: meta-arm; +Cc: nd, Nathan Dunne

From: Nathan Dunne <Nathan.Dunne@arm.com>

Seperated guest inclusion for image into seperate recipe, allowing
a do_install task to be used rather than directly copying from the
local path.

This allows all bitbake fetcher types to be used rather than only
local files. Alternate fetchers are enabled through parsing
ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS with set_src_uri_from_var.bbclass

Issue-Id: SCM-2225
Signed-off-by: Nathan Dunne <Nathan.Dunne@arm.com>
Change-Id: Iff5483926a5cde8ce7519da60f1b9119946a7f4e
---
 .../images/arm-autonomy-host-image-minimal.bb | 139 +-----------------
 .../xenguest/xenguest-extern-guests.bb        | 118 +++++++++++++++
 2 files changed, 119 insertions(+), 138 deletions(-)
 create mode 100644 meta-arm-autonomy/recipes-extended/xenguest/xenguest-extern-guests.bb

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 ea5d889..cce632f 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 0000000..9310cbc
--- /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}"
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [meta-arm] [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass
  2021-03-24 15:32 [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass Nathan Dunne
  2021-03-24 15:32 ` [PATCH 2/3] arm-autonomy/docker: Updated fetcher to use set_src_uri_from_var.bbclass Nathan Dunne
  2021-03-24 15:32 ` [PATCH 3/3] arm-autonomy/images: Introduced xenguest-extern-guests recipe Nathan Dunne
@ 2021-03-26 13:26 ` Jon Mason
  2 siblings, 0 replies; 4+ messages in thread
From: Jon Mason @ 2021-03-26 13:26 UTC (permalink / raw)
  To: Nathan Dunne; +Cc: meta-arm, nd

On Wed, Mar 24, 2021 at 03:32:55PM +0000, Nathan Dunne wrote:
> From: Nathan Dunne <Nathan.Dunne@arm.com>
> 
> Introduced set_src_uri_from_var.bbclass to add entries to the
> SRC_URI based on a named variable, and generate a manifest
> file alongside fetched items containing a number of parameters
> for each entry.
> 
> Parameters can have an optional default value, or cause an error
> if omitted.
> 
> Issue-Id: SCM-2225
> Signed-off-by: Nathan Dunne <Nathan.Dunne@arm.com>
> Change-Id: Ia85b3f4bc3fa666fa7e7aec2d670979ac9348f52
> ---

Series pulled into master.

Thanks,
Jon

>  .../classes/set_src_uri_from_var.bbclass      | 224 ++++++++++++++++++
>  1 file changed, 224 insertions(+)
>  create mode 100644 meta-arm-autonomy/classes/set_src_uri_from_var.bbclass
> 
> diff --git a/meta-arm-autonomy/classes/set_src_uri_from_var.bbclass b/meta-arm-autonomy/classes/set_src_uri_from_var.bbclass
> new file mode 100644
> index 0000000..b2d8aec
> --- /dev/null
> +++ b/meta-arm-autonomy/classes/set_src_uri_from_var.bbclass
> @@ -0,0 +1,224 @@
> +# Set SRC_URI from Variable
> +
> +# This class parses a variable named in SRC_URI_FROM_VAR_NAME for entries that
> +# should be added to the SRC_URI
> +#
> +# There are 4 supported formats for entries:
> +#
> +# - http/https url
> +#   - Note that a checksum (md5sum or sha256sum) must be provided for http(s)
> +#
> +# - file:// absolute local path from root
> +#   - In this case the filename will be added to SRC_URI and the path from '/'
> +#   added to FILESEXTRAPATHS
> +#
> +# - file:// path relative to FILESEXTRAPATHS
> +#   - In this case the filename will be added to SRC_URI and the preceding path
> +#   added to FILESOVERRIDES, so that the full path to the file will
> +#   be available in FILESPATH when it is generated by combining
> +#   FILESEXTRAPATHS and FILESOVERRIDES.
> +#
> +# - plain absolute local path from root
> +#   - This will be treated the same as an file:// path from root. Plain paths
> +#   must be absolute, and cannot be relative to FILESEXTRAPATHS
> +#
> +# It is not recommended to use other yocto URL types, as they may result in
> +# undefined behaviour.
> +#
> +# These entries will be added to the SRC_URI so that the yocto fetcher can
> +# unpack a copy into ${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}
> +#
> +#
> +# A list of arguments can follow each entry in the input variable, seperated
> +# by semi-colons (;). Arguments may be FETCH arguments or MANIFEST arguments.
> +#
> +# FETCH arguments will be appended to the entry in SRC_URI, for example
> +# "downloadfilename" to specify the filename used when storing a
> +# downloaded file.
> +# Each SRC_URI entry will automatically have the arguments
> +# "unpack=0;subdir=${SRC_URI_FROM_VAR_UNPACK_DIR}" added to them, so do not
> +# attempt to set these options.
> +#
> +# MANIFEST arguments are defined in the variable
> +# SRC_URI_FROM_VAR_MANIFEST_PARAMS which should be a space seperated list of
> +# names, each optionally followed by an equals sign (=) and a default value.
> +#
> +# The values provided for the manifest arguments will be written to the manifest
> +# file in ${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR} as columns, in the same
> +# order as they appear in SRC_URI_FROM_VAR_MANIFEST_PARAMS.
> +#
> +# For entries that do not provide a value for a manifest argument, the default
> +# value will be used if possible.
> +# If no default is availale, omitting the parameter on any item will cause
> +# an error.
> +#
> +# "[basename]" is a special case default that will set the value to
> +# the filename without the path or file extension.
> +#
> +# e.g.
> +# SRC_URI_FROM_VAR_MANIFEST_PARAMS="conname=[basename] contag=local conkeep"
> +#
> +# Any arguments that follow an entry in SRC_URI_FROM_VAR_NAME, that are not
> +# named in SRC_URI_FROM_VAR_MANIFEST_PARAMS are assumed to be FETCH arguments,
> +# so are added to the corresponding entry in the SRC_URI.
> +
> +SRC_URI_FROM_VAR_NAME ??= ""
> +SRC_URI_FROM_VAR_MANIFEST_PARAMS ??= ""
> +SRC_URI_FROM_VAR_UNPACK_DIR ??= "items"
> +
> +python __anonymous() {
> +
> +    parse_var = d.getVar('SRC_URI_FROM_VAR_NAME')
> +
> +    if not parse_var:
> +        return
> +
> +    parse_var_items = d.getVar(parse_var)
> +
> +    if parse_var_items:
> +        for item in parse_var_items.split(' '):
> +            if not item:
> +                continue
> +
> +            if item.startswith('/'):
> +                # If not a Yocto URL, must be an absolute path
> +                yocto_url = "file://" + item
> +            else:
> +                # Otherwise assume valid Yocto URL.
> +                # Error case is caught later
> +                yocto_url = item
> +
> +            fetcher = host = path = parm = None
> +            try:
> +                # Attempt to parse a Yocto URL
> +                fetcher,host,path,_,_,parm = bb.fetch.decodeurl(yocto_url)
> +            except:
> +                # Something invalid is in the variable!
> +                raise bb.parse.SkipRecipe(parse_var + \
> +                                          " contains an invalid entry:\n'" + \
> +                                          item + "'")
> +
> +            # This var is space seperated list of parameter names,
> +            # with optional default value following an equals sign
> +            # (name=default)
> +            item_params_str = d.getVar('SRC_URI_FROM_VAR_MANIFEST_PARAMS')
> +
> +            # remove directories from path
> +            filename = os.path.basename(path)
> +
> +            if "downloadfilename" in parm:
> +                filename = parm["downloadfilename"]
> +
> +            item_manifest_args = {"filename": filename}
> +
> +            if item_params_str:
> +                # required manifest arguments have been provided
> +
> +                # If no default is given add "=" for map parsing
> +                item_params_list = [ arg + "=" if '=' not in arg
> +                                     else arg
> +                                     for arg in item_params_str.split(' ')
> +                                   ]
> +
> +                # Generate key value pairs of argument names and
> +                # default values
> +                item_params_map = dict( (name.strip(), val.strip())
> +                                        for name, val in (arg.split('=')
> +                                        for arg in item_params_list)
> +                                      )
> +
> +                for argname in item_params_map:
> +                    # Iterate over required manifest arguments
> +
> +                    argvalue = parm.pop(argname, None)
> +                    if argvalue:
> +                        # a value has been provided for this item
> +                        item_manifest_args[argname] = argvalue
> +
> +                    else:
> +                        # No value provided, process default value
> +                        default = item_params_map[argname]
> +                        if default:
> +                            # A default value is provided
> +                            if default == "[basename]":
> +                                # use the filename without extension
> +                                default = os.path.splitext(filename)[0]
> +
> +                            # store default value in dict
> +                            item_manifest_args[argname] = default
> +
> +                        else:
> +                            # No default provided
> +                            raise bb.fatal(parse_var + \
> +                              " entry is missing a required parameter '" + \
> +                              argname + "':\n'" + item + "'")
> +
> +            # Write value to var flags to ensure data structure is preserved
> +            # Each entry of parse_var will have a varflag  where the value
> +            # is a dictionary of argument names and values
> +            d.setVarFlags(parse_var, {item: item_manifest_args})
> +
> +            src_uri_entry_suffix = ';'
> +
> +            # HTTP(S) fetcher must provide a checksum
> +            if fetcher.startswith('http') and not \
> +            ( 'md5sum' in parm or 'sha256sum' in parm ):
> +                # Ensure http/https fetchers get a checksum
> +                raise bb.parse.SkipRecipe(parse_var + \
> +                                          " entry is missing a checksum:\n'" + \
> +                                          item + "'")
> +
> +            # add remaining fetch parameters including checksum
> +            for arg in parm:
> +                src_uri_entry_suffix += ";" + arg + "=" + parm[arg]
> +
> +            # Add default and extra parameters to SRC_URI entry
> +            src_uri_entry_suffix += ';unpack=0;subdir=' + \
> +                                    d.getVar('SRC_URI_FROM_VAR_UNPACK_DIR')
> +
> +            if fetcher == 'file':
> +                # Prevent local fetcher from re-creating dir structure
> +                filedir = os.path.split(path)[0]
> +                if filedir.startswith('/'):
> +                    # Path is from the root
> +                    d.appendVar('FILESEXTRAPATHS', filedir + ':')
> +                else:
> +                    # Path is relative to FILESEXTRAPATHS
> +                    d.appendVar('FILESOVERRIDES', ':' + filedir)
> +
> +                # Add filename without path to SRC_URI
> +                d.appendVar('SRC_URI', ' file://' + \
> +                                        filename + src_uri_entry_suffix)
> +            else:
> +                # Add full entry to SRC_URI
> +                d.appendVar('SRC_URI', ' ' + fetcher + \
> +                            "://" + host + path + src_uri_entry_suffix)
> +}
> +
> +python generate_manifest() {
> +
> +    parse_var = d.getVar('SRC_URI_FROM_VAR_NAME')
> +
> +    if not parse_var:
> +        return
> +
> +    target_dir = os.path.join(d.getVar('WORKDIR'),
> +                              d.getVar('SRC_URI_FROM_VAR_UNPACK_DIR'))
> +
> +    # Write a manifest file containing the parameters so SRC_URI
> +    # doesn't need to be parsed by do_install
> +    with open (target_dir + "/manifest", 'w') as manifest_file:
> +        manifest_args = d.getVarFlags(parse_var)
> +
> +        parse_var_items = d.getVar(parse_var)
> +
> +        if parse_var_items:
> +            for item in parse_var_items.split():
> +
> +                manifest_file.write(" ".join(manifest_args[item].values())+"\n")
> +
> +}
> +
> +do_unpack[cleandirs] += "${WORKDIR}/${SRC_URI_FROM_VAR_UNPACK_DIR}"
> +do_unpack[postfuncs] += "generate_manifest"
> +do_unpack[vardeps] += "${SRC_URI_FROM_VAR_NAME}"
> -- 
> 2.17.1
> 

> 
> 
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-03-26 13:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-24 15:32 [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass Nathan Dunne
2021-03-24 15:32 ` [PATCH 2/3] arm-autonomy/docker: Updated fetcher to use set_src_uri_from_var.bbclass Nathan Dunne
2021-03-24 15:32 ` [PATCH 3/3] arm-autonomy/images: Introduced xenguest-extern-guests recipe Nathan Dunne
2021-03-26 13:26 ` [meta-arm] [PATCH 1/3] arm-autonomy/classes: Introduced set_src_uri_from_var.bbclass Jon Mason

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.