dey-image-container: add final artifact bundle generation

Add the artifact packaging stage that assembles deployable LXC/Podman
bundles with a normalized layout (manifest, payload, checksums, metadata).

The task also computes digests/metadata and removes intermediate build
outputs once final artifacts are produced.

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:
Francisco Gil 2026-03-10 11:37:19 +01:00
parent 3efe532995
commit 2da298408e
20 changed files with 691 additions and 3 deletions

View File

@ -0,0 +1,236 @@
# meta-digi-containers
Yocto layer for Digi container-focused image generation and packaging.
This layer provides the `dey-image-container` image recipe and related logic to produce:
- A base rootfs (`tar.xz`)
- An OCI image output
- A Podman archive (`*.tar`)
- An LXC bundle (`*.tar.xz`)
- Final container artifacts (`*.tar.gz`) with:
- `manifest.json`
- `payload/`
- `checksums/sha256sums.txt`
- optional `metadata/`
Note: Podman archive generation requires an OCI image output as intermediate input.
The recipe keeps `oci` in `IMAGE_FSTYPES` because `do_image_podman_archive` converts
that OCI artifact into a `docker-archive` tar using `skopeo`.
## Layer Scope
Main recipe:
- `recipes-core/images/dey-image-container.bb`
Recipe includes:
- `dey-image-container-fragments.inc`
- `dey-image-container-lxc.inc`
- `dey-image-container-podman.inc`
- `dey-image-container-artifact.inc`
Container support files:
- `containers/<profile>/configs_lxc/` (profile LXC config fragments)
- `containers/<profile>/rootfs_files/` (profile rootfs overlays)
- `containers/<profile>/artifact/` (optional artifact metadata template)
## Add The Layer
In your build environment:
```bash
bitbake-layers add-layer /path/to/sources/meta-digi/meta-digi-containers
bitbake-layers add-layer /path/to/sources/meta-virtualization
bitbake-layers add-layer /path/to/sources/meta-openembedded/meta-filesystems
```
Or add it manually to `conf/bblayers.conf`.
## Basic Usage
Set profile and naming in `conf/local.conf`:
```conf
DISTRO_FEATURES:append = " virtualization"
CONTAINER_TYPE = "webkit" # or: lvgl, base, custom profile
CONTAINER_NAME = "webkit-example"
# PODMAN_TAG defaults to "${CONTAINER_NAME}-tag"
```
Build:
```bash
bitbake dey-image-container
```
Outputs are generated in:
- `tmp/deploy/images/${MACHINE}/`
Final outputs:
- `${CONTAINER_NAME}_artifact_podman_${MACHINE}.tar.gz`
- `${CONTAINER_NAME}_artifact_lxc_${MACHINE}.tar.gz`
Intermediate outputs generated during the build (LXC bundle, Podman archive, OCI/rootfs files)
are removed automatically at the end of artifact creation.
## Profiles
Profile-specific behavior is controlled with:
- `CONTAINER_TYPE`
- `OVERRIDES:append = ":container-${CONTAINER_TYPE}"` (handled in recipe)
Current built-in profile examples:
- `container-lvgl`
- `container-webkit`
You can add new profiles by appending variables with `:container-<name>` overrides.
For customer-defined profiles, use:
```conf
CONTAINER_TYPE = "myprofile"
CONTAINER_NAME = "myprofile-demo"
PODMAN_TAG = "myprofile-demo-tag"
IMAGE_INSTALL:append:container-myprofile = " package-a package-b"
CONTAINER_INIT_MANAGER:container-myprofile = "/usr/bin/docker-init"
CONTAINER_INIT_SCRIPT:container-myprofile = "/usr/bin/my-app --foreground"
# Manifest-related overrides can also be profile-specific:
CONTAINER_ARTIFACT_VERSION:container-myprofile = "1.2.0"
CONTAINER_FIRMWARE_VERSIONS:container-myprofile = ">=25.01"
CONTAINER_DEVICE_TYPES_JSON:container-myprofile = "[\"ccmp25-dvk\"]"
CONTAINER_ARTIFACT_DESCRIPTION:container-myprofile = "My profile demo container"
CONTAINER_ARTIFACT_LABELS_JSON:container-myprofile = "{\"vendor\":\"digi\",\"component\":\"demo\"}"
```
## Rootfs Overlay
Use the following variables to inject directories into the container rootfs:
```conf
CONTAINER_ROOTFS_OVERLAY_DIRS = "/absolute/path/to/overlay"
CONTAINER_ROOTFS_OVERLAY_TARBALLS = "/absolute/path/to/overlay.tar.gz"
```
Notes:
- Multiple entries are supported (space-separated).
- `*.sh` files copied from overlay directories are marked executable automatically.
- If `CONTAINER_ROOTFS_OVERLAY_DIRS` is not set
and `containers/${CONTAINER_TYPE}/rootfs_files` exists,
it is used automatically.
## LXC Fragment Configuration
LXC fragments are loaded from:
- `containers/${CONTAINER_TYPE}/configs_lxc/`
Config file naming:
- `config_lxc_<machine>`
Example:
- `config_lxc_ccmp25-dvk`
`<machine>` matches the full `MACHINE` value.
Supported placeholders in LXC config fragments:
- `@LXC_ARCH@`
- `@LXC_FOLDER@`
- `@CONTAINER_NAME@`
- `@CONTAINER_INIT_MANAGER@`
- `@CONTAINER_INIT_SCRIPT@`
## Artifact Manifest Fields
The artifact manifest is generated automatically and includes:
- `package_id`
- `version`
- `runtime`
- `artifact_type`
- `create_args` [optional] for Podman artifacts (only when non-empty)
- `created_at`
- `digest`
- `device_types`
- `firmware_versions`
- `size_bytes`
- `build_id`
- `description`
- `labels`
`build_id` behavior:
- Uses `CONTAINER_ARTIFACT_BUILD_ID` if explicitly set.
- Otherwise uses the current `meta-digi` git commit SHA (`git rev-parse HEAD`).
Relevant variables:
- `CONTAINER_PACKAGE_ID`
- `CONTAINER_ARTIFACT_VERSION`
- `CONTAINER_CREATE_ARGS_PODMAN`
- `CONTAINER_FIRMWARE_VERSIONS`
- `CONTAINER_DEVICE_TYPES_JSON`
- `CONTAINER_ARTIFACT_DESCRIPTION`
- `CONTAINER_ARTIFACT_BUILD_ID`
- `CONTAINER_ARTIFACT_LABELS_JSON`
## Optional Artifact Metadata Template
If you set:
```conf
CONTAINER_ARTIFACT_TEMPLATE_DIR = "/path/to/artifact-template"
```
and the template contains `metadata/`, it is copied into final artifact bundles.
`manifest.json`, `payload/*`, and `checksums/sha256sums.txt` are always generated during
build time and should not be pre-created in the template.
If `CONTAINER_ARTIFACT_TEMPLATE_DIR` is not set and `containers/${CONTAINER_TYPE}/artifact` exists,
it is used automatically.
## Container Folder Layout
Each profile is self-contained under `containers/`:
```text
containers/
lvgl/
rootfs_files/
configs_lxc/
artifact/
webkit/
rootfs_files/
configs_lxc/
artifact/
custom/
rootfs_files/
configs_lxc/
artifact/
```
To create a new profile:
1. Create `containers/<profile>/configs_lxc/config_lxc_<machine>`.
2. Optionally add `containers/<profile>/rootfs_files/` for rootfs content.
3. Set `CONTAINER_TYPE = "<profile>"` in `local.conf`.
4. Add profile packages with `IMAGE_INSTALL:append:container-<profile> = " ... "`.
## Notes
- Intermediate container artifacts from the current build are removed at the end of the artifact task.
- If `dey-image-container` is not found, verify the layer is present in `BBLAYERS`.

View File

@ -0,0 +1 @@
Placeholder metadata for custom container artifacts.

View File

@ -0,0 +1 @@
Placeholder changelog for custom container artifacts.

View File

@ -0,0 +1,17 @@
# LXC base config for custom profile on CCIMX95.
# Placeholders are replaced by the image recipe.
lxc.arch = @LXC_ARCH@
lxc.rootfs.path = dir:@LXC_FOLDER@/@CONTAINER_NAME@/rootfs
lxc.uts.name = @CONTAINER_NAME@
lxc.mount.auto = cgroup:mixed proc:mixed
lxc.mount.entry = /sys sys none bind,create=dir
lxc.mount.entry = tmpfs run tmpfs rw,nosuid,nodev,mode=0755,create=dir
# custom prompt
lxc.environment = 'PS1=\h:\w$ '
# no network
lxc.net.0.type = empty
lxc.init.cmd = @CONTAINER_INIT_MANAGER@ @CONTAINER_INIT_SCRIPT@

View File

@ -0,0 +1,17 @@
# LXC base config for custom profile on CCMP25.
# Placeholders are replaced by the image recipe.
lxc.arch = @LXC_ARCH@
lxc.rootfs.path = dir:@LXC_FOLDER@/@CONTAINER_NAME@/rootfs
lxc.uts.name = @CONTAINER_NAME@
lxc.mount.auto = cgroup:mixed proc:mixed
lxc.mount.entry = /sys sys none bind,create=dir
lxc.mount.entry = tmpfs run tmpfs rw,nosuid,nodev,mode=0755,create=dir
# custom prompt
lxc.environment = 'PS1=\h:\w$ '
# no network
lxc.net.0.type = empty
lxc.init.cmd = @CONTAINER_INIT_MANAGER@ @CONTAINER_INIT_SCRIPT@

View File

@ -0,0 +1 @@
Placeholder metadata for lvgl container artifacts.

View File

@ -0,0 +1 @@
Placeholder changelog for lvgl container artifacts.

View File

@ -0,0 +1,30 @@
# LXC config for LVGL on CCIMX95.
# Placeholders are replaced by the image recipe.
lxc.arch = @LXC_ARCH@
lxc.rootfs.path = dir:@LXC_FOLDER@/@CONTAINER_NAME@/rootfs
lxc.uts.name = @CONTAINER_NAME@
lxc.mount.auto = cgroup:mixed proc:mixed
lxc.mount.entry = /sys sys none bind,create=dir
lxc.mount.entry = tmpfs run tmpfs rw,nosuid,nodev,mode=0755,create=dir
# custom prompt
lxc.environment = 'PS1=\h:\w$ '
# no network
lxc.net.0.type = empty
lxc.init.cmd = @CONTAINER_INIT_MANAGER@ @CONTAINER_INIT_SCRIPT@
lxc.mount.entry = /dev/dri dev/dri none bind,create=dir
lxc.mount.entry = /dev/input dev/input none bind,create=dir
lxc.mount.entry = tmpfs dev/shm tmpfs rw,nosuid,nodev,mode=1777,create=dir
lxc.mount.entry = /dev/dri dev/dri none bind,create=dir
lxc.mount.entry = /dev/mali0 dev/mali0 none bind,create=file
lxc.mount.entry = /dev/input dev/input none bind,create=dir
lxc.mount.entry = /dev/tty dev/tty none bind,create=file
lxc.mount.entry = /dev/tty0 dev/tty0 none bind,create=file
lxc.mount.entry = /dev/tty1 dev/tty1 none bind,create=file
lxc.mount.entry = /dev/tty7 dev/tty7 none bind,create=file
lxc.mount.entry = /run/udev run/udev none bind,ro,create=dir
lxc.pty.max = 1024
lxc.mount.entry = devpts dev/pts devpts rw,nosuid,noexec,relatime,mode=0620,ptmxmod

View File

@ -0,0 +1,30 @@
# LXC config for LVGL on CCMP25.
# Placeholders are replaced by the image recipe.
lxc.arch = @LXC_ARCH@
lxc.rootfs.path = dir:@LXC_FOLDER@/@CONTAINER_NAME@/rootfs
lxc.uts.name = @CONTAINER_NAME@
lxc.mount.auto = cgroup:mixed proc:mixed
lxc.mount.entry = /sys sys none bind,create=dir
lxc.mount.entry = tmpfs run tmpfs rw,nosuid,nodev,mode=0755,create=dir
# custom prompt
lxc.environment = 'PS1=\h:\w$ '
# no network
lxc.net.0.type = empty
lxc.init.cmd = @CONTAINER_INIT_MANAGER@ @CONTAINER_INIT_SCRIPT@
lxc.mount.entry = tmpfs dev/shm tmpfs rw,nosuid,nodev,mode=1777,create=dir
lxc.mount.entry = /dev/dri dev/dri none bind,create=dir
lxc.mount.entry = /dev/input dev/input none bind,create=dir
lxc.mount.entry = /dev/dri dev/dri none bind,create=dir
lxc.mount.entry = /dev/galcore dev/galcore none bind,create=file
lxc.mount.entry = /dev/input dev/input none bind,create=dir
lxc.mount.entry = /dev/tty dev/tty none bind,create=file
lxc.mount.entry = /dev/tty0 dev/tty0 none bind,create=file
lxc.mount.entry = /dev/tty1 dev/tty1 none bind,create=file
lxc.mount.entry = /dev/tty7 dev/tty7 none bind,create=file
lxc.mount.entry = /run/udev run/udev none bind,ro,create=dir
lxc.pty.max = 1024
lxc.mount.entry = devpts dev/pts devpts rw,nosuid,noexec,relatime,mode=0620,ptmxmod

View File

@ -0,0 +1,26 @@
#!/bin/sh
export XDG_RUNTIME_DIR="/run/user/0"
export WAYLAND_DISPLAY="@WAYLAND_DISPLAY@"
rm -rf "$XDG_RUNTIME_DIR"
mkdir -p "$XDG_RUNTIME_DIR"
chmod 0700 "$XDG_RUNTIME_DIR"
chown root:root "$XDG_RUNTIME_DIR"
rm -rf /tmp/.X11-unix
mkdir -p /tmp/.X11-unix
chmod 1777 /tmp/.X11-unix
rm -f /tmp/weston.log
weston --backend=drm-backend.so --idle-time=0 --log=/tmp/weston.log &
while :; do
if [ -S "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" ]; then
break
fi
sleep 0.1
done
sleep 0.1
exec /usr/bin/lvgl-demo

View File

@ -0,0 +1 @@
Placeholder metadata for webkit container artifacts.

View File

@ -0,0 +1 @@
Placeholder changelog for webkit container artifacts.

View File

@ -0,0 +1,55 @@
# LXC config for WebKit on CCIMX95.
# Placeholders are replaced by the image recipe.
lxc.arch = @LXC_ARCH@
lxc.rootfs.path = dir:@LXC_FOLDER@/@CONTAINER_NAME@/rootfs
lxc.uts.name = @CONTAINER_NAME@
lxc.mount.auto = cgroup:mixed proc:mixed
lxc.mount.entry = /sys sys none bind,create=dir
lxc.mount.entry = tmpfs run tmpfs rw,nosuid,nodev,mode=0755,create=dir
# use host network
lxc.net.0.type = none
lxc.init.cmd = @CONTAINER_INIT_MANAGER@ @CONTAINER_INIT_SCRIPT@
lxc.environment = 'PS1=webkit-ccimx95:\w$ '
# audio
lxc.mount.entry = /dev/snd dev/snd none bind,create=dir
lxc.mount.entry = /etc/asound.conf etc/asound.conf none bind,create=file
lxc.mount.entry = /run/pulse run/pulse none bind,create=dir
lxc.environment = PULSE_SERVER=unix:/run/pulse/native
# bluetooth
lxc.mount.entry = /run/dbus/system_bus_socket run/dbus/system_bus_socket none bind,create=file
# python logging
lxc.mount.entry = /dev/log dev/log none bind,create=file
lxc.mount.entry = /run/systemd/journal run/systemd/journal none bind,create=dir
# fw_printenv
lxc.mount.entry = /etc/fw_env.config etc/fw_env.config none bind,create=file
lxc.mount.entry = /dev/mmcblk0boot0 dev/mmcblk0boot0 none bind,optional,create=file
lxc.mount.entry = /dev/mmcblk0boot1 dev/mmcblk0boot1 none bind,optional,create=file
# gpu for ccimx95
lxc.mount.entry = /dev/dri dev/dri none bind,create=dir
lxc.mount.entry = /dev/galcore dev/galcore none bind,create=file
lxc.mount.entry = /dev/fb0 dev/fb0 none bind,create=file
lxc.mount.entry = /dev/input dev/input none bind,create=dir
# tty
lxc.mount.entry = /dev/tty dev/tty none bind,create=file
lxc.mount.entry = /dev/tty0 dev/tty0 none bind,create=file
lxc.mount.entry = /dev/tty1 dev/tty1 none bind,create=file
lxc.mount.entry = /dev/tty7 dev/tty7 none bind,create=file
# udev + pty
lxc.mount.entry = /run/udev run/udev none bind,ro,create=dir
lxc.pty.max = 1024
lxc.mount.entry = devpts dev/pts devpts rw,nosuid,noexec,relatime,mode=0620,ptmxmode=0666,newinstance 0 0
# gpiochip access for webkit demo
# NEED TO BE UPDATED
lxc.mount.entry = /dev/gpiochip5 dev/gpiochip5 none bind,create=file
lxc.mount.entry = /dev/gpiochip5 dev/gpiochip5 none bind,create=file

View File

@ -0,0 +1,53 @@
# LXC config for WebKit on CCMP25.
# Placeholders are replaced by the image recipe.
lxc.arch = @LXC_ARCH@
lxc.rootfs.path = dir:@LXC_FOLDER@/@CONTAINER_NAME@/rootfs
lxc.uts.name = @CONTAINER_NAME@
lxc.mount.auto = cgroup:mixed proc:mixed
lxc.mount.entry = /sys sys none bind,create=dir
lxc.mount.entry = tmpfs run tmpfs rw,nosuid,nodev,mode=0755,create=dir
# use host network
lxc.net.0.type = none
lxc.init.cmd = @CONTAINER_INIT_MANAGER@ @CONTAINER_INIT_SCRIPT@
lxc.environment = 'PS1=webkit-ccmp25:\w$ '
# audio
lxc.mount.entry = /dev/snd dev/snd none bind,create=dir
lxc.mount.entry = /etc/asound.conf etc/asound.conf none bind,create=file
lxc.mount.entry = /run/pulse run/pulse none bind,create=dir
lxc.environment = PULSE_SERVER=unix:/run/pulse/native
# bluetooth
lxc.mount.entry = /run/dbus/system_bus_socket run/dbus/system_bus_socket none bind,create=file
# python logging
lxc.mount.entry = /dev/log dev/log none bind,create=file
lxc.mount.entry = /run/systemd/journal run/systemd/journal none bind,create=dir
# fw_printenv
lxc.mount.entry = /etc/fw_env.config etc/fw_env.config none bind,create=file
lxc.mount.entry = /dev/mmcblk0boot0 dev/mmcblk0boot0 none bind,create=file
lxc.mount.entry = /dev/mmcblk0boot1 dev/mmcblk0boot1 none bind,create=file
# gpu for ccmp25
lxc.mount.entry = /dev/dri dev/dri none bind,create=dir
lxc.mount.entry = /dev/galcore dev/galcore none bind,create=file
lxc.mount.entry = /dev/fb0 dev/fb0 none bind,create=file
lxc.mount.entry = /dev/input dev/input none bind,create=dir
# tty
lxc.mount.entry = /dev/tty dev/tty none bind,create=file
lxc.mount.entry = /dev/tty0 dev/tty0 none bind,create=file
lxc.mount.entry = /dev/tty1 dev/tty1 none bind,create=file
lxc.mount.entry = /dev/tty7 dev/tty7 none bind,create=file
# udev + pty
lxc.mount.entry = /run/udev run/udev none bind,ro,create=dir
lxc.pty.max = 1024
lxc.mount.entry = devpts dev/pts devpts rw,nosuid,noexec,relatime,mode=0620,ptmxmode=0666,newinstance 0 0
# gpiochip access for webkit demo
lxc.mount.entry = /dev/gpiochip5 dev/gpiochip5 none bind,create=file

View File

@ -0,0 +1,36 @@
#!/bin/sh
export XDG_RUNTIME_DIR="/run/user/0"
export WAYLAND_DISPLAY="@WAYLAND_DISPLAY@"
rm -rf "$XDG_RUNTIME_DIR"
mkdir -p "$XDG_RUNTIME_DIR"
chmod 0700 "$XDG_RUNTIME_DIR"
chown root:root "$XDG_RUNTIME_DIR"
rm -rf /tmp/.X11-unix
mkdir -p /tmp/.X11-unix
chmod 1777 /tmp/.X11-unix
rm -f /tmp/weston.log
weston --backend=drm-backend.so --idle-time=0 --log=/tmp/weston.log &
while :; do
if [ -S "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" ]; then
break
fi
sleep 0.1
done
sleep 0.1
/etc/connectcore-demo-server start
# wait for server to be ready
until nc -w 1 localhost 9090 </dev/null >/dev/null 2>&1; do
sleep 0.1
done
/etc/connectcore-demo-example-webkit start
# We need a process waiting indefinetily, if not the "init" process dies
# and there is not any remaining process
exec /usr/bin/docker-init -- sleep infinity

View File

@ -0,0 +1,153 @@
#
# Copyright (C) 2026, Digi International Inc.
#
########################
# Unified artifact bundles
########################
do_image_container_artifacts() {
lxc_bundle="${DEPLOY_DIR_IMAGE}/${LXC_OUTPUT_NAME}"
podman_archive="${DEPLOY_DIR_IMAGE}/${PODMAN_OUTPUT_NAME}"
template_dir="${CONTAINER_ARTIFACT_TEMPLATE_DIR}"
default_template_dir="${CONTAINER_DEFAULT_ARTIFACT_TEMPLATE_DIR}"
image_prefix="${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}"
workdir="$(mktemp -d)"
trap 'rm -rf "${workdir}"' EXIT
if [ -z "${template_dir}" ] && [ -d "${default_template_dir}" ]; then
template_dir="${default_template_dir}"
bbnote "Using default artifact template dir: ${default_template_dir}"
fi
if [ ! -f "${lxc_bundle}" ]; then
bbfatal "Expected LXC bundle not found: ${lxc_bundle}"
fi
if [ ! -f "${podman_archive}" ]; then
bbfatal "Expected Podman archive not found: ${podman_archive}"
fi
copy_template_files() {
artifact_dir="$1"
if [ -z "${template_dir}" ]; then
return 0
fi
if [ ! -d "${template_dir}" ]; then
bbfatal "CONTAINER_ARTIFACT_TEMPLATE_DIR does not exist: ${template_dir}"
fi
if [ -d "${template_dir}/metadata" ]; then
cp -a "${template_dir}/metadata" "${artifact_dir}/metadata"
fi
}
json_escape() {
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
}
write_manifest() {
artifact_dir="$1"
runtime="$2"
artifact_type="$3"
payload_name="$4"
digest="$5"
size_bytes="$6"
created_at="$7"
create_args="$8"
build_id="$9"
package_id_esc="$(json_escape "${CONTAINER_PACKAGE_ID}")"
version_esc="$(json_escape "${CONTAINER_ARTIFACT_VERSION}")"
create_args_esc="$(json_escape "${create_args}")"
fw_versions_esc="$(json_escape "${CONTAINER_FIRMWARE_VERSIONS}")"
description_esc="$(json_escape "${CONTAINER_ARTIFACT_DESCRIPTION}")"
build_id_esc="$(json_escape "${build_id}")"
printf '%s\n' \
'{' \
" \"package_id\": \"${package_id_esc}\"," \
" \"version\": \"${version_esc}\"," \
" \"runtime\": \"${runtime}\"," \
" \"artifact_type\": \"${artifact_type}\"," \
> "${artifact_dir}/manifest.json"
if [ -n "${create_args}" ]; then
printf '%s\n' " \"create_args\": \"${create_args_esc}\"," >> "${artifact_dir}/manifest.json"
fi
printf '%s\n' \
" \"created_at\": \"${created_at}\"," \
" \"digest\": \"sha256:${digest}\"," \
" \"device_types\": ${CONTAINER_DEVICE_TYPES_JSON}," \
" \"firmware_versions\": \"${fw_versions_esc}\"," \
" \"size_bytes\": ${size_bytes}," \
" \"build_id\": \"${build_id_esc}\"," \
" \"description\": \"${description_esc}\"," \
" \"labels\": ${CONTAINER_ARTIFACT_LABELS_JSON}" \
'}' \
>> "${artifact_dir}/manifest.json"
}
create_artifact_bundle() {
runtime="$1"
src_payload="$2"
payload_name="$3"
output_name="$4"
mode="$5"
artifact_type="$6"
create_args="$7"
bundle_dir="${workdir}/bundle-${runtime}"
artifact_dir="${bundle_dir}"
rm -rf "${bundle_dir}"
mkdir -p "${artifact_dir}/payload" "${artifact_dir}/checksums"
copy_template_files "${artifact_dir}"
if [ "${mode}" = "lxc" ]; then
lxc_unpack="${workdir}/lxc-unpack"
rm -rf "${lxc_unpack}"
mkdir -p "${lxc_unpack}"
tar -xJf "${src_payload}" -C "${lxc_unpack}"
if [ ! -d "${lxc_unpack}/${CONTAINER_NAME}/rootfs" ] || [ ! -f "${lxc_unpack}/${CONTAINER_NAME}/config" ]; then
bbfatal "LXC bundle does not contain expected ${CONTAINER_NAME}/rootfs and ${CONTAINER_NAME}/config"
fi
tar -C "${lxc_unpack}/${CONTAINER_NAME}" \
-czf "${artifact_dir}/payload/${payload_name}" \
rootfs config
else
cp "${src_payload}" "${artifact_dir}/payload/${payload_name}"
fi
digest="$(sha256sum "${artifact_dir}/payload/${payload_name}" | awk '{print $1}')"
size_bytes="$(stat -c %s "${artifact_dir}/payload/${payload_name}")"
created_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
build_id="${CONTAINER_ARTIFACT_BUILD_ID}"
if [ -z "${build_id}" ]; then
if command -v git >/dev/null 2>&1; then
build_id="$(git -C "${META_DIGI_REPO_DIR}" rev-parse HEAD 2>/dev/null || true)"
fi
fi
printf '%s %s\n' "${digest}" "payload/${payload_name}" > "${artifact_dir}/checksums/sha256sums.txt"
write_manifest "${artifact_dir}" "${runtime}" "${artifact_type}" "${payload_name}" "${digest}" "${size_bytes}" "${created_at}" "${create_args}" "${build_id}"
tar -C "${bundle_dir}" -czf "${DEPLOY_DIR_IMAGE}/${output_name}" .
if [ ! -s "${DEPLOY_DIR_IMAGE}/${output_name}" ]; then
bbfatal "Container artifact bundle not generated correctly: ${DEPLOY_DIR_IMAGE}/${output_name}"
fi
bbnote "Container ${runtime} artifact ready: ${DEPLOY_DIR_IMAGE}/${output_name}"
}
create_artifact_bundle "lxc" "${lxc_bundle}" "rootfs_and_config.tgz" "${LXC_ARTIFACT_OUTPUT_NAME}" "lxc" "lxc-tgz" ""
create_artifact_bundle "podman" "${podman_archive}" "image.tar" "${PODMAN_ARTIFACT_OUTPUT_NAME}" "podman" "podman-image-tar" "${CONTAINER_CREATE_ARGS_PODMAN}"
bbnote "Removing intermediate container artifacts from this build..."
rm -f "${lxc_bundle}" "${podman_archive}"
rm -f "${image_prefix}.tar.xz" "${image_prefix}.rootfs-oci.tar" "${image_prefix}.rootfs-oci-dir.tar"
rm -rf "${image_prefix}.rootfs-oci"
}
addtask image_container_artifacts after do_image_lxc_bundle do_image_podman_archive before do_build

View File

@ -25,7 +25,7 @@ do_image_lxc_bundle() {
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}"
bbfatal "LXC config file not found for CONTAINER_TYPE='${CONTAINER_TYPE}' and MACHINE='${MACHINE}': ${config_in}"
fi
sed \

View File

@ -48,11 +48,10 @@ PODMAN_ARTIFACT_OUTPUT_NAME ?= "${CONTAINER_NAME}_artifact_podman_${MACHINE}.tar
########################
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}"
LXC_CONFIG_FILE ?= "${LXC_CONFIG_DIR}/config_lxc_${MACHINE}"
########################
# Artifact layout knobs
@ -95,3 +94,33 @@ IMAGE_INSTALL = " \
netbase \
tini \
"
########################
# Container type customizations LVGL
########################
CONTAINER_INIT_SCRIPT:container-lvgl = "/start-lvgl-demo.sh"
IMAGE_INSTALL:append:container-lvgl = " lvgl-demo weston"
DISTRO_FEATURES:remove:container-lvgl = " wayland"
########################
# Container type customizations webkit
########################
CONTAINER_INIT_SCRIPT:container-webkit = "/start-webkit-demo.sh"
IMAGE_INSTALL:append:container-webkit = " \
alsa-utils \
bluez5 \
connectcore-demo-example \
dbus \
libdrm \
libgpiod-tools \
libinput \
libubootenv-bin \
mesa \
networkmanager-nmcli \
packagegroup-dey-webkit \
pulseaudio-server \
python3-dbus \
wayland \
wayland-protocols \
weston \
"