diff --git a/meta-arm-autonomy/classes/docker_extern_containers.bbclass b/meta-arm-autonomy/classes/docker_extern_containers.bbclass index 7aa1691f..363784a9 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" +inherit set_src_uri_from_var -# 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 +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}" -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) - - filedir, filename = os.path.split(entry) - - 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"