mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-25 15:02:45 +00:00
compatibility: keep oldstore for compatibility
Keep old store restore functions for keeping backward compatibility, if old store files are found from disk, restore them with old store first. Signed-off-by: Wei Zhang <weizhang555.zw@gmail.com>
This commit is contained in:
parent
4a298cb9b7
commit
290339da6b
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/kata-containers/runtime/pkg/rootless"
|
"github.com/kata-containers/runtime/pkg/rootless"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/config"
|
"github.com/kata-containers/runtime/virtcontainers/device/config"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/manager"
|
"github.com/kata-containers/runtime/virtcontainers/device/manager"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/major.h
|
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/major.h
|
||||||
@ -335,6 +336,8 @@ type Container struct {
|
|||||||
systemMountsInfo SystemMountsInfo
|
systemMountsInfo SystemMountsInfo
|
||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
|
store *store.VCStore
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the container identifier string.
|
// ID returns the container identifier string.
|
||||||
@ -426,10 +429,18 @@ func (c *Container) setContainerState(state types.StateString) error {
|
|||||||
// update in-memory state
|
// update in-memory state
|
||||||
c.state.State = 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
|
// flush data to storage
|
||||||
if err := c.sandbox.Save(); err != nil {
|
if err := c.sandbox.Save(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -678,6 +689,22 @@ func newContainer(sandbox *Sandbox, contConfig *ContainerConfig) (*Container, er
|
|||||||
ctx: sandbox.ctx,
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// experimental runtime use "persist.json" instead of legacy "state.json" as storage
|
||||||
err := c.Restore()
|
err := c.Restore()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -689,20 +716,49 @@ func newContainer(sandbox *Sandbox, contConfig *ContainerConfig) (*Container, er
|
|||||||
if !os.IsNotExist(err) && err != errContainerPersistNotExist {
|
if !os.IsNotExist(err) && err != errContainerPersistNotExist {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Go to next step for first created container
|
// Go to next step for first created container
|
||||||
if err = c.createMounts(); err != nil {
|
if err := c.createMounts(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = c.createDevices(contConfig); err != nil {
|
if err := c.createDevices(contConfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, nil
|
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 {
|
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
|
// Create block devices for newly created container
|
||||||
if err := c.createBlockDevices(); err != nil {
|
if err := c.createBlockDevices(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -712,6 +768,18 @@ func (c *Container) createMounts() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) createDevices(contConfig *ContainerConfig) 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
|
// If devices were not found in storage, create Device implementations
|
||||||
// from the configuration. This should happen at create.
|
// from the configuration. This should happen at create.
|
||||||
var storedDevices []ContainerDevice
|
var storedDevices []ContainerDevice
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
ns "github.com/kata-containers/runtime/virtcontainers/pkg/nsenter"
|
ns "github.com/kata-containers/runtime/virtcontainers/pkg/nsenter"
|
||||||
vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
|
vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
|
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/types"
|
"github.com/kata-containers/runtime/virtcontainers/types"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
opentracing "github.com/opentracing/opentracing-go"
|
opentracing "github.com/opentracing/opentracing-go"
|
||||||
@ -317,6 +318,12 @@ func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config interface
|
|||||||
|
|
||||||
k.proxyBuiltIn = isProxyBuiltIn(sandbox.config.ProxyType)
|
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
|
return disableVMShutdown, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,14 @@
|
|||||||
package virtcontainers
|
package virtcontainers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/api"
|
"github.com/kata-containers/runtime/virtcontainers/device/api"
|
||||||
exp "github.com/kata-containers/runtime/virtcontainers/experimental"
|
exp "github.com/kata-containers/runtime/virtcontainers/experimental"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/persist"
|
"github.com/kata-containers/runtime/virtcontainers/persist"
|
||||||
persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
|
persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/types"
|
"github.com/kata-containers/runtime/virtcontainers/types"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
@ -559,3 +561,25 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) {
|
|||||||
}
|
}
|
||||||
return sconfig, nil
|
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
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
"github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/pkg/compatoci"
|
"github.com/kata-containers/runtime/virtcontainers/pkg/compatoci"
|
||||||
vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
|
vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/types"
|
"github.com/kata-containers/runtime/virtcontainers/types"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/utils"
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
||||||
)
|
)
|
||||||
@ -177,6 +178,8 @@ type Sandbox struct {
|
|||||||
factory Factory
|
factory Factory
|
||||||
hypervisor hypervisor
|
hypervisor hypervisor
|
||||||
agent agent
|
agent agent
|
||||||
|
store *store.VCStore
|
||||||
|
// store is used to replace VCStore step by step
|
||||||
newStore persistapi.PersistDriver
|
newStore persistapi.PersistDriver
|
||||||
|
|
||||||
network Network
|
network Network
|
||||||
@ -544,6 +547,36 @@ func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factor
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if useOldStore(ctx) {
|
||||||
|
vcStore, err := store.NewVCSandboxStore(ctx, s.id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.store = vcStore
|
||||||
|
|
||||||
|
// 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, 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, nil)
|
s.devManager = deviceManager.NewDeviceManager(sandboxConfig.HypervisorConfig.BlockDeviceDriver, nil)
|
||||||
|
|
||||||
// Ignore the error. Restore can fail for a new sandbox
|
// Ignore the error. Restore can fail for a new sandbox
|
||||||
@ -555,6 +588,7 @@ func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factor
|
|||||||
if err = s.hypervisor.createSandbox(ctx, s.id, s.networkNS, &sandboxConfig.HypervisorConfig, s.stateful); err != nil {
|
if err = s.hypervisor.createSandbox(ctx, s.id, s.networkNS, &sandboxConfig.HypervisorConfig, s.stateful); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
agentConfig, err := newAgentConfig(sandboxConfig.AgentType, sandboxConfig.AgentConfig)
|
agentConfig, err := newAgentConfig(sandboxConfig.AgentType, sandboxConfig.AgentConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -612,12 +646,22 @@ func fetchSandbox(ctx context.Context, sandboxID string) (sandbox *Sandbox, err
|
|||||||
|
|
||||||
var config SandboxConfig
|
var config SandboxConfig
|
||||||
|
|
||||||
c, err := loadSandboxConfig(sandboxID)
|
// Try to load sandbox config from old store at first.
|
||||||
|
c, ctx, err := loadSandboxConfigFromOldStore(ctx, sandboxID)
|
||||||
if err != nil {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
config = *c
|
config = *c
|
||||||
|
|
||||||
|
if useOldStore(ctx) {
|
||||||
|
virtLog.Infof("Warning: old store has been deprecated.")
|
||||||
|
}
|
||||||
// fetchSandbox is not suppose to create new sandbox VM.
|
// fetchSandbox is not suppose to create new sandbox VM.
|
||||||
sandbox, err = createSandbox(ctx, config, nil)
|
sandbox, err = createSandbox(ctx, config, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1478,6 +1522,10 @@ func (s *Sandbox) setSandboxState(state types.StateString) error {
|
|||||||
|
|
||||||
// update in-memory state
|
// update in-memory state
|
||||||
s.state.State = state
|
s.state.State = state
|
||||||
|
|
||||||
|
if useOldStore(s.ctx) {
|
||||||
|
return s.store.Store(store.State, s.state)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/kata-containers/runtime/virtcontainers/persist/fs"
|
"github.com/kata-containers/runtime/virtcontainers/persist/fs"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/utils"
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -60,10 +61,14 @@ func cleanUp() {
|
|||||||
os.RemoveAll(testDir)
|
os.RemoveAll(testDir)
|
||||||
os.MkdirAll(testDir, DirMode)
|
os.MkdirAll(testDir, DirMode)
|
||||||
|
|
||||||
|
store.DeleteAll()
|
||||||
|
store.VCStorePrefix = ""
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup() {
|
func setup() {
|
||||||
|
store.VCStorePrefix = testDir
|
||||||
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)
|
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)
|
||||||
|
|
||||||
for _, filename := range []string{testQemuKernelPath, testQemuInitrdPath, testQemuImagePath, testQemuPath} {
|
for _, filename := range []string{testQemuKernelPath, testQemuInitrdPath, testQemuImagePath, testQemuPath} {
|
||||||
|
Loading…
Reference in New Issue
Block a user