diff --git a/pkg/katautils/create.go b/pkg/katautils/create.go index 630b32c991..de41c7ff49 100644 --- a/pkg/katautils/create.go +++ b/pkg/katautils/create.go @@ -162,7 +162,10 @@ func HandleFactory(ctx context.Context, vci vc.VC, runtimeConfig *oci.RuntimeCon func SetEphemeralStorageType(ociSpec oci.CompatOCISpec) oci.CompatOCISpec { for idx, mnt := range ociSpec.Mounts { if vc.IsEphemeralStorage(mnt.Source) { - ociSpec.Mounts[idx].Type = "ephemeral" + ociSpec.Mounts[idx].Type = vc.KataEphemeralDevType + } + if vc.Isk8sHostEmptyDir(mnt.Source) { + ociSpec.Mounts[idx].Type = vc.KataLocalDevType } } return ociSpec diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index 84352d84b7..d9b5411fb3 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -43,6 +43,15 @@ import ( grpcStatus "google.golang.org/grpc/status" ) +const ( + // KataEphemeralDevType creates a tmpfs backed volume for sharing files between containers. + KataEphemeralDevType = "ephemeral" + + // KataLocalDevType creates a local directory inside the VM for sharing files between + // containers. + KataLocalDevType = "local" +) + var ( checkRequestTimeout = 30 * time.Second defaultKataSocketName = "kata.sock" @@ -67,8 +76,7 @@ var ( kataNvdimmDevType = "nvdimm" sharedDir9pOptions = []string{"trans=virtio,version=9p2000.L,cache=mmap", "nodev"} shmDir = "shm" - kataEphemeralDevType = "ephemeral" - ephemeralPath = filepath.Join(kataGuestSandboxDir, kataEphemeralDevType) + ephemeralPath = filepath.Join(kataGuestSandboxDir, KataEphemeralDevType) grpcMaxDataSize = int64(1024 * 1024) ) @@ -672,7 +680,7 @@ func (k *kataAgent) startSandbox(sandbox *Sandbox) error { shmSizeOption := fmt.Sprintf("size=%d", sandbox.shmSize) shmStorage := &grpc.Storage{ - Driver: kataEphemeralDevType, + Driver: KataEphemeralDevType, MountPoint: path, Source: "shm", Fstype: "tmpfs", @@ -1038,6 +1046,9 @@ func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process, epheStorages := k.handleEphemeralStorage(ociSpec.Mounts) ctrStorages = append(ctrStorages, epheStorages...) + localStorages := k.handleLocalStorage(ociSpec.Mounts, sandbox.id) + ctrStorages = append(ctrStorages, localStorages...) + // We replace all OCI mount sources that match our container mount // with the right source path (The guest one). if err = k.replaceOCIMountSource(ociSpec, newMounts); err != nil { @@ -1116,14 +1127,14 @@ func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process, func (k *kataAgent) handleEphemeralStorage(mounts []specs.Mount) []*grpc.Storage { var epheStorages []*grpc.Storage for idx, mnt := range mounts { - if mnt.Type == kataEphemeralDevType { + if mnt.Type == KataEphemeralDevType { // Set the mount source path to a path that resides inside the VM mounts[idx].Source = filepath.Join(ephemeralPath, filepath.Base(mnt.Source)) // Create a storage struct so that kata agent is able to create // tmpfs backed volume inside the VM epheStorage := &grpc.Storage{ - Driver: kataEphemeralDevType, + Driver: KataEphemeralDevType, Source: "tmpfs", Fstype: "tmpfs", MountPoint: mounts[idx].Source, @@ -1134,6 +1145,33 @@ func (k *kataAgent) handleEphemeralStorage(mounts []specs.Mount) []*grpc.Storage return epheStorages } +// handleLocalStorage handles local storage within the VM +// by creating a directory in the VM from the source of the mount point. +func (k *kataAgent) handleLocalStorage(mounts []specs.Mount, sandboxID string) []*grpc.Storage { + var localStorages []*grpc.Storage + for idx, mnt := range mounts { + if mnt.Type == KataLocalDevType { + // Set the mount source path to a the desired directory point in the VM. + // In this case it is located in the sandbox directory. + // We rely on the fact that the first container in the VM has the same ID as the sandbox ID. + // In Kubernetes, this is usually the pause container and we depend on it existing for + // local directories to work. + mounts[idx].Source = filepath.Join(kataGuestSharedDir, sandboxID, KataLocalDevType, filepath.Base(mnt.Source)) + + // Create a storage struct so that the kata agent is able to create the + // directory inside the VM. + localStorage := &grpc.Storage{ + Driver: KataLocalDevType, + Source: KataLocalDevType, + Fstype: KataLocalDevType, + MountPoint: mounts[idx].Source, + } + localStorages = append(localStorages, localStorage) + } + } + return localStorages +} + // handleBlockVolumes handles volumes that are block devices files // by passing the block devices as Storage to the agent. func (k *kataAgent) handleBlockVolumes(c *Container) []*grpc.Storage { diff --git a/virtcontainers/kata_agent_test.go b/virtcontainers/kata_agent_test.go index bdc869a0e3..ef3a1ad4e2 100644 --- a/virtcontainers/kata_agent_test.go +++ b/virtcontainers/kata_agent_test.go @@ -365,7 +365,7 @@ func TestHandleEphemeralStorage(t *testing.T) { mountSource := "/tmp/mountPoint" mount := specs.Mount{ - Type: kataEphemeralDevType, + Type: KataEphemeralDevType, Source: mountSource, } diff --git a/virtcontainers/mount_test.go b/virtcontainers/mount_test.go index 7d0b3c4768..2edc87e4a7 100644 --- a/virtcontainers/mount_test.go +++ b/virtcontainers/mount_test.go @@ -311,7 +311,7 @@ func TestIsEphemeralStorage(t *testing.T) { } defer os.RemoveAll(dir) - sampleEphePath := filepath.Join(dir, k8sEmptyDir, "tmp-volume") + sampleEphePath := filepath.Join(dir, K8sEmptyDir, "tmp-volume") err = os.MkdirAll(sampleEphePath, testDirMode) assert.Nil(t, err)