mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-21 06:11:31 +08:00
* test(vm): add composable QEMU test guests Signed-off-by: Drew Newberry <anewberry@nvidia.com> * docs(vm): describe test VM directory structure Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(vm): replace shell catalog functions Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(vm): add Fedora release guest support Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(vm): enable rootless Podman socket Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(test-guest): add OCI-backed image caching Signed-off-by: Drew Newberry <anewberry@nvidia.com> * perf(test-guest): accelerate cached guest startup Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): address review feedback Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): verify OCI cache provenance Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): harden cached guest reuse Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): refresh runtime setup state Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(test-guest): support E2E runner inputs Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): harden runner and OCI reuse Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(test-guest): prepare Podman E2E artifacts Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(e2e): add host and test VM runner Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(e2e): add VM-backed Podman shutdown suite Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(e2e): use renamed test guest app Signed-off-by: Drew Newberry <anewberry@nvidia.com> * chore(e2e): rename runner task Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(e2e): make guest smoke examples portable Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(e2e): remove Podman shutdown suite Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): use test guest Podman setup Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): run Rust suites directly Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): simplify suite runner Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): isolate runner runtime state Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(e2e): prepare Podman VM runtime Signed-off-by: Drew Newberry <anewberry@nvidia.com> * perf(e2e): speed up cached guest startup Signed-off-by: Drew Newberry <anewberry@nvidia.com> * perf(e2e): streamline guest gateway startup Signed-off-by: Drew Newberry <anewberry@nvidia.com> --------- Signed-off-by: Drew Newberry <anewberry@nvidia.com>
159 lines
4.5 KiB
Bash
159 lines
4.5 KiB
Bash
#!/usr/bin/env bash
|
|
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
# Shared cache identity and validation helpers for the test guest runner.
|
|
|
|
TEST_GUEST_CACHE_SCHEMA_VERSION=1
|
|
TEST_GUEST_CACHE_DISK_LAYOUT=standalone-qcow2-zstd-v1
|
|
TEST_GUEST_CACHE_ARTIFACT_TYPE=application/vnd.nvidia.openshell.test-guest.cache.v1
|
|
TEST_GUEST_CACHE_METADATA_TYPE=application/vnd.nvidia.openshell.test-guest.cache.metadata.v1+json
|
|
TEST_GUEST_CACHE_DISK_TYPE=application/vnd.nvidia.openshell.test-guest.cache.disk.qcow2.v1+zstd
|
|
|
|
test_vm_cache_root() {
|
|
if [ -n "${OPENSHELL_TEST_GUEST_CACHE_DIR:-}" ]; then
|
|
printf '%s\n' "${OPENSHELL_TEST_GUEST_CACHE_DIR}"
|
|
else
|
|
printf '%s\n' "${XDG_CACHE_HOME:-${HOME}/.cache}/openshell/test-guest"
|
|
fi
|
|
}
|
|
|
|
test_vm_cache_oci_architecture() {
|
|
case "${TEST_GUEST_ARCHITECTURE}" in
|
|
x86_64) printf '%s\n' amd64 ;;
|
|
aarch64) printf '%s\n' arm64 ;;
|
|
*)
|
|
echo "unsupported cache architecture: ${TEST_GUEST_ARCHITECTURE}" >&2
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
test_vm_cache_sha256() {
|
|
if [ ! -r "$1" ]; then
|
|
echo "cache identity input is not readable: $1" >&2
|
|
return 1
|
|
fi
|
|
sha256sum "$1" | cut -d ' ' -f 1
|
|
}
|
|
|
|
test_vm_cache_key() {
|
|
local distro_name=$1
|
|
shift
|
|
local configuration
|
|
local configuration_hash
|
|
local architecture
|
|
local seal_hash
|
|
local material
|
|
local configuration_line
|
|
|
|
architecture=$(test_vm_cache_oci_architecture) || return 1
|
|
seal_hash=$(test_vm_cache_sha256 "${OPENSHELL_TEST_GUEST_CACHE_SEAL}") || return 1
|
|
printf -v material \
|
|
'schema=%s\ngeneration=%s\ndisk_layout=%s\ndistro=%s\nos_version=%s\narchitecture=%s\nbase_url=%s\nbase_hash=%s\noverlay_growth=%s\nansible_version=%s\nseal_sha256=%s\n' \
|
|
"${TEST_GUEST_CACHE_SCHEMA_VERSION}" \
|
|
"${TEST_GUEST_CACHE_GENERATION}" \
|
|
"${TEST_GUEST_CACHE_DISK_LAYOUT}" \
|
|
"${distro_name}" \
|
|
"${TEST_GUEST_OS_VERSION}" \
|
|
"${architecture}" \
|
|
"${TEST_GUEST_IMAGE_URL}" \
|
|
"${TEST_GUEST_IMAGE_HASH}" \
|
|
16G \
|
|
"${TEST_GUEST_ANSIBLE_VERSION}" \
|
|
"${seal_hash}"
|
|
|
|
for configuration in "$@"; do
|
|
configuration_hash=$(
|
|
test_vm_cache_sha256 \
|
|
"${OPENSHELL_TEST_GUEST_CONFIGURATIONS}/${configuration}"
|
|
) || return 1
|
|
printf -v configuration_line \
|
|
'configuration=%s:%s\n' \
|
|
"${configuration}" \
|
|
"${configuration_hash}"
|
|
material+=${configuration_line}
|
|
done
|
|
|
|
printf '%s' "${material}" | sha256sum | cut -d ' ' -f 1
|
|
}
|
|
|
|
test_vm_cache_tag() {
|
|
local distro_name=$1
|
|
local key=$2
|
|
printf 'v%s-%s-%s-%s\n' \
|
|
"${TEST_GUEST_CACHE_SCHEMA_VERSION}" \
|
|
"${distro_name}" \
|
|
"$(test_vm_cache_oci_architecture)" \
|
|
"${key}"
|
|
}
|
|
|
|
test_vm_cache_entry_dir() {
|
|
local root=$1
|
|
local key=$2
|
|
printf '%s/entries/%s\n' "${root}" "${key}"
|
|
}
|
|
|
|
test_vm_cache_metadata_matches() {
|
|
local metadata=$1
|
|
local key=$2
|
|
local distro_name=$3
|
|
shift 3
|
|
local architecture
|
|
local expected_configurations
|
|
architecture=$(test_vm_cache_oci_architecture) || return 1
|
|
expected_configurations=$(jq -cn --args '$ARGS.positional' "$@") || return 1
|
|
|
|
jq -e \
|
|
--argjson schema "${TEST_GUEST_CACHE_SCHEMA_VERSION}" \
|
|
--arg key "${key}" \
|
|
--arg distro "${distro_name}" \
|
|
--arg os_version "${TEST_GUEST_OS_VERSION}" \
|
|
--arg architecture "$(test_vm_cache_oci_architecture)" \
|
|
--arg base_hash "${TEST_GUEST_IMAGE_HASH}" \
|
|
--argjson configurations "${expected_configurations}" \
|
|
'
|
|
.schema == $schema and
|
|
.key == $key and
|
|
.distro == $distro and
|
|
.os_version == $os_version and
|
|
.architecture == $architecture and
|
|
.base_image_hash == $base_hash and
|
|
.configurations == $configurations
|
|
' "${metadata}" >/dev/null
|
|
}
|
|
|
|
test_vm_cache_local_entry_valid() {
|
|
local root=$1
|
|
local key=$2
|
|
local distro_name=$3
|
|
shift 3
|
|
local entry
|
|
entry=$(test_vm_cache_entry_dir "${root}" "${key}")
|
|
|
|
# Cache builders and OCI pulls verify the disk before atomically installing
|
|
# the complete entry. Keep cache-hit validation metadata-only so launching a
|
|
# guest does not hash and inspect the entire QCOW2 on every run.
|
|
[ -f "${entry}/complete" ] &&
|
|
[ -s "${entry}/disk.qcow2" ] &&
|
|
[ -f "${entry}/metadata.json" ] &&
|
|
test_vm_cache_metadata_matches \
|
|
"${entry}/metadata.json" "${key}" "${distro_name}" "$@"
|
|
}
|
|
|
|
test_vm_cache_validate_disk() {
|
|
local disk=$1
|
|
local info
|
|
info=$(qemu-img info --output=json "${disk}")
|
|
|
|
jq -e '
|
|
.format == "qcow2" and
|
|
(.["backing-filename"]? == null) and
|
|
(.["data-file"]? == null) and
|
|
((.snapshots? // []) | length == 0) and
|
|
(.["virtual-size"] > 0) and
|
|
(.["virtual-size"] <= 68719476736)
|
|
' <<<"${info}" >/dev/null
|
|
qemu-img check "${disk}" >/dev/null
|
|
}
|