diff options
| author | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-06-12 17:13:19 +0000 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-06-12 17:13:19 +0000 |
| commit | 27e41b91d68d4adb6cd967871c59fd1e32830fe6 (patch) | |
| tree | 5c77d108211652dea8e4fcc9105736e20704b84e /docs | |
| parent | 5470cd0a37044ef316bec00cc5c476b39876179c (diff) | |
| download | meta-virtualization-27e41b91d68d4adb6cd967871c59fd1e32830fe6.tar.gz | |
docs/container-bundling: refresh multi-layer mode section
Three related updates to the multi-layer documentation, all driven by
patterns that came up reviewing recent OCI image recipes:
- Drop the "IMAGE_INSTALL must include all packages to trigger
builds" guidance from the example. As of the matching bbclass
change, image-oci.bbclass folds OCI_LAYERS packages: entries into
IMAGE_INSTALL automatically, so recipes only set the package list
once. The example used to demonstrate the dual-source-of-truth
workaround for the original limitation; with the limitation gone
the example was actively misleading.
- Add a "Conditional Packages per Layer" subsection documenting the
bb.utils.contains() pattern for adding/omitting packages from a
packages: layer based on PACKAGECONFIG (or any other variable),
without duplicating the whole OCI_LAYERS declaration in two
branches. This is a real, useful idiom that recipes have started
using; previously undocumented.
- Fill in the "host" layer type row in the layer-type table. The
type was already supported and explained in image-oci.bbclass
inline docs, but the user-facing reference table only listed
packages / directories / files.
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/container-bundling.md | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/docs/container-bundling.md b/docs/container-bundling.md index f4587a99..0a0209ec 100644 --- a/docs/container-bundling.md +++ b/docs/container-bundling.md | |||
| @@ -155,11 +155,15 @@ Create explicit layers with fine-grained control: | |||
| 155 | app:packages:curl \ | 155 | app:packages:curl \ |
| 156 | " | 156 | " |
| 157 | 157 | ||
| 158 | # IMAGE_INSTALL must include all packages to trigger builds | ||
| 159 | IMAGE_INSTALL = "base-files base-passwd netbase busybox curl" | ||
| 160 | |||
| 161 | Result: 3 layers (base, shell, app) | 158 | Result: 3 layers (base, shell, app) |
| 162 | 159 | ||
| 160 | Packages named in any `packages:` layer are automatically folded into | ||
| 161 | `IMAGE_INSTALL`, so do_rootfs's recrdeptask builds them. You do not | ||
| 162 | need to repeat the package list in `IMAGE_INSTALL`. If a recipe needs | ||
| 163 | additional packages that aren't part of any final layer (e.g. for a | ||
| 164 | rootfs-only postprocess fixup), it can still add to `IMAGE_INSTALL` | ||
| 165 | itself — the auto-derivation is additive. | ||
| 166 | |||
| 163 | #### Layer Definition Format | 167 | #### Layer Definition Format |
| 164 | 168 | ||
| 165 | name:type:content | 169 | name:type:content |
| @@ -169,6 +173,7 @@ Result: 3 layers (base, shell, app) | |||
| 169 | | `packages` | `pkg1+pkg2+pkg3` | Install packages (use + delimiter) | | 173 | | `packages` | `pkg1+pkg2+pkg3` | Install packages (use + delimiter) | |
| 170 | | `directories` | `/path1+/path2` | Copy directories from IMAGE_ROOTFS | | 174 | | `directories` | `/path1+/path2` | Copy directories from IMAGE_ROOTFS | |
| 171 | | `files` | `/file1+/file2` | Copy specific files from IMAGE_ROOTFS | | 175 | | `files` | `/file1+/file2` | Copy specific files from IMAGE_ROOTFS | |
| 176 | | `host` | `src:dst+src:dst` | Copy from build machine (sparingly — see below) | | ||
| 172 | 177 | ||
| 173 | #### Example Recipes | 178 | #### Example Recipes |
| 174 | 179 | ||
| @@ -180,7 +185,6 @@ OCI_LAYERS = "\ | |||
| 180 | python:packages:python3+python3-pip \ | 185 | python:packages:python3+python3-pip \ |
| 181 | app:directories:/opt/myapp \ | 186 | app:directories:/opt/myapp \ |
| 182 | " | 187 | " |
| 183 | IMAGE_INSTALL = "base-files base-passwd netbase python3 python3-pip myapp" | ||
| 184 | ``` | 188 | ``` |
| 185 | 189 | ||
| 186 | **Two-layer with base image + multi-layer app:** | 190 | **Two-layer with base image + multi-layer app:** |
| @@ -193,6 +197,33 @@ OCI_LAYERS = "\ | |||
| 193 | " | 197 | " |
| 194 | ``` | 198 | ``` |
| 195 | 199 | ||
| 200 | #### Conditional Packages per Layer | ||
| 201 | |||
| 202 | Use `${@bb.utils.contains(...)}` directly inside a layer's package list | ||
| 203 | to add or omit packages based on `PACKAGECONFIG` (or any other | ||
| 204 | distro/recipe variable) without duplicating the whole `OCI_LAYERS` | ||
| 205 | declaration in two branches: | ||
| 206 | |||
| 207 | ```bitbake | ||
| 208 | PACKAGECONFIG ??= "" | ||
| 209 | PACKAGECONFIG[dev] = "" | ||
| 210 | |||
| 211 | OCI_LAYER_MODE = "multi" | ||
| 212 | OCI_LAYERS = "\ | ||
| 213 | base:packages:base-files+base-passwd+netbase \ | ||
| 214 | python:packages:python3+coreutils${@bb.utils.contains('PACKAGECONFIG', 'dev', '+python3-pip', '', d)} \ | ||
| 215 | " | ||
| 216 | ``` | ||
| 217 | |||
| 218 | The expression expands to `+python3-pip` when `dev` is enabled and to | ||
| 219 | nothing otherwise. Because the `+` delimiter is folded into the | ||
| 220 | substituted text, the resulting layer string is well-formed in both | ||
| 221 | cases (`python3+coreutils` or `python3+coreutils+python3-pip`). | ||
| 222 | |||
| 223 | This composes with the auto-derivation above: `python3-pip` is added to | ||
| 224 | `IMAGE_INSTALL` only when the `dev` config is active, exactly as if you | ||
| 225 | had written it out by hand. | ||
| 226 | |||
| 196 | ### Layer Caching | 227 | ### Layer Caching |
| 197 | 228 | ||
| 198 | Multi-layer builds cache pre-installed package layers for faster rebuilds. | 229 | Multi-layer builds cache pre-installed package layers for faster rebuilds. |
