Compare commits

...

1 Commits

Author SHA1 Message Date
Dan Mihai
1901c9b841 DO NOT MERGE: CI test
Test of the ci-devel pipeline
2025-12-19 09:56:15 +00:00
5 changed files with 84 additions and 35 deletions

View File

@@ -157,7 +157,7 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
s.config.SandboxCPUs, s.config.SandboxMemMB = oci.CalculateContainerSizing(ociSpec)
}
if rootFs.Mounted, err = checkAndMount(s, r); err != nil {
if rootFs.Mounted, rootFs.PluggedBlockDevice, err = checkAndMount(s, r); err != nil {
return nil, err
}
@@ -211,7 +211,7 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
return nil, fmt.Errorf("BUG: Cannot start the container, since the sandbox hasn't been created")
}
if rootFs.Mounted, err = checkAndMount(s, r); err != nil {
if rootFs.Mounted, rootFs.PluggedBlockDevice, err = checkAndMount(s, r); err != nil {
return nil, err
}
@@ -308,33 +308,39 @@ func loadRuntimeConfig(s *service, r *taskAPI.CreateTaskRequest, anno map[string
return &runtimeConfig, nil
}
func checkAndMount(s *service, r *taskAPI.CreateTaskRequest) (bool, error) {
func checkAndMount(s *service, r *taskAPI.CreateTaskRequest) (bool, bool, error) {
mounted := false
pluggedBlockDevice := false
if len(r.Rootfs) == 1 {
m := r.Rootfs[0]
// Plug the block backed rootfs directly instead of mounting it.
if katautils.IsBlockDevice(m.Source) && !s.config.HypervisorConfig.DisableBlockDeviceUse {
return false, nil
pluggedBlockDevice = true
return mounted, pluggedBlockDevice, nil
}
if virtcontainers.HasOptionPrefix(m.Options, annotations.FileSystemLayer) {
return false, nil
return mounted, pluggedBlockDevice, nil
}
if virtcontainers.IsErofsRootFS(virtcontainers.RootFs{Options: m.Options, Type: m.Type}) {
return false, nil
return mounted, pluggedBlockDevice, nil
}
if vc.IsNydusRootFSType(m.Type) {
// if kata + nydus, do not mount
return false, nil
return mounted, pluggedBlockDevice, nil
}
}
rootfs := filepath.Join(r.Bundle, "rootfs")
if err := doMount(r.Rootfs, rootfs); err != nil {
return false, err
return mounted, pluggedBlockDevice, err
}
return true, nil
mounted = true
return mounted, pluggedBlockDevice, nil
}
func doMount(mounts []*containerd_types.Mount, rootfs string) error {

View File

@@ -27,7 +27,6 @@ import (
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
"github.com/moby/sys/mountinfo"
specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -319,6 +318,8 @@ type RootFs struct {
Options []string
// Mounted specifies whether the rootfs has be mounted or not
Mounted bool
// PluggedBlockDevice specifies whether Source should be plugged into the Guest as block block.
PluggedBlockDevice bool
}
// Container is composed of a set of containers and a runtime environment.
@@ -1237,7 +1238,7 @@ func (c *Container) create(ctx context.Context) (err error) {
}
}()
if c.checkBlockDeviceSupport(ctx) && !IsNydusRootFSType(c.rootFs.Type) && !IsErofsRootFS(c.rootFs) {
if c.checkBlockDeviceSupport(ctx) {
// If the rootfs is backed by a block device, go ahead and hotplug it to the guest
if err = c.hotplugDrive(ctx); err != nil {
return
@@ -1586,19 +1587,21 @@ func (c *Container) resume(ctx context.Context) error {
// hotplugDrive will attempt to hotplug the container rootfs if it is backed by a
// block device
func (c *Container) hotplugDrive(ctx context.Context) error {
var dev device
var err error
c.Logger().WithFields(logrus.Fields{
"rootfs-source": c.rootFs.Source,
"rootfs-mounted": c.rootFs.Mounted,
"plugged-device": c.rootFs.PluggedBlockDevice,
}).Info("rootfs properties")
// Check to see if the rootfs is an umounted block device (source) or if the
// mount (target) is backed by a block device:
if !c.rootFs.Mounted {
dev, err = getDeviceForPath(c.rootFs.Source)
// there is no "rootfs" dir on block device backed rootfs
c.rootfsSuffix = ""
} else {
dev, err = getDeviceForPath(c.rootFs.Target)
if !c.rootFs.PluggedBlockDevice {
return nil
}
if c.rootFs.Mounted {
panic("Mounted cannot be true when PluggedBlockDevice is true")
}
dev, err := getDeviceForPath(c.rootFs.Source)
if err == errMountPointNotFound {
return nil
}
@@ -1607,6 +1610,8 @@ func (c *Container) hotplugDrive(ctx context.Context) error {
return err
}
c.rootfsSuffix = ""
c.Logger().WithFields(logrus.Fields{
"device-major": dev.major,
"device-minor": dev.minor,
@@ -1622,23 +1627,11 @@ func (c *Container) hotplugDrive(ctx context.Context) error {
return nil
}
devicePath := c.rootFs.Source
fsType := c.rootFs.Type
if c.rootFs.Mounted {
if dev.mountPoint == c.rootFs.Target {
c.rootfsSuffix = ""
}
// If device mapper device, then fetch the full path of the device
devicePath, fsType, _, err = utils.GetDevicePathAndFsTypeOptions(dev.mountPoint)
if err != nil {
return err
}
}
devicePath, err = filepath.EvalSymlinks(devicePath)
devicePath, err := filepath.EvalSymlinks(c.rootFs.Source)
if err != nil {
return err
}
fsType := c.rootFs.Type
c.Logger().WithFields(logrus.Fields{
"device-path": devicePath,

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bats
#
# Copyright (c) 2025 NVIDIA Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
load "${BATS_TEST_DIRNAME}/../../common.bash"
load "${BATS_TEST_DIRNAME}/lib.sh"
load "${BATS_TEST_DIRNAME}/tests_common.sh"
setup() {
setup_common || die "setup_common failed"
pod_name="no-layer-image"
get_pod_config_dir
yaml_file="${pod_config_dir}/${pod_name}.yaml"
auto_generate_policy "${pod_config_dir}" "${yaml_file}"
}
@test "Test image with no layers cannot run" {
assert_pod_fail "${yaml_file}"
kubectl get pods "${pod_name}" -o jsonpath='{.status.containerStatuses[0].lastState.terminated.message}' | grep "the file sleep was not found"
}
teardown() {
# Debugging information
kubectl describe "pod/${pod_name}"
kubectl get "pod/${pod_name}" -o yaml
kubectl delete pod "${pod_name}"
node_end_time "${node}"
echo "setup_common starts at ${node_start_time:-}, teardown_common ends at ${node_end_time:-}"
teardown_common "${node}" "${node_start_time:-}"
}

View File

@@ -42,6 +42,7 @@ else
)
K8S_TEST_SMALL_HOST_UNION=( \
"k8s-empty-image.bats" \
"k8s-guest-pull-image.bats" \
"k8s-confidential.bats" \
"k8s-sealed-secret.bats" \

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
name: no-layer-image
spec:
runtimeClassName: kata
containers:
- name: no-layer-image
image: ghcr.io/kata-containers/no-layer-image:latest
resources: {}
command:
- sleep
- infinity