diff options
| author | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-02-19 16:08:45 +0000 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-02-26 01:05:01 +0000 |
| commit | c734621380aed127ee515839aeeb8126f2dcf9ad (patch) | |
| tree | 42b9ad081b4a9c627dc06d65262c9b2176f72d52 | |
| parent | 035e0daebeb53880ea2a6bd0f0e31785f3ec9e55 (diff) | |
| download | meta-virtualization-c734621380aed127ee515839aeeb8126f2dcf9ad.tar.gz | |
vxn: add host-side OCI image cache and fix Docker iptables conflict
Add a host-side OCI image cache at ~/.vxn/images/ for the vdkr/vpdmn
standalone Xen path. Images pulled via skopeo are stored in a
content-addressed layout (refs/ symlinks + store/ OCI dirs) so
subsequent runs hit the cache without network access.
New commands on Xen: pull, images, rmi, tag, inspect, image <subcmd>.
The run path is unchanged — cache integration into hv_prepare_container
is deferred to a follow-up.
Also fix Docker iptables conflict: when docker-moby and vxn-docker-config
coexist on Dom0, Docker's default FORWARD DROP policy blocks DHCP for
Xen DomU vifs on xenbr0. Adding "iptables": false to daemon.json
prevents Docker from modifying iptables since VM-based containers
manage their own network stack.
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
| -rwxr-xr-x | recipes-containers/vcontainer/files/vcontainer-common.sh | 274 | ||||
| -rw-r--r-- | recipes-core/vxn/vxn_1.0.bb | 12 |
2 files changed, 275 insertions, 11 deletions
diff --git a/recipes-containers/vcontainer/files/vcontainer-common.sh b/recipes-containers/vcontainer/files/vcontainer-common.sh index ea78b265..c7160860 100755 --- a/recipes-containers/vcontainer/files/vcontainer-common.sh +++ b/recipes-containers/vcontainer/files/vcontainer-common.sh | |||
| @@ -486,6 +486,105 @@ EOF | |||
| 486 | return 0 | 486 | return 0 |
| 487 | } | 487 | } |
| 488 | 488 | ||
| 489 | # ============================================================================ | ||
| 490 | # Host-side OCI Image Cache (Xen standalone path) | ||
| 491 | # ============================================================================ | ||
| 492 | # Cache layout: | ||
| 493 | # ~/.vxn/images/refs/ - Symlinks from normalized image names to store dirs | ||
| 494 | # ~/.vxn/images/store/ - Content-addressed OCI layout dirs by manifest digest | ||
| 495 | |||
| 496 | VXN_IMAGE_CACHE="${VXN_IMAGE_CACHE:-$HOME/.vxn/images}" | ||
| 497 | |||
| 498 | vxn_normalize_image_name() { | ||
| 499 | # alpine → docker.io/library/alpine:latest | ||
| 500 | # nginx:1.25 → docker.io/library/nginx:1.25 | ||
| 501 | # ghcr.io/foo/bar → ghcr.io/foo/bar:latest | ||
| 502 | local name="$1" | ||
| 503 | # Add default registry | ||
| 504 | case "$name" in | ||
| 505 | *.*/*) ;; # has registry (contains . before /) | ||
| 506 | */*) name="docker.io/$name" ;; # has namespace, no registry | ||
| 507 | *) name="docker.io/library/$name" ;; # bare name | ||
| 508 | esac | ||
| 509 | # Add default tag | ||
| 510 | case "$name" in | ||
| 511 | *:*) ;; # already has tag/digest | ||
| 512 | *) name="$name:latest" ;; | ||
| 513 | esac | ||
| 514 | echo "$name" | ||
| 515 | } | ||
| 516 | |||
| 517 | vxn_image_ref_key() { | ||
| 518 | # docker.io/library/alpine:latest → docker.io_library_alpine:latest | ||
| 519 | local name="$1" | ||
| 520 | echo "$name" | tr '/' '_' | ||
| 521 | } | ||
| 522 | |||
| 523 | vxn_image_cache_lookup() { | ||
| 524 | # Returns OCI dir path if cached, empty if not | ||
| 525 | local image="$1" | ||
| 526 | local normalized ref_key ref_link | ||
| 527 | normalized=$(vxn_normalize_image_name "$image") | ||
| 528 | ref_key=$(vxn_image_ref_key "$normalized") | ||
| 529 | ref_link="$VXN_IMAGE_CACHE/refs/$ref_key" | ||
| 530 | if [ -L "$ref_link" ] && [ -d "$ref_link" ]; then | ||
| 531 | readlink -f "$ref_link" | ||
| 532 | fi | ||
| 533 | } | ||
| 534 | |||
| 535 | vxn_image_cache_store() { | ||
| 536 | # Store OCI dir in cache, create ref symlink | ||
| 537 | # $1 = image name, $2 = source OCI dir | ||
| 538 | local image="$1" oci_dir="$2" | ||
| 539 | local normalized ref_key manifest_digest store_dir | ||
| 540 | normalized=$(vxn_normalize_image_name "$image") | ||
| 541 | ref_key=$(vxn_image_ref_key "$normalized") | ||
| 542 | |||
| 543 | mkdir -p "$VXN_IMAGE_CACHE/refs" "$VXN_IMAGE_CACHE/store/sha256" | ||
| 544 | |||
| 545 | # Get manifest digest for content-addressed storage | ||
| 546 | manifest_digest=$(grep -o '"sha256:[a-f0-9]*"' "$oci_dir/index.json" 2>/dev/null | head -1 | tr -d '"') | ||
| 547 | manifest_digest="${manifest_digest#sha256:}" | ||
| 548 | if [ -z "$manifest_digest" ]; then | ||
| 549 | # Fallback: hash the index.json itself | ||
| 550 | manifest_digest=$(sha256sum "$oci_dir/index.json" | cut -d' ' -f1) | ||
| 551 | fi | ||
| 552 | |||
| 553 | store_dir="$VXN_IMAGE_CACHE/store/sha256/$manifest_digest" | ||
| 554 | if [ ! -d "$store_dir" ]; then | ||
| 555 | cp -a "$oci_dir" "$store_dir" | ||
| 556 | fi | ||
| 557 | |||
| 558 | # Create/update ref symlink (relative path) | ||
| 559 | ln -sfn "../store/sha256/$manifest_digest" "$VXN_IMAGE_CACHE/refs/$ref_key" | ||
| 560 | } | ||
| 561 | |||
| 562 | vxn_image_cache_inspect() { | ||
| 563 | # Print OCI config info (Entrypoint, Cmd, Env, WorkingDir) | ||
| 564 | local oci_dir="$1" | ||
| 565 | if ! command -v jq >/dev/null 2>&1; then | ||
| 566 | echo "jq not found, cannot inspect image" >&2 | ||
| 567 | return 1 | ||
| 568 | fi | ||
| 569 | local manifest_digest config_digest manifest_file config_file | ||
| 570 | manifest_digest=$(jq -r '.manifests[0].digest' "$oci_dir/index.json" 2>/dev/null) | ||
| 571 | manifest_file="$oci_dir/blobs/${manifest_digest/://}" | ||
| 572 | [ -f "$manifest_file" ] || { echo "Manifest not found" >&2; return 1; } | ||
| 573 | config_digest=$(jq -r '.config.digest' "$manifest_file" 2>/dev/null) | ||
| 574 | config_file="$oci_dir/blobs/${config_digest/://}" | ||
| 575 | [ -f "$config_file" ] || { echo "Config not found" >&2; return 1; } | ||
| 576 | jq '{ | ||
| 577 | Entrypoint: .config.Entrypoint, | ||
| 578 | Cmd: .config.Cmd, | ||
| 579 | Env: .config.Env, | ||
| 580 | WorkingDir: .config.WorkingDir, | ||
| 581 | ExposedPorts: .config.ExposedPorts, | ||
| 582 | Labels: .config.Labels, | ||
| 583 | Architecture: .architecture, | ||
| 584 | Os: .os | ||
| 585 | }' "$config_file" | ||
| 586 | } | ||
| 587 | |||
| 489 | show_usage() { | 588 | show_usage() { |
| 490 | local PROG_NAME=$(basename "$0") | 589 | local PROG_NAME=$(basename "$0") |
| 491 | local RUNTIME_UPPER=$(echo "$VCONTAINER_RUNTIME_CMD" | sed 's/./\U&/') | 590 | local RUNTIME_UPPER=$(echo "$VCONTAINER_RUNTIME_CMD" | sed 's/./\U&/') |
| @@ -1470,13 +1569,102 @@ case "$COMMAND" in | |||
| 1470 | # docker image rm → docker rmi | 1569 | # docker image rm → docker rmi |
| 1471 | # docker image pull → docker pull | 1570 | # docker image pull → docker pull |
| 1472 | # etc. | 1571 | # etc. |
| 1473 | [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ] && vxn_not_yet "image" | ||
| 1474 | if [ ${#COMMAND_ARGS[@]} -lt 1 ]; then | 1572 | if [ ${#COMMAND_ARGS[@]} -lt 1 ]; then |
| 1475 | echo -e "${RED}[$VCONTAINER_RUNTIME_NAME]${NC} image requires a subcommand (ls, rm, pull, inspect, tag, push, prune)" >&2 | 1573 | echo -e "${RED}[$VCONTAINER_RUNTIME_NAME]${NC} image requires a subcommand (ls, rm, pull, inspect, tag, push, prune)" >&2 |
| 1476 | exit 1 | 1574 | exit 1 |
| 1477 | fi | 1575 | fi |
| 1478 | SUBCMD="${COMMAND_ARGS[0]}" | 1576 | SUBCMD="${COMMAND_ARGS[0]}" |
| 1479 | SUBCMD_ARGS=("${COMMAND_ARGS[@]:1}") | 1577 | SUBCMD_ARGS=("${COMMAND_ARGS[@]:1}") |
| 1578 | if [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ]; then | ||
| 1579 | # Xen: delegate to cache-based image subcommands | ||
| 1580 | case "$SUBCMD" in | ||
| 1581 | ls|list) | ||
| 1582 | printf "%-40s %-15s %-12s\n" "REPOSITORY:TAG" "SIZE" "CACHED" | ||
| 1583 | if [ -d "$VXN_IMAGE_CACHE/refs" ]; then | ||
| 1584 | for ref in "$VXN_IMAGE_CACHE/refs"/*; do | ||
| 1585 | [ -L "$ref" ] || continue | ||
| 1586 | _vxn_ref_name=$(basename "$ref" | tr '_' '/') | ||
| 1587 | _vxn_store_dir=$(readlink -f "$ref") | ||
| 1588 | _vxn_size="unknown" | ||
| 1589 | [ -d "$_vxn_store_dir" ] && _vxn_size=$(du -sh "$_vxn_store_dir" 2>/dev/null | cut -f1) | ||
| 1590 | printf "%-40s %-15s %-12s\n" "$_vxn_ref_name" "$_vxn_size" "yes" | ||
| 1591 | done | ||
| 1592 | fi | ||
| 1593 | exit 0 | ||
| 1594 | ;; | ||
| 1595 | rm|remove) | ||
| 1596 | [ ${#SUBCMD_ARGS[@]} -lt 1 ] && { echo "rmi requires <image>" >&2; exit 1; } | ||
| 1597 | _vxn_normalized=$(vxn_normalize_image_name "${SUBCMD_ARGS[0]}") | ||
| 1598 | _vxn_ref_key=$(vxn_image_ref_key "$_vxn_normalized") | ||
| 1599 | _vxn_ref_link="$VXN_IMAGE_CACHE/refs/$_vxn_ref_key" | ||
| 1600 | if [ -L "$_vxn_ref_link" ]; then | ||
| 1601 | _vxn_store_dir=$(readlink -f "$_vxn_ref_link") | ||
| 1602 | rm -f "$_vxn_ref_link" | ||
| 1603 | _vxn_other_refs=$(find "$VXN_IMAGE_CACHE/refs" -lname "*/$(basename "$_vxn_store_dir")" 2>/dev/null | wc -l) | ||
| 1604 | [ "$_vxn_other_refs" -eq 0 ] && rm -rf "$_vxn_store_dir" | ||
| 1605 | echo "Removed: $_vxn_normalized" | ||
| 1606 | else | ||
| 1607 | echo "Image not found: $_vxn_normalized" >&2; exit 1 | ||
| 1608 | fi | ||
| 1609 | exit 0 | ||
| 1610 | ;; | ||
| 1611 | pull) | ||
| 1612 | [ ${#SUBCMD_ARGS[@]} -lt 1 ] && { echo "pull requires <image>" >&2; exit 1; } | ||
| 1613 | IMAGE_NAME="${SUBCMD_ARGS[0]}" | ||
| 1614 | command -v skopeo >/dev/null 2>&1 || { echo "skopeo not found" >&2; exit 1; } | ||
| 1615 | _vxn_normalized=$(vxn_normalize_image_name "$IMAGE_NAME") | ||
| 1616 | echo "Pulling $_vxn_normalized..." | ||
| 1617 | _vxn_tmpoci="$(mktemp -d)/oci-image" | ||
| 1618 | if skopeo copy "docker://$_vxn_normalized" "oci:$_vxn_tmpoci:latest" 2>&1; then | ||
| 1619 | vxn_image_cache_store "$IMAGE_NAME" "$_vxn_tmpoci" | ||
| 1620 | rm -rf "$(dirname "$_vxn_tmpoci")" | ||
| 1621 | echo "Pulled: $_vxn_normalized" | ||
| 1622 | else | ||
| 1623 | rm -rf "$(dirname "$_vxn_tmpoci")" | ||
| 1624 | echo "Failed to pull $_vxn_normalized" >&2; exit 1 | ||
| 1625 | fi | ||
| 1626 | exit 0 | ||
| 1627 | ;; | ||
| 1628 | inspect) | ||
| 1629 | [ ${#SUBCMD_ARGS[@]} -lt 1 ] && { echo "inspect requires <image>" >&2; exit 1; } | ||
| 1630 | _vxn_cached_oci=$(vxn_image_cache_lookup "${SUBCMD_ARGS[0]}") | ||
| 1631 | if [ -n "$_vxn_cached_oci" ]; then | ||
| 1632 | vxn_image_cache_inspect "$_vxn_cached_oci" | ||
| 1633 | else | ||
| 1634 | echo "Image not found: ${SUBCMD_ARGS[0]}" >&2; exit 1 | ||
| 1635 | fi | ||
| 1636 | exit 0 | ||
| 1637 | ;; | ||
| 1638 | tag) | ||
| 1639 | [ ${#SUBCMD_ARGS[@]} -lt 2 ] && { echo "tag requires <source> <target>" >&2; exit 1; } | ||
| 1640 | _vxn_src_oci=$(vxn_image_cache_lookup "${SUBCMD_ARGS[0]}") | ||
| 1641 | if [ -z "$_vxn_src_oci" ]; then | ||
| 1642 | echo "Image not found: ${SUBCMD_ARGS[0]}" >&2; exit 1 | ||
| 1643 | fi | ||
| 1644 | _vxn_target_normalized=$(vxn_normalize_image_name "${SUBCMD_ARGS[1]}") | ||
| 1645 | _vxn_target_ref_key=$(vxn_image_ref_key "$_vxn_target_normalized") | ||
| 1646 | mkdir -p "$VXN_IMAGE_CACHE/refs" | ||
| 1647 | # Point new ref to same store dir | ||
| 1648 | _vxn_store_base=$(basename "$_vxn_src_oci") | ||
| 1649 | ln -sfn "../store/sha256/$_vxn_store_base" "$VXN_IMAGE_CACHE/refs/$_vxn_target_ref_key" | ||
| 1650 | echo "Tagged: $_vxn_target_normalized" | ||
| 1651 | exit 0 | ||
| 1652 | ;; | ||
| 1653 | push) | ||
| 1654 | vxn_not_yet "image push" | ||
| 1655 | ;; | ||
| 1656 | prune) | ||
| 1657 | vxn_not_yet "image prune" | ||
| 1658 | ;; | ||
| 1659 | history) | ||
| 1660 | vxn_not_yet "image history" | ||
| 1661 | ;; | ||
| 1662 | *) | ||
| 1663 | echo -e "${RED}[$VCONTAINER_RUNTIME_NAME]${NC} Unknown image subcommand: $SUBCMD" >&2 | ||
| 1664 | exit 1 | ||
| 1665 | ;; | ||
| 1666 | esac | ||
| 1667 | fi | ||
| 1480 | case "$SUBCMD" in | 1668 | case "$SUBCMD" in |
| 1481 | ls|list) | 1669 | ls|list) |
| 1482 | run_runtime_command "$VCONTAINER_RUNTIME_CMD images ${SUBCMD_ARGS[*]}" | 1670 | run_runtime_command "$VCONTAINER_RUNTIME_CMD images ${SUBCMD_ARGS[*]}" |
| @@ -1525,15 +1713,26 @@ case "$COMMAND" in | |||
| 1525 | ;; | 1713 | ;; |
| 1526 | 1714 | ||
| 1527 | images) | 1715 | images) |
| 1528 | [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ] && vxn_not_yet "images" | 1716 | if [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ]; then |
| 1717 | printf "%-40s %-15s %-12s\n" "REPOSITORY:TAG" "SIZE" "CACHED" | ||
| 1718 | if [ -d "$VXN_IMAGE_CACHE/refs" ]; then | ||
| 1719 | for ref in "$VXN_IMAGE_CACHE/refs"/*; do | ||
| 1720 | [ -L "$ref" ] || continue | ||
| 1721 | _vxn_ref_name=$(basename "$ref" | tr '_' '/') | ||
| 1722 | _vxn_store_dir=$(readlink -f "$ref") | ||
| 1723 | _vxn_size="unknown" | ||
| 1724 | [ -d "$_vxn_store_dir" ] && _vxn_size=$(du -sh "$_vxn_store_dir" 2>/dev/null | cut -f1) | ||
| 1725 | printf "%-40s %-15s %-12s\n" "$_vxn_ref_name" "$_vxn_size" "yes" | ||
| 1726 | done | ||
| 1727 | fi | ||
| 1728 | exit 0 | ||
| 1729 | fi | ||
| 1529 | # runtime images | 1730 | # runtime images |
| 1530 | run_runtime_command "$VCONTAINER_RUNTIME_CMD images ${COMMAND_ARGS[*]}" | 1731 | run_runtime_command "$VCONTAINER_RUNTIME_CMD images ${COMMAND_ARGS[*]}" |
| 1531 | ;; | 1732 | ;; |
| 1532 | 1733 | ||
| 1533 | pull) | 1734 | pull) |
| 1534 | [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ] && vxn_not_yet "pull" | ||
| 1535 | # runtime pull <image> | 1735 | # runtime pull <image> |
| 1536 | # Daemon mode already has networking enabled, so this works via daemon | ||
| 1537 | if [ ${#COMMAND_ARGS[@]} -lt 1 ]; then | 1736 | if [ ${#COMMAND_ARGS[@]} -lt 1 ]; then |
| 1538 | echo -e "${RED}[$VCONTAINER_RUNTIME_NAME]${NC} pull requires <image>" >&2 | 1737 | echo -e "${RED}[$VCONTAINER_RUNTIME_NAME]${NC} pull requires <image>" >&2 |
| 1539 | exit 1 | 1738 | exit 1 |
| @@ -1541,6 +1740,24 @@ case "$COMMAND" in | |||
| 1541 | 1740 | ||
| 1542 | IMAGE_NAME="${COMMAND_ARGS[0]}" | 1741 | IMAGE_NAME="${COMMAND_ARGS[0]}" |
| 1543 | 1742 | ||
| 1743 | if [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ]; then | ||
| 1744 | # Host-side pull via skopeo → cache | ||
| 1745 | command -v skopeo >/dev/null 2>&1 || { echo "skopeo not found" >&2; exit 1; } | ||
| 1746 | _vxn_normalized=$(vxn_normalize_image_name "$IMAGE_NAME") | ||
| 1747 | echo "Pulling $_vxn_normalized..." | ||
| 1748 | _vxn_tmpoci="$(mktemp -d)/oci-image" | ||
| 1749 | if skopeo copy "docker://$_vxn_normalized" "oci:$_vxn_tmpoci:latest" 2>&1; then | ||
| 1750 | vxn_image_cache_store "$IMAGE_NAME" "$_vxn_tmpoci" | ||
| 1751 | rm -rf "$(dirname "$_vxn_tmpoci")" | ||
| 1752 | echo "Pulled: $_vxn_normalized" | ||
| 1753 | else | ||
| 1754 | rm -rf "$(dirname "$_vxn_tmpoci")" | ||
| 1755 | echo "Failed to pull $_vxn_normalized" >&2; exit 1 | ||
| 1756 | fi | ||
| 1757 | exit 0 | ||
| 1758 | fi | ||
| 1759 | |||
| 1760 | # Daemon mode already has networking enabled, so this works via daemon | ||
| 1544 | if daemon_is_running; then | 1761 | if daemon_is_running; then |
| 1545 | # Use daemon mode (already has networking) | 1762 | # Use daemon mode (already has networking) |
| 1546 | run_runtime_command "$VCONTAINER_RUNTIME_CMD pull $IMAGE_NAME && $VCONTAINER_RUNTIME_CMD images" | 1763 | run_runtime_command "$VCONTAINER_RUNTIME_CMD pull $IMAGE_NAME && $VCONTAINER_RUNTIME_CMD images" |
| @@ -1768,7 +1985,42 @@ case "$COMMAND" in | |||
| 1768 | ;; | 1985 | ;; |
| 1769 | 1986 | ||
| 1770 | tag|rmi) | 1987 | tag|rmi) |
| 1771 | [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ] && vxn_not_yet "$COMMAND" | 1988 | if [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ]; then |
| 1989 | case "$COMMAND" in | ||
| 1990 | rmi) | ||
| 1991 | [ ${#COMMAND_ARGS[@]} -lt 1 ] && { echo "rmi requires <image>" >&2; exit 1; } | ||
| 1992 | IMAGE_NAME="${COMMAND_ARGS[0]}" | ||
| 1993 | _vxn_normalized=$(vxn_normalize_image_name "$IMAGE_NAME") | ||
| 1994 | _vxn_ref_key=$(vxn_image_ref_key "$_vxn_normalized") | ||
| 1995 | _vxn_ref_link="$VXN_IMAGE_CACHE/refs/$_vxn_ref_key" | ||
| 1996 | if [ -L "$_vxn_ref_link" ]; then | ||
| 1997 | _vxn_store_dir=$(readlink -f "$_vxn_ref_link") | ||
| 1998 | rm -f "$_vxn_ref_link" | ||
| 1999 | # Remove store dir if no other refs point to it | ||
| 2000 | _vxn_other_refs=$(find "$VXN_IMAGE_CACHE/refs" -lname "*/$(basename "$_vxn_store_dir")" 2>/dev/null | wc -l) | ||
| 2001 | [ "$_vxn_other_refs" -eq 0 ] && rm -rf "$_vxn_store_dir" | ||
| 2002 | echo "Removed: $_vxn_normalized" | ||
| 2003 | else | ||
| 2004 | echo "Image not found: $_vxn_normalized" >&2; exit 1 | ||
| 2005 | fi | ||
| 2006 | exit 0 | ||
| 2007 | ;; | ||
| 2008 | tag) | ||
| 2009 | [ ${#COMMAND_ARGS[@]} -lt 2 ] && { echo "tag requires <source> <target>" >&2; exit 1; } | ||
| 2010 | _vxn_src_oci=$(vxn_image_cache_lookup "${COMMAND_ARGS[0]}") | ||
| 2011 | if [ -z "$_vxn_src_oci" ]; then | ||
| 2012 | echo "Image not found: ${COMMAND_ARGS[0]}" >&2; exit 1 | ||
| 2013 | fi | ||
| 2014 | _vxn_target_normalized=$(vxn_normalize_image_name "${COMMAND_ARGS[1]}") | ||
| 2015 | _vxn_target_ref_key=$(vxn_image_ref_key "$_vxn_target_normalized") | ||
| 2016 | mkdir -p "$VXN_IMAGE_CACHE/refs" | ||
| 2017 | _vxn_store_base=$(basename "$_vxn_src_oci") | ||
| 2018 | ln -sfn "../store/sha256/$_vxn_store_base" "$VXN_IMAGE_CACHE/refs/$_vxn_target_ref_key" | ||
| 2019 | echo "Tagged: $_vxn_target_normalized" | ||
| 2020 | exit 0 | ||
| 2021 | ;; | ||
| 2022 | esac | ||
| 2023 | fi | ||
| 1772 | # Commands that work with existing images | 2024 | # Commands that work with existing images |
| 1773 | run_runtime_command "$VCONTAINER_RUNTIME_CMD $COMMAND ${COMMAND_ARGS[*]}" | 2025 | run_runtime_command "$VCONTAINER_RUNTIME_CMD $COMMAND ${COMMAND_ARGS[*]}" |
| 1774 | ;; | 2026 | ;; |
| @@ -1872,7 +2124,17 @@ case "$COMMAND" in | |||
| 1872 | ;; | 2124 | ;; |
| 1873 | 2125 | ||
| 1874 | inspect) | 2126 | inspect) |
| 1875 | [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ] && vxn_not_yet "inspect" | 2127 | if [ "${VCONTAINER_HYPERVISOR:-}" = "xen" ]; then |
| 2128 | [ ${#COMMAND_ARGS[@]} -lt 1 ] && { echo "inspect requires <image>" >&2; exit 1; } | ||
| 2129 | _vxn_cached_oci=$(vxn_image_cache_lookup "${COMMAND_ARGS[0]}") | ||
| 2130 | if [ -n "$_vxn_cached_oci" ]; then | ||
| 2131 | vxn_image_cache_inspect "$_vxn_cached_oci" | ||
| 2132 | exit 0 | ||
| 2133 | fi | ||
| 2134 | # Not in image cache — could be a container name on Xen | ||
| 2135 | echo "Not found: ${COMMAND_ARGS[0]}" >&2 | ||
| 2136 | exit 1 | ||
| 2137 | fi | ||
| 1876 | # Inspect container or image | 2138 | # Inspect container or image |
| 1877 | run_runtime_command "$VCONTAINER_RUNTIME_CMD inspect ${COMMAND_ARGS[*]}" | 2139 | run_runtime_command "$VCONTAINER_RUNTIME_CMD inspect ${COMMAND_ARGS[*]}" |
| 1878 | ;; | 2140 | ;; |
diff --git a/recipes-core/vxn/vxn_1.0.bb b/recipes-core/vxn/vxn_1.0.bb index a08dac09..278911d5 100644 --- a/recipes-core/vxn/vxn_1.0.bb +++ b/recipes-core/vxn/vxn_1.0.bb | |||
| @@ -228,12 +228,14 @@ do_install() { | |||
| 228 | install -m 0755 ${S}/vpdmn.sh ${D}${bindir}/vpdmn | 228 | install -m 0755 ${S}/vpdmn.sh ${D}${bindir}/vpdmn |
| 229 | 229 | ||
| 230 | # Docker daemon config: register vxn-oci-runtime (vxn-docker-config sub-package) | 230 | # Docker daemon config: register vxn-oci-runtime (vxn-docker-config sub-package) |
| 231 | # no-new-privileges=false is needed because vxn ignores Linux security features. | 231 | # iptables=false: Docker's default FORWARD DROP policy blocks DHCP and |
| 232 | # Users must use --network=none or --network=host with vxn containers since | 232 | # bridged traffic for Xen DomU vifs on xenbr0. Since vxn containers are |
| 233 | # Xen DomUs have their own kernel network stack and Docker's veth/namespace | 233 | # full VMs with their own network stack, Docker's iptables rules are |
| 234 | # setup is incompatible with VM-based runtimes. | 234 | # unnecessary and harmful. Note: bridge networking is left enabled so |
| 235 | # that 'docker pull' works (needs bridge for DNS). Users must pass | ||
| 236 | # --network=none for 'docker run' (veth/netns incompatible with VMs). | ||
| 235 | install -d ${D}${sysconfdir}/docker | 237 | install -d ${D}${sysconfdir}/docker |
| 236 | printf '{\n "runtimes": {\n "vxn": {\n "path": "/usr/bin/vxn-oci-runtime"\n }\n },\n "default-runtime": "vxn"\n}\n' \ | 238 | printf '{\n "runtimes": {\n "vxn": {\n "path": "/usr/bin/vxn-oci-runtime"\n }\n },\n "default-runtime": "vxn",\n "iptables": false\n}\n' \ |
| 237 | > ${D}${sysconfdir}/docker/daemon.json | 239 | > ${D}${sysconfdir}/docker/daemon.json |
| 238 | 240 | ||
| 239 | # Podman config: register vxn-oci-runtime (vxn-podman-config sub-package) | 241 | # Podman config: register vxn-oci-runtime (vxn-podman-config sub-package) |
