mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-04-11 06:22:55 +00:00
Compare commits
1 Commits
topic/runt
...
ci-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1901c9b841 |
@@ -157,7 +157,7 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
|
|||||||
s.config.SandboxCPUs, s.config.SandboxMemMB = oci.CalculateContainerSizing(ociSpec)
|
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
|
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")
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,33 +308,39 @@ func loadRuntimeConfig(s *service, r *taskAPI.CreateTaskRequest, anno map[string
|
|||||||
return &runtimeConfig, nil
|
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 {
|
if len(r.Rootfs) == 1 {
|
||||||
m := r.Rootfs[0]
|
m := r.Rootfs[0]
|
||||||
|
|
||||||
// Plug the block backed rootfs directly instead of mounting it.
|
// Plug the block backed rootfs directly instead of mounting it.
|
||||||
if katautils.IsBlockDevice(m.Source) && !s.config.HypervisorConfig.DisableBlockDeviceUse {
|
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) {
|
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}) {
|
if virtcontainers.IsErofsRootFS(virtcontainers.RootFs{Options: m.Options, Type: m.Type}) {
|
||||||
return false, nil
|
return mounted, pluggedBlockDevice, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if vc.IsNydusRootFSType(m.Type) {
|
if vc.IsNydusRootFSType(m.Type) {
|
||||||
// if kata + nydus, do not mount
|
// if kata + nydus, do not mount
|
||||||
return false, nil
|
return mounted, pluggedBlockDevice, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootfs := filepath.Join(r.Bundle, "rootfs")
|
rootfs := filepath.Join(r.Bundle, "rootfs")
|
||||||
if err := doMount(r.Rootfs, rootfs); err != nil {
|
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 {
|
func doMount(mounts []*containerd_types.Mount, rootfs string) error {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import (
|
|||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
|
"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"
|
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/types"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
|
||||||
|
|
||||||
"github.com/moby/sys/mountinfo"
|
"github.com/moby/sys/mountinfo"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
@@ -319,6 +318,8 @@ type RootFs struct {
|
|||||||
Options []string
|
Options []string
|
||||||
// Mounted specifies whether the rootfs has be mounted or not
|
// Mounted specifies whether the rootfs has be mounted or not
|
||||||
Mounted bool
|
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.
|
// 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 the rootfs is backed by a block device, go ahead and hotplug it to the guest
|
||||||
if err = c.hotplugDrive(ctx); err != nil {
|
if err = c.hotplugDrive(ctx); err != nil {
|
||||||
return
|
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
|
// hotplugDrive will attempt to hotplug the container rootfs if it is backed by a
|
||||||
// block device
|
// block device
|
||||||
func (c *Container) hotplugDrive(ctx context.Context) error {
|
func (c *Container) hotplugDrive(ctx context.Context) error {
|
||||||
var dev device
|
c.Logger().WithFields(logrus.Fields{
|
||||||
var err error
|
"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
|
if !c.rootFs.PluggedBlockDevice {
|
||||||
// mount (target) is backed by a block device:
|
return nil
|
||||||
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.Mounted {
|
||||||
|
panic("Mounted cannot be true when PluggedBlockDevice is true")
|
||||||
|
}
|
||||||
|
|
||||||
|
dev, err := getDeviceForPath(c.rootFs.Source)
|
||||||
if err == errMountPointNotFound {
|
if err == errMountPointNotFound {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1607,6 +1610,8 @@ func (c *Container) hotplugDrive(ctx context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.rootfsSuffix = ""
|
||||||
|
|
||||||
c.Logger().WithFields(logrus.Fields{
|
c.Logger().WithFields(logrus.Fields{
|
||||||
"device-major": dev.major,
|
"device-major": dev.major,
|
||||||
"device-minor": dev.minor,
|
"device-minor": dev.minor,
|
||||||
@@ -1622,23 +1627,11 @@ func (c *Container) hotplugDrive(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
devicePath := c.rootFs.Source
|
devicePath, err := filepath.EvalSymlinks(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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fsType := c.rootFs.Type
|
||||||
|
|
||||||
c.Logger().WithFields(logrus.Fields{
|
c.Logger().WithFields(logrus.Fields{
|
||||||
"device-path": devicePath,
|
"device-path": devicePath,
|
||||||
|
|||||||
36
tests/integration/kubernetes/k8s-empty-image.bats
Normal file
36
tests/integration/kubernetes/k8s-empty-image.bats
Normal 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:-}"
|
||||||
|
}
|
||||||
@@ -42,6 +42,7 @@ else
|
|||||||
)
|
)
|
||||||
|
|
||||||
K8S_TEST_SMALL_HOST_UNION=( \
|
K8S_TEST_SMALL_HOST_UNION=( \
|
||||||
|
"k8s-empty-image.bats" \
|
||||||
"k8s-guest-pull-image.bats" \
|
"k8s-guest-pull-image.bats" \
|
||||||
"k8s-confidential.bats" \
|
"k8s-confidential.bats" \
|
||||||
"k8s-sealed-secret.bats" \
|
"k8s-sealed-secret.bats" \
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user