dey-image-container: add core image flow for LXC and Podman outputs
Introduce the base dey-image-container recipe and split core logic into dedicated include files for rootfs overlays, LXC bundle generation and Podman archive conversion. This commit defines the profile-driven variables/overrides and the native build tasks required to produce runtime-specific container outputs. Also allow the recipe to overwrite WAYLAND_DISPLAY on init scripts to match with different platforms. https://onedigi.atlassian.net/browse/DEL-10004 Signed-off-by: Francisco Gil <francisco.gilmartinez@digi.com> Signed-off-by: Isaac Hermida <isaac.hermida@digi.com>
This commit is contained in:
parent
8ba3905c2e
commit
3efe532995
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# Copyright (C) 2026, Digi International Inc.
|
||||
#
|
||||
########################
|
||||
# Rootfs postprocess
|
||||
########################
|
||||
ROOTFS_POSTPROCESS_COMMAND += "apply_container_rootfs_overlays; "
|
||||
apply_container_rootfs_overlays() {
|
||||
overlay_dirs="${CONTAINER_ROOTFS_OVERLAY_DIRS}"
|
||||
overlay_tarballs="${CONTAINER_ROOTFS_OVERLAY_TARBALLS}"
|
||||
default_overlay_dir="${CONTAINER_DEFAULT_ROOTFS_DIR}"
|
||||
|
||||
if [ -z "${overlay_dirs}" ] && [ -d "${default_overlay_dir}" ]; then
|
||||
overlay_dirs="${default_overlay_dir}"
|
||||
bbnote "Using default profile rootfs overlay: ${default_overlay_dir}"
|
||||
fi
|
||||
|
||||
for overlay_dir in ${overlay_dirs}; do
|
||||
if [ ! -d "${overlay_dir}" ]; then
|
||||
bbfatal "CONTAINER_ROOTFS_OVERLAY_DIRS entry does not exist or is not a directory: ${overlay_dir}"
|
||||
fi
|
||||
bbnote "Applying rootfs overlay directory: ${overlay_dir}"
|
||||
(
|
||||
cd "${overlay_dir}" || exit 1
|
||||
tar -cf - --exclude='.keep' --exclude='*/.keep' .
|
||||
) | tar -xf - -C "${IMAGE_ROOTFS}"
|
||||
|
||||
# Ensure copied shell scripts are executable inside the container rootfs.
|
||||
(
|
||||
cd "${overlay_dir}" || exit 1
|
||||
find . -type f -name '*.sh'
|
||||
) | while IFS= read -r relpath; do
|
||||
relpath="${relpath#./}"
|
||||
chmod 0755 "${IMAGE_ROOTFS}/${relpath}"
|
||||
done
|
||||
done
|
||||
|
||||
for overlay_tarball in ${overlay_tarballs}; do
|
||||
if [ ! -f "${overlay_tarball}" ]; then
|
||||
bbfatal "CONTAINER_ROOTFS_OVERLAY_TARBALLS entry does not exist: ${overlay_tarball}"
|
||||
fi
|
||||
bbnote "Extracting rootfs overlay tarball: ${overlay_tarball}"
|
||||
tar -xzf "${overlay_tarball}" -C "${IMAGE_ROOTFS}"
|
||||
done
|
||||
}
|
||||
|
||||
ROOTFS_POSTPROCESS_COMMAND += "apply_container_rootfs_runtime_defaults; "
|
||||
apply_container_rootfs_runtime_defaults() {
|
||||
if [ -n "${CONTAINER_INIT_SCRIPT}" ] && \
|
||||
[ -f "${IMAGE_ROOTFS}${CONTAINER_INIT_SCRIPT}" ] && \
|
||||
grep -q "@WAYLAND_DISPLAY@" "${IMAGE_ROOTFS}${CONTAINER_INIT_SCRIPT}"; then
|
||||
sed -i \
|
||||
-e "s|@WAYLAND_DISPLAY@|${WAYLAND_DISPLAY}|g" \
|
||||
"${IMAGE_ROOTFS}${CONTAINER_INIT_SCRIPT}"
|
||||
bbnote "Applied WAYLAND_DISPLAY='${WAYLAND_DISPLAY}' to ${IMAGE_ROOTFS}${CONTAINER_INIT_SCRIPT}"
|
||||
fi
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# Copyright (C) 2026, Digi International Inc.
|
||||
#
|
||||
########################
|
||||
# LXC artifact
|
||||
########################
|
||||
do_image_lxc_bundle() {
|
||||
rootfs_tar="${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.tar.xz"
|
||||
if [ ! -f "${rootfs_tar}" ]; then
|
||||
rootfs_tar="${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.tar.xz"
|
||||
fi
|
||||
lxc_tar="${DEPLOY_DIR_IMAGE}/${LXC_OUTPUT_NAME}"
|
||||
workdir="$(mktemp -d)"
|
||||
trap 'rm -rf "${workdir}"' EXIT
|
||||
|
||||
if [ ! -f "${rootfs_tar}" ]; then
|
||||
bbfatal "Expected rootfs tarball not found: ${rootfs_tar}"
|
||||
fi
|
||||
|
||||
lxc_dir="${workdir}/${CONTAINER_NAME}"
|
||||
mkdir -p "${lxc_dir}/rootfs"
|
||||
|
||||
bbnote "Extracting rootfs for LXC bundle..."
|
||||
tar -xf "${rootfs_tar}" -C "${lxc_dir}/rootfs"
|
||||
|
||||
config_in="${LXC_CONFIG_FILE}"
|
||||
if [ ! -f "${config_in}" ]; then
|
||||
bbfatal "LXC config file not found for CONTAINER_TYPE='${CONTAINER_TYPE}' and platform='${LXC_PLATFORM}': ${config_in}"
|
||||
fi
|
||||
|
||||
sed \
|
||||
-e "s|@LXC_ARCH@|${TARGET_ARCH}|g" \
|
||||
-e "s|@LXC_FOLDER@|${LXC_FOLDER}|g" \
|
||||
-e "s|@CONTAINER_NAME@|${CONTAINER_NAME}|g" \
|
||||
-e "s|@CONTAINER_INIT_MANAGER@|${CONTAINER_INIT_MANAGER}|g" \
|
||||
-e "s|@CONTAINER_INIT_SCRIPT@|${CONTAINER_INIT_SCRIPT}|g" \
|
||||
"${config_in}" > "${lxc_dir}/config"
|
||||
|
||||
tar -C "${workdir}" -cJf "${lxc_tar}" "${CONTAINER_NAME}"
|
||||
|
||||
if [ ! -s "${lxc_tar}" ]; then
|
||||
bbfatal "LXC bundle was not generated correctly: ${lxc_tar}"
|
||||
fi
|
||||
|
||||
bbnote "LXC bundle ready: ${lxc_tar}"
|
||||
}
|
||||
|
||||
addtask image_lxc_bundle after do_image_complete before do_build
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# Copyright (C) 2026, Digi International Inc.
|
||||
#
|
||||
########################
|
||||
# Podman artifact
|
||||
########################
|
||||
do_image_podman_archive[depends] += "skopeo-native:do_populate_sysroot"
|
||||
do_image_podman_archive() {
|
||||
src_tar="${DEPLOY_DIR_IMAGE}/${IMAGE_BASENAME}-${OCI_IMAGE_TAG_SAFE}-oci.tar"
|
||||
if [ ! -f "${src_tar}" ]; then
|
||||
src_tar="${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs-oci.tar"
|
||||
fi
|
||||
dst_tar="${DEPLOY_DIR_IMAGE}/${PODMAN_OUTPUT_NAME}"
|
||||
image_ref="${CONTAINER_NAME}:${PODMAN_TAG}"
|
||||
|
||||
if [ ! -f "${src_tar}" ]; then
|
||||
bbfatal "Expected OCI tarball not found: ${src_tar}"
|
||||
fi
|
||||
|
||||
# skopeo docker-archive destination must not already exist.
|
||||
rm -f "${dst_tar}"
|
||||
|
||||
bbnote "Converting OCI archive to docker-archive (${image_ref})..."
|
||||
PATH="${STAGING_BINDIR_NATIVE}:${PATH}" \
|
||||
skopeo --insecure-policy copy \
|
||||
"oci-archive:${src_tar}" \
|
||||
"docker-archive:${dst_tar}:${image_ref}"
|
||||
|
||||
if [ ! -s "${dst_tar}" ]; then
|
||||
bbfatal "Podman archive not generated correctly: ${dst_tar}"
|
||||
fi
|
||||
|
||||
bbnote "Podman archive ready: ${dst_tar} (${image_ref})"
|
||||
}
|
||||
|
||||
addtask image_podman_archive after do_image_complete before do_build
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
# Copyright (C) 2026, Digi International Inc.
|
||||
|
||||
SUMMARY = "Minimal LXC container image"
|
||||
LICENSE = "MIT"
|
||||
|
||||
require dey-image-container-artifact.inc
|
||||
require dey-image-container-fragments.inc
|
||||
require dey-image-container-lxc.inc
|
||||
require dey-image-container-podman.inc
|
||||
|
||||
inherit core-image image-container image-oci
|
||||
|
||||
########################
|
||||
# Image base settings
|
||||
########################
|
||||
IMAGE_FEATURES = ""
|
||||
IMAGE_FSTYPES = "tar.xz oci"
|
||||
IMAGE_LINGUAS = "en-us"
|
||||
NO_RECOMMENDATIONS = "1"
|
||||
|
||||
########################
|
||||
# Container profile
|
||||
########################
|
||||
# Select profile in local.conf (e.g. CONTAINER_TYPE = "lvgl" or "webkit").
|
||||
CONTAINER_TYPE ?= "base"
|
||||
OVERRIDES:append = ":container-${CONTAINER_TYPE}"
|
||||
|
||||
########################
|
||||
# Container runtime knobs
|
||||
########################
|
||||
CONTAINER_INIT_MANAGER ?= "/usr/bin/docker-init"
|
||||
CONTAINER_INIT_SCRIPT ?= "sleep infinity"
|
||||
CONTAINER_NAME ?= "${CONTAINER_TYPE}-container"
|
||||
CONTAINER_PROFILE_DIR ?= "${CONTAINERS_DIR}/${CONTAINER_TYPE}"
|
||||
CONTAINER_ROOTFS_OVERLAY_DIRS ?= ""
|
||||
CONTAINER_DEFAULT_ROOTFS_DIR ?= "${CONTAINER_PROFILE_DIR}/rootfs_files"
|
||||
CONTAINER_ROOTFS_OVERLAY_TARBALLS ?= ""
|
||||
|
||||
########################
|
||||
# Podman output knobs
|
||||
########################
|
||||
PODMAN_TAG ?= "${CONTAINER_NAME}-tag"
|
||||
PODMAN_OUTPUT_NAME ?= "${CONTAINER_NAME}_podman_${MACHINE}.tar"
|
||||
PODMAN_ARTIFACT_OUTPUT_NAME ?= "${CONTAINER_NAME}_artifact_podman_${MACHINE}.tar.gz"
|
||||
|
||||
########################
|
||||
# LXC output knobs
|
||||
########################
|
||||
CONTAINERS_DIR ?= "${THISDIR}/../../containers"
|
||||
LXC_FOLDER ?= "/var/lib/lxc"
|
||||
LXC_PLATFORM ?= "${@d.getVar('MACHINE').split('-')[0]}"
|
||||
LXC_OUTPUT_NAME ?= "${CONTAINER_NAME}_lxc_${MACHINE}.tar.xz"
|
||||
LXC_ARTIFACT_OUTPUT_NAME ?= "${CONTAINER_NAME}_artifact_lxc_${MACHINE}.tar.gz"
|
||||
LXC_CONFIG_DIR ?= "${CONTAINER_PROFILE_DIR}/configs_lxc"
|
||||
LXC_CONFIG_FILE ?= "${LXC_CONFIG_DIR}/config_lxc_${LXC_PLATFORM}"
|
||||
|
||||
########################
|
||||
# Artifact layout knobs
|
||||
########################
|
||||
CONTAINER_ARTIFACT_TEMPLATE_DIR ?= ""
|
||||
CONTAINER_DEFAULT_ARTIFACT_TEMPLATE_DIR ?= "${CONTAINER_PROFILE_DIR}/artifact"
|
||||
META_DIGI_REPO_DIR ?= "${THISDIR}/../../.."
|
||||
CONTAINER_PACKAGE_ID ?= "${CONTAINER_NAME}"
|
||||
CONTAINER_ARTIFACT_VERSION ?= "${PV}"
|
||||
CONTAINER_CREATE_ARGS ?= ""
|
||||
CONTAINER_CREATE_ARGS_PODMAN ?= "${CONTAINER_CREATE_ARGS}"
|
||||
CONTAINER_FIRMWARE_VERSIONS ?= ""
|
||||
CONTAINER_DEVICE_TYPES_JSON ?= "[\"${MACHINE}\"]"
|
||||
CONTAINER_ARTIFACT_DESCRIPTION ?= ""
|
||||
CONTAINER_ARTIFACT_BUILD_ID ?= ""
|
||||
CONTAINER_ARTIFACT_LABELS_JSON ?= "{}"
|
||||
|
||||
########################
|
||||
# Container image behavior
|
||||
########################
|
||||
VIRTUAL-RUNTIME_init_manager = ""
|
||||
VIRTUAL-RUNTIME_initscripts = ""
|
||||
IMAGE_CONTAINER_NO_DUMMY = "1"
|
||||
|
||||
########################
|
||||
# OCI metadata mapping
|
||||
########################
|
||||
OCI_IMAGE_TAG ?= "${PODMAN_TAG}"
|
||||
OCI_IMAGE_TAG_SAFE = "${@d.getVar('OCI_IMAGE_TAG').replace(':', '_')}"
|
||||
OCI_IMAGE_ENTRYPOINT = "${CONTAINER_INIT_MANAGER}"
|
||||
OCI_IMAGE_ENTRYPOINT_ARGS = "${CONTAINER_INIT_SCRIPT}"
|
||||
|
||||
########################
|
||||
# Base packages
|
||||
########################
|
||||
IMAGE_INSTALL = " \
|
||||
base-files \
|
||||
base-passwd \
|
||||
busybox \
|
||||
netbase \
|
||||
tini \
|
||||
"
|
||||
Loading…
Reference in New Issue