From 26f0430a7c0123feeb857b9f7b71922c9d66adbc Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 16 Aug 2018 16:07:10 -0700 Subject: [PATCH 1/2] virtcontainers: storage: Add a noop version of filesystem This noop implementation of resourceStorage will allow for easier unit testing of some sandbox functions. Fixes #632 Signed-off-by: Sebastien Boeuf --- virtcontainers/noop_resource_storage.go | 112 +++++++++++ virtcontainers/noop_resource_storage_test.go | 188 +++++++++++++++++++ 2 files changed, 300 insertions(+) create mode 100644 virtcontainers/noop_resource_storage.go create mode 100644 virtcontainers/noop_resource_storage_test.go diff --git a/virtcontainers/noop_resource_storage.go b/virtcontainers/noop_resource_storage.go new file mode 100644 index 0000000000..2c1b931e0c --- /dev/null +++ b/virtcontainers/noop_resource_storage.go @@ -0,0 +1,112 @@ +// Copyright (c) 2018 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package virtcontainers + +import ( + "github.com/kata-containers/runtime/virtcontainers/device/api" +) + +type noopResourceStorage struct{} + +func (n *noopResourceStorage) createAllResources(sandbox *Sandbox) error { + return nil +} + +func (n *noopResourceStorage) containerURI(sandboxID, containerID string, resource sandboxResource) (string, string, error) { + return "", "", nil +} + +func (n *noopResourceStorage) sandboxURI(sandboxID string, resource sandboxResource) (string, string, error) { + return "", "", nil +} + +func (n *noopResourceStorage) storeSandboxResource(sandboxID string, resource sandboxResource, data interface{}) error { + return nil +} + +func (n *noopResourceStorage) deleteSandboxResources(sandboxID string, resources []sandboxResource) error { + return nil +} + +func (n *noopResourceStorage) fetchSandboxConfig(sandboxID string) (SandboxConfig, error) { + return SandboxConfig{}, nil +} + +func (n *noopResourceStorage) fetchSandboxState(sandboxID string) (State, error) { + return State{}, nil +} + +func (n *noopResourceStorage) fetchSandboxNetwork(sandboxID string) (NetworkNamespace, error) { + return NetworkNamespace{}, nil +} + +func (n *noopResourceStorage) storeSandboxNetwork(sandboxID string, networkNS NetworkNamespace) error { + return nil +} + +func (n *noopResourceStorage) fetchSandboxDevices(sandboxID string) ([]api.Device, error) { + return []api.Device{}, nil +} + +func (n *noopResourceStorage) storeSandboxDevices(sandboxID string, devices []api.Device) error { + return nil +} + +func (n *noopResourceStorage) fetchHypervisorState(sandboxID string, state interface{}) error { + return nil +} + +func (n *noopResourceStorage) storeHypervisorState(sandboxID string, state interface{}) error { + return nil +} + +func (n *noopResourceStorage) fetchAgentState(sandboxID string, state interface{}) error { + return nil +} + +func (n *noopResourceStorage) storeAgentState(sandboxID string, state interface{}) error { + return nil +} + +func (n *noopResourceStorage) storeContainerResource(sandboxID, containerID string, resource sandboxResource, data interface{}) error { + return nil +} + +func (n *noopResourceStorage) deleteContainerResources(sandboxID, containerID string, resources []sandboxResource) error { + return nil +} + +func (n *noopResourceStorage) fetchContainerConfig(sandboxID, containerID string) (ContainerConfig, error) { + return ContainerConfig{}, nil +} + +func (n *noopResourceStorage) fetchContainerState(sandboxID, containerID string) (State, error) { + return State{}, nil +} + +func (n *noopResourceStorage) fetchContainerProcess(sandboxID, containerID string) (Process, error) { + return Process{}, nil +} + +func (n *noopResourceStorage) storeContainerProcess(sandboxID, containerID string, process Process) error { + return nil +} + +func (n *noopResourceStorage) fetchContainerMounts(sandboxID, containerID string) ([]Mount, error) { + return []Mount{}, nil +} + +func (n *noopResourceStorage) storeContainerMounts(sandboxID, containerID string, mounts []Mount) error { + return nil +} + +func (n *noopResourceStorage) fetchContainerDevices(sandboxID, containerID string) ([]ContainerDevice, error) { + return []ContainerDevice{}, nil +} + +func (n *noopResourceStorage) storeContainerDevices(sandboxID, containerID string, devices []ContainerDevice) error { + return nil +} diff --git a/virtcontainers/noop_resource_storage_test.go b/virtcontainers/noop_resource_storage_test.go new file mode 100644 index 0000000000..1e4a696bf6 --- /dev/null +++ b/virtcontainers/noop_resource_storage_test.go @@ -0,0 +1,188 @@ +// Copyright (c) 2018 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package virtcontainers + +import ( + "testing" + + "github.com/kata-containers/runtime/virtcontainers/device/api" + "github.com/stretchr/testify/assert" +) + +func TestNoopCreateAllResources(t *testing.T) { + n := &noopResourceStorage{} + + err := n.createAllResources(nil) + assert.Nil(t, err) +} + +func TestNoopContainerURI(t *testing.T) { + n := &noopResourceStorage{} + + _, _, err := n.containerURI("", "", 0) + assert.Nil(t, err) +} + +func TestNoopSandboxURI(t *testing.T) { + n := &noopResourceStorage{} + + _, _, err := n.sandboxURI("", 0) + assert.Nil(t, err) +} + +func TestNoopStoreSandboxResource(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeSandboxResource("", 0, nil) + assert.Nil(t, err) +} + +func TestNoopDeleteSandboxResources(t *testing.T) { + n := &noopResourceStorage{} + + err := n.deleteSandboxResources("", []sandboxResource{0}) + assert.Nil(t, err) +} + +func TestNoopFetchSandboxConfig(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchSandboxConfig("") + assert.Nil(t, err) +} + +func TestNoopFetchSandboxState(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchSandboxState("") + assert.Nil(t, err) +} + +func TestNoopFetchSandboxNetwork(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchSandboxNetwork("") + assert.Nil(t, err) +} + +func TestNoopStoreSandboxNetwork(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeSandboxNetwork("", NetworkNamespace{}) + assert.Nil(t, err) +} + +func TestNoopFetchSandboxDevices(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchSandboxDevices("") + assert.Nil(t, err) +} + +func TestNoopStoreSandboxDevices(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeSandboxDevices("", []api.Device{}) + assert.Nil(t, err) +} + +func TestNoopFetchHypervisorState(t *testing.T) { + n := &noopResourceStorage{} + + err := n.fetchHypervisorState("", nil) + assert.Nil(t, err) +} + +func TestNoopStoreHypervisorState(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeHypervisorState("", nil) + assert.Nil(t, err) +} + +func TestNoopFetchAgentState(t *testing.T) { + n := &noopResourceStorage{} + + err := n.fetchAgentState("", nil) + assert.Nil(t, err) +} + +func TestNoopStoreAgentState(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeAgentState("", nil) + assert.Nil(t, err) +} + +func TestNoopStoreContainerResource(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeContainerResource("", "", 0, nil) + assert.Nil(t, err) +} + +func TestNoopDeleteContainerResources(t *testing.T) { + n := &noopResourceStorage{} + + err := n.deleteContainerResources("", "", []sandboxResource{0}) + assert.Nil(t, err) +} + +func TestNoopFetchContainerConfig(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchContainerConfig("", "") + assert.Nil(t, err) +} + +func TestNoopFetchContainerState(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchContainerState("", "") + assert.Nil(t, err) +} + +func TestNoopFetchContainerProcess(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchContainerProcess("", "") + assert.Nil(t, err) +} + +func TestNoopStoreContainerProcess(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeContainerProcess("", "", Process{}) + assert.Nil(t, err) +} + +func TestNoopFetchContainerMounts(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchContainerMounts("", "") + assert.Nil(t, err) +} + +func TestNoopStoreContainerMounts(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeContainerMounts("", "", []Mount{}) + assert.Nil(t, err) +} + +func TestNoopFetchContainerDevices(t *testing.T) { + n := &noopResourceStorage{} + + _, err := n.fetchContainerDevices("", "") + assert.Nil(t, err) +} + +func TestNoopStoreContainerDevices(t *testing.T) { + n := &noopResourceStorage{} + + err := n.storeContainerDevices("", "", []ContainerDevice{}) + assert.Nil(t, err) +} From 8b20c3f26d8e1334d6c0470fdaf292c48fa97a30 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 23 Aug 2018 16:29:39 -0700 Subject: [PATCH 2/2] virtcontainers: storage: Separate storage interface from implementations The storage implementation of filesystem was in the same file where the resource storage interface was declared. It's more proper to separate implementations and interface into different files. Fixes #633 Signed-off-by: Sebastien Boeuf --- ...stem.go => filesystem_resource_storage.go} | 54 --------------- ...go => filesystem_resource_storage_test.go} | 0 virtcontainers/resource_storage.go | 67 +++++++++++++++++++ 3 files changed, 67 insertions(+), 54 deletions(-) rename virtcontainers/{filesystem.go => filesystem_resource_storage.go} (89%) rename virtcontainers/{filesystem_test.go => filesystem_resource_storage_test.go} (100%) create mode 100644 virtcontainers/resource_storage.go diff --git a/virtcontainers/filesystem.go b/virtcontainers/filesystem_resource_storage.go similarity index 89% rename from virtcontainers/filesystem.go rename to virtcontainers/filesystem_resource_storage.go index 0723a39bba..b2ccc77943 100644 --- a/virtcontainers/filesystem.go +++ b/virtcontainers/filesystem_resource_storage.go @@ -112,49 +112,6 @@ var runStoragePath = filepath.Join("/run", storagePathSuffix, sandboxPathSuffix) // It will contain all guest vm sockets and shared mountpoints. var RunVMStoragePath = filepath.Join("/run", storagePathSuffix, vmPathSuffix) -// resourceStorage is the virtcontainers resources (configuration, state, etc...) -// storage interface. -// The default resource storage implementation is filesystem. -type resourceStorage interface { - // Create all resources for a sandbox - createAllResources(ctx context.Context, sandbox *Sandbox) error - - // Resources URIs functions return both the URI - // for the actual resource and the URI base. - containerURI(sandboxID, containerID string, resource sandboxResource) (string, string, error) - sandboxURI(sandboxID string, resource sandboxResource) (string, string, error) - - // Sandbox resources - storeSandboxResource(sandboxID string, resource sandboxResource, data interface{}) error - deleteSandboxResources(sandboxID string, resources []sandboxResource) error - fetchSandboxConfig(sandboxID string) (SandboxConfig, error) - fetchSandboxState(sandboxID string) (State, error) - fetchSandboxNetwork(sandboxID string) (NetworkNamespace, error) - storeSandboxNetwork(sandboxID string, networkNS NetworkNamespace) error - fetchSandboxDevices(sandboxID string) ([]api.Device, error) - storeSandboxDevices(sandboxID string, devices []api.Device) error - - // Hypervisor resources - fetchHypervisorState(sandboxID string, state interface{}) error - storeHypervisorState(sandboxID string, state interface{}) error - - // Agent resources - fetchAgentState(sandboxID string, state interface{}) error - storeAgentState(sandboxID string, state interface{}) error - - // Container resources - storeContainerResource(sandboxID, containerID string, resource sandboxResource, data interface{}) error - deleteContainerResources(sandboxID, containerID string, resources []sandboxResource) error - fetchContainerConfig(sandboxID, containerID string) (ContainerConfig, error) - fetchContainerState(sandboxID, containerID string) (State, error) - fetchContainerProcess(sandboxID, containerID string) (Process, error) - storeContainerProcess(sandboxID, containerID string, process Process) error - fetchContainerMounts(sandboxID, containerID string) ([]Mount, error) - storeContainerMounts(sandboxID, containerID string, mounts []Mount) error - fetchContainerDevices(sandboxID, containerID string) ([]ContainerDevice, error) - storeContainerDevices(sandboxID, containerID string, devices []ContainerDevice) error -} - // filesystem is a resourceStorage interface implementation for a local filesystem. type filesystem struct { ctx context.Context @@ -246,17 +203,6 @@ func (fs *filesystem) storeFile(file string, data interface{}) error { return nil } -// TypedDevice is used as an intermediate representation for marshalling -// and unmarshalling Device implementations. -type TypedDevice struct { - Type string - - // Data is assigned the Device object. - // This being declared as RawMessage prevents it from being marshalled/unmarshalled. - // We do that explicitly depending on Type. - Data json.RawMessage -} - // storeDeviceIDFile is used to marshal and store device IDs to disk. func (fs *filesystem) storeDeviceIDFile(file string, data interface{}) error { if file == "" { diff --git a/virtcontainers/filesystem_test.go b/virtcontainers/filesystem_resource_storage_test.go similarity index 100% rename from virtcontainers/filesystem_test.go rename to virtcontainers/filesystem_resource_storage_test.go diff --git a/virtcontainers/resource_storage.go b/virtcontainers/resource_storage.go new file mode 100644 index 0000000000..e4f06ebc09 --- /dev/null +++ b/virtcontainers/resource_storage.go @@ -0,0 +1,67 @@ +// Copyright (c) 2018 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package virtcontainers + +import ( + "context" + "encoding/json" + + "github.com/kata-containers/runtime/virtcontainers/device/api" +) + +// TypedDevice is used as an intermediate representation for marshalling +// and unmarshalling Device implementations. +type TypedDevice struct { + Type string + + // Data is assigned the Device object. + // This being declared as RawMessage prevents it from being marshalled/unmarshalled. + // We do that explicitly depending on Type. + Data json.RawMessage +} + +// resourceStorage is the virtcontainers resources (configuration, state, etc...) +// storage interface. +// The default resource storage implementation is filesystem. +type resourceStorage interface { + // Create all resources for a sandbox + createAllResources(ctx context.Context, sandbox *Sandbox) error + + // Resources URIs functions return both the URI + // for the actual resource and the URI base. + containerURI(sandboxID, containerID string, resource sandboxResource) (string, string, error) + sandboxURI(sandboxID string, resource sandboxResource) (string, string, error) + + // Sandbox resources + storeSandboxResource(sandboxID string, resource sandboxResource, data interface{}) error + deleteSandboxResources(sandboxID string, resources []sandboxResource) error + fetchSandboxConfig(sandboxID string) (SandboxConfig, error) + fetchSandboxState(sandboxID string) (State, error) + fetchSandboxNetwork(sandboxID string) (NetworkNamespace, error) + storeSandboxNetwork(sandboxID string, networkNS NetworkNamespace) error + fetchSandboxDevices(sandboxID string) ([]api.Device, error) + storeSandboxDevices(sandboxID string, devices []api.Device) error + + // Hypervisor resources + fetchHypervisorState(sandboxID string, state interface{}) error + storeHypervisorState(sandboxID string, state interface{}) error + + // Agent resources + fetchAgentState(sandboxID string, state interface{}) error + storeAgentState(sandboxID string, state interface{}) error + + // Container resources + storeContainerResource(sandboxID, containerID string, resource sandboxResource, data interface{}) error + deleteContainerResources(sandboxID, containerID string, resources []sandboxResource) error + fetchContainerConfig(sandboxID, containerID string) (ContainerConfig, error) + fetchContainerState(sandboxID, containerID string) (State, error) + fetchContainerProcess(sandboxID, containerID string) (Process, error) + storeContainerProcess(sandboxID, containerID string, process Process) error + fetchContainerMounts(sandboxID, containerID string) ([]Mount, error) + storeContainerMounts(sandboxID, containerID string, mounts []Mount) error + fetchContainerDevices(sandboxID, containerID string) ([]ContainerDevice, error) + storeContainerDevices(sandboxID, containerID string, devices []ContainerDevice) error +}