summaryrefslogtreecommitdiffstats
path: root/recipes-containers
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2026-02-09 03:19:29 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2026-02-09 03:34:12 +0000
commitff406688aef6eb0e89cfcb6698734a7e9e1e001c (patch)
tree116acc2dd06fd116d4d6f13ee91bcf81a8013bca /recipes-containers
parentd04103169c462913a68e7346e4f78682b74d93f0 (diff)
downloadmeta-virtualization-ff406688aef6eb0e89cfcb6698734a7e9e1e001c.tar.gz
container-registry: add tests and documentation for secure registry
Add comprehensive test coverage and documentation for the secure registry infrastructure. Tests added: TestRegistryAuthentication - auth modes (none, home, authfile, credsfile, env, creds, token) for push and import TestSecureRegistryTLSOnly - TLS-only mode using running registry TestSecureRegistryWithAuth - isolated TLS+auth instance on port 5001 TestDockerRegistryConfig - static analysis of bbclass/recipe logic TestContainerCrossInstallSecure - auto IMAGE_INSTALL verification TestVcontainerSecureRegistry - script pattern verification for virtio-9p CA transport, daemon _9p=1, shared folder reads README.md: Document authentication modes (none, home, authfile, credsfile, env), secure registry setup, PKI generation, target integration, and CI/CD examples. conftest.py: Add --secure-registry pytest option and skip_secure fixture for tests requiring openssl/htpasswd. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'recipes-containers')
-rw-r--r--recipes-containers/container-registry/README.md245
1 files changed, 244 insertions, 1 deletions
diff --git a/recipes-containers/container-registry/README.md b/recipes-containers/container-registry/README.md
index 1a0f74eb..470442b9 100644
--- a/recipes-containers/container-registry/README.md
+++ b/recipes-containers/container-registry/README.md
@@ -171,6 +171,247 @@ DOCKER_REGISTRY_INSECURE = "localhost:5000"
171CONTAINER_REGISTRY_STORAGE = "/data/container-registry" 171CONTAINER_REGISTRY_STORAGE = "/data/container-registry"
172``` 172```
173 173
174## Authentication
175
176Support for pushing to authenticated registries (Docker Hub, GitHub Container Registry, private registries).
177
178### Authentication Modes
179
180| Mode | BitBake | Script | Description |
181|------|---------|--------|-------------|
182| `none` | Yes | Yes | No authentication (default, local registries) |
183| `home` | Yes | Yes | Use `~/.docker/config.json` (opt-in) |
184| `authfile` | Yes | Yes | Explicit Docker-style config.json path |
185| `credsfile` | Yes | Yes | Simple key=value credentials file |
186| `env` | No | Yes | Environment variables (script only) |
187
188### BitBake Configuration
189
190```bitbake
191# Authentication mode
192CONTAINER_REGISTRY_AUTH_MODE = "none" # Default, no auth
193CONTAINER_REGISTRY_AUTH_MODE = "home" # Use ~/.docker/config.json
194CONTAINER_REGISTRY_AUTH_MODE = "authfile" # Explicit auth file
195CONTAINER_REGISTRY_AUTH_MODE = "credsfile" # Simple credentials file
196
197# For authfile mode
198CONTAINER_REGISTRY_AUTHFILE = "/path/to/docker-config.json"
199
200# For credsfile mode
201CONTAINER_REGISTRY_CREDSFILE = "${HOME}/.config/container-registry/credentials"
202```
203
204### Script Options
205
206```bash
207# Use existing Docker login (~/.docker/config.json)
208container-registry.sh push --use-home-auth
209
210# Explicit auth file
211container-registry.sh push --authfile /path/to/docker-config.json
212
213# Simple credentials file
214container-registry.sh push --credsfile ~/.config/container-registry/credentials
215
216# Environment variables
217export CONTAINER_REGISTRY_AUTH_MODE=env
218export CONTAINER_REGISTRY_TOKEN=ghp_xxxxx
219container-registry.sh push
220
221# Direct credentials (less secure - in shell history)
222container-registry.sh push --creds user:password
223container-registry.sh push --token ghp_xxxxx
224
225# Import from authenticated source registry
226container-registry.sh import ghcr.io/org/private:v1 --src-authfile ~/.docker/config.json
227container-registry.sh import ghcr.io/org/private:v1 --src-credsfile ~/.config/ghcr-creds
228```
229
230### Credentials File Format
231
232Simple key=value format (not checked into source control):
233
234```bash
235# ~/.config/container-registry/credentials
236# Username/password OR token (token takes precedence)
237CONTAINER_REGISTRY_USER=myuser
238CONTAINER_REGISTRY_PASSWORD=mypassword
239
240# Or for token-based auth (GitHub, GitLab, etc.):
241CONTAINER_REGISTRY_TOKEN=ghp_xxxxxxxxxxxx
242```
243
244Create with proper permissions:
245```bash
246mkdir -p ~/.config/container-registry
247cat > ~/.config/container-registry/credentials << 'EOF'
248CONTAINER_REGISTRY_TOKEN=ghp_xxxxxxxxxxxx
249EOF
250chmod 600 ~/.config/container-registry/credentials
251```
252
253### CI/CD Integration
254
255For CI/CD with BitBake, use `credsfile` mode and have CI write the credentials file:
256
257```yaml
258# Example GitHub Actions
259- name: Setup registry credentials
260 run: |
261 mkdir -p ~/.config/container-registry
262 echo "CONTAINER_REGISTRY_TOKEN=${{ secrets.GHCR_TOKEN }}" > ~/.config/container-registry/credentials
263 chmod 600 ~/.config/container-registry/credentials
264
265- name: Build and push
266 run: |
267 bitbake container-base
268 ./container-registry/container-registry.sh push --credsfile ~/.config/container-registry/credentials
269```
270
271For script-only usage, environment variables are simpler:
272
273```yaml
274- name: Push to registry
275 env:
276 CONTAINER_REGISTRY_AUTH_MODE: env
277 CONTAINER_REGISTRY_TOKEN: ${{ secrets.GHCR_TOKEN }}
278 run: ./container-registry/container-registry.sh push
279```
280
281### Security Notes
282
283- **No credentials in BitBake variables**: Like git fetcher, avoid passwords in metadata that gets logged/shared
284- **Use file-based auth**: Credentials files can be excluded from version control and have proper permissions
285- **Opt-in for home directory**: `home` mode requires explicit opt-in (like `BB_USE_HOME_NPMRC`)
286- **Prefer tokens over passwords**: Tokens can be scoped and revoked
287
288## Secure Registry Mode
289
290Enable TLS and authentication for the local registry (opt-in).
291
292### Configuration
293
294```bitbake
295# Enable secure mode
296CONTAINER_REGISTRY_SECURE = "1"
297
298# Optional: custom username (default: yocto)
299CONTAINER_REGISTRY_USERNAME = "myuser"
300
301# Optional: explicit password (default: auto-generate)
302CONTAINER_REGISTRY_PASSWORD = "mypassword"
303
304# Optional: certificate validity (days)
305CONTAINER_REGISTRY_CERT_DAYS = "365" # Server cert
306CONTAINER_REGISTRY_CA_DAYS = "3650" # CA cert (10 years)
307
308# Optional: additional SAN entries for server cert
309CONTAINER_REGISTRY_CERT_SAN = "DNS:myhost.local,IP:192.168.1.100"
310```
311
312### Setup
313
314PKI (CA and server certificates) is auto-generated during the bitbake build:
315
316```bash
317# Generate script AND PKI infrastructure
318bitbake container-registry-index -c generate_registry_script
319
320# Build target image (CA cert is automatically baked in)
321bitbake container-image-host
322```
323
324The `generate_registry_script` task automatically generates the PKI if it doesn't exist. No manual steps required.
325
326### Starting the Registry
327
328To actually run the registry (for pushing/pulling images):
329
330```bash
331# Start registry (generates htpasswd auth on first run)
332./container-registry/container-registry.sh start
333```
334
335Output:
336```
337Setting up authentication...
338 Password saved to: .../auth/password
339Starting SECURE container registry...
340 URL: https://localhost:5000
341```
342
343### Generated Files
344
345```
346${CONTAINER_REGISTRY_STORAGE}/
347├── pki/ # Generated by: bitbake ... -c generate_registry_script
348│ ├── ca.key # CA private key (600)
349│ ├── ca.crt # CA certificate - baked into target images
350│ ├── server.key # Server private key (600)
351│ └── server.crt # Server certificate with SAN
352├── auth/ # Generated by: container-registry.sh start
353│ ├── htpasswd # Bcrypt credentials for registry
354│ └── password # Plaintext password for reference (600)
355└── ...
356```
357
358### Push (auto-uses credentials)
359
360```bash
361./container-registry/container-registry.sh push
362# Automatically uses:
363# --dest-cert-dir=.../pki
364# --dest-creds=yocto:<auto-password>
365```
366
367### Target Integration
368
369Install CA certificate on target images:
370
371```bitbake
372# Automatically included when CONTAINER_REGISTRY_SECURE = "1"
373# and IMAGE_FEATURES:append = " container-registry"
374IMAGE_INSTALL:append = " container-registry-ca"
375```
376
377This installs CA cert to:
378- `/etc/docker/certs.d/{registry}/ca.crt` (Docker)
379- `/etc/containers/certs.d/{registry}/ca.crt` (Podman/CRI-O)
380- `/usr/local/share/ca-certificates/container-registry-ca.crt` (system)
381
382### vdkr with Secure Registry
383
384```bash
385# Pass secure mode and CA cert to VM
386vdkr --secure-registry --ca-cert $STORAGE/pki/ca.crt pull myimage
387
388# Or with credentials
389vdkr --secure-registry --ca-cert $STORAGE/pki/ca.crt \
390 --registry-user yocto --registry-password mypass pull myimage
391```
392
393### Verification
394
395```bash
396# Verify TLS with curl
397curl --cacert $STORAGE/pki/ca.crt \
398 -u yocto:$(cat $STORAGE/auth/password) \
399 https://localhost:5000/v2/_catalog
400
401# Check server certificate SAN
402openssl x509 -in $STORAGE/pki/server.crt -noout -text | grep -A1 "Subject Alternative Name"
403```
404
405### Secure Mode vs Insecure Mode
406
407| Feature | Insecure (`SECURE=0`) | Secure (`SECURE=1`) |
408|---------|----------------------|---------------------|
409| Protocol | HTTP | HTTPS |
410| TLS | None | Self-signed CA + server cert |
411| Auth | Optional | Required (htpasswd) |
412| Target config | `insecure-registries` | CA cert distribution |
413| Skopeo args | `--dest-tls-verify=false` | `--dest-cert-dir` |
414
174## vdkr Registry Usage 415## vdkr Registry Usage
175 416
176### Pull Behavior with Registry Fallback 417### Pull Behavior with Registry Fallback
@@ -233,9 +474,11 @@ This installs:
233|------|-------------| 474|------|-------------|
234| `container-registry-index.bb` | Generates helper script with baked-in paths | 475| `container-registry-index.bb` | Generates helper script with baked-in paths |
235| `container-registry-populate.bb` | Alternative bitbake-driven push | 476| `container-registry-populate.bb` | Alternative bitbake-driven push |
477| `container-registry-ca.bb` | Target package for CA certificate (secure mode) |
236| `container-oci-registry-config.bb` | OCI tools config (Podman/Skopeo/Buildah/CRI-O) | 478| `container-oci-registry-config.bb` | OCI tools config (Podman/Skopeo/Buildah/CRI-O) |
237| `docker-registry-config.bb` | Docker daemon config | 479| `docker-registry-config.bb` | Docker daemon config |
238| `files/container-registry-dev.yml` | Development registry config | 480| `files/container-registry-dev.yml` | Development registry config (HTTP) |
481| `files/container-registry-secure.yml` | Secure registry config template (HTTPS+auth) |
239 482
240## Storage 483## Storage
241 484