From 6e77fc03699bc118afd0ea91f8aa5c1e6225fb5b Mon Sep 17 00:00:00 2001 From: Zygmunt Krynicki Date: Tue, 19 May 2026 23:40:00 +0200 Subject: [PATCH 1/3] test(snap): add spread integration tests The integration test suite runs on typical Linux distribution images and ensures that openshell can create a sandbox and execute a hello-world program inside. Tests have two components: 1) The `image-garden` program uses built-in rules, as well as `.image-garden.mk` to prepare virtual machine images for testing. The virtual machines are vanilla cloud images booted once with a cloud-init profile that prepares them for testing. At runtime garden downloads images to ~/.cache/garden/dl or $SNAP_USER_COMMON/cache/dl (when using the snap) and then saves customized differential images in `.image-garden/` in the project directory. In practice the pre-created environment has snapd, the docker snap and the "ghcr.io/nvidia/openshell-community/sandboxes/base:latest" docker image pre-pulled for faster test iteration. 2) The `spread` program uses `spread.yaml` and a collection of `task.yaml` files to run tests. The top-level file defines the set of test systems, contains project wide preparation logic where we install the snap and defines a single test suite which corresponds to the `tests/` directory. An initial smoke test that creates a sandbox and ensures it can run a shell hello world is provided. This ensures that the locally built snap really works on the set of test environments: - centos-cloud-10 - debian-cloud-13 - fedora-cloud-44 - ubuntu-cloud-24.04 - ubuntu-cloud-26.04 Those tests are typically used with the `image-garden` snap, which also includes spread: https://snapcraft.io/image-garden/ Signed-off-by: Zygmunt Krynicki --- .gitignore | 3 ++ .image-garden.mk | 42 +++++++++++++++++++++ .image-garden/.gitignore | 11 ++++++ spread.yaml | 80 ++++++++++++++++++++++++++++++++++++++++ tests/smoke/task.yaml | 20 ++++++++++ 5 files changed, 156 insertions(+) create mode 100644 .image-garden.mk create mode 100644 .image-garden/.gitignore create mode 100644 spread.yaml create mode 100644 tests/smoke/task.yaml diff --git a/.gitignore b/.gitignore index 24a77fce2..7e5bbf40c 100644 --- a/.gitignore +++ b/.gitignore @@ -219,5 +219,8 @@ rfc.md *.snap *.comp +# Spread reuse files +.spread-reuse.*.yaml + # Markdown/mermaid lint tooling deps scripts/lint-mermaid/node_modules/ diff --git a/.image-garden.mk b/.image-garden.mk new file mode 100644 index 000000000..f5a857359 --- /dev/null +++ b/.image-garden.mk @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +default_sandbox_image=ghcr.io/nvidia/openshell-community/sandboxes/base:latest + +define UBUNTU_CLOUD_INIT_USER_DATA_TEMPLATE +$(CLOUD_INIT_USER_DATA_TEMPLATE) +- snap wait system seed.loaded +- snap install docker +- snap run docker pull $(default_sandbox_image) +endef + +define DEBIAN_CLOUD_INIT_USER_DATA_TEMPLATE +$(CLOUD_INIT_USER_DATA_TEMPLATE) +- systemctl enable --now snapd.socket snapd.service snapd.apparmor.service +- snap wait system seed.loaded +- snap install docker +- snap run docker pull $(default_sandbox_image) +packages: +- snapd +endef + +define FEDORA_CLOUD_INIT_USER_DATA_TEMPLATE +$(CLOUD_INIT_USER_DATA_TEMPLATE) +- dnf install -y snapd +- systemctl enable --now snapd.socket +- snap wait system seed.loaded +- sudo ln -s /var/lib/snapd/snap /snap +- snap install docker +- snap run docker pull $(default_sandbox_image) +endef + +define CENTOS_CLOUD_INIT_USER_DATA_TEMPLATE +$(CLOUD_INIT_USER_DATA_TEMPLATE) +- yum install -y epel-release +- yum install -y snapd +- systemctl enable --now snapd.socket snapd.service +- snap wait system seed.loaded +- sudo ln -s /var/lib/snapd/snap /snap +- snap install docker +- snap run docker pull $(default_sandbox_image) +endef diff --git a/.image-garden/.gitignore b/.image-garden/.gitignore new file mode 100644 index 000000000..5e4f04d29 --- /dev/null +++ b/.image-garden/.gitignore @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +*.img +*.iso +*.lock +*.log +*.meta-data +*.qcow2 +*.run +*.user-data diff --git a/spread.yaml b/spread.yaml new file mode 100644 index 000000000..b3f7f9df5 --- /dev/null +++ b/spread.yaml @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +project: openshell + +backends: + garden: + type: adhoc + allocate: | + if [ -n "${SPREAD_HOST_PATH-}" ]; then + PATH="${SPREAD_HOST_PATH}" + fi + exec image-garden allocate --spread "$SPREAD_SYSTEM"."$(uname -m)" + discard: | + if [ -n "${SPREAD_HOST_PATH-}" ]; then + PATH="${SPREAD_HOST_PATH}" + fi + image-garden discard "$SPREAD_SYSTEM_ADDRESS" + systems: + - ubuntu-cloud-24.04: + username: ubuntu + password: ubuntu + - ubuntu-cloud-26.04: + username: ubuntu + password: ubuntu + - debian-cloud-13: + username: debian + password: debian + - fedora-cloud-44: + username: fedora + password: fedora + - centos-cloud-10: + username: centos + password: centos + +exclude: + - ".cache/*" + - ".image-garden/*" + - "target/*" + +path: /root/openshell + +prepare: | + # Install the openshell snap that was copied into the test environment. + snap install $(ls ./openshell_*.snap | sort -r | head -n 1) --dangerous + + # Connect snap interfaces. When installing from the store this + # is auto-connected by the snap declaration assertion, but locally + # we need to do it manually. + snap connect openshell:docker docker:docker-daemon + snap connect openshell:log-observe + snap connect openshell:system-observe + snap connect openshell:ssh-keys + + # Add the local gateway to user configuration. + openshell gateway add http://127.0.0.1:17670 --local --name snap-docker + openshell gateway select snap-docker + openshell status + +debug-each: | + echo "Kernel and architecture:" + uname -a + + echo "OS release info:" + cat /etc/os-release + + echo "Installed snaps:" + snap list + + set +e + + echo "Snap connections of the openshell snap:" + snap connections openshell + + echo "Openshell version:" + snap run openshell --version + +suites: + tests/: + summary: Smoke tests for OpenShell snap diff --git a/tests/smoke/task.yaml b/tests/smoke/task.yaml new file mode 100644 index 000000000..91cc719ab --- /dev/null +++ b/tests/smoke/task.yaml @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +summary: Smoke test for creating a sandbox +details: | + This test verifies that the openshell snap is properly installed + and that the openshell command is available and functional. + A test sandbox is created on the selected gateway. A hello world program is + then invoked in the sandbox. + +prepare: | + snap run openshell sandbox list | MATCH "No sandboxes found." + +execute: | + snap run openshell sandbox create -- echo "Hello, OpenShell!" | MATCH "Hello, OpenShell!" + snap run openshell sandbox list | MATCH ".*Ready" + +restore: | + snap run openshell sandbox delete --all | MATCH ".*Deleted.*" + snap run openshell sandbox list | MATCH "No sandboxes found." From e9f76e2fc35bfbff6dfbfcf025bb8724f3733b81 Mon Sep 17 00:00:00 2001 From: Zygmunt Krynicki Date: Wed, 20 May 2026 09:07:34 +0200 Subject: [PATCH 2/3] test(snap): pre-pull default image more reliably We need to give docker a moment to finish setting up. We an also add a docker system group while we are at it. With this setting it is worth to keep prepared images around in CI but the time advantage is worth it. Signed-off-by: Zygmunt Krynicki --- .image-garden.mk | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.image-garden.mk b/.image-garden.mk index f5a857359..1ca16faa0 100644 --- a/.image-garden.mk +++ b/.image-garden.mk @@ -3,19 +3,24 @@ default_sandbox_image=ghcr.io/nvidia/openshell-community/sandboxes/base:latest +define install_and_setup_docker +- addgroup --system docker +- snap install docker +- while [ ! -S /run/docker.sock ]; do sleep 3; done +- "snap run docker pull $(default_sandbox_image)" +endef + define UBUNTU_CLOUD_INIT_USER_DATA_TEMPLATE $(CLOUD_INIT_USER_DATA_TEMPLATE) - snap wait system seed.loaded -- snap install docker -- snap run docker pull $(default_sandbox_image) +$(install_and_setup_docker) endef define DEBIAN_CLOUD_INIT_USER_DATA_TEMPLATE $(CLOUD_INIT_USER_DATA_TEMPLATE) - systemctl enable --now snapd.socket snapd.service snapd.apparmor.service - snap wait system seed.loaded -- snap install docker -- snap run docker pull $(default_sandbox_image) +$(install_and_setup_docker) packages: - snapd endef @@ -26,8 +31,7 @@ $(CLOUD_INIT_USER_DATA_TEMPLATE) - systemctl enable --now snapd.socket - snap wait system seed.loaded - sudo ln -s /var/lib/snapd/snap /snap -- snap install docker -- snap run docker pull $(default_sandbox_image) +$(install_and_setup_docker) endef define CENTOS_CLOUD_INIT_USER_DATA_TEMPLATE @@ -37,6 +41,5 @@ $(CLOUD_INIT_USER_DATA_TEMPLATE) - systemctl enable --now snapd.socket snapd.service - snap wait system seed.loaded - sudo ln -s /var/lib/snapd/snap /snap -- snap install docker -- snap run docker pull $(default_sandbox_image) +$(install_and_setup_docker) endef From 551d47fed4ae591541fb59fdfa9fbe4ed47d1ee0 Mon Sep 17 00:00:00 2001 From: Zygmunt Krynicki Date: Wed, 20 May 2026 09:35:03 +0200 Subject: [PATCH 3/3] test(snap): remove centos 10 from test loop CentOS 10 cloud image has a truncated checksum file causing each download to fail validation. Let's remove it from spread.yaml while keeping the .image-garden.mk entry for another day. Signed-off-by: Zygmunt Krynicki --- spread.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/spread.yaml b/spread.yaml index b3f7f9df5..265ef7b17 100644 --- a/spread.yaml +++ b/spread.yaml @@ -29,9 +29,6 @@ backends: - fedora-cloud-44: username: fedora password: fedora - - centos-cloud-10: - username: centos - password: centos exclude: - ".cache/*"