diff options
| author | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-02-09 03:17:37 +0000 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-02-09 03:34:12 +0000 |
| commit | 7297ba3aeba2cef546c9245b2b6ae1139568cf40 (patch) | |
| tree | 44aaa859e1641b057dd39a9c46bf8321db50ca24 /recipes-containers | |
| parent | 52fc4ca7c75594fe8b3c92a9f88df19f8f4d0944 (diff) | |
| download | meta-virtualization-7297ba3aeba2cef546c9245b2b6ae1139568cf40.tar.gz | |
vcontainer: add secure registry support with virtio-9p CA transport
Enable vdkr/vcontainer to pull from TLS-secured registries by
transporting the CA certificate via virtio-9p shared folder.
vcontainer-common.sh: Add --secure-registry, --ca-cert, --registry-user,
--registry-password CLI options. Auto-detect bundled CA cert at
registry/ca.crt in the tarball and enable secure mode automatically.
vrunner.sh: Copy CA cert to the virtio-9p shared folder for both
daemon and non-daemon modes. Fix daemon mode missing _9p=1 kernel
cmdline parameter which prevented the init script from mounting the
shared folder.
vdkr-init.sh: Read CA cert from /mnt/share/ca.crt (virtio-9p) instead
of base64-decoding from kernel cmdline (which caused truncation for
large certificates). Install cert to /etc/docker/certs.d/{host}/ca.crt
for Docker TLS verification. Support optional credential passing for
authenticated registries.
vcontainer-tarball.bb: Add script files to SRC_URI for proper file
tracking and rebuild triggers.
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'recipes-containers')
| -rwxr-xr-x | recipes-containers/vcontainer/files/vcontainer-common.sh | 34 | ||||
| -rwxr-xr-x | recipes-containers/vcontainer/files/vdkr-init.sh | 127 | ||||
| -rwxr-xr-x | recipes-containers/vcontainer/files/vrunner.sh | 63 | ||||
| -rw-r--r-- | recipes-containers/vcontainer/vcontainer-tarball.bb | 28 |
4 files changed, 246 insertions, 6 deletions
diff --git a/recipes-containers/vcontainer/files/vcontainer-common.sh b/recipes-containers/vcontainer/files/vcontainer-common.sh index 792bd7a2..cb48e1bb 100755 --- a/recipes-containers/vcontainer/files/vcontainer-common.sh +++ b/recipes-containers/vcontainer/files/vcontainer-common.sh | |||
| @@ -752,6 +752,12 @@ build_runner_args() { | |||
| 752 | args+=("--insecure-registry" "$reg") | 752 | args+=("--insecure-registry" "$reg") |
| 753 | done | 753 | done |
| 754 | 754 | ||
| 755 | # Add secure registry options | ||
| 756 | [ "$SECURE_REGISTRY" = "true" ] && args+=("--secure-registry") | ||
| 757 | [ -n "$CA_CERT" ] && args+=("--ca-cert" "$CA_CERT") | ||
| 758 | [ -n "$REGISTRY_USER" ] && args+=("--registry-user" "$REGISTRY_USER") | ||
| 759 | [ -n "$REGISTRY_PASS" ] && args+=("--registry-pass" "$REGISTRY_PASS") | ||
| 760 | |||
| 755 | echo "${args[@]}" | 761 | echo "${args[@]}" |
| 756 | } | 762 | } |
| 757 | 763 | ||
| @@ -767,9 +773,21 @@ DISABLE_KVM="false" | |||
| 767 | NO_DAEMON="false" | 773 | NO_DAEMON="false" |
| 768 | REGISTRY="" | 774 | REGISTRY="" |
| 769 | INSECURE_REGISTRIES=() | 775 | INSECURE_REGISTRIES=() |
| 776 | SECURE_REGISTRY="false" | ||
| 777 | CA_CERT="" | ||
| 778 | REGISTRY_USER="" | ||
| 779 | REGISTRY_PASS="" | ||
| 770 | COMMAND="" | 780 | COMMAND="" |
| 771 | COMMAND_ARGS=() | 781 | COMMAND_ARGS=() |
| 772 | 782 | ||
| 783 | # Auto-detect bundled CA certificate for secure registry | ||
| 784 | # If CA cert is bundled in the tarball, automatically enable secure mode | ||
| 785 | BUNDLED_CA_CERT="$SCRIPT_DIR/registry/ca.crt" | ||
| 786 | if [ -f "$BUNDLED_CA_CERT" ]; then | ||
| 787 | SECURE_REGISTRY="true" | ||
| 788 | CA_CERT="$BUNDLED_CA_CERT" | ||
| 789 | fi | ||
| 790 | |||
| 773 | while [ $# -gt 0 ]; do | 791 | while [ $# -gt 0 ]; do |
| 774 | case $1 in | 792 | case $1 in |
| 775 | --arch|-a) | 793 | --arch|-a) |
| @@ -840,6 +858,22 @@ while [ $# -gt 0 ]; do | |||
| 840 | INSECURE_REGISTRIES+=("$2") | 858 | INSECURE_REGISTRIES+=("$2") |
| 841 | shift 2 | 859 | shift 2 |
| 842 | ;; | 860 | ;; |
| 861 | --secure-registry) | ||
| 862 | SECURE_REGISTRY="true" | ||
| 863 | shift | ||
| 864 | ;; | ||
| 865 | --ca-cert) | ||
| 866 | CA_CERT="$2" | ||
| 867 | shift 2 | ||
| 868 | ;; | ||
| 869 | --registry-user) | ||
| 870 | REGISTRY_USER="$2" | ||
| 871 | shift 2 | ||
| 872 | ;; | ||
| 873 | --registry-password|--registry-pass) | ||
| 874 | REGISTRY_PASS="$2" | ||
| 875 | shift 2 | ||
| 876 | ;; | ||
| 843 | -it|--interactive) | 877 | -it|--interactive) |
| 844 | INTERACTIVE="true" | 878 | INTERACTIVE="true" |
| 845 | shift | 879 | shift |
diff --git a/recipes-containers/vcontainer/files/vdkr-init.sh b/recipes-containers/vcontainer/files/vdkr-init.sh index 084a8791..a993aca4 100755 --- a/recipes-containers/vcontainer/files/vdkr-init.sh +++ b/recipes-containers/vcontainer/files/vdkr-init.sh | |||
| @@ -22,8 +22,12 @@ | |||
| 22 | # docker_network=1 Enable networking (configure eth0, DNS) | 22 | # docker_network=1 Enable networking (configure eth0, DNS) |
| 23 | # docker_registry=<url> Default registry for unqualified images (e.g., 10.0.2.2:5000/yocto) | 23 | # docker_registry=<url> Default registry for unqualified images (e.g., 10.0.2.2:5000/yocto) |
| 24 | # docker_insecure_registry=<host:port> Mark registry as insecure (HTTP). Can repeat. | 24 | # docker_insecure_registry=<host:port> Mark registry as insecure (HTTP). Can repeat. |
| 25 | # docker_registry_secure=1 Enable TLS verification for registry | ||
| 26 | # docker_registry_ca=1 CA certificate available in /mnt/share/ca.crt | ||
| 27 | # docker_registry_user=<user> Registry username for authentication | ||
| 28 | # docker_registry_pass=<base64> Base64-encoded registry password | ||
| 25 | # | 29 | # |
| 26 | # Version: 2.4.0 | 30 | # Version: 2.5.0 |
| 27 | 31 | ||
| 28 | # Set runtime-specific parameters before sourcing common code | 32 | # Set runtime-specific parameters before sourcing common code |
| 29 | VCONTAINER_RUNTIME_NAME="vdkr" | 33 | VCONTAINER_RUNTIME_NAME="vdkr" |
| @@ -31,13 +35,21 @@ VCONTAINER_RUNTIME_CMD="docker" | |||
| 31 | VCONTAINER_RUNTIME_PREFIX="docker" | 35 | VCONTAINER_RUNTIME_PREFIX="docker" |
| 32 | VCONTAINER_STATE_DIR="/var/lib/docker" | 36 | VCONTAINER_STATE_DIR="/var/lib/docker" |
| 33 | VCONTAINER_SHARE_NAME="vdkr_share" | 37 | VCONTAINER_SHARE_NAME="vdkr_share" |
| 34 | VCONTAINER_VERSION="2.4.0" | 38 | VCONTAINER_VERSION="2.5.0" |
| 35 | 39 | ||
| 36 | # Docker-specific: default registry for unqualified image names | 40 | # Docker-specific: default registry for unqualified image names |
| 37 | # Set via kernel param: docker_registry=10.0.2.2:5000/yocto | 41 | # Set via kernel param: docker_registry=10.0.2.2:5000/yocto |
| 38 | # Or baked into rootfs: /etc/vdkr/registry.conf | 42 | # Or baked into rootfs: /etc/vdkr/registry.conf |
| 39 | DOCKER_DEFAULT_REGISTRY="" | 43 | DOCKER_DEFAULT_REGISTRY="" |
| 40 | 44 | ||
| 45 | # Secure registry mode (TLS verification) | ||
| 46 | # Set via kernel param: docker_registry_secure=1 | ||
| 47 | # CA cert passed via: virtio-9p share at /mnt/share/ca.crt | ||
| 48 | DOCKER_REGISTRY_SECURE="" | ||
| 49 | DOCKER_REGISTRY_CA="" | ||
| 50 | DOCKER_REGISTRY_USER="" | ||
| 51 | DOCKER_REGISTRY_PASS="" | ||
| 52 | |||
| 41 | # Source common init functions | 53 | # Source common init functions |
| 42 | # When installed as /init, common file is at /vcontainer-init-common.sh | 54 | # When installed as /init, common file is at /vcontainer-init-common.sh |
| 43 | . /vcontainer-init-common.sh | 55 | . /vcontainer-init-common.sh |
| @@ -56,6 +68,97 @@ load_registry_config() { | |||
| 56 | fi | 68 | fi |
| 57 | } | 69 | } |
| 58 | 70 | ||
| 71 | # Parse secure registry settings from kernel cmdline | ||
| 72 | parse_secure_registry_config() { | ||
| 73 | # Check for secure mode flag | ||
| 74 | GREP_RESULT=$(grep -o 'docker_registry_secure=[^ ]*' /proc/cmdline 2>/dev/null || true) | ||
| 75 | if [ -n "$GREP_RESULT" ]; then | ||
| 76 | DOCKER_REGISTRY_SECURE=$(echo "$GREP_RESULT" | sed 's/docker_registry_secure=//') | ||
| 77 | log "Secure registry mode: $DOCKER_REGISTRY_SECURE" | ||
| 78 | fi | ||
| 79 | |||
| 80 | # Check for CA certificate in shared folder (passed via virtio-9p) | ||
| 81 | if [ -f "/mnt/share/ca.crt" ]; then | ||
| 82 | DOCKER_REGISTRY_CA="/mnt/share/ca.crt" | ||
| 83 | log "Found CA certificate in shared folder" | ||
| 84 | fi | ||
| 85 | |||
| 86 | # Check for registry user | ||
| 87 | GREP_RESULT=$(grep -o 'docker_registry_user=[^ ]*' /proc/cmdline 2>/dev/null || true) | ||
| 88 | if [ -n "$GREP_RESULT" ]; then | ||
| 89 | DOCKER_REGISTRY_USER=$(echo "$GREP_RESULT" | sed 's/docker_registry_user=//') | ||
| 90 | log "Registry user: $DOCKER_REGISTRY_USER" | ||
| 91 | fi | ||
| 92 | |||
| 93 | # Check for registry password (base64 encoded) | ||
| 94 | GREP_RESULT=$(grep -o 'docker_registry_pass=[^ ]*' /proc/cmdline 2>/dev/null || true) | ||
| 95 | if [ -n "$GREP_RESULT" ]; then | ||
| 96 | DOCKER_REGISTRY_PASS=$(echo "$GREP_RESULT" | sed 's/docker_registry_pass=//') | ||
| 97 | log "Received registry password from cmdline" | ||
| 98 | fi | ||
| 99 | } | ||
| 100 | |||
| 101 | # Install CA certificate for secure registry | ||
| 102 | # Creates /etc/docker/certs.d/{registry}/ca.crt | ||
| 103 | install_registry_ca() { | ||
| 104 | if [ "$DOCKER_REGISTRY_SECURE" != "1" ]; then | ||
| 105 | return 0 | ||
| 106 | fi | ||
| 107 | |||
| 108 | if [ -z "$DOCKER_DEFAULT_REGISTRY" ]; then | ||
| 109 | log "WARNING: Secure mode enabled but no registry configured" | ||
| 110 | return 0 | ||
| 111 | fi | ||
| 112 | |||
| 113 | # Extract registry host (strip path/namespace) | ||
| 114 | local registry_host=$(echo "$DOCKER_DEFAULT_REGISTRY" | cut -d'/' -f1) | ||
| 115 | |||
| 116 | # Install CA cert if provided via shared folder | ||
| 117 | if [ -n "$DOCKER_REGISTRY_CA" ] && [ -f "$DOCKER_REGISTRY_CA" ]; then | ||
| 118 | local cert_dir="/etc/docker/certs.d/$registry_host" | ||
| 119 | mkdir -p "$cert_dir" | ||
| 120 | |||
| 121 | # Copy CA cert from shared folder | ||
| 122 | if cp "$DOCKER_REGISTRY_CA" "$cert_dir/ca.crt" 2>/dev/null && [ -s "$cert_dir/ca.crt" ]; then | ||
| 123 | log "Installed CA certificate: $cert_dir/ca.crt" | ||
| 124 | else | ||
| 125 | log "WARNING: Failed to copy CA certificate from $DOCKER_REGISTRY_CA" | ||
| 126 | rm -f "$cert_dir/ca.crt" | ||
| 127 | fi | ||
| 128 | else | ||
| 129 | # Check if CA cert exists from baked rootfs | ||
| 130 | local cert_dir="/etc/docker/certs.d/$registry_host" | ||
| 131 | if [ -f "$cert_dir/ca.crt" ]; then | ||
| 132 | log "Using baked CA certificate: $cert_dir/ca.crt" | ||
| 133 | else | ||
| 134 | log "WARNING: Secure mode enabled but no CA certificate available" | ||
| 135 | fi | ||
| 136 | fi | ||
| 137 | |||
| 138 | # Setup Docker auth if credentials provided | ||
| 139 | if [ -n "$DOCKER_REGISTRY_USER" ] && [ -n "$DOCKER_REGISTRY_PASS" ]; then | ||
| 140 | local password=$(echo "$DOCKER_REGISTRY_PASS" | base64 -d 2>/dev/null) | ||
| 141 | if [ -n "$password" ]; then | ||
| 142 | mkdir -p /root/.docker | ||
| 143 | # Create auth config | ||
| 144 | local auth=$(echo -n "$DOCKER_REGISTRY_USER:$password" | base64 | tr -d '\n') | ||
| 145 | cat > /root/.docker/config.json << EOF | ||
| 146 | { | ||
| 147 | "auths": { | ||
| 148 | "$registry_host": { | ||
| 149 | "auth": "$auth" | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | EOF | ||
| 154 | chmod 600 /root/.docker/config.json | ||
| 155 | log "Configured Docker auth for: $registry_host" | ||
| 156 | else | ||
| 157 | log "WARNING: Failed to decode registry password" | ||
| 158 | fi | ||
| 159 | fi | ||
| 160 | } | ||
| 161 | |||
| 59 | # ============================================================================ | 162 | # ============================================================================ |
| 60 | # Docker-Specific Functions | 163 | # Docker-Specific Functions |
| 61 | # ============================================================================ | 164 | # ============================================================================ |
| @@ -141,10 +244,16 @@ start_dockerd() { | |||
| 141 | if [ -n "$DOCKER_DEFAULT_REGISTRY" ]; then | 244 | if [ -n "$DOCKER_DEFAULT_REGISTRY" ]; then |
| 142 | # Extract host:port for insecure registry config (strip path/namespace) | 245 | # Extract host:port for insecure registry config (strip path/namespace) |
| 143 | REGISTRY_HOST=$(echo "$DOCKER_DEFAULT_REGISTRY" | cut -d'/' -f1) | 246 | REGISTRY_HOST=$(echo "$DOCKER_DEFAULT_REGISTRY" | cut -d'/' -f1) |
| 144 | # Auto-add to insecure registries if it looks like a local/private registry | 247 | |
| 145 | if echo "$REGISTRY_HOST" | grep -qE '^(localhost|127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)'; then | 248 | # In secure mode, DO NOT add to insecure-registries (use TLS verification) |
| 146 | DOCKER_OPTS="$DOCKER_OPTS --insecure-registry=$REGISTRY_HOST" | 249 | if [ "$DOCKER_REGISTRY_SECURE" = "1" ]; then |
| 147 | log "Auto-added insecure registry: $REGISTRY_HOST" | 250 | log "Secure mode: using TLS verification for $REGISTRY_HOST" |
| 251 | else | ||
| 252 | # Auto-add to insecure registries if it looks like a local/private registry | ||
| 253 | if echo "$REGISTRY_HOST" | grep -qE '^(localhost|127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)'; then | ||
| 254 | DOCKER_OPTS="$DOCKER_OPTS --insecure-registry=$REGISTRY_HOST" | ||
| 255 | log "Auto-added insecure registry: $REGISTRY_HOST" | ||
| 256 | fi | ||
| 148 | fi | 257 | fi |
| 149 | fi | 258 | fi |
| 150 | 259 | ||
| @@ -569,6 +678,12 @@ configure_networking | |||
| 569 | # Load baked registry config (can be overridden by kernel cmdline) | 678 | # Load baked registry config (can be overridden by kernel cmdline) |
| 570 | load_registry_config | 679 | load_registry_config |
| 571 | 680 | ||
| 681 | # Parse secure registry settings from kernel cmdline | ||
| 682 | parse_secure_registry_config | ||
| 683 | |||
| 684 | # Install CA certificate for secure registry | ||
| 685 | install_registry_ca | ||
| 686 | |||
| 572 | # Start containerd and dockerd (Docker-specific) | 687 | # Start containerd and dockerd (Docker-specific) |
| 573 | start_containerd | 688 | start_containerd |
| 574 | start_dockerd | 689 | start_dockerd |
diff --git a/recipes-containers/vcontainer/files/vrunner.sh b/recipes-containers/vcontainer/files/vrunner.sh index 4e99cba7..22e9229a 100755 --- a/recipes-containers/vcontainer/files/vrunner.sh +++ b/recipes-containers/vcontainer/files/vrunner.sh | |||
| @@ -311,6 +311,10 @@ PORT_FORWARDS=() | |||
| 311 | # Registry configuration | 311 | # Registry configuration |
| 312 | DOCKER_REGISTRY="" | 312 | DOCKER_REGISTRY="" |
| 313 | INSECURE_REGISTRIES=() | 313 | INSECURE_REGISTRIES=() |
| 314 | SECURE_REGISTRY="false" | ||
| 315 | CA_CERT="" | ||
| 316 | REGISTRY_USER="" | ||
| 317 | REGISTRY_PASS="" | ||
| 314 | 318 | ||
| 315 | # Batch import mode | 319 | # Batch import mode |
| 316 | BATCH_IMPORT="false" | 320 | BATCH_IMPORT="false" |
| @@ -381,6 +385,26 @@ while [ $# -gt 0 ]; do | |||
| 381 | INSECURE_REGISTRIES+=("$2") | 385 | INSECURE_REGISTRIES+=("$2") |
| 382 | shift 2 | 386 | shift 2 |
| 383 | ;; | 387 | ;; |
| 388 | --secure-registry) | ||
| 389 | # Enable TLS verification for registry | ||
| 390 | SECURE_REGISTRY="true" | ||
| 391 | shift | ||
| 392 | ;; | ||
| 393 | --ca-cert) | ||
| 394 | # Path to CA certificate for TLS verification | ||
| 395 | CA_CERT="$2" | ||
| 396 | shift 2 | ||
| 397 | ;; | ||
| 398 | --registry-user) | ||
| 399 | # Registry username | ||
| 400 | REGISTRY_USER="$2" | ||
| 401 | shift 2 | ||
| 402 | ;; | ||
| 403 | --registry-pass) | ||
| 404 | # Registry password | ||
| 405 | REGISTRY_PASS="$2" | ||
| 406 | shift 2 | ||
| 407 | ;; | ||
| 384 | --interactive|-it) | 408 | --interactive|-it) |
| 385 | INTERACTIVE="true" | 409 | INTERACTIVE="true" |
| 386 | shift | 410 | shift |
| @@ -1153,6 +1177,22 @@ for reg in "${INSECURE_REGISTRIES[@]}"; do | |||
| 1153 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_insecure_registry=$reg" | 1177 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_insecure_registry=$reg" |
| 1154 | done | 1178 | done |
| 1155 | 1179 | ||
| 1180 | # Secure registry mode (TLS verification) | ||
| 1181 | # CA certificate is passed via virtio-9p share, not kernel cmdline (too large) | ||
| 1182 | if [ "$SECURE_REGISTRY" = "true" ]; then | ||
| 1183 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_registry_secure=1" | ||
| 1184 | fi | ||
| 1185 | |||
| 1186 | # Registry credentials | ||
| 1187 | if [ -n "$REGISTRY_USER" ]; then | ||
| 1188 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_registry_user=$REGISTRY_USER" | ||
| 1189 | fi | ||
| 1190 | if [ -n "$REGISTRY_PASS" ]; then | ||
| 1191 | # Base64 encode the password to handle special characters | ||
| 1192 | REGISTRY_PASS_B64=$(echo -n "$REGISTRY_PASS" | base64 -w0) | ||
| 1193 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_registry_pass=$REGISTRY_PASS_B64" | ||
| 1194 | fi | ||
| 1195 | |||
| 1156 | # Tell init script if interactive mode | 1196 | # Tell init script if interactive mode |
| 1157 | if [ "$INTERACTIVE" = "true" ]; then | 1197 | if [ "$INTERACTIVE" = "true" ]; then |
| 1158 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_interactive=1" | 1198 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_interactive=1" |
| @@ -1246,6 +1286,8 @@ if [ "$DAEMON_MODE" = "start" ]; then | |||
| 1246 | # Use security_model=none for simplest file sharing (no permission mapping) | 1286 | # Use security_model=none for simplest file sharing (no permission mapping) |
| 1247 | # This allows writes from container (running as root) to propagate to host | 1287 | # This allows writes from container (running as root) to propagate to host |
| 1248 | QEMU_OPTS="$QEMU_OPTS -virtfs local,path=$DAEMON_SHARE_DIR,mount_tag=$SHARE_TAG,security_model=none,id=$SHARE_TAG" | 1288 | QEMU_OPTS="$QEMU_OPTS -virtfs local,path=$DAEMON_SHARE_DIR,mount_tag=$SHARE_TAG,security_model=none,id=$SHARE_TAG" |
| 1289 | # Tell init script to mount the share | ||
| 1290 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_9p=1" | ||
| 1249 | 1291 | ||
| 1250 | # Add virtio-serial device for command channel | 1292 | # Add virtio-serial device for command channel |
| 1251 | # Using virtserialport creates /dev/vport0p1 in guest, host sees unix socket | 1293 | # Using virtserialport creates /dev/vport0p1 in guest, host sees unix socket |
| @@ -1298,6 +1340,12 @@ if [ "$DAEMON_MODE" = "start" ]; then | |||
| 1298 | fi | 1340 | fi |
| 1299 | fi | 1341 | fi |
| 1300 | 1342 | ||
| 1343 | # Copy CA certificate to shared folder (too large for kernel cmdline) | ||
| 1344 | if [ -n "$CA_CERT" ] && [ -f "$CA_CERT" ]; then | ||
| 1345 | cp "$CA_CERT" "$DAEMON_SHARE_DIR/ca.crt" | ||
| 1346 | log "DEBUG" "CA certificate copied to shared folder" | ||
| 1347 | fi | ||
| 1348 | |||
| 1301 | log "INFO" "Starting daemon..." | 1349 | log "INFO" "Starting daemon..." |
| 1302 | log "DEBUG" "PID file: $DAEMON_PID_FILE" | 1350 | log "DEBUG" "PID file: $DAEMON_PID_FILE" |
| 1303 | log "DEBUG" "Socket: $DAEMON_SOCKET" | 1351 | log "DEBUG" "Socket: $DAEMON_SOCKET" |
| @@ -1406,6 +1454,21 @@ if [ "$DAEMON_MODE" = "start" ]; then | |||
| 1406 | fi | 1454 | fi |
| 1407 | fi | 1455 | fi |
| 1408 | 1456 | ||
| 1457 | # For non-daemon mode with CA cert, we need virtio-9p to pass the cert | ||
| 1458 | # (kernel cmdline is too small for base64-encoded certs) | ||
| 1459 | if [ -n "$CA_CERT" ] && [ -f "$CA_CERT" ]; then | ||
| 1460 | # Create temp share dir for CA cert | ||
| 1461 | CA_SHARE_DIR="$TEMP_DIR/ca_share" | ||
| 1462 | mkdir -p "$CA_SHARE_DIR" | ||
| 1463 | cp "$CA_CERT" "$CA_SHARE_DIR/ca.crt" | ||
| 1464 | |||
| 1465 | # Add virtio-9p mount for CA cert | ||
| 1466 | SHARE_TAG="${TOOL_NAME}_share" | ||
| 1467 | QEMU_OPTS="$QEMU_OPTS -virtfs local,path=$CA_SHARE_DIR,mount_tag=$SHARE_TAG,security_model=none,readonly=on,id=cashare" | ||
| 1468 | KERNEL_APPEND="$KERNEL_APPEND ${CMDLINE_PREFIX}_9p=1" | ||
| 1469 | log "DEBUG" "CA certificate available via virtio-9p" | ||
| 1470 | fi | ||
| 1471 | |||
| 1409 | log "INFO" "Starting QEMU..." | 1472 | log "INFO" "Starting QEMU..." |
| 1410 | log "DEBUG" "Command: $QEMU_CMD $QEMU_OPTS -append \"$KERNEL_APPEND\"" | 1473 | log "DEBUG" "Command: $QEMU_CMD $QEMU_OPTS -append \"$KERNEL_APPEND\"" |
| 1411 | 1474 | ||
diff --git a/recipes-containers/vcontainer/vcontainer-tarball.bb b/recipes-containers/vcontainer/vcontainer-tarball.bb index a4e9a9a5..8d7cecf9 100644 --- a/recipes-containers/vcontainer/vcontainer-tarball.bb +++ b/recipes-containers/vcontainer/vcontainer-tarball.bb | |||
| @@ -31,6 +31,15 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda | |||
| 31 | FILESEXTRAPATHS:prepend := "${THISDIR}/files:" | 31 | FILESEXTRAPATHS:prepend := "${THISDIR}/files:" |
| 32 | TOOLCHAIN_SHAR_EXT_TMPL = "${THISDIR}/files/toolchain-shar-extract.sh" | 32 | TOOLCHAIN_SHAR_EXT_TMPL = "${THISDIR}/files/toolchain-shar-extract.sh" |
| 33 | 33 | ||
| 34 | # Declare script sources so BitBake tracks changes and rebuilds when they change | ||
| 35 | SRC_URI = "\ | ||
| 36 | file://vrunner.sh \ | ||
| 37 | file://vcontainer-common.sh \ | ||
| 38 | file://vdkr.sh \ | ||
| 39 | file://vpdmn.sh \ | ||
| 40 | file://toolchain-shar-extract.sh \ | ||
| 41 | " | ||
| 42 | |||
| 34 | # No target sysroot - host tools only (like buildtools-tarball) | 43 | # No target sysroot - host tools only (like buildtools-tarball) |
| 35 | TOOLCHAIN_TARGET_TASK = "" | 44 | TOOLCHAIN_TARGET_TASK = "" |
| 36 | TARGET_ARCH = "none" | 45 | TARGET_ARCH = "none" |
| @@ -62,6 +71,7 @@ EXCLUDE_FROM_WORLD = "1" | |||
| 62 | inherit populate_sdk | 71 | inherit populate_sdk |
| 63 | inherit toolchain-scripts-base | 72 | inherit toolchain-scripts-base |
| 64 | inherit nopackages | 73 | inherit nopackages |
| 74 | inherit container-registry | ||
| 65 | 75 | ||
| 66 | # Must be set AFTER inherit populate_sdk (class sets it to target arch) | 76 | # Must be set AFTER inherit populate_sdk (class sets it to target arch) |
| 67 | REAL_MULTIMACH_TARGET_SYS = "none" | 77 | REAL_MULTIMACH_TARGET_SYS = "none" |
| @@ -169,6 +179,8 @@ create_sdk_files:append () { | |||
| 169 | TOPDIR="${TOPDIR}" | 179 | TOPDIR="${TOPDIR}" |
| 170 | THISDIR="${THISDIR}" | 180 | THISDIR="${THISDIR}" |
| 171 | ARCHITECTURES="${VCONTAINER_ARCHITECTURES}" | 181 | ARCHITECTURES="${VCONTAINER_ARCHITECTURES}" |
| 182 | CONTAINER_REGISTRY_SECURE="${CONTAINER_REGISTRY_SECURE}" | ||
| 183 | CONTAINER_REGISTRY_CA_CERT="${CONTAINER_REGISTRY_CA_CERT}" | ||
| 172 | 184 | ||
| 173 | # SDK output directory | 185 | # SDK output directory |
| 174 | SDK_OUT="${SDK_OUTPUT}/${SDKPATH}" | 186 | SDK_OUT="${SDK_OUTPUT}/${SDKPATH}" |
| @@ -290,6 +302,18 @@ create_sdk_files:append () { | |||
| 290 | bbnote "Installed vpdmn" | 302 | bbnote "Installed vpdmn" |
| 291 | fi | 303 | fi |
| 292 | 304 | ||
| 305 | # Copy CA certificate for secure registry mode (if available) | ||
| 306 | SECURE_MODE="${CONTAINER_REGISTRY_SECURE}" | ||
| 307 | CA_CERT="${CONTAINER_REGISTRY_CA_CERT}" | ||
| 308 | if [ "${SECURE_MODE}" = "1" ] && [ -f "${CA_CERT}" ]; then | ||
| 309 | mkdir -p "${SDK_OUT}/registry" | ||
| 310 | cp "${CA_CERT}" "${SDK_OUT}/registry/ca.crt" | ||
| 311 | bbnote "Included secure registry CA certificate" | ||
| 312 | elif [ "${SECURE_MODE}" = "1" ]; then | ||
| 313 | bbwarn "Secure registry mode enabled but CA cert not found at ${CA_CERT}" | ||
| 314 | bbwarn "Run: bitbake container-registry-index -c generate_registry_script" | ||
| 315 | fi | ||
| 316 | |||
| 293 | # Create README | 317 | # Create README |
| 294 | cat > "${SDK_OUT}/README.txt" <<EOF | 318 | cat > "${SDK_OUT}/README.txt" <<EOF |
| 295 | vcontainer Standalone SDK | 319 | vcontainer Standalone SDK |
| @@ -314,6 +338,10 @@ Contents: | |||
| 314 | vdkr-blobs/ - Docker QEMU blobs (per-arch subdirectories) | 338 | vdkr-blobs/ - Docker QEMU blobs (per-arch subdirectories) |
| 315 | vpdmn-blobs/ - Podman QEMU blobs (per-arch subdirectories) | 339 | vpdmn-blobs/ - Podman QEMU blobs (per-arch subdirectories) |
| 316 | sysroots/ - SDK binaries (QEMU, socat, libraries) | 340 | sysroots/ - SDK binaries (QEMU, socat, libraries) |
| 341 | registry/ca.crt - CA cert for secure registry (if CONTAINER_REGISTRY_SECURE=1) | ||
| 342 | |||
| 343 | Secure Registry Usage: | ||
| 344 | vdkr --secure-registry --ca-cert registry/ca.crt pull myimage | ||
| 317 | 345 | ||
| 318 | Requirements: | 346 | Requirements: |
| 319 | - Linux x86_64 host | 347 | - Linux x86_64 host |
