1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-06-07 03:04:27 +00:00

arm-autonomy/docker: Updated fetcher to use set_src_uri_from_var.bbclass

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
Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
Nathan Dunne
2021-03-24 15:32:56 +00:00
committed by Jon Mason
parent 5e3d09e234
commit 8195b2c953
@@ -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"