diff --git a/src/runtime/virtcontainers/api.go b/src/runtime/virtcontainers/api.go index 8bbbd371f7..8a3a918767 100644 --- a/src/runtime/virtcontainers/api.go +++ b/src/runtime/virtcontainers/api.go @@ -17,7 +17,6 @@ import ( "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/cgroups" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci" vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/store" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" specs "github.com/opencontainers/runtime-spec/specs-go" opentracing "github.com/opentracing/opentracing-go" @@ -52,7 +51,6 @@ func SetLogger(ctx context.Context, logger *logrus.Entry) { deviceApi.SetLogger(virtLog) compatoci.SetLogger(virtLog) - store.SetLogger(virtLog) deviceConfig.SetLogger(virtLog) cgroups.SetLogger(virtLog) } diff --git a/src/runtime/virtcontainers/container.go b/src/runtime/virtcontainers/container.go index 0030b1a1e1..49b3bfeecf 100644 --- a/src/runtime/virtcontainers/container.go +++ b/src/runtime/virtcontainers/container.go @@ -30,7 +30,6 @@ import ( "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/manager" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/rootless" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/store" ) // https://github.com/torvalds/linux/blob/master/include/uapi/linux/major.h @@ -337,8 +336,6 @@ type Container struct { systemMountsInfo SystemMountsInfo ctx context.Context - - store *store.VCStore } // ID returns the container identifier string. @@ -430,17 +427,9 @@ func (c *Container) setContainerState(state types.StateString) error { // update in-memory state c.state.State = state - if useOldStore(c.sandbox.ctx) { - // experimental runtime use "persist.json" which doesn't need "state.json" anymore - // update on-disk state - if err := c.store.Store(store.State, c.state); err != nil { - return err - } - } else { - // flush data to storage - if err := c.sandbox.Save(); err != nil { - return err - } + // flush data to storage + if err := c.sandbox.Save(); err != nil { + return err } return nil @@ -724,33 +713,16 @@ func newContainer(sandbox *Sandbox, contConfig *ContainerConfig) (*Container, er ctx: sandbox.ctx, } - if useOldStore(sandbox.ctx) { - ctrStore, err := store.NewVCContainerStore(sandbox.ctx, c.sandboxID, c.id) - if err != nil { - return nil, err - } - c.store = ctrStore - state, err := c.store.LoadContainerState() - if err == nil { - c.state = state - } + // experimental runtime use "persist.json" instead of legacy "state.json" as storage + err := c.Restore() + if err == nil { + //container restored + return c, nil + } - var process Process - if err := c.store.Load(store.Process, &process); err == nil { - c.process = process - } - } else { - // experimental runtime use "persist.json" instead of legacy "state.json" as storage - err := c.Restore() - if err == nil { - //container restored - return c, nil - } - - // Unexpected error - if !os.IsNotExist(err) && err != errContainerPersistNotExist { - return nil, err - } + // Unexpected error + if !os.IsNotExist(err) && err != errContainerPersistNotExist { + return nil, err } // Go to next step for first created container @@ -765,35 +737,7 @@ func newContainer(sandbox *Sandbox, contConfig *ContainerConfig) (*Container, er return c, nil } -func (c *Container) loadMounts() ([]Mount, error) { - var mounts []Mount - if err := c.store.Load(store.Mounts, &mounts); err != nil { - return []Mount{}, err - } - - return mounts, nil -} - -func (c *Container) loadDevices() ([]ContainerDevice, error) { - var devices []ContainerDevice - - if err := c.store.Load(store.DeviceIDs, &devices); err != nil { - return []ContainerDevice{}, err - } - - return devices, nil -} - func (c *Container) createMounts() error { - if useOldStore(c.sandbox.ctx) { - mounts, err := c.loadMounts() - if err == nil { - // restore mounts from disk - c.mounts = mounts - return nil - } - } - // Create block devices for newly created container if err := c.createBlockDevices(); err != nil { return err @@ -803,18 +747,6 @@ func (c *Container) createMounts() error { } func (c *Container) createDevices(contConfig *ContainerConfig) error { - // If sandbox supports "newstore", only newly created container can reach this function, - // so we don't call restore when `supportNewStore` is true - if useOldStore(c.sandbox.ctx) { - // Devices will be found in storage after create stage has completed. - // We load devices from storage at all other stages. - storedDevices, err := c.loadDevices() - if err == nil { - c.devices = storedDevices - return nil - } - } - // If devices were not found in storage, create Device implementations // from the configuration. This should happen at create. var storedDevices []ContainerDevice diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index 92098af250..1006aa63be 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -30,7 +30,6 @@ import ( "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/rootless" vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/uuid" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/store" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" "github.com/gogo/protobuf/proto" @@ -345,12 +344,6 @@ func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config interface k.proxyBuiltIn = isProxyBuiltIn(sandbox.config.ProxyType) - // Fetch agent runtime info. - if useOldStore(sandbox.ctx) { - if err := sandbox.store.Load(store.Agent, &k.state); err != nil { - k.Logger().Debug("Could not retrieve anything from storage") - } - } return disableVMShutdown, nil } diff --git a/src/runtime/virtcontainers/persist.go b/src/runtime/virtcontainers/persist.go index 595a8c4707..851e4e2653 100644 --- a/src/runtime/virtcontainers/persist.go +++ b/src/runtime/virtcontainers/persist.go @@ -6,14 +6,12 @@ package virtcontainers import ( - "context" "errors" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api" exp "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/experimental" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist" persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/store" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" "github.com/mitchellh/mapstructure" ) @@ -579,25 +577,3 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) { } return sconfig, nil } - -var oldstoreKey = struct{}{} - -func loadSandboxConfigFromOldStore(ctx context.Context, sid string) (*SandboxConfig, context.Context, error) { - var config SandboxConfig - // We're bootstrapping - vcStore, err := store.NewVCSandboxStore(ctx, sid) - if err != nil { - return nil, ctx, err - } - - if err := vcStore.Load(store.Configuration, &config); err != nil { - return nil, ctx, err - } - - return &config, context.WithValue(ctx, oldstoreKey, true), nil -} - -func useOldStore(ctx context.Context) bool { - v := ctx.Value(oldstoreKey) - return v != nil -} diff --git a/src/runtime/virtcontainers/sandbox.go b/src/runtime/virtcontainers/sandbox.go index 3e70779174..00e058b562 100644 --- a/src/runtime/virtcontainers/sandbox.go +++ b/src/runtime/virtcontainers/sandbox.go @@ -25,7 +25,6 @@ import ( "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/drivers" @@ -33,12 +32,12 @@ import ( exp "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/experimental" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist" persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api" + "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations" vccgroups "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/cgroups" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/rootless" vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/store" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils" ) @@ -183,9 +182,7 @@ type Sandbox struct { factory Factory hypervisor hypervisor agent agent - store *store.VCStore - // store is used to replace VCStore step by step - newStore persistapi.PersistDriver + newStore persistapi.PersistDriver network Network monitor *monitor @@ -559,51 +556,18 @@ func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factor sandboxConfig.HypervisorConfig.SELinuxProcessLabel = spec.Process.SelinuxLabel } - if useOldStore(ctx) { - vcStore, err := store.NewVCSandboxStore(ctx, s.id) - if err != nil { - return nil, err - } + s.devManager = deviceManager.NewDeviceManager(sandboxConfig.HypervisorConfig.BlockDeviceDriver, + sandboxConfig.HypervisorConfig.EnableVhostUserStore, + sandboxConfig.HypervisorConfig.VhostUserStorePath, nil) - s.store = vcStore + // Ignore the error. Restore can fail for a new sandbox + if err := s.Restore(); err != nil { + s.Logger().WithError(err).Debug("restore sandbox failed") + } - // Fetch sandbox network to be able to access it from the sandbox structure. - var networkNS NetworkNamespace - if err = s.store.Load(store.Network, &networkNS); err == nil { - s.networkNS = networkNS - } - - devices, err := s.store.LoadDevices() - if err != nil { - s.Logger().WithError(err).WithField("sandboxid", s.id).Warning("load sandbox devices failed") - } - s.devManager = deviceManager.NewDeviceManager(sandboxConfig.HypervisorConfig.BlockDeviceDriver, - sandboxConfig.HypervisorConfig.EnableVhostUserStore, - sandboxConfig.HypervisorConfig.VhostUserStorePath, devices) - - // Load sandbox state. The hypervisor.createSandbox call, may need to access statei. - state, err := s.store.LoadState() - if err == nil { - s.state = state - } - - if err = s.hypervisor.createSandbox(ctx, s.id, s.networkNS, &sandboxConfig.HypervisorConfig, s.stateful); err != nil { - return nil, err - } - } else { - s.devManager = deviceManager.NewDeviceManager(sandboxConfig.HypervisorConfig.BlockDeviceDriver, - sandboxConfig.HypervisorConfig.EnableVhostUserStore, - sandboxConfig.HypervisorConfig.VhostUserStorePath, nil) - - // Ignore the error. Restore can fail for a new sandbox - if err := s.Restore(); err != nil { - s.Logger().WithError(err).Debug("restore sandbox failed") - } - - // new store doesn't require hypervisor to be stored immediately - if err = s.hypervisor.createSandbox(ctx, s.id, s.networkNS, &sandboxConfig.HypervisorConfig, s.stateful); err != nil { - return nil, err - } + // new store doesn't require hypervisor to be stored immediately + if err = s.hypervisor.createSandbox(ctx, s.id, s.networkNS, &sandboxConfig.HypervisorConfig, s.stateful); err != nil { + return nil, err } if err := s.createCgroupManager(); err != nil { @@ -717,22 +681,15 @@ func fetchSandbox(ctx context.Context, sandboxID string) (sandbox *Sandbox, err var config SandboxConfig - // Try to load sandbox config from old store at first. - c, ctx, err := loadSandboxConfigFromOldStore(ctx, sandboxID) + // load sandbox config fromld store. + c, err := loadSandboxConfig(sandboxID) if err != nil { - virtLog.Warningf("failed to get sandbox config from old store: %v", err) - // If we failed to load sandbox config from old store, try again with new store. - c, err = loadSandboxConfig(sandboxID) - if err != nil { - virtLog.Warningf("failed to get sandbox config from new store: %v", err) - return nil, err - } + virtLog.Warningf("failed to get sandbox config from new store: %v", err) + return nil, err } + config = *c - if useOldStore(ctx) { - virtLog.Infof("Warning: old store has been deprecated.") - } // fetchSandbox is not suppose to create new sandbox VM. sandbox, err = createSandbox(ctx, config, nil) if err != nil { @@ -1594,9 +1551,6 @@ func (s *Sandbox) setSandboxState(state types.StateString) error { // update in-memory state s.state.State = state - if useOldStore(s.ctx) { - return s.store.Store(store.State, s.state) - } return nil } diff --git a/src/runtime/virtcontainers/store/backend.go b/src/runtime/virtcontainers/store/backend.go deleted file mode 100644 index 99a56317c1..0000000000 --- a/src/runtime/virtcontainers/store/backend.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2019 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -// - -package store - -import ( - "context" - "fmt" -) - -type backendType string - -const ( - filesystemBackend backendType = "filesystem" -) - -const ( - filesystemScheme string = "file" -) - -func schemeToBackendType(scheme string) (backendType, error) { - switch scheme { - case filesystemScheme: - return filesystemBackend, nil - } - - return "", fmt.Errorf("Unsupported scheme %s", scheme) -} - -func newBackend(scheme string) (backend, error) { - t, err := schemeToBackendType(scheme) - if err != nil { - return nil, err - } - - switch t { - case filesystemBackend: - return &filesystem{}, nil - } - - return nil, fmt.Errorf("Unsupported scheme %s", scheme) -} - -type backend interface { - new(ctx context.Context, path string, host string) error - delete() error - load(item Item, data interface{}) error - store(item Item, data interface{}) error - // raw creates a raw Store item. A raw item is one that is - // not defined through the Item enum. - // The caller gets an item URL back and handles it directly, - // outside of the top level Store API. - raw(id string) (string, error) - lock(item Item, exclusive bool) (string, error) - unlock(item Item, token string) error -} diff --git a/src/runtime/virtcontainers/store/filesystem_backend.go b/src/runtime/virtcontainers/store/filesystem_backend.go deleted file mode 100644 index 294e76e65f..0000000000 --- a/src/runtime/virtcontainers/store/filesystem_backend.go +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright (c) 2019 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -// - -package store - -import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "syscall" - - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/rootless" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/uuid" - opentracing "github.com/opentracing/opentracing-go" - "github.com/sirupsen/logrus" -) - -const ( - // ConfigurationFile is the file name used for every JSON sandbox configuration. - ConfigurationFile string = "config.json" - - // StateFile is the file name storing a sandbox state. - StateFile = "state.json" - - // NetworkFile is the file name storing a sandbox network. - NetworkFile = "network.json" - - // HypervisorFile is the file name storing a hypervisor's state. - HypervisorFile = "hypervisor.json" - - // AgentFile is the file name storing an agent's state. - AgentFile = "agent.json" - - // ProcessFile is the file name storing a container process. - ProcessFile = "process.json" - - // LockFile is the file name locking the usage of a resource. - LockFile = "lock" - - // MountsFile is the file name storing a container's mount points. - MountsFile = "mounts.json" - - // DevicesFile is the file name storing a container's devices. - DevicesFile = "devices.json" - - // uuidFile is the file name storing a guest VM uuid state. - uuidFile = "uuid.json" -) - -// DirMode is the permission bits used for creating a directory -const DirMode = os.FileMode(0750) | os.ModeDir - -// StoragePathSuffix is the suffix used for all storage paths -// -// Note: this very brief path represents "virtcontainers". It is as -// terse as possible to minimise path length. -const StoragePathSuffix = "vc" - -// SandboxPathSuffix is the suffix used for sandbox storage -const SandboxPathSuffix = "sbs" - -// VMPathSuffix is the suffix used for guest VMs. -const VMPathSuffix = "vm" - -// UUIDPathSuffix is the suffix used for uuid storage -const UUIDPathSuffix = "uuid" - -// ConfigStoragePath is the sandbox configuration directory. -// It will contain one config.json file for each created sandbox. -// The function is declared this way for mocking in unit tests -var ConfigStoragePath = func() string { - path := filepath.Join("/var/lib", StoragePathSuffix, SandboxPathSuffix) - if rootless.IsRootless() { - return filepath.Join(rootless.GetRootlessDir(), path) - } - return path -} - -// RunStoragePath is the sandbox runtime directory. -// It will contain one state.json and one lock file for each created sandbox. -// The function is declared this way for mocking in unit tests -var RunStoragePath = func() string { - path := filepath.Join("/run", StoragePathSuffix, SandboxPathSuffix) - if rootless.IsRootless() { - return filepath.Join(rootless.GetRootlessDir(), path) - } - return path -} - -// RunVMStoragePath is the vm directory. -// It will contain all guest vm sockets and shared mountpoints. -// The function is declared this way for mocking in unit tests -var RunVMStoragePath = func() string { - path := filepath.Join("/run", StoragePathSuffix, VMPathSuffix) - if rootless.IsRootless() { - return filepath.Join(rootless.GetRootlessDir(), path) - } - return path -} - -// VMUUIDStoragePath is the uuid directory. -// It will contain all uuid info used by guest vm. -var VMUUIDStoragePath = func() string { - path := filepath.Join("/var/lib", StoragePathSuffix, UUIDPathSuffix) - if rootless.IsRootless() { - return filepath.Join(rootless.GetRootlessDir(), path) - } - return path - -} - -func itemToFile(item Item) (string, error) { - switch item { - case Configuration: - return ConfigurationFile, nil - case State: - return StateFile, nil - case Network: - return NetworkFile, nil - case Hypervisor: - return HypervisorFile, nil - case Agent: - return AgentFile, nil - case Process: - return ProcessFile, nil - case Lock: - return LockFile, nil - case Mounts: - return MountsFile, nil - case Devices, DeviceIDs: - return DevicesFile, nil - case UUID: - return uuidFile, nil - } - - return "", fmt.Errorf("Unknown item %s", item) -} - -type filesystem struct { - ctx context.Context - - path string - rawPath string - - lockTokens map[string]*os.File -} - -// Logger returns a logrus logger appropriate for logging Store filesystem messages -func (f *filesystem) logger() *logrus.Entry { - return storeLog.WithFields(logrus.Fields{ - "subsystem": "store", - "backend": "filesystem", - "path": f.path, - }) -} - -func (f *filesystem) trace(name string) (opentracing.Span, context.Context) { - if f.ctx == nil { - f.logger().WithField("type", "bug").Error("trace called before context set") - f.ctx = context.Background() - } - - span, ctx := opentracing.StartSpanFromContext(f.ctx, name) - - span.SetTag("subsystem", "store") - span.SetTag("type", "filesystem") - span.SetTag("path", f.path) - - return span, ctx -} - -func (f *filesystem) itemToPath(item Item) (string, error) { - fileName, err := itemToFile(item) - if err != nil { - return "", err - } - - return filepath.Join(f.path, fileName), nil -} - -func (f *filesystem) initialize() error { - _, err := os.Stat(f.path) - if err == nil { - return nil - } - - // Our root path does not exist, we need to create the initial layout: - // The root directory, a lock file and a raw files directory. - - // Root directory - f.logger().WithField("path", f.path).Debugf("Creating root directory") - if err := os.MkdirAll(f.path, DirMode); err != nil { - return err - } - - // Raw directory - f.logger().WithField("path", f.rawPath).Debugf("Creating raw directory") - if err := os.MkdirAll(f.rawPath, DirMode); err != nil { - return err - } - - // Lock - lockPath := filepath.Join(f.path, LockFile) - - lockFile, err := os.Create(lockPath) - if err != nil { - f.delete() - return err - } - lockFile.Close() - - return nil -} - -func (f *filesystem) new(ctx context.Context, path string, host string) error { - f.ctx = ctx - f.path = path - f.rawPath = filepath.Join(f.path, "raw") - f.lockTokens = make(map[string]*os.File) - - f.logger().Debugf("New filesystem store backend for %s", path) - - return f.initialize() -} - -func (f *filesystem) delete() error { - f.logger().WithField("path", f.path).Debugf("Deleting files") - return os.RemoveAll(f.path) -} - -func (f *filesystem) load(item Item, data interface{}) error { - span, _ := f.trace("load") - defer span.Finish() - - span.SetTag("item", item) - - filePath, err := f.itemToPath(item) - if err != nil { - return err - } - - fileData, err := ioutil.ReadFile(filePath) - if err != nil { - return err - } - - if err := json.Unmarshal(fileData, data); err != nil { - return err - } - - return nil -} - -func (f *filesystem) store(item Item, data interface{}) error { - span, _ := f.trace("store") - defer span.Finish() - - span.SetTag("item", item) - - filePath, err := f.itemToPath(item) - if err != nil { - return err - } - - file, err := os.Create(filePath) - if err != nil { - return err - } - defer file.Close() - - jsonOut, err := json.Marshal(data) - if err != nil { - return fmt.Errorf("Could not marshall data: %s", err) - } - file.Write(jsonOut) - - return nil -} - -func (f *filesystem) raw(id string) (string, error) { - span, _ := f.trace("raw") - defer span.Finish() - - span.SetTag("id", id) - - // We must use the item ID. - if id != "" { - filePath := filepath.Join(f.rawPath, id) - file, err := os.Create(filePath) - if err != nil { - return "", err - } - - return filesystemScheme + "://" + file.Name(), nil - } - - // Generate a random temporary file. - file, err := ioutil.TempFile(f.rawPath, "raw-") - if err != nil { - return "", err - } - defer file.Close() - - return filesystemScheme + "://" + file.Name(), nil -} - -func (f *filesystem) lock(item Item, exclusive bool) (string, error) { - itemPath, err := f.itemToPath(item) - if err != nil { - return "", err - } - - itemFile, err := os.Open(itemPath) - if err != nil { - return "", err - } - - var lockType int - if exclusive { - lockType = syscall.LOCK_EX - } else { - lockType = syscall.LOCK_SH - } - - if err := syscall.Flock(int(itemFile.Fd()), lockType); err != nil { - itemFile.Close() - return "", err - } - - token := uuid.Generate().String() - f.lockTokens[token] = itemFile - - return token, nil -} - -func (f *filesystem) unlock(item Item, token string) error { - itemFile := f.lockTokens[token] - if itemFile == nil { - return fmt.Errorf("No lock for token %s", token) - } - - if err := syscall.Flock(int(itemFile.Fd()), syscall.LOCK_UN); err != nil { - return err - } - - itemFile.Close() - delete(f.lockTokens, token) - - return nil -} diff --git a/src/runtime/virtcontainers/store/filesystem_backend_test.go b/src/runtime/virtcontainers/store/filesystem_backend_test.go deleted file mode 100644 index 2b1f9e5dc7..0000000000 --- a/src/runtime/virtcontainers/store/filesystem_backend_test.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2019 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -// - -package store - -import ( - "context" - "io/ioutil" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" -) - -type TestNoopStructure struct { - Field1 string - Field2 string -} - -var rootPath = func() string { - dir, _ := ioutil.TempDir("", "") - return dir -}() - -var expectedFilesystemData = "{\"Field1\":\"value1\",\"Field2\":\"value2\"}" - -func TestStoreFilesystemStore(t *testing.T) { - f := filesystem{} - - err := f.new(context.Background(), rootPath, "") - defer f.delete() - assert.Nil(t, err) - - data := TestNoopStructure{ - Field1: "value1", - Field2: "value2", - } - - err = f.store(State, data) - assert.Nil(t, err) - - filesystemData, err := ioutil.ReadFile(filepath.Join(rootPath, StateFile)) - assert.Nil(t, err) - assert.Equal(t, string(filesystemData), expectedFilesystemData) -} - -func TestStoreFilesystemLoad(t *testing.T) { - f := filesystem{} - - err := f.new(context.Background(), rootPath, "") - defer f.delete() - assert.Nil(t, err) - - data := TestNoopStructure{ - Field1: "value1", - Field2: "value2", - } - - // Store test data - err = f.store(State, data) - assert.Nil(t, err) - - // Load and compare - newData := TestNoopStructure{} - err = f.load(State, &newData) - assert.Nil(t, err) - assert.Equal(t, newData, data) -} - -func TestStoreFilesystemDelete(t *testing.T) { - f := filesystem{} - - err := f.new(context.Background(), rootPath, "") - assert.Nil(t, err) - - data := TestNoopStructure{ - Field1: "value1", - Field2: "value2", - } - - // Store test data - err = f.store(State, data) - assert.Nil(t, err) - - err = f.delete() - assert.Nil(t, err) - - _, err = os.Stat(f.path) - assert.NotNil(t, err) -} - -func TestStoreFilesystemRaw(t *testing.T) { - f := filesystem{} - - err := f.new(context.Background(), rootPath, "") - defer f.delete() - assert.Nil(t, err) - - path, err := f.raw("roah") - assert.Nil(t, err) - assert.Equal(t, path, filesystemScheme+"://"+filepath.Join(rootPath, "raw", "roah")) -} - -func TestStoreFilesystemLockShared(t *testing.T) { - f := filesystem{} - - err := f.new(context.Background(), rootPath, "") - defer f.delete() - assert.Nil(t, err) - - // Take 2 shared locks - token1, err := f.lock(Lock, false) - assert.Nil(t, err) - - token2, err := f.lock(Lock, false) - assert.Nil(t, err) - - err = f.unlock(Lock, token1) - assert.Nil(t, err) - - err = f.unlock(Lock, token2) - assert.Nil(t, err) - - err = f.unlock(Lock, token2) - assert.NotNil(t, err) -} - -func TestStoreFilesystemLockExclusive(t *testing.T) { - f := filesystem{} - - err := f.new(context.Background(), rootPath, "") - defer f.delete() - assert.Nil(t, err) - - // Take 1 exclusive lock - token, err := f.lock(Lock, true) - assert.Nil(t, err) - - err = f.unlock(Lock, token) - assert.Nil(t, err) - - token, err = f.lock(Lock, true) - assert.Nil(t, err) - - err = f.unlock(Lock, token) - assert.Nil(t, err) - - err = f.unlock(Lock, token) - assert.NotNil(t, err) -} diff --git a/src/runtime/virtcontainers/store/manager.go b/src/runtime/virtcontainers/store/manager.go deleted file mode 100644 index dba6b2ca97..0000000000 --- a/src/runtime/virtcontainers/store/manager.go +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (c) 2019 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -// - -package store - -import ( - "context" - "fmt" - "net/url" - "sync" - - opentracing "github.com/opentracing/opentracing-go" - "github.com/sirupsen/logrus" -) - -// Item represents a virtcontainers items that will be managed through the store. -type Item uint8 - -const ( - // Configuration represents a configuration item to be stored - Configuration Item = iota - - // State represents a state item to be stored. - State - - // Network represents a networking item to be stored. - Network - - // Hypervisor represents an hypervisor item to be stored. - Hypervisor - - // Agent represents a agent item to be stored. - Agent - - // Process represents a container process item to be stored. - Process - - // Lock represents a lock item to be stored. - Lock - - // Mounts represents a set of mounts related item to be stored. - Mounts - - // Devices represents a set of devices related item to be stored. - Devices - - // DeviceIDs represents a set of reference IDs item to be stored. - DeviceIDs - - // UUID represents a set of uuids item to be stored. - UUID -) - -func (i Item) String() string { - switch i { - case Configuration: - return "Configuration" - case State: - return "State" - case Network: - return "Network" - case Hypervisor: - return "Hypervisor" - case Agent: - return "Agent" - case Process: - return "Process" - case Lock: - return "Lock" - case Mounts: - return "Mounts" - case Devices: - return "Devices" - case DeviceIDs: - return "Device IDs" - } - - return "" -} - -// Store is an opaque structure representing a virtcontainers Store. -type Store struct { - sync.RWMutex - ctx context.Context - - url string - scheme string - path string - host string - - backend backend -} - -type manager struct { - sync.RWMutex - stores map[string]*Store -} - -var stores = &manager{stores: make(map[string]*Store)} - -func (m *manager) addStore(s *Store) (rs *Store, err error) { - if s == nil { - return nil, fmt.Errorf("Store can not be nil") - } - - if s.url == "" { - return nil, fmt.Errorf("Store URL can not be nil") - } - - m.Lock() - defer m.Unlock() - - if m.stores[s.url] == nil { - m.stores[s.url] = s - } - - return m.stores[s.url], nil -} - -func (m *manager) removeStore(url string) { - m.Lock() - defer m.Unlock() - - delete(m.stores, url) -} - -func (m *manager) findStore(url string) *Store { - m.RLock() - defer m.RUnlock() - - return m.stores[url] -} - -// New will return a new virtcontainers Store. -// If there is already a Store for the URL, we will re-use it. -// Otherwise a new Store is created. -func New(ctx context.Context, storeURL string) (*Store, error) { - // Do we already have such store? - if s := stores.findStore(storeURL); s != nil { - return s, nil - } - - u, err := url.Parse(storeURL) - if err != nil { - return nil, err - } - - s := &Store{ - ctx: ctx, - url: storeURL, - scheme: u.Scheme, - path: u.Path, - host: u.Host, - } - - backend, err := newBackend(s.scheme) - if err != nil { - return nil, err - } - - s.backend = backend - - // Create new backend - if err = s.backend.new(ctx, s.path, s.host); err != nil { - return nil, err - } - - if s, err = stores.addStore(s); err != nil { - return nil, err - } - - return s, nil -} - -// DeleteAll deletes all Stores from the manager. -func DeleteAll() { - for _, s := range stores.stores { - s.Delete() - } -} - -var storeLog = logrus.WithField("source", "virtcontainers/store") - -// SetLogger sets the custom logger to be used by this package. If not called, -// the package will create its own logger. -func SetLogger(logger *logrus.Entry) { - fields := storeLog.Data - storeLog = logger.WithFields(fields) -} - -// Logger returns a logrus logger appropriate for logging Store messages -func (s *Store) Logger() *logrus.Entry { - return storeLog.WithFields(logrus.Fields{ - "subsystem": "store", - "path": s.path, - }) -} - -func (s *Store) trace(name string) (opentracing.Span, context.Context) { - if s.ctx == nil { - s.Logger().WithField("type", "bug").Error("trace called before context set") - s.ctx = context.Background() - } - - span, ctx := opentracing.StartSpanFromContext(s.ctx, name) - - span.SetTag("subsystem", "store") - span.SetTag("path", s.path) - - return span, ctx -} - -// Load loads a virtcontainers item from a Store. -func (s *Store) Load(item Item, data interface{}) error { - span, _ := s.trace("Load") - defer span.Finish() - - span.SetTag("item", item) - - s.RLock() - defer s.RUnlock() - - return s.backend.load(item, data) -} - -// Store stores a virtcontainers item into a Store. -func (s *Store) Store(item Item, data interface{}) error { - span, _ := s.trace("Store") - defer span.Finish() - - span.SetTag("item", item) - - s.Lock() - defer s.Unlock() - - return s.backend.store(item, data) -} - -// Delete deletes all artifacts created by a Store. -// The Store is also removed from the manager. -func (s *Store) Delete() error { - span, _ := s.trace("Store") - defer span.Finish() - - s.Lock() - defer s.Unlock() - - if err := s.backend.delete(); err != nil { - return err - } - - stores.removeStore(s.url) - s.url = "" - - return nil -} - -// Raw creates a raw item to be handled directly by the API caller. -// It returns a full URL to the item and the caller is responsible -// for handling the item through this URL. -func (s *Store) Raw(id string) (string, error) { - span, _ := s.trace("Raw") - defer span.Finish() - - s.Lock() - defer s.Unlock() - - return s.backend.raw(id) -} - -// ItemLock takes a lock on an item. -func (s *Store) ItemLock(item Item, exclusive bool) (string, error) { - return s.backend.lock(item, exclusive) -} - -// ItemUnlock unlocks an item. -func (s *Store) ItemUnlock(item Item, token string) error { - return s.backend.unlock(item, token) -} diff --git a/src/runtime/virtcontainers/store/manager_test.go b/src/runtime/virtcontainers/store/manager_test.go deleted file mode 100644 index be6e56a3e6..0000000000 --- a/src/runtime/virtcontainers/store/manager_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2019 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -// - -package store - -import ( - "context" - "io/ioutil" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" -) - -const testSandboxID = "7f49d00d-1995-4156-8c79-5f5ab24ce138" - -var sandboxDirConfig = "" -var sandboxFileConfig = "" -var sandboxDirState = "" -var sandboxDirLock = "" -var sandboxFileState = "" -var sandboxFileLock = "" -var storeRoot, storeRootDir = func() (string, string) { - dir, _ := ioutil.TempDir("", "") - return "file://" + dir, dir -}() -var testDir = "" -var ConfigStoragePathSaved = func() string { return "" } -var RunStoragePathSaved = func() string { return "" } - -func TestNewStore(t *testing.T) { - s, err := New(context.Background(), storeRoot) - assert.Nil(t, err) - assert.Equal(t, s.scheme, "file") - assert.Equal(t, s.host, "") - assert.Equal(t, s.path, storeRootDir) -} - -func TestDeleteStore(t *testing.T) { - s, err := New(context.Background(), storeRoot) - assert.Nil(t, err) - - err = s.Delete() - assert.Nil(t, err) - - // We should no longer find storeRoot - newStore := stores.findStore(storeRoot) - assert.Nil(t, newStore, "findStore should not have found %s", storeRoot) -} - -func TestManagerAddStore(t *testing.T) { - s, err := New(context.Background(), storeRoot) - assert.Nil(t, err) - defer stores.removeStore(storeRoot) - - // Positive find - newStore := stores.findStore(storeRoot) - assert.NotNil(t, newStore, "findStore failed") - - // Duplicate, should fail - ns, err := stores.addStore(s) - assert.Nil(t, err, "addStore should not failed") - assert.Equal(t, s, ns) - - // Try with an empty URL - sEmpty, err := New(context.Background(), storeRoot) - assert.Nil(t, err) - sEmpty.url = "" - _, err = stores.addStore(sEmpty) - assert.NotNil(t, err, "addStore should have failed on an empty store URL") - -} - -func TestManagerRemoveStore(t *testing.T) { - _, err := New(context.Background(), storeRoot) - assert.Nil(t, err) - - // Positive find - newStore := stores.findStore(storeRoot) - assert.NotNil(t, newStore, "findStore failed") - - // Negative removal - stores.removeStore(storeRoot + "foobar") - - // We should still find storeRoot - newStore = stores.findStore(storeRoot) - assert.NotNil(t, newStore, "findStore failed") - - // Positive removal - stores.removeStore(storeRoot) - - // We should no longer find storeRoot - newStore = stores.findStore(storeRoot) - assert.Nil(t, newStore, "findStore should not have found %s", storeRoot) -} - -func TestManagerFindStore(t *testing.T) { - _, err := New(context.Background(), storeRoot) - assert.Nil(t, err) - defer stores.removeStore(storeRoot) - - // Positive find - newStore := stores.findStore(storeRoot) - assert.NotNil(t, newStore, "findStore failed") - - // Negative find - newStore = stores.findStore(storeRoot + "foobar") - assert.Nil(t, newStore, "findStore should not have found a new store") -} - -// TestMain is the common main function used by ALL the test functions -// for the store. -func TestMain(m *testing.M) { - setup() - rt := m.Run() - shutdown() - os.Exit(rt) -} - -func shutdown() { - os.RemoveAll(testDir) - ConfigStoragePath = ConfigStoragePathSaved - RunStoragePath = RunStoragePathSaved -} - -func setup() { - var err error - testDir, err = ioutil.TempDir("", "store-tmp-") - if err != nil { - panic(err) - } - - ConfigStoragePathSaved = ConfigStoragePath - RunStoragePathSaved = RunStoragePath - // allow the tests to run without affecting the host system. - ConfigStoragePath = func() string { return filepath.Join(testDir, StoragePathSuffix, "config") } - RunStoragePath = func() string { return filepath.Join(testDir, StoragePathSuffix, "run") } - - // set now that ConfigStoragePath has been overridden. - sandboxDirConfig = filepath.Join(ConfigStoragePath(), testSandboxID) - sandboxFileConfig = filepath.Join(ConfigStoragePath(), testSandboxID, ConfigurationFile) - sandboxDirState = filepath.Join(RunStoragePath(), testSandboxID) - sandboxDirLock = filepath.Join(RunStoragePath(), testSandboxID) - sandboxFileState = filepath.Join(RunStoragePath(), testSandboxID, StateFile) - sandboxFileLock = filepath.Join(RunStoragePath(), testSandboxID, LockFile) -} diff --git a/src/runtime/virtcontainers/store/vc.go b/src/runtime/virtcontainers/store/vc.go deleted file mode 100644 index e73b2e4a3f..0000000000 --- a/src/runtime/virtcontainers/store/vc.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (c) 2019 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -// - -package store - -import ( - "context" - "encoding/json" - "fmt" - "path/filepath" - - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/drivers" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" -) - -// VCStorePrefix is only used for tests to config a temp store dir -var VCStorePrefix = "" - -// VCStore is a virtcontainers specific Store. -// Virtcontainers typically needs a configuration Store for -// storing permanent items across reboots. -// It also needs a state Store for storing states and other run-time -// related items. Those should not survive a reboot. -// -// VCStore simply dispatches items into the right Store. -type VCStore struct { - config, state, uuid *Store -} - -func (s *VCStore) itemToStore(item Item) *Store { - switch item { - case Configuration: - return s.config - case State, Network, Hypervisor, Agent, Process, Lock, Mounts, Devices, DeviceIDs: - return s.state - case UUID: - return s.uuid - } - - return s.state -} - -// NewVCStore creates a virtcontainers specific Store. -func NewVCStore(ctx context.Context, configRoot, stateRoot string) (*VCStore, error) { - config, err := New(ctx, configRoot) - if err != nil { - fmt.Printf("config root %s\n", configRoot) - return nil, err - } - - state, err := New(ctx, stateRoot) - if err != nil { - return nil, err - } - - uuid, err := New(ctx, VCStoreUUIDPath()) - if err != nil { - return nil, err - } - - return &VCStore{ - config: config, - state: state, - uuid: uuid, - }, nil -} - -// NewVCSandboxStore creates a virtcontainers sandbox Store, with filesystem backend. -func NewVCSandboxStore(ctx context.Context, sandboxID string) (*VCStore, error) { - if sandboxID == "" { - return nil, fmt.Errorf("sandbox ID can not be empty") - } - - return NewVCStore(ctx, - SandboxConfigurationRoot(sandboxID), - SandboxRuntimeRoot(sandboxID), - ) -} - -// NewVCContainerStore creates a virtcontainers container Store, with filesystem backend. -func NewVCContainerStore(ctx context.Context, sandboxID, containerID string) (*VCStore, error) { - if sandboxID == "" { - return nil, fmt.Errorf("sandbox ID can not be empty") - } - - if containerID == "" { - return nil, fmt.Errorf("container ID can not be empty") - } - - return NewVCStore(ctx, - ContainerConfigurationRoot(sandboxID, containerID), - ContainerRuntimeRoot(sandboxID, containerID), - ) -} - -// Store stores a virtcontainers item into the right Store. -func (s *VCStore) Store(item Item, data interface{}) error { - return s.itemToStore(item).Store(item, data) -} - -// Load loads a virtcontainers item from the right Store. -func (s *VCStore) Load(item Item, data interface{}) error { - return s.itemToStore(item).Load(item, data) -} - -// Delete deletes all artifacts created by a VCStore. -// Both config and state Stores are also removed from the manager. -func (s *VCStore) Delete() error { - if err := s.config.Delete(); err != nil { - return err - } - - if err := s.state.Delete(); err != nil { - return err - } - - return nil -} - -// LoadState loads an returns a virtcontainer state -func (s *VCStore) LoadState() (types.SandboxState, error) { - var state types.SandboxState - - if err := s.state.Load(State, &state); err != nil { - return types.SandboxState{}, err - } - - return state, nil -} - -// LoadContainerState loads an returns a virtcontainer state -func (s *VCStore) LoadContainerState() (types.ContainerState, error) { - var state types.ContainerState - - if err := s.state.Load(State, &state); err != nil { - return types.ContainerState{}, err - } - - return state, 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 -} - -// StoreDevices stores a virtcontainers devices slice. -// The Device slice is first marshalled into a TypedDevice -// one to include the type of the Device objects. -func (s *VCStore) StoreDevices(devices []api.Device) error { - var typedDevices []TypedDevice - - for _, d := range devices { - tempJSON, _ := json.Marshal(d) - typedDevice := TypedDevice{ - Type: string(d.DeviceType()), - Data: tempJSON, - } - typedDevices = append(typedDevices, typedDevice) - } - - return s.state.Store(Devices, typedDevices) -} - -// LoadDevices loads an returns a virtcontainer devices slice. -// We need a custom unmarshalling routine for translating TypedDevices -// into api.Devices based on their type. -func (s *VCStore) LoadDevices() ([]api.Device, error) { - var typedDevices []TypedDevice - var devices []api.Device - - if err := s.state.Load(Devices, &typedDevices); err != nil { - return []api.Device{}, err - } - - for _, d := range typedDevices { - switch d.Type { - case string(config.DeviceVFIO): - // TODO: remove dependency of drivers package - var device drivers.VFIODevice - if err := json.Unmarshal(d.Data, &device); err != nil { - return []api.Device{}, err - } - devices = append(devices, &device) - case string(config.DeviceBlock): - // TODO: remove dependency of drivers package - var device drivers.BlockDevice - if err := json.Unmarshal(d.Data, &device); err != nil { - return []api.Device{}, err - } - devices = append(devices, &device) - case string(config.DeviceGeneric): - // TODO: remove dependency of drivers package - var device drivers.GenericDevice - if err := json.Unmarshal(d.Data, &device); err != nil { - return []api.Device{}, err - } - devices = append(devices, &device) - default: - return []api.Device{}, fmt.Errorf("Unknown device type, could not unmarshal") - } - } - - return devices, nil -} - -// Raw creates a raw item in the virtcontainer state Store. A raw -// item is a custom one, not defined through the Item enum, and that -// the caller needs to handle directly. -// Typically this is used to create a custom virtcontainers file. -// For example the Firecracker code uses this API to create temp -// files under the sandbox state root path, and uses them as block -// driver backend placeholder. -func (s *VCStore) Raw(id string) (string, error) { - return s.state.Raw(id) -} - -// Lock takes an exclusive lock on the virtcontainers state Lock item. -func (s *VCStore) Lock() (string, error) { - return s.state.ItemLock(Lock, true) -} - -// RLock takes a shared lock on the virtcontainers state Lock item. -func (s *VCStore) RLock() (string, error) { - return s.state.ItemLock(Lock, false) -} - -// Unlock unlocks the virtcontainers state Lock item. -func (s *VCStore) Unlock(token string) error { - return s.state.ItemUnlock(Lock, token) -} - -// Utilities for virtcontainers - -// SandboxConfigurationRoot returns a virtcontainers sandbox configuration root URL. -// This will hold across host reboot persistent data about a sandbox configuration. -// It should look like file:///var/lib/vc/sbs// -// Or for rootless: file:///var/lib/vc/sbs// -func SandboxConfigurationRoot(id string) string { - return filesystemScheme + "://" + SandboxConfigurationRootPath(id) -} - -// SandboxConfigurationRootPath returns a virtcontainers sandbox configuration root path. -func SandboxConfigurationRootPath(id string) string { - return filepath.Join(VCStorePrefix, ConfigStoragePath(), id) -} - -// SandboxConfigurationItemPath returns a virtcontainers sandbox configuration item path. -func SandboxConfigurationItemPath(id string, item Item) (string, error) { - if id == "" { - return "", fmt.Errorf("Empty sandbox ID") - } - - itemFile, err := itemToFile(item) - if err != nil { - return "", err - } - - return filepath.Join(VCStorePrefix, ConfigStoragePath(), id, itemFile), nil -} - -// VCStoreUUIDPath returns a virtcontainers runtime uuid URL. -func VCStoreUUIDPath() string { - return filesystemScheme + "://" + filepath.Join(VCStorePrefix, VMUUIDStoragePath()) -} - -// SandboxRuntimeRoot returns a virtcontainers sandbox runtime root URL. -// This will hold data related to a sandbox run-time state that will not -// be persistent across host reboots. -// It should look like file:///run/vc/sbs// -// or if rootless: file:///run/vc/sbs// -func SandboxRuntimeRoot(id string) string { - return filesystemScheme + "://" + SandboxRuntimeRootPath(id) -} - -// SandboxRuntimeRootPath returns a virtcontainers sandbox runtime root path. -func SandboxRuntimeRootPath(id string) string { - return filepath.Join(VCStorePrefix, RunStoragePath(), id) -} - -// SandboxRuntimeItemPath returns a virtcontainers sandbox runtime item path. -func SandboxRuntimeItemPath(id string, item Item) (string, error) { - if id == "" { - return "", fmt.Errorf("Empty sandbox ID") - } - - itemFile, err := itemToFile(item) - if err != nil { - return "", err - } - - return filepath.Join(RunStoragePath(), id, itemFile), nil -} - -// ContainerConfigurationRoot returns a virtcontainers container configuration root URL. -// This will hold across host reboot persistent data about a container configuration. -// It should look like file:///var/lib/vc/sbs// -// Or if rootless file:///var/lib/vc/sbs// -func ContainerConfigurationRoot(sandboxID, containerID string) string { - return filesystemScheme + "://" + ContainerConfigurationRootPath(sandboxID, containerID) -} - -// ContainerConfigurationRootPath returns a virtcontainers container configuration root path. -func ContainerConfigurationRootPath(sandboxID, containerID string) string { - return filepath.Join(VCStorePrefix, ConfigStoragePath(), sandboxID, containerID) -} - -// ContainerRuntimeRoot returns a virtcontainers container runtime root URL. -// This will hold data related to a container run-time state that will not -// be persistent across host reboots. -// It should look like file:///run/vc/sbs/// -// Or for rootless file:///run/vc/sbs/// -func ContainerRuntimeRoot(sandboxID, containerID string) string { - return filesystemScheme + "://" + ContainerRuntimeRootPath(sandboxID, containerID) -} - -// ContainerRuntimeRootPath returns a virtcontainers container runtime root path. -func ContainerRuntimeRootPath(sandboxID, containerID string) string { - return filepath.Join(VCStorePrefix, RunStoragePath(), sandboxID, containerID) -} - -// VCSandboxStoreExists returns true if a sandbox store already exists. -func VCSandboxStoreExists(ctx context.Context, sandboxID string) bool { - s := stores.findStore(SandboxConfigurationRoot(sandboxID)) - return s != nil -} diff --git a/src/runtime/virtcontainers/store/vc_test.go b/src/runtime/virtcontainers/store/vc_test.go deleted file mode 100644 index 38f327fd5e..0000000000 --- a/src/runtime/virtcontainers/store/vc_test.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2019 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -// - -package store - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreVCRoots(t *testing.T) { - rootURL := filesystemScheme + "://" + ConfigStoragePath() - sandboxID := "sandbox" - containerID := "container" - sConfigRoot := rootURL + "/" + sandboxID - cConfigRoot := rootURL + "/" + sandboxID + "/" + containerID - - assert.Equal(t, SandboxConfigurationRoot(sandboxID), sConfigRoot) - assert.Equal(t, ContainerConfigurationRoot(sandboxID, containerID), cConfigRoot) -} - -func testStoreVCSandboxDir(t *testing.T, item Item, expected string) error { - var dir string - if item == Configuration { - dir = SandboxConfigurationRootPath(testSandboxID) - } else { - dir = SandboxRuntimeRootPath(testSandboxID) - } - - if dir != expected { - return fmt.Errorf("Unexpected sandbox directory %s vs %s", dir, expected) - } - - return nil -} - -func testStoreVCSandboxFile(t *testing.T, item Item, expected string) error { - var file string - var err error - - if item == Configuration { - file, err = SandboxConfigurationItemPath(testSandboxID, item) - } else { - file, err = SandboxRuntimeItemPath(testSandboxID, item) - } - - if err != nil { - return err - } - - if file != expected { - return fmt.Errorf("Unexpected sandbox file %s vs %s", file, expected) - } - - return nil -} - -func TestStoreVCSandboxDirConfig(t *testing.T) { - err := testStoreVCSandboxDir(t, Configuration, sandboxDirConfig) - assert.Nil(t, err) -} - -func TestStoreVCSandboxDirState(t *testing.T) { - err := testStoreVCSandboxDir(t, State, sandboxDirState) - assert.Nil(t, err) -} - -func TestStoreVCSandboxDirLock(t *testing.T) { - err := testStoreVCSandboxDir(t, Lock, sandboxDirLock) - assert.Nil(t, err) -} - -func TestStoreVCSandboxFileConfig(t *testing.T) { - err := testStoreVCSandboxFile(t, Configuration, sandboxFileConfig) - assert.Nil(t, err) -} - -func TestStoreVCSandboxFileState(t *testing.T) { - err := testStoreVCSandboxFile(t, State, sandboxFileState) - assert.Nil(t, err) -} - -func TestStoreVCSandboxFileLock(t *testing.T) { - err := testStoreVCSandboxFile(t, Lock, sandboxFileLock) - assert.Nil(t, err) -} - -func TestStoreVCSandboxFileNegative(t *testing.T) { - _, err := SandboxConfigurationItemPath("", State) - assert.NotNil(t, err) - - _, err = SandboxRuntimeItemPath("", State) - assert.NotNil(t, err) -} - -func TestStoreVCNewVCSandboxStore(t *testing.T) { - testDir, _ := ioutil.TempDir("", "vmfactory-tmp-") - defer func() { - os.RemoveAll(testDir) - }() - - var savedStorePath = VCStorePrefix - VCStorePrefix = testDir - defer func() { - VCStorePrefix = savedStorePath - }() - - _, err := NewVCSandboxStore(context.Background(), testSandboxID) - assert.Nil(t, err) - - _, err = NewVCSandboxStore(context.Background(), "") - assert.NotNil(t, err) -} - -func TestStoreVCNewVCContainerStore(t *testing.T) { - testDir, _ := ioutil.TempDir("", "vmfactory-tmp-") - defer func() { - os.RemoveAll(testDir) - }() - - var savedStorePath = VCStorePrefix - VCStorePrefix = testDir - defer func() { - VCStorePrefix = savedStorePath - }() - - _, err := NewVCContainerStore(context.Background(), testSandboxID, "foobar") - assert.Nil(t, err) - - _, err = NewVCContainerStore(context.Background(), "", "foobar") - assert.NotNil(t, err) - - _, err = NewVCContainerStore(context.Background(), "", "foobar") - assert.NotNil(t, err) -} diff --git a/src/runtime/virtcontainers/virtcontainers_test.go b/src/runtime/virtcontainers/virtcontainers_test.go index 3580e4604a..f955534c42 100644 --- a/src/runtime/virtcontainers/virtcontainers_test.go +++ b/src/runtime/virtcontainers/virtcontainers_test.go @@ -18,7 +18,6 @@ import ( "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/fs" - "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/store" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils" "github.com/sirupsen/logrus" ) @@ -64,14 +63,10 @@ func cleanUp() { os.RemoveAll(testDir) os.MkdirAll(testDir, DirMode) - store.DeleteAll() - store.VCStorePrefix = "" - setup() } func setup() { - store.VCStorePrefix = testDir os.Mkdir(filepath.Join(testDir, testBundle), DirMode) for _, filename := range []string{testQemuKernelPath, testQemuInitrdPath, testQemuImagePath, testQemuPath} {