summaryrefslogtreecommitdiffstats
path: root/classes/container-bundle.bbclass
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2026-02-06 03:54:16 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2026-02-09 03:34:12 +0000
commitcd5081a5e9ff1c6f5eb74ab90326d602142248f9 (patch)
tree942b4954cb73e217d5c914d381d262b231ee8ab8 /classes/container-bundle.bbclass
parentb4ad3f9eb2f022b6f69b2e78dbca80974d5bf84a (diff)
downloadmeta-virtualization-cd5081a5e9ff1c6f5eb74ab90326d602142248f9.tar.gz
container-cross-install: add CONTAINER_SERVICE_FILE support
Add support for custom systemd service files (Docker) or Quadlet container files (Podman) instead of auto-generated ones for container autostart. For containers requiring specific startup configuration (ports, volumes, capabilities, dependencies), users can now provide custom service files using the CONTAINER_SERVICE_FILE varflag: CONTAINER_SERVICE_FILE[container-name] = "${UNPACKDIR}/myservice.service" For BUNDLED_CONTAINERS in image recipes: SRC_URI += "file://myapp.service" BUNDLED_CONTAINERS = "myapp-container:docker:autostart" CONTAINER_SERVICE_FILE[myapp-container] = "${UNPACKDIR}/myapp.service" For container-bundle packages: SRC_URI = "file://myapp.service" CONTAINER_BUNDLES = "myapp-container:autostart" CONTAINER_SERVICE_FILE[myapp-container] = "${UNPACKDIR}/myapp.service" Implementation: - container-cross-install.bbclass: Add get_container_service_file_map() to build varflag map, install_custom_service() for BUNDLED_CONTAINERS, and install_custom_service_from_bundle() for bundle packages - container-bundle.bbclass: Install custom service files to ${datadir}/container-bundles/${runtime}/services/ Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'classes/container-bundle.bbclass')
-rw-r--r--classes/container-bundle.bbclass80
1 files changed, 80 insertions, 0 deletions
diff --git a/classes/container-bundle.bbclass b/classes/container-bundle.bbclass
index 3d3f3a16..3c8ad030 100644
--- a/classes/container-bundle.bbclass
+++ b/classes/container-bundle.bbclass
@@ -141,6 +141,30 @@
141# The runtime subdirectory (docker/ vs podman/) tells container-cross-install 141# The runtime subdirectory (docker/ vs podman/) tells container-cross-install
142# which vrunner runtime to use for import. 142# which vrunner runtime to use for import.
143# 143#
144# ===========================================================================
145# Custom Service Files (CONTAINER_SERVICE_FILE)
146# ===========================================================================
147#
148# For containers requiring specific startup configuration, provide custom
149# service files instead of auto-generated ones:
150#
151# SRC_URI = "file://myapp.service file://mydb.container"
152#
153# CONTAINER_BUNDLES = "\
154# myapp-container:autostart \
155# mydb-container:autostart \
156# "
157#
158# CONTAINER_SERVICE_FILE[myapp-container] = "${UNPACKDIR}/myapp.service"
159# CONTAINER_SERVICE_FILE[mydb-container] = "${UNPACKDIR}/mydb.container"
160#
161# Custom files are installed to ${datadir}/container-bundles/${RUNTIME}/services/
162# and used by container-cross-install instead of generating default services.
163#
164# For Docker, provide a .service file; for Podman, provide a .container Quadlet.
165#
166# See docs/container-bundling.md for detailed examples.
167#
144# See also: container-cross-install.bbclass 168# See also: container-cross-install.bbclass
145 169
146CONTAINER_BUNDLES ?= "" 170CONTAINER_BUNDLES ?= ""
@@ -247,6 +271,29 @@ python __anonymous() {
247 d.setVar('_REMOTE_CONTAINERS', ' '.join(remote_urls)) 271 d.setVar('_REMOTE_CONTAINERS', ' '.join(remote_urls))
248 d.setVar('_PROCESSED_BUNDLES', ' '.join(processed_bundles)) 272 d.setVar('_PROCESSED_BUNDLES', ' '.join(processed_bundles))
249 d.setVar('_BUNDLE_RUNTIME', runtime) 273 d.setVar('_BUNDLE_RUNTIME', runtime)
274
275 # Build service file map for custom service files
276 # Format: container1=/path/to/file1;container2=/path/to/file2
277 service_mappings = []
278 for bundle in bundles:
279 # Extract container name (handle both local and remote formats)
280 if is_remote_container(bundle):
281 if bundle.endswith(':autostart') or bundle.endswith(':always') or \
282 bundle.endswith(':unless-stopped') or bundle.endswith(':on-failure') or \
283 bundle.endswith(':no'):
284 last_colon = bundle.rfind(':')
285 source = bundle[:last_colon]
286 else:
287 source = bundle
288 else:
289 parts = bundle.split(':')
290 source = parts[0]
291
292 custom_file = d.getVarFlag('CONTAINER_SERVICE_FILE', source)
293 if custom_file:
294 service_mappings.append(f"{source}={custom_file}")
295
296 d.setVar('_CONTAINER_SERVICE_FILE_MAP', ';'.join(service_mappings))
250} 297}
251 298
252# S must be a real directory 299# S must be a real directory
@@ -402,6 +449,39 @@ do_install() {
402 install -m 0644 ${B}/bundle-metadata.txt \ 449 install -m 0644 ${B}/bundle-metadata.txt \
403 ${D}${datadir}/container-bundles/${PN}.meta 450 ${D}${datadir}/container-bundles/${PN}.meta
404 fi 451 fi
452
453 # Install custom service files from CONTAINER_SERVICE_FILE varflags
454 # Format: container1=/path/to/file1;container2=/path/to/file2
455 if [ -n "${_CONTAINER_SERVICE_FILE_MAP}" ]; then
456 install -d ${D}${datadir}/container-bundles/${RUNTIME}/services
457 echo "${_CONTAINER_SERVICE_FILE_MAP}" | tr ';' '\n' | while IFS='=' read -r container_name service_file; do
458 [ -z "$container_name" ] && continue
459 [ -z "$service_file" ] && continue
460
461 if [ ! -f "$service_file" ]; then
462 bbwarn "Custom service file not found: $service_file (for container $container_name)"
463 continue
464 fi
465
466 # Sanitize container name for filename (replace / and : with _)
467 local sanitized_name=$(echo "$container_name" | sed 's|[/:]|_|g')
468
469 # Determine file extension based on runtime and source file
470 local dest_file
471 if [ "${RUNTIME}" = "docker" ]; then
472 dest_file="${sanitized_name}.service"
473 elif [ "${RUNTIME}" = "podman" ]; then
474 dest_file="${sanitized_name}.container"
475 else
476 # Keep original extension
477 dest_file="${sanitized_name}.$(echo "$service_file" | sed 's/.*\.//')"
478 fi
479
480 bbnote "Installing custom service file: $service_file -> services/${dest_file}"
481 install -m 0644 "$service_file" \
482 ${D}${datadir}/container-bundles/${RUNTIME}/services/${dest_file}
483 done
484 fi
405} 485}
406 486
407FILES:${PN} = "${datadir}/container-bundles" 487FILES:${PN} = "${datadir}/container-bundles"