Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ jobs:
${{
(inputs.test-name == 'badaml-sandbox' && 'badaml-sandbox') ||
(inputs.test-name == 'badaml-vuln' && 'badaml-vuln') ||
(inputs.test-name == 'runtime-rs-tmp' && 'runtime-rs') ||
'base'
}}
steps:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/e2e_manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ on:
- policy
- proxy
- regression
- runtime-rs-tmp
- servicemesh
- vault
- volumestatefulset
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/e2e_nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ jobs:
- policy
- proxy
- regression
- runtime-rs-tmp
- servicemesh
- vault
- volumestatefulset
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/e2e_runtime_rs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: e2e test runtime-rs

on:
pull_request:
paths:
- overlays/sets/runtime-rs.nix
- packages/by-name/kata/runtime/**
- packages/by-name/kata/runtime-rs/**
- e2e/runtime-rs-tmp/**

jobs:
tests:
strategy:
matrix:
platform:
- name: Metal-QEMU-SNP
runner: SNP
self-hosted: true
- name: Metal-QEMU-TDX
runner: TDX
self-hosted: true
- name: Metal-QEMU-SNP-GPU
runner: SNP-GPU
self-hosted: true
- name: Metal-QEMU-TDX-GPU
runner: TDX-GPU
self-hosted: true
test-name:
- runtime-rs-tmp
fail-fast: false
name: "${{ matrix.platform.name }}"
uses: ./.github/workflows/e2e.yml
with:
skip-undeploy: false
test-name: ${{ matrix.test-name }}
platform: ${{ matrix.platform.name }}
runner: ${{ matrix.platform.runner }}
self-hosted: ${{ matrix.platform.self-hosted }}
debug-shell: true
Comment on lines +32 to +39
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to change the SET?

SET: >-
${{
(inputs.test-name == 'badaml-sandbox' && 'badaml-sandbox') ||
(inputs.test-name == 'badaml-vuln' && 'badaml-vuln') ||
'base'
}}

secrets:
GITHUB_TOKEN_IN: ${{ secrets.GITHUB_TOKEN }}
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
NUNKI_CI_COMMIT_PUSH_PR: ${{ secrets.NUNKI_CI_COMMIT_PUSH_PR }}
TEAMS_CI_WEBHOOK: ${{ secrets.TEAMS_CI_WEBHOOK }}
CONTRAST_GHCR_READ: ${{ secrets.CONTRAST_GHCR_READ }}
permissions:
contents: read
packages: write
54 changes: 54 additions & 0 deletions e2e/runtime-rs-tmp/runtimers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2026 Edgeless Systems GmbH
// SPDX-License-Identifier: BUSL-1.1

package runtimerstmp

import (
"context"
"flag"
"os"
"testing"
"time"

"github.com/edgelesssys/contrast/e2e/internal/contrasttest"
"github.com/edgelesssys/contrast/internal/kuberesource"
"github.com/edgelesssys/contrast/internal/manifest"
"github.com/edgelesssys/contrast/internal/platforms"
"github.com/stretchr/testify/require"
)

// TODO: remove when runtime-rs is fully integrated.
// Right now there are some failures left, so we only test that we can start up a container.
// Remove the test and use openssl and other tests when ready.

func TestRuntimeRS(t *testing.T) {
platform, err := platforms.FromString(contrasttest.Flags.PlatformStr)
require.NoError(t, err)

ct := contrasttest.New(t)

require.True(t, contrasttest.Flags.InsecureEnableDebugShell, "the --insecure-enable-debug-shell-access flag must be set to true to extract the initrd start address")

runtimeHandler, err := manifest.RuntimeHandler(platform)
require.NoError(t, err)
resources := kuberesource.CoordinatorBundle()
resources = kuberesource.PatchRuntimeHandlers(resources, runtimeHandler)
resources = kuberesource.AddPortForwarders(resources)
ct.Init(t, resources)

require.True(t, t.Run("generate", ct.Generate), "contrast generate needs to succeed for subsequent tests")
require.True(t, t.Run("apply", ct.Apply), "Kubernetes resources need to be applied for subsequent tests")

// 'set' currently errors because of wrong measurements, but the debugshell init container should come up.
require.True(t, t.Run("wait for debugshell", func(t *testing.T) {
ctx, cancel := context.WithTimeout(t.Context(), ct.FactorPlatformTimeout(2*time.Minute))
defer cancel()
require.NoError(t, ct.Kubeclient.WaitForContainer(ctx, ct.Namespace, "coordinator-0", "contrast-debug-shell"))
}), "debugshell start must succeed for subsequent tests")
}

func TestMain(m *testing.M) {
contrasttest.RegisterFlags()
flag.Parse()
os.Exit(m.Run())
}
48 changes: 10 additions & 38 deletions nodeinstaller/internal/kataconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,15 @@
package kataconfig

import (
_ "embed"
"fmt"
"path/filepath"

"github.com/edgelesssys/contrast/internal/platforms"
"github.com/pelletier/go-toml/v2"
)

var (
// kataBareMetalQEMUTDXBaseConfig is the configuration file for the Kata runtime on bare-metal TDX
// with QEMU.
//
//go:embed configuration-qemu-tdx.toml
kataBareMetalQEMUTDXBaseConfig string

// kataBareMetalQEMUSNPBaseConfig is the configuration file for the Kata runtime on bare-metal SNP
// with QEMU.
//
//go:embed configuration-qemu-snp.toml
kataBareMetalQEMUSNPBaseConfig string

// RuntimeNamePlaceholder is the placeholder for the per-runtime path (i.e. /opt/edgeless/contrast-cc...) in the target file paths.
RuntimeNamePlaceholder = "@@runtimeName@@"
)
// RuntimeNamePlaceholder is the placeholder for the per-runtime path (i.e. /opt/edgeless/contrast-cc...) in the target file paths.
var RuntimeNamePlaceholder = "@@runtimeName@@"

// KataRuntimeConfig returns the Kata runtime configuration.
func KataRuntimeConfig(
Expand Down Expand Up @@ -68,18 +53,6 @@ func KataRuntimeConfig(
config.Agent["kata"]["debug_console_enabled"] = true
config.Runtime["enable_debug"] = true
}
// For larger images, we've been running into timeouts in e2e tests.
config.Agent["kata"]["dial_timeout"] = 120
config.Runtime["create_container_timeout"] = 120
// GPU-specific settings
if platforms.IsGPU(platform) {
config.Hypervisor["qemu"]["cold_plug_vfio"] = "root-port"
// GPU images tend to be larger, so give a better default timeout that
// allows for pulling those.
config.Agent["kata"]["dial_timeout"] = 600
config.Runtime["create_container_timeout"] = 600
config.Runtime["pod_resource_api_sock"] = "/var/lib/kubelet/pod-resources/kubelet.sock"
}

// Use the resources installed by Contrast node-installer.
config.Hypervisor["qemu"]["initrd"] = filepath.Join(baseDir, "share", "kata-initrd.zst")
Expand All @@ -92,8 +65,6 @@ func KataRuntimeConfig(
// TODO(katexochen): Remove after https://github.com/kata-containers/kata-containers/pull/12472 is merged.
config.Hypervisor["qemu"]["disable_image_nvdimm"] = true

// Force container image gust pull so we don't have to use nydus-snapshotter.
config.Runtime["experimental_force_guest_pull"] = true
// Replace the kernel params entirely (and don't append) since that's
// also what we do when calculating the launch measurement.
config.Hypervisor["qemu"]["kernel_params"] = qemuExtraKernelParams
Expand All @@ -105,23 +76,24 @@ func KataRuntimeConfig(
// Fix and align guest memory calculation.
config.Hypervisor["qemu"]["default_memory"] = platforms.DefaultMemoryInMebiBytes(platform)
config.Runtime["sandbox_cgroup_only"] = true
// Currently not using the upstream encrypted emptyDir feature.
config.Runtime["emptydir_mode"] = "shared-fs"

// TODO: Check again why we need this and how we can avoid it.
config.Hypervisor["qemu"]["block_device_aio"] = "threads"

config = extraRuntimeConfig(config, platform)

return &config, nil
}

// Config is the configuration for the Kata runtime.
// Source: https://github.com/kata-containers/kata-containers/blob/4029d154ba0c26fcf4a8f9371275f802e3ef522c/src/runtime/pkg/katautils/Config.go
// This is a simplified version of the actual configuration.
type Config struct {
Hypervisor map[string]hypervisorConfig
Agent map[string]agentConfig
Image imageConfig
Factory factoryConfig
Runtime runtimeConfig
Hypervisor map[string]hypervisorConfig `toml:"hypervisor"`
Agent map[string]agentConfig `toml:"agent"`
Image imageConfig `toml:"image"`
Factory factoryConfig `toml:"factory"`
Runtime runtimeConfig `toml:"runtime"`
}

// Marshal encodes the configuration as TOML.
Expand Down
17 changes: 3 additions & 14 deletions nodeinstaller/internal/kataconfig/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,6 @@ import (
"github.com/stretchr/testify/require"
)

var (
//go:embed testdata/expected-configuration-qemu-snp.toml
expectedConfMetalQEMUSNP []byte
//go:embed testdata/expected-configuration-qemu-tdx.toml
expectedConfMetalQEMUTDX []byte
//go:embed testdata/expected-configuration-qemu-snp-gpu.toml
expectedConfMetalQEMUSNPGPU []byte
//go:embed testdata/expected-configuration-qemu-tdx-gpu.toml
expectedConfMetalQEMUTDXGPU []byte
)

func TestKataRuntimeConfig(t *testing.T) {
testCases := map[platforms.Platform]struct {
changeSnpFields bool
Expand Down Expand Up @@ -63,9 +52,9 @@ func TestKataRuntimeConfig(t *testing.T) {
// section and no section are handled differently by Kata, so we make sure that this section is
// always present.
// It's covered by the comparison with testdata, but we want to keep this explicit.
assert.Contains(string(configBytes), "[Agent.kata]")
assert.Contains(string(configBytes), "[Runtime]")
assert.Contains(string(configBytes), "[Hypervisor.qemu]")
assert.Contains(string(configBytes), "[agent.kata]")
assert.Contains(string(configBytes), "[runtime]")
assert.Contains(string(configBytes), "[hypervisor.qemu]")
})
}
}
Loading
Loading