chore: move bash tests to integration

move extensions and secureboot tests to integration.
Makes it easier to test.

Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
Noel Georgi
2023-08-11 21:29:34 +05:30
parent 52b3d8d37c
commit 6b0373ebef
16 changed files with 834 additions and 180 deletions

View File

@@ -443,7 +443,7 @@ local integration_qemu_trusted_boot = Step('e2e-qemu-trusted-boot', target='e2e-
IMAGE_REGISTRY: local_registry, IMAGE_REGISTRY: local_registry,
VIA_MAINTENANCE_MODE: 'true', VIA_MAINTENANCE_MODE: 'true',
WITH_TRUSTED_BOOT_ISO: 'true', WITH_TRUSTED_BOOT_ISO: 'true',
WITH_TEST: 'validate_booted_secureboot', EXTRA_TEST_ARGS: '-talos.trustedboot',
}); });
local build_race = Step('build-race', target='initramfs installer', depends_on=[load_artifacts], environment={ IMAGE_REGISTRY: local_registry, PUSH: true, TAG_SUFFIX: '-race', WITH_RACE: '1', PLATFORM: 'linux/amd64' }); local build_race = Step('build-race', target='initramfs installer', depends_on=[load_artifacts], environment={ IMAGE_REGISTRY: local_registry, PUSH: true, TAG_SUFFIX: '-race', WITH_RACE: '1', PLATFORM: 'linux/amd64' });
@@ -455,11 +455,10 @@ local integration_provision_tests_track_1 = Step('provision-tests-track-1', priv
local integration_provision_tests_track_2 = Step('provision-tests-track-2', privileged=true, depends_on=[integration_provision_tests_prepare], environment={ IMAGE_REGISTRY: local_registry }); local integration_provision_tests_track_2 = Step('provision-tests-track-2', privileged=true, depends_on=[integration_provision_tests_prepare], environment={ IMAGE_REGISTRY: local_registry });
local integration_extensions = Step('e2e-extensions', target='e2e-qemu', privileged=true, depends_on=[extensions_patch_manifest], environment={ local integration_extensions = Step('e2e-extensions', target='e2e-qemu', privileged=true, depends_on=[extensions_patch_manifest], environment={
SHORT_INTEGRATION_TEST: 'yes', QEMU_MEMORY_WORKERS: '4096',
QEMU_MEMORY_WORKERS: '3072',
WITH_CONFIG_PATCH_WORKER: '@_out/extensions-patch.json', WITH_CONFIG_PATCH_WORKER: '@_out/extensions-patch.json',
WITH_TEST: 'run_extensions_test',
IMAGE_REGISTRY: local_registry, IMAGE_REGISTRY: local_registry,
EXTRA_TEST_ARGS: '-talos.extensions.testtype=qemu',
}); });
local integration_cilium = Step('e2e-cilium', target='e2e-qemu', privileged=true, depends_on=[load_artifacts], environment={ local integration_cilium = Step('e2e-cilium', target='e2e-qemu', privileged=true, depends_on=[load_artifacts], environment={
SHORT_INTEGRATION_TEST: 'yes', SHORT_INTEGRATION_TEST: 'yes',

View File

@@ -16,7 +16,7 @@ CLOUD_IMAGES_EXTRA_ARGS ?= ""
ARTIFACTS := _out ARTIFACTS := _out
TOOLS ?= ghcr.io/siderolabs/tools:v1.5.0 TOOLS ?= ghcr.io/siderolabs/tools:v1.5.0
PKGS ?= v1.5.0 PKGS ?= v1.6.0-alpha.0-5-g7717b7e
EXTRAS ?= v1.5.0 EXTRAS ?= v1.5.0
# renovate: datasource=github-tags depName=golang/go # renovate: datasource=github-tags depName=golang/go
GO_VERSION ?= 1.20 GO_VERSION ?= 1.20

View File

@@ -195,8 +195,6 @@ case "${TEST_MODE:-default}" in
;; ;;
*) *)
get_kubeconfig get_kubeconfig
validate_virtio_modules
validate_rlimit_nofile
run_talos_integration_test run_talos_integration_test
run_kubernetes_integration_test run_kubernetes_integration_test

View File

@@ -150,7 +150,7 @@ function run_talos_integration_test {
;; ;;
esac esac
"${INTEGRATION_TEST}" -test.v -talos.failfast -talos.talosctlpath "${TALOSCTL}" -talos.kubectlpath "${KUBECTL}" -talos.provisioner "${PROVISIONER}" -talos.name "${CLUSTER_NAME}" "${TEST_RUN[@]}" "${TEST_SHORT[@]}" "${INTEGRATION_TEST}" -test.v -talos.failfast -talos.talosctlpath "${TALOSCTL}" -talos.kubectlpath "${KUBECTL}" -talos.provisioner "${PROVISIONER}" -talos.name "${CLUSTER_NAME}" "${EXTRA_TEST_ARGS[@]}" "${TEST_RUN[@]}" "${TEST_SHORT[@]}"
} }
function run_talos_integration_test_docker { function run_talos_integration_test_docker {
@@ -170,7 +170,7 @@ function run_talos_integration_test_docker {
;; ;;
esac esac
"${INTEGRATION_TEST}" -test.v -talos.talosctlpath "${TALOSCTL}" -talos.kubectlpath "${KUBECTL}" -talos.k8sendpoint 127.0.0.1:6443 -talos.provisioner "${PROVISIONER}" -talos.name "${CLUSTER_NAME}" "${TEST_RUN[@]}" "${TEST_SHORT[@]}" "${INTEGRATION_TEST}" -test.v -talos.talosctlpath "${TALOSCTL}" -talos.kubectlpath "${KUBECTL}" -talos.k8sendpoint 127.0.0.1:6443 -talos.provisioner "${PROVISIONER}" -talos.name "${CLUSTER_NAME}" "${EXTRA_TEST_ARGS[@]}" "${TEST_RUN[@]}" "${TEST_SHORT[@]}"
} }
function run_kubernetes_conformance_test { function run_kubernetes_conformance_test {
@@ -221,81 +221,6 @@ function build_registry_mirrors {
fi fi
} }
function run_extensions_test {
# e2e-qemu creates 3 controlplanes
# use a worker node to test extensions
"${TALOSCTL}" config node 172.20.1.5
echo "Testing firmware extensions..."
${TALOSCTL} ls /lib/firmware | grep amd-ucode
${TALOSCTL} ls /lib/firmware | grep bnx2x
${TALOSCTL} ls /lib/firmware | grep i915
${TALOSCTL} ls /lib/firmware | grep intel-ucode
echo "Testing kernel modules tree extension..."
${TALOSCTL} get extensions modules.dep
KERNEL_VERSION=$(${TALOSCTL} get extensions modules.dep -o json | jq -r '.spec.metadata.version')
${TALOSCTL} ls "/lib/modules/${KERNEL_VERSION}/extras/" | grep gasket
${TALOSCTL} read "/lib/modules/${KERNEL_VERSION}/modules.dep" | grep -E gasket
${TALOSCTL} ls "/lib/modules/${KERNEL_VERSION}/extras/" | grep drbd
${TALOSCTL} read "/lib/modules/${KERNEL_VERSION}/modules.dep" | grep -E drbd
${TALOSCTL} ls "/lib/modules/${KERNEL_VERSION}/kernel/drivers/video/" | grep nvidia
${TALOSCTL} read "/lib/modules/${KERNEL_VERSION}/modules.dep" | grep -E nvidia
echo "Testing drbd and gasket modules are loaded..."
${TALOSCTL} read /proc/modules | grep -E drbd
${TALOSCTL} read /proc/modules | grep -E gasket
echo "Testing kernel modules signature..."
${TALOSCTL} read "/lib/modules/${KERNEL_VERSION}/extras/drbd.ko" | ${MODULE_SIG_VERIFY} -cert "${KERNEL_MODULE_SIGNING_PUBLIC_KEY}" -module -
${TALOSCTL} read "/lib/modules/${KERNEL_VERSION}/extras/gasket.ko" | ${MODULE_SIG_VERIFY} -cert "${KERNEL_MODULE_SIGNING_PUBLIC_KEY}" -module -
${TALOSCTL} read "/lib/modules/${KERNEL_VERSION}/kernel/drivers/video/nvidia.ko" | ${MODULE_SIG_VERIFY} -cert "${KERNEL_MODULE_SIGNING_PUBLIC_KEY}" -module -
echo "Testing iscsi-tools extensions service..."
${TALOSCTL} services ext-iscsid | grep -E "STATE\s+Running"
${TALOSCTL} services ext-tgtd | grep -E "STATE\s+Running"
echo "Testing nut-client extensions service..."
${TALOSCTL} services ext-nut-client | grep -E "STATE\s+Running"
echo "Testing gVsisor..."
${KUBECTL} apply -f "${PWD}/hack/test/gvisor/manifest.yaml"
sleep 10
${KUBECTL} wait --for=condition=ready pod nginx-gvisor --timeout=2m
echo "Testing hello-world extension service..."
${TALOSCTL} services ext-hello-world | grep -E "STATE\s+Running"
curl http://172.20.1.5/ | grep Hello
echo "Testing tailscale extension service..."
${TALOSCTL} services ext-tailscale | grep -E "STATE\s+Running"
${TALOSCTL} get links tailscale0
echo "Testing qemu-guest-agent extension service..."
${TALOSCTL} services ext-qemu-guest-agent | grep -E "STATE\s+Running"
# get exisitng boot id
BOOT_ID=$(get_boot_id)
NODE_HOSTNAME=$(${TALOSCTL} get hostname -o json | jq -r '.spec.hostname')
CLUSTERNAME=$(cut -d '-' -f 1-2 <<< "${NODE_HOSTNAME}")
# issue a reboot via qemu-guest-agent
echo '{"execute":"guest-shutdown", "arguments": {"mode": "reboot"}}' | socat - unix-connect:"${HOME}/.talos/clusters/${CLUSTERNAME}/${NODE_HOSTNAME}.sock"
# wait for the node to reboot
${TALOSCTL} -n 172.20.1.2 health
NEW_BOOT_ID=$(get_boot_id)
# verify that the boot id has changed
if [ "${BOOT_ID}" == "${NEW_BOOT_ID}" ]; then
echo "ERROR: boot id has not changed, reboot failed"
exit 1
fi
# set talosctl config back to the first controlplane
"${TALOSCTL}" config node 172.20.1.2
}
function get_boot_id() {
${TALOSCTL} read /proc/sys/kernel/random/boot_id
}
function run_csi_tests { function run_csi_tests {
${HELM} repo add rook-release https://charts.rook.io/release ${HELM} repo add rook-release https://charts.rook.io/release
${HELM} repo update ${HELM} repo update
@@ -314,21 +239,6 @@ function run_csi_tests {
KUBERNETES_SERVICE_HOST="" KUBECONFIG="${TMP}/kubeconfig" "${KUBESTR}" fio --storageclass ceph-block --size 10G KUBERNETES_SERVICE_HOST="" KUBECONFIG="${TMP}/kubeconfig" "${KUBESTR}" fio --storageclass ceph-block --size 10G
} }
function validate_virtio_modules {
${TALOSCTL} read /proc/modules | grep -q virtio
}
function validate_rlimit_nofile {
# verify that RLIMIT_NOFILE is set to 1048576
${KUBECTL} run --rm --restart=Never -it rlimit-test --image=alpine -- /bin/sh -c "ulimit -n" | grep 1048576
}
function validate_booted_secureboot {
${TALOSCTL} dmesg | grep "Secure boot enabled"
${TALOSCTL} get securitystate -o json
${TALOSCTL} get securitystate -o json | jq -e '.spec.secureBoot == true'
}
function install_and_run_cilium_cni_tests { function install_and_run_cilium_cni_tests {
get_kubeconfig get_kubeconfig

View File

@@ -4,7 +4,7 @@
"path": "/machine/install/extensions", "path": "/machine/install/extensions",
"value": [ "value": [
{ {
"image": map(select(. | contains("nvidia-container-toolkit") or contains("nvidia-fabricmanager") | not)) | .[] "image": map(select(. | contains("nvidia") or contains("tailscale") | not)) | .[]
} }
] ]
}, },
@@ -20,11 +20,68 @@
"path": "/machine/kernel", "path": "/machine/kernel",
"value": { "value": {
"modules": [ "modules": [
{
"name": "asix"
},
{
"name": "ax88179_178a"
},
{
"name": "ax88796b"
},
{
"name": "cdc_ether"
},
{
"name": "cdc_mbim"
},
{
"name": "cdc_ncm"
},
{
"name": "cdc_subset"
},
{
"name": "cdc_wdm"
},
{ {
"name": "drbd" "name": "drbd"
}, },
{ {
"name": "gasket" "name": "gasket"
},
{
"name": "net1080"
},
{
"name": "option"
},
{
"name": "qmi_wwan"
},
{
"name": "r8153_ecm"
},
{
"name": "thunderbolt"
},
{
"name": "thunderbolt_net"
},
{
"name": "usb_wwan"
},
{
"name": "usbnet"
},
{
"name": "usbserial"
},
{
"name": "zaurus"
},
{
"name": "zfs"
} }
] ]
} }

View File

@@ -11,6 +11,11 @@ import "github.com/stretchr/testify/suite"
var allSuites []suite.TestingSuite var allSuites []suite.TestingSuite
const (
provisionerDocker = "docker"
provisionerQEMU = "qemu"
)
// GetAllSuites returns all the suites for API test. // GetAllSuites returns all the suites for API test.
// //
// Depending on build tags, this might return different lists. // Depending on build tags, this might return different lists.

View File

@@ -0,0 +1,198 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//go:build integration_api
package api
import (
"bufio"
"bytes"
"context"
"strings"
"time"
"github.com/siderolabs/go-retry/retry"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/remotecommand"
"k8s.io/kubectl/pkg/scheme"
"github.com/siderolabs/talos/internal/integration/base"
"github.com/siderolabs/talos/pkg/machinery/client"
)
// CommonSuite verifies some default settings such as ulimits.
type CommonSuite struct {
base.K8sSuite
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
// SuiteName ...
func (suite *CommonSuite) SuiteName() string {
return "api.CommonSuite"
}
// SetupTest ...
func (suite *CommonSuite) SetupTest() {
if suite.Cluster.Provisioner() == provisionerDocker {
suite.T().Skip("skipping default values tests in docker")
}
// make sure API calls have timeout
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
}
// TearDownTest ...
func (suite *CommonSuite) TearDownTest() {
if suite.ctxCancel != nil {
suite.ctxCancel()
}
}
// TestVirtioModulesLoaded verifies that the virtio modules are loaded.
func (suite *CommonSuite) TestVirtioModulesLoaded() {
if suite.Cluster.Provisioner() == provisionerQEMU {
suite.T().Skip("skipping virtio modules tests in qemu")
}
expectedVirtIOModules := []string{
"virtio_balloon",
"virtio_pci",
"virtio_pci_legacy_dev",
"virtio_pci_modern_dev",
}
node := suite.RandomDiscoveredNodeInternalIP()
ctx := client.WithNode(suite.ctx, node)
fileReader, err := suite.Client.Read(ctx, "/proc/modules")
defer func() {
err = fileReader.Close()
}()
suite.Require().NoError(err)
scanner := bufio.NewScanner(fileReader)
var loadedModules []string
for scanner.Scan() {
loadedModules = append(loadedModules, strings.Split(scanner.Text(), " ")[0])
}
suite.Require().NoError(scanner.Err())
for _, expectedModule := range expectedVirtIOModules {
suite.Require().Contains(loadedModules, expectedModule, "expected module %s to be loaded", expectedModule)
}
}
// TestCommonDefaults verifies that the default ulimits are set.
func (suite *CommonSuite) TestCommonDefaults() {
expectedUlimit := `
core file size (blocks) (-c) 0
data seg size (kb) (-d) unlimited
scheduling priority (-e) 0
file size (blocks) (-f) unlimited
max locked memory (kb) (-l) 8192
max memory size (kb) (-m) unlimited
open files (-n) 1048576
POSIX message queues (bytes) (-q) 819200
real-time priority (-r) 0
stack size (kb) (-s) 8192
cpu time (seconds) (-t) unlimited
virtual memory (kb) (-v) unlimited
file locks (-x) unlimited
`
_, err := suite.Clientset.CoreV1().Pods("default").Create(suite.ctx, &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "defaults-test",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "defaults-test",
Image: "alpine",
Command: []string{
"tail",
"-f",
"/dev/null",
},
},
},
},
}, metav1.CreateOptions{})
defer suite.Clientset.CoreV1().Pods("default").Delete(suite.ctx, "defaults-test", metav1.DeleteOptions{}) //nolint:errcheck
suite.Require().NoError(err)
// wait for the pod to be ready
suite.Require().NoError(retry.Constant(8*time.Minute, retry.WithUnits(time.Second*10)).Retry(
func() error {
pod, podErr := suite.Clientset.CoreV1().Pods("default").Get(suite.ctx, "defaults-test", metav1.GetOptions{})
if podErr != nil {
return retry.ExpectedErrorf("error getting pod: %s", podErr)
}
if pod.Status.Phase != corev1.PodRunning {
return retry.ExpectedErrorf("pod is not running yet: %s", pod.Status.Phase)
}
return nil
},
))
stdout, stderr, err := suite.executeRemoteCommand("default", "defaults-test", "ulimit -c -d -e -f -l -m -n -q -r -s -t -v -x")
suite.Require().NoError(err)
suite.Require().Equal("", stderr)
suite.Require().Equal(strings.TrimPrefix(expectedUlimit, "\n"), stdout)
}
func (suite *CommonSuite) executeRemoteCommand(namespace, podName, command string) (string, string, error) {
cmd := []string{
"/bin/sh",
"-c",
command,
}
req := suite.Clientset.CoreV1().RESTClient().Post().Resource("pods").Name(podName).
Namespace(namespace).SubResource("exec")
option := &corev1.PodExecOptions{
Command: cmd,
Stdin: false,
Stdout: true,
Stderr: true,
TTY: false,
}
req.VersionedParams(
option,
scheme.ParameterCodec,
)
exec, err := remotecommand.NewSPDYExecutor(suite.RestConfig, "POST", req.URL())
if err != nil {
return "", "", err
}
var stdout, stderr bytes.Buffer
err = exec.StreamWithContext(suite.ctx, remotecommand.StreamOptions{
Stdout: &stdout,
Stderr: &stderr,
})
if err != nil {
return "", "", err
}
return stdout.String(), stderr.String(), nil
}
func init() {
allSuites = append(allSuites, &CommonSuite{})
}

View File

@@ -0,0 +1,382 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//go:build integration_api
package api
import (
"bufio"
"context"
"fmt"
"io"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/go-retry/retry"
corev1 "k8s.io/api/core/v1"
nodev1 "k8s.io/api/node/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/siderolabs/talos/cmd/talosctl/pkg/talos/helpers"
"github.com/siderolabs/talos/internal/integration/base"
machineapi "github.com/siderolabs/talos/pkg/machinery/api/machine"
"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
"github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
)
// ExtensionsSuite verifies Talos is securebooted.
type ExtensionsSuite struct {
base.K8sSuite
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
// ExtensionsTestType specifies the type of extensions test to run.
type ExtensionsTestType string
const (
// ExtensionsTestTypeNone disables extensions tests.
ExtensionsTestTypeNone ExtensionsTestType = "none"
// ExtensionsTestTypeQEMU enables qemu extensions tests.
ExtensionsTestTypeQEMU ExtensionsTestType = "qemu"
// ExtensionsTestTypeNvidia enables nvidia extensions tests.
ExtensionsTestTypeNvidia ExtensionsTestType = "nvidia"
// ExtensionsTestTypeNvidiaFabricManager enables nvidia fabric manager extensions tests.
ExtensionsTestTypeNvidiaFabricManager ExtensionsTestType = "nvidia-fabricmanager"
)
// SuiteName ...
func (suite *ExtensionsSuite) SuiteName() string {
return "api.ExtensionsSuite"
}
// SetupTest ...
func (suite *ExtensionsSuite) SetupTest() {
if testing.Short() {
suite.T().Skip("skipping in short mode")
}
if suite.Cluster.Provisioner() == provisionerDocker {
suite.T().Skip("skipping extensions tests in docker")
}
if suite.ExtensionsTestType == string(ExtensionsTestTypeNone) {
suite.T().Skip("skipping as extensions test are not enabled")
}
// make sure API calls have timeout
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 5*time.Minute)
}
// TearDownTest ...
func (suite *ExtensionsSuite) TearDownTest() {
if suite.ctxCancel != nil {
suite.ctxCancel()
}
}
// TestExtensionsExpectedPaths verifies expected paths are present.
func (suite *ExtensionsSuite) TestExtensionsExpectedPaths() {
if suite.ExtensionsTestType != string(ExtensionsTestTypeQEMU) {
suite.T().Skip("skipping as qemu extensions test are not enabled")
}
expectedPaths := []string{
"/lib/firmware/amd-ucode",
"/lib/firmware/bnx2x",
"/lib/firmware/i915",
"/lib/firmware/intel-ucode",
}
node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker)
ctx := client.WithNode(suite.ctx, node)
for _, path := range expectedPaths {
stream, err := suite.Client.LS(ctx, &machineapi.ListRequest{
Root: path,
Types: []machineapi.ListRequest_Type{machineapi.ListRequest_DIRECTORY},
})
suite.Require().NoError(err)
suite.Require().NoError(helpers.ReadGRPCStream(stream, func(info *machineapi.FileInfo, node string, multipleNodes bool) error {
suite.Require().Equal(path, info.Name, "expected %s to exist", path)
return nil
}))
}
}
// TestExtensionsExpectedModules verifies expected modules are loaded and in modules.dep.
func (suite *ExtensionsSuite) TestExtensionsExpectedModules() {
// expectedModulesModDep is a map of module name to module.dep name
expectedModulesModDep := map[string]string{
"asix": "asix.ko",
"ax88179_178a": "ax88179_178a.ko",
"ax88796b": "ax88796b.ko",
"cdc_ether": "cdc_ether.ko",
"cdc_mbim": "cdc_mbim.ko",
"cdc_ncm": "cdc_ncm.ko",
"cdc_subset": "cdc_subset.ko",
"cdc_wdm": "cdc-wdm.ko",
"drbd": "drbd.ko",
"gasket": "gasket.ko",
"net1080": "net1080.ko",
"option": "option.ko",
"qmi_wwan": "qmi_wwan.ko",
"r8153_ecm": "r8153_ecm.ko",
"thunderbolt": "thunderbolt.ko",
"thunderbolt_net": "thunderbolt-net.ko",
"usb_wwan": "usb_wwan.ko",
"usbnet": "usbnet.ko",
"zaurus": "zaurus.ko",
"zfs": "zfs.ko",
}
if suite.ExtensionsTestType == string(ExtensionsTestTypeNvidia) || suite.ExtensionsTestType == string(ExtensionsTestTypeNvidiaFabricManager) {
expectedModulesModDep = map[string]string{
"nvidia": "nvidia.ko",
}
}
node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker)
ctx := client.WithNode(suite.ctx, node)
fileReader, err := suite.Client.Read(ctx, "/proc/modules")
defer func() {
err = fileReader.Close()
}()
suite.Require().NoError(err)
scanner := bufio.NewScanner(fileReader)
var loadedModules []string
for scanner.Scan() {
loadedModules = append(loadedModules, strings.Split(scanner.Text(), " ")[0])
}
suite.Require().NoError(scanner.Err())
fileReader, err = suite.Client.Read(ctx, fmt.Sprintf("/lib/modules/%s/modules.dep", constants.DefaultKernelVersion))
defer func() {
err = fileReader.Close()
}()
suite.Require().NoError(err)
scanner = bufio.NewScanner(fileReader)
var modulesDep []string
for scanner.Scan() {
modulesDep = append(modulesDep, filepath.Base(strings.Split(scanner.Text(), ":")[0]))
}
suite.Require().NoError(scanner.Err())
for module, moduleDep := range expectedModulesModDep {
suite.Require().Contains(loadedModules, module, "expected %s to be loaded", module)
suite.Require().Contains(modulesDep, moduleDep, "expected %s to be in modules.dep", moduleDep)
}
}
// TestExtensionsExpectedServices verifies expected services are running.
func (suite *ExtensionsSuite) TestExtensionsExpectedServices() {
expectedServices := []string{
"ext-hello-world",
"ext-iscsid",
"ext-nut-client",
"ext-qemu-guest-agent",
"ext-tgtd",
}
// Tailscale service keeps on restarting unless authed, so this test is disabled for now.
if ok := os.Getenv("TALOS_INTEGRATION_RUN_TAILSCALE"); ok != "" {
expectedServices = append(expectedServices, "ext-tailscale")
}
switch ExtensionsTestType(suite.ExtensionsTestType) {
case ExtensionsTestTypeNone:
case ExtensionsTestTypeQEMU:
case ExtensionsTestTypeNvidia:
expectedServices = []string{"ext-nvidia-persistenced"}
case ExtensionsTestTypeNvidiaFabricManager:
expectedServices = []string{
"ext-nvidia-persistenced",
"ext-nvidia-fabricmanager",
}
}
suite.testServicesRunning(expectedServices)
}
// TestExtensionsQEMUGuestAgent verifies qemu guest agent is working.
func (suite *ExtensionsSuite) TestExtensionsQEMUGuestAgent() {
if suite.ExtensionsTestType != string(ExtensionsTestTypeQEMU) || suite.Cluster.Provisioner() != "qemu" {
suite.T().Skip("skipping as qemu extensions test are not enabled")
}
node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker)
ctx := client.WithNode(suite.ctx, node)
hostnameSpec, err := safe.StateWatchFor[*network.HostnameStatus](
ctx,
suite.Client.COSI,
network.NewHostnameStatus(network.NamespaceName, resource.ID("hostname")).Metadata(),
state.WithEventTypes(state.Created, state.Updated),
)
suite.Require().NoError(err)
bootID, err := suite.ReadBootID(ctx)
suite.Require().NoError(err)
clusterStatePath, err := suite.Cluster.StatePath()
suite.Require().NoError(err)
conn, err := net.Dial("unix", filepath.Join(clusterStatePath, hostnameSpec.TypedSpec().Hostname+".sock"))
suite.Require().NoError(err)
defer conn.Close() //nolint:errcheck
_, err = conn.Write([]byte(`{"execute":"guest-shutdown", "arguments": {"mode": "reboot"}}`))
suite.Require().NoError(err)
suite.AssertBootIDChanged(ctx, bootID, node, time.Minute*5)
}
// TestExtensionsTailscale verifies tailscale is working.
func (suite *ExtensionsSuite) TestExtensionsTailscale() {
if suite.ExtensionsTestType != string(ExtensionsTestTypeQEMU) {
suite.T().Skip("skipping as qemu extensions test are not enabled")
}
// Tailscale service keeps on restarting unless authed, so this test is disabled for now.
if ok := os.Getenv("TALOS_INTEGRATION_RUN_TAILSCALE"); ok == "" {
suite.T().Skip("skipping as tailscale integration tests are not enabled")
}
node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker)
ctx := client.WithNode(suite.ctx, node)
linkSpec, err := safe.StateWatchFor[*network.LinkStatus](
ctx,
suite.Client.COSI,
network.NewHostnameStatus(network.NamespaceName, resource.ID("tailscale0")).Metadata(),
state.WithEventTypes(state.Created, state.Updated),
)
suite.Require().NoError(err)
suite.Require().Equal("tun", linkSpec.TypedSpec().Kind)
}
// TestExtensionsHelloWorldService verifies hello world service is working.
func (suite *ExtensionsSuite) TestExtensionsHelloWorldService() {
if suite.ExtensionsTestType != string(ExtensionsTestTypeQEMU) {
suite.T().Skip("skipping as qemu extensions test are not enabled")
}
node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker)
url := url.URL{
Scheme: "http",
Host: node,
}
resp, err := http.Get(url.String()) //nolint:noctx
suite.Require().NoError(err)
defer resp.Body.Close() //nolint:errcheck
respBody, err := io.ReadAll(resp.Body)
suite.Require().NoError(err)
suite.Require().Equal("Hello from Talos Linux Extension Service!", string(respBody))
}
// TestExtensionsGvisor verifies gvisor runtime class is working.
func (suite *ExtensionsSuite) TestExtensionsGvisor() {
if suite.ExtensionsTestType != string(ExtensionsTestTypeQEMU) {
suite.T().Skip("skipping as qemu extensions test are not enabled")
}
_, err := suite.Clientset.NodeV1().RuntimeClasses().Create(suite.ctx, &nodev1.RuntimeClass{
ObjectMeta: metav1.ObjectMeta{
Name: "gvisor",
},
Handler: "runsc",
}, metav1.CreateOptions{})
defer suite.Clientset.NodeV1().RuntimeClasses().Delete(suite.ctx, "gvisor", metav1.DeleteOptions{}) //nolint:errcheck
suite.Require().NoError(err)
_, err = suite.Clientset.CoreV1().Pods("default").Create(suite.ctx, &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "nginx-gvisor",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "nginx-gvisor",
Image: "nginx",
},
},
},
}, metav1.CreateOptions{})
defer suite.Clientset.CoreV1().Pods("default").Delete(suite.ctx, "nginx-gvisor", metav1.DeleteOptions{}) //nolint:errcheck
suite.Require().NoError(err)
// wait for the pod to be ready
suite.Require().NoError(retry.Constant(4*time.Minute, retry.WithUnits(time.Second*10)).Retry(
func() error {
pod, err := suite.Clientset.CoreV1().Pods("default").Get(suite.ctx, "nginx-gvisor", metav1.GetOptions{})
if err != nil {
return retry.ExpectedErrorf("error getting pod: %s", err)
}
if pod.Status.Phase != corev1.PodRunning {
return retry.ExpectedErrorf("pod is not running yet: %s", pod.Status.Phase)
}
return nil
},
))
}
func (suite *ExtensionsSuite) testServicesRunning(services []string) {
node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker)
ctx := client.WithNode(suite.ctx, node)
items, err := safe.StateListAll[*v1alpha1.Service](ctx, suite.Client.COSI)
suite.Require().NoError(err)
for _, expected := range services {
svc, found := items.Find(func(s *v1alpha1.Service) bool {
return s.Metadata().ID() == expected
})
if !found {
suite.T().Fatalf("expected %s to be registered", expected)
}
suite.Require().True(svc.TypedSpec().Running, "expected %s to be running", expected)
}
}
func init() {
allSuites = append(allSuites, &ExtensionsSuite{})
}

View File

@@ -42,6 +42,14 @@ func (suite *ResetSuite) SetupTest() {
suite.T().Skip("skipping in short mode") suite.T().Skip("skipping in short mode")
} }
if !suite.Capabilities().SupportsReboot {
suite.T().Skip("cluster doesn't support reboot (and reset)")
}
if suite.Cluster == nil {
suite.T().Skip("without full cluster state reset test is not reliable (can't wait for cluster readiness in between resets)")
}
// make sure we abort at some point in time, but give enough room for Resets // make sure we abort at some point in time, but give enough room for Resets
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 30*time.Minute) suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 30*time.Minute)
} }
@@ -55,17 +63,9 @@ func (suite *ResetSuite) TearDownTest() {
// TestResetNodeByNode Resets cluster node by node, waiting for health between Resets. // TestResetNodeByNode Resets cluster node by node, waiting for health between Resets.
func (suite *ResetSuite) TestResetNodeByNode() { func (suite *ResetSuite) TestResetNodeByNode() {
if !suite.Capabilities().SupportsReboot { if suite.Capabilities().SecureBooted {
suite.T().Skip("cluster doesn't support reboot (and reset)") // this is because in secure boot mode, the machine config is only applied and cannot be passed as kernel args
} suite.T().Skip("skipping as talos is explicitly trusted booted")
if suite.Capabilities().TrustedBoot {
// this is because with trusted boot the talos.config is only applied and cannot be passed as kernel args
suite.T().Skip("cluster has trusted boot enabled, doesn't support reset")
}
if suite.Cluster == nil {
suite.T().Skip("without full cluster state reset test is not reliable (can't wait for cluster readiness in between resets)")
} }
initNodeAddress := "" initNodeAddress := ""
@@ -114,17 +114,9 @@ func (suite *ResetSuite) TestResetNodeByNode() {
} }
func (suite *ResetSuite) testResetNoGraceful(nodeType machine.Type) { func (suite *ResetSuite) testResetNoGraceful(nodeType machine.Type) {
if !suite.Capabilities().SupportsReboot { if suite.Capabilities().SecureBooted {
suite.T().Skip("cluster doesn't support reboot (and reset)") // this is because in secure boot mode, the machine config is only applied and cannot be passed as kernel args
} suite.T().Skip("skipping as talos is explicitly trusted booted")
if suite.Capabilities().TrustedBoot {
// this is because with trusted boot the talos.config is only applied and cannot be passed as kernel args
suite.T().Skip("cluster has trusted boot enabled, doesn't support reset")
}
if suite.Cluster == nil {
suite.T().Skip("without full cluster state reset test is not reliable (can't wait for cluster readiness in between resets)")
} }
node := suite.RandomDiscoveredNodeInternalIP(nodeType) node := suite.RandomDiscoveredNodeInternalIP(nodeType)
@@ -165,14 +157,6 @@ func (suite *ResetSuite) TestResetNoGracefulControlplane() {
// //
//nolint:dupl //nolint:dupl
func (suite *ResetSuite) TestResetWithSpecEphemeral() { func (suite *ResetSuite) TestResetWithSpecEphemeral() {
if !suite.Capabilities().SupportsReboot {
suite.T().Skip("cluster doesn't support reboot (and reset)")
}
if suite.Cluster == nil {
suite.T().Skip("without full cluster state reset test is not reliable (can't wait for cluster readiness in between resets)")
}
node := suite.RandomDiscoveredNodeInternalIP() node := suite.RandomDiscoveredNodeInternalIP()
suite.T().Log("Resetting node with spec=[EPHEMERAL]", node) suite.T().Log("Resetting node with spec=[EPHEMERAL]", node)
@@ -214,17 +198,9 @@ func (suite *ResetSuite) TestResetWithSpecEphemeral() {
// //
//nolint:dupl //nolint:dupl
func (suite *ResetSuite) TestResetWithSpecState() { func (suite *ResetSuite) TestResetWithSpecState() {
if !suite.Capabilities().SupportsReboot { if suite.Capabilities().SecureBooted {
suite.T().Skip("cluster doesn't support reboot (and reset)") // this is because in secure boot mode, the machine config is only applied and cannot be passed as kernel args
} suite.T().Skip("skipping as talos is explicitly trusted booted")
if suite.Capabilities().TrustedBoot {
// this is because with trusted boot the talos.config is only applied and cannot be passed as kernel args
suite.T().Skip("cluster has trusted boot enabled, doesn't support reset")
}
if suite.Cluster == nil {
suite.T().Skip("without full cluster state reset test is not reliable (can't wait for cluster readiness in between resets)")
} }
node := suite.RandomDiscoveredNodeInternalIP() node := suite.RandomDiscoveredNodeInternalIP()
@@ -281,14 +257,6 @@ func (suite *ResetSuite) TestResetWithSpecState() {
// //
//nolint:dupl //nolint:dupl
func (suite *ResetSuite) TestResetDuringBoot() { func (suite *ResetSuite) TestResetDuringBoot() {
if !suite.Capabilities().SupportsReboot {
suite.T().Skip("cluster doesn't support reboot (and reset)")
}
if suite.Cluster == nil {
suite.T().Skip("without full cluster state reset test is not reliable (can't wait for cluster readiness in between resets)")
}
node := suite.RandomDiscoveredNodeInternalIP() node := suite.RandomDiscoveredNodeInternalIP()
nodeCtx := client.WithNodes(suite.ctx, node) nodeCtx := client.WithNodes(suite.ctx, node)

View File

@@ -0,0 +1,114 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//go:build integration_api
package api
import (
"bufio"
"bytes"
"context"
"io"
"time"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/talos/internal/integration/base"
"github.com/siderolabs/talos/pkg/machinery/client"
runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime"
)
// TrustedBootSuite verifies Talos is securebooted.
type TrustedBootSuite struct {
base.K8sSuite
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
// SuiteName ...
func (suite *TrustedBootSuite) SuiteName() string {
return "api.TrustedBootSuite"
}
// SetupTest ...
func (suite *TrustedBootSuite) SetupTest() {
if suite.Cluster.Provisioner() == provisionerDocker {
suite.T().Skip("skipping trustedboot tests in docker")
}
if !suite.TrustedBoot {
suite.T().Skip("skipping since talos.trustedboot is false")
}
// make sure API calls have timeout
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 3*time.Minute)
}
// TearDownTest ...
func (suite *TrustedBootSuite) TearDownTest() {
if suite.ctxCancel != nil {
suite.ctxCancel()
}
}
// TestTrustedBootState verifies that the system is booted in secure boot mode
// and that the disks are encrypted.
func (suite *TrustedBootSuite) TestTrustedBootState() {
node := suite.RandomDiscoveredNodeInternalIP()
ctx := client.WithNode(suite.ctx, node)
securityResource, err := safe.StateWatchFor[*runtimeres.SecurityState](
ctx,
suite.Client.COSI,
runtimeres.NewSecurityStateSpec(runtimeres.NamespaceName).Metadata(),
state.WithEventTypes(state.Created, state.Updated),
)
suite.Require().NoError(err)
suite.Require().True(securityResource.TypedSpec().SecureBoot)
stateResource, err := safe.StateWatchFor[*runtimeres.MountStatus](
ctx,
suite.Client.COSI,
runtimeres.NewMountStatus(runtimeres.NamespaceName, resource.ID("STATE")).Metadata(),
state.WithEventTypes(state.Created, state.Updated),
)
suite.Require().NoError(err)
suite.Require().True(stateResource.TypedSpec().Encrypted)
ephemeralResource, err := safe.StateWatchFor[*runtimeres.MountStatus](
ctx,
suite.Client.COSI,
runtimeres.NewMountStatus(runtimeres.NamespaceName, resource.ID("EPHEMERAL")).Metadata(),
state.WithEventTypes(state.Created, state.Updated),
)
suite.Require().NoError(err)
suite.Require().True(ephemeralResource.TypedSpec().Encrypted)
dmesgStream, err := suite.Client.Dmesg(
suite.ctx,
false,
false,
)
suite.Require().NoError(err)
logReader, err := client.ReadStream(dmesgStream)
suite.Require().NoError(err)
var dmesg bytes.Buffer
_, err = io.Copy(bufio.NewWriter(&dmesg), logReader)
suite.Require().NoError(err)
suite.Require().Contains(dmesg.String(), "Secure boot enabled")
}
func init() {
allSuites = append(allSuites, &TrustedBootSuite{})
}

View File

@@ -17,12 +17,13 @@ import (
"strings" "strings"
"time" "time"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/go-retry/retry" "github.com/siderolabs/go-retry/retry"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"google.golang.org/grpc/backoff" "google.golang.org/grpc/backoff"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime" "github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/sdboot"
"github.com/siderolabs/talos/pkg/cluster" "github.com/siderolabs/talos/pkg/cluster"
"github.com/siderolabs/talos/pkg/cluster/check" "github.com/siderolabs/talos/pkg/cluster/check"
machineapi "github.com/siderolabs/talos/pkg/machinery/api/machine" machineapi "github.com/siderolabs/talos/pkg/machinery/api/machine"
@@ -32,6 +33,7 @@ import (
"github.com/siderolabs/talos/pkg/machinery/config/configloader" "github.com/siderolabs/talos/pkg/machinery/config/configloader"
"github.com/siderolabs/talos/pkg/machinery/config/machine" "github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/constants" "github.com/siderolabs/talos/pkg/machinery/constants"
runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime"
"github.com/siderolabs/talos/pkg/provision" "github.com/siderolabs/talos/pkg/provision"
"github.com/siderolabs/talos/pkg/provision/access" "github.com/siderolabs/talos/pkg/provision/access"
) )
@@ -147,7 +149,7 @@ type Capabilities struct {
RunsTalosKernel bool RunsTalosKernel bool
SupportsReboot bool SupportsReboot bool
SupportsRecover bool SupportsRecover bool
TrustedBoot bool SecureBooted bool
} }
// Capabilities returns a set of capabilities to skip tests for different environments. // Capabilities returns a set of capabilities to skip tests for different environments.
@@ -167,12 +169,20 @@ func (apiSuite *APISuite) Capabilities() Capabilities {
} }
} }
if _, err = apiSuite.Client.LS(context.Background(), &machineapi.ListRequest{ ctx := context.Background()
Root: sdboot.SystemdBootStubInfoPath, ctx, ctxCancel := context.WithTimeout(ctx, 2*time.Minute)
Types: []machineapi.ListRequest_Type{machineapi.ListRequest_REGULAR},
}); err == nil { defer ctxCancel()
caps.TrustedBoot = true
} securityResource, err := safe.StateWatchFor[*runtimeres.SecurityState](
ctx,
apiSuite.Client.COSI,
runtimeres.NewSecurityStateSpec(runtimeres.NamespaceName).Metadata(),
state.WithEventTypes(state.Created, state.Updated),
)
apiSuite.Require().NoError(err)
caps.SecureBooted = securityResource.TypedSpec().SecureBoot
return caps return caps
} }

View File

@@ -33,6 +33,10 @@ type TalosSuite struct {
TalosctlPath string TalosctlPath string
// KubectlPath is a path to kubectl binary // KubectlPath is a path to kubectl binary
KubectlPath string KubectlPath string
// ExtensionsTestType the type of extensions test to run
ExtensionsTestType string
// TrustedBoot tells if the cluster is secure booted and disks are encrypted
TrustedBoot bool
discoveredNodes cluster.Info discoveredNodes cluster.Info
} }

View File

@@ -21,6 +21,7 @@ import (
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api" clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
@@ -34,6 +35,7 @@ type K8sSuite struct {
Clientset *kubernetes.Clientset Clientset *kubernetes.Clientset
DynamicClient dynamic.Interface DynamicClient dynamic.Interface
DiscoveryClient *discovery.DiscoveryClient DiscoveryClient *discovery.DiscoveryClient
RestConfig *rest.Config
} }
// SetupSuite initializes Kubernetes client. // SetupSuite initializes Kubernetes client.
@@ -54,6 +56,7 @@ func (k8sSuite *K8sSuite) SetupSuite() {
config.Host = k8sSuite.K8sEndpoint config.Host = k8sSuite.K8sEndpoint
} }
k8sSuite.RestConfig = config
k8sSuite.Clientset, err = kubernetes.NewForConfig(config) k8sSuite.Clientset, err = kubernetes.NewForConfig(config)
k8sSuite.Require().NoError(err) k8sSuite.Require().NoError(err)

View File

@@ -34,18 +34,20 @@ var allSuites []suite.TestingSuite
// Flag values. // Flag values.
var ( var (
failFast bool failFast bool
crashdumpEnabled bool crashdumpEnabled bool
talosConfig string trustedBoot bool
endpoint string talosConfig string
k8sEndpoint string endpoint string
expectedVersion string k8sEndpoint string
expectedGoVersion string expectedVersion string
talosctlPath string expectedGoVersion string
kubectlPath string talosctlPath string
provisionerName string kubectlPath string
clusterName string extensionsTestType string
stateDir string provisionerName string
clusterName string
stateDir string
) )
// TestIntegration ... // TestIntegration ...
@@ -85,14 +87,16 @@ func TestIntegration(t *testing.T) {
for _, s := range allSuites { for _, s := range allSuites {
if configuredSuite, ok := s.(base.ConfiguredSuite); ok { if configuredSuite, ok := s.(base.ConfiguredSuite); ok {
configuredSuite.SetConfig(base.TalosSuite{ configuredSuite.SetConfig(base.TalosSuite{
Endpoint: endpoint, Endpoint: endpoint,
K8sEndpoint: k8sEndpoint, K8sEndpoint: k8sEndpoint,
Cluster: cluster, Cluster: cluster,
TalosConfig: talosConfig, TalosConfig: talosConfig,
Version: expectedVersion, Version: expectedVersion,
GoVersion: expectedGoVersion, GoVersion: expectedGoVersion,
TalosctlPath: talosctlPath, TalosctlPath: talosctlPath,
KubectlPath: kubectlPath, KubectlPath: kubectlPath,
ExtensionsTestType: extensionsTestType,
TrustedBoot: trustedBoot,
}) })
} }
@@ -129,6 +133,7 @@ func init() {
flag.BoolVar(&failFast, "talos.failfast", false, "fail the test run on the first failed test") flag.BoolVar(&failFast, "talos.failfast", false, "fail the test run on the first failed test")
flag.BoolVar(&crashdumpEnabled, "talos.crashdump", true, "print crashdump on test failure (only if provisioner is enabled)") flag.BoolVar(&crashdumpEnabled, "talos.crashdump", true, "print crashdump on test failure (only if provisioner is enabled)")
flag.BoolVar(&trustedBoot, "talos.trustedboot", false, "enable tests for trusted boot mode")
flag.StringVar( flag.StringVar(
&talosConfig, &talosConfig,
@@ -149,6 +154,7 @@ func init() {
flag.StringVar(&expectedGoVersion, "talos.go.version", constants.GoVersion, "expected Talos version") flag.StringVar(&expectedGoVersion, "talos.go.version", constants.GoVersion, "expected Talos version")
flag.StringVar(&talosctlPath, "talos.talosctlpath", "talosctl", "The path to 'talosctl' binary") flag.StringVar(&talosctlPath, "talos.talosctlpath", "talosctl", "The path to 'talosctl' binary")
flag.StringVar(&kubectlPath, "talos.kubectlpath", "kubectl", "The path to 'kubectl' binary") flag.StringVar(&kubectlPath, "talos.kubectlpath", "kubectl", "The path to 'kubectl' binary")
flag.StringVar(&extensionsTestType, "talos.extensions.testtype", "none", "The type of extensions test to run (none, qemu, nvida, nvidia-fabricmanager)")
flag.StringVar(&provision_test.DefaultSettings.CIDR, "talos.provision.cidr", provision_test.DefaultSettings.CIDR, "CIDR to use to provision clusters (provision tests only)") flag.StringVar(&provision_test.DefaultSettings.CIDR, "talos.provision.cidr", provision_test.DefaultSettings.CIDR, "CIDR to use to provision clusters (provision tests only)")
flag.Var(&provision_test.DefaultSettings.RegistryMirrors, "talos.provision.registry-mirror", "registry mirrors to use (provision tests only)") flag.Var(&provision_test.DefaultSettings.RegistryMirrors, "talos.provision.registry-mirror", "registry mirrors to use (provision tests only)")

View File

@@ -13,7 +13,7 @@ import (
const ( const (
// DefaultKernelVersion is the default Linux kernel version. // DefaultKernelVersion is the default Linux kernel version.
DefaultKernelVersion = "6.1.42-talos" DefaultKernelVersion = "6.1.45-talos"
// DefaultKernelModulesPath is the default path to the kernel modules. // DefaultKernelModulesPath is the default path to the kernel modules.
DefaultKernelModulesPath = "/lib/modules" + "/" + DefaultKernelVersion DefaultKernelModulesPath = "/lib/modules" + "/" + DefaultKernelVersion
@@ -440,7 +440,7 @@ const (
TrustdUserID = 51 TrustdUserID = 51
// DefaultContainerdVersion is the default container runtime version. // DefaultContainerdVersion is the default container runtime version.
DefaultContainerdVersion = "1.6.22" DefaultContainerdVersion = "1.6.23"
// SystemContainerdNamespace is the Containerd namespace for Talos services. // SystemContainerdNamespace is the Containerd namespace for Talos services.
SystemContainerdNamespace = "system" SystemContainerdNamespace = "system"

View File

@@ -1 +1 @@
v1.5.0 v1.6.0-alpha.0-5-g7717b7e