virtconainers: add SetFactory API

Add SetFactory to allow virtcontainers consumers to set a vm factory.
And use it to create new VMs whenever the factory is set.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
This commit is contained in:
Peng Tao 2018-07-13 17:39:23 +08:00
parent bdd5c66fc5
commit a7d888febc
12 changed files with 128 additions and 54 deletions

View File

@ -34,13 +34,13 @@ func SetLogger(logger logrus.FieldLogger) {
// CreateSandbox is the virtcontainers sandbox creation entry point.
// CreateSandbox creates a sandbox and its containers. It does not start them.
func CreateSandbox(sandboxConfig SandboxConfig) (VCSandbox, error) {
return createSandboxFromConfig(sandboxConfig)
func CreateSandbox(sandboxConfig SandboxConfig, factory Factory) (VCSandbox, error) {
return createSandboxFromConfig(sandboxConfig, factory)
}
func createSandboxFromConfig(sandboxConfig SandboxConfig) (*Sandbox, error) {
func createSandboxFromConfig(sandboxConfig SandboxConfig, factory Factory) (*Sandbox, error) {
// Create the sandbox.
s, err := createSandbox(sandboxConfig)
s, err := createSandbox(sandboxConfig, factory)
if err != nil {
return nil, err
}
@ -206,8 +206,8 @@ func StopSandbox(sandboxID string) (VCSandbox, error) {
// RunSandbox is the virtcontainers sandbox running entry point.
// RunSandbox creates a sandbox and its containers and then it starts them.
func RunSandbox(sandboxConfig SandboxConfig) (VCSandbox, error) {
s, err := createSandboxFromConfig(sandboxConfig)
func RunSandbox(sandboxConfig SandboxConfig, factory Factory) (VCSandbox, error) {
s, err := createSandboxFromConfig(sandboxConfig, factory)
if err != nil {
return nil, err
}

View File

@ -244,7 +244,7 @@ func TestCreateSandboxNoopAgentSuccessful(t *testing.T) {
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -289,7 +289,7 @@ func TestCreateSandboxHyperstartAgentSuccessful(t *testing.T) {
proxy.Start()
defer proxy.Stop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -330,7 +330,7 @@ func TestCreateSandboxKataAgentSuccessful(t *testing.T) {
}
defer kataProxyMock.Stop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -347,7 +347,7 @@ func TestCreateSandboxFailing(t *testing.T) {
config := SandboxConfig{}
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p.(*Sandbox) != nil || err == nil {
t.Fatal()
}
@ -358,7 +358,7 @@ func TestDeleteSandboxNoopAgentSuccessful(t *testing.T) {
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -401,7 +401,7 @@ func TestDeleteSandboxHyperstartAgentSuccessful(t *testing.T) {
proxy.Start()
defer proxy.Stop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -452,7 +452,7 @@ func TestDeleteSandboxKataAgentSuccessful(t *testing.T) {
}
defer kataProxyMock.Stop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -751,7 +751,7 @@ func TestRunSandboxNoopAgentSuccessful(t *testing.T) {
config := newTestSandboxConfigNoop()
p, err := RunSandbox(config)
p, err := RunSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -787,7 +787,7 @@ func TestRunSandboxHyperstartAgentSuccessful(t *testing.T) {
hyperConfig := config.AgentConfig.(HyperConfig)
config.AgentConfig = hyperConfig
p, err := RunSandbox(config)
p, err := RunSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -833,7 +833,7 @@ func TestRunSandboxKataAgentSuccessful(t *testing.T) {
}
defer kataProxyMock.Stop()
p, err := RunSandbox(config)
p, err := RunSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -855,7 +855,7 @@ func TestRunSandboxFailing(t *testing.T) {
config := SandboxConfig{}
p, err := RunSandbox(config)
p, err := RunSandbox(config, nil)
if p != nil || err == nil {
t.Fatal()
}
@ -868,7 +868,7 @@ func TestListSandboxSuccessful(t *testing.T) {
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -928,7 +928,7 @@ func TestStatusSandboxSuccessfulStateReady(t *testing.T) {
},
}
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -985,7 +985,7 @@ func TestStatusSandboxSuccessfulStateRunning(t *testing.T) {
},
}
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1014,7 +1014,7 @@ func TestStatusSandboxFailingFetchSandboxConfig(t *testing.T) {
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1034,7 +1034,7 @@ func TestStatusPodSandboxFailingFetchSandboxState(t *testing.T) {
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1069,7 +1069,7 @@ func TestCreateContainerSuccessful(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1100,7 +1100,7 @@ func TestCreateContainerFailingNoSandbox(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1130,7 +1130,7 @@ func TestDeleteContainerSuccessful(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1184,7 +1184,7 @@ func TestDeleteContainerFailingNoContainer(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1249,7 +1249,7 @@ func TestStartContainerFailingNoContainer(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1272,7 +1272,7 @@ func TestStartContainerFailingSandboxNotStarted(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1493,7 +1493,7 @@ func TestStopContainerFailingNoContainer(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1674,7 +1674,7 @@ func TestEnterContainerFailingNoContainer(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1731,7 +1731,7 @@ func TestStatusContainerSuccessful(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1782,7 +1782,7 @@ func TestStatusContainerStateReady(t *testing.T) {
contID := "101"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1845,7 +1845,7 @@ func TestStatusContainerStateRunning(t *testing.T) {
contID := "101"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1917,7 +1917,7 @@ func TestStatusContainerFailing(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1940,7 +1940,7 @@ func TestStatsContainerFailing(t *testing.T) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if p == nil || err != nil {
t.Fatal(err)
}
@ -1973,7 +1973,7 @@ func TestStatsContainer(t *testing.T) {
assert.Error(err)
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
assert.NoError(err)
assert.NotNil(p)
@ -2023,7 +2023,7 @@ func TestProcessListContainer(t *testing.T) {
assert.Error(err)
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
assert.NoError(err)
assert.NotNil(p)
@ -2117,7 +2117,7 @@ func createAndStartSandbox(config SandboxConfig) (sandbox VCSandbox, sandboxDir
err error) {
// Create sandbox
sandbox, err = CreateSandbox(config)
sandbox, err = CreateSandbox(config, nil)
if sandbox == nil || err != nil {
return nil, "", err
}
@ -2158,7 +2158,7 @@ func createStartStopDeleteSandbox(b *testing.B, sandboxConfig SandboxConfig) {
func createStartStopDeleteContainers(b *testing.B, sandboxConfig SandboxConfig, contConfigs []ContainerConfig) {
// Create sandbox
p, err := CreateSandbox(sandboxConfig)
p, err := CreateSandbox(sandboxConfig, nil)
if err != nil {
b.Fatalf("Could not create sandbox: %s", err)
}
@ -2326,7 +2326,7 @@ func TestFetchSandbox(t *testing.T) {
config := newTestSandboxConfigNoop()
s, err := CreateSandbox(config)
s, err := CreateSandbox(config, nil)
if s == nil || err != nil {
t.Fatal(err)
}
@ -2348,7 +2348,7 @@ func TestReleaseSandbox(t *testing.T) {
config := newTestSandboxConfigNoop()
s, err := CreateSandbox(config)
s, err := CreateSandbox(config, nil)
if s == nil || err != nil {
t.Fatal(err)
}

View File

@ -68,7 +68,7 @@ func Example_createAndStartSandbox() {
Containers: []vc.ContainerConfig{container},
}
_, err := vc.RunSandbox(sandboxConfig)
_, err := vc.RunSandbox(sandboxConfig, nil)
if err != nil {
fmt.Printf("Could not run sandbox: %s", err)
}

View File

@ -324,7 +324,7 @@ func runSandbox(context *cli.Context) error {
return fmt.Errorf("Could not build sandbox config: %s", err)
}
_, err = vc.RunSandbox(sandboxConfig)
_, err = vc.RunSandbox(sandboxConfig, nil)
if err != nil {
return fmt.Errorf("Could not run sandbox: %s", err)
}
@ -338,7 +338,7 @@ func createSandbox(context *cli.Context) error {
return fmt.Errorf("Could not build sandbox config: %s", err)
}
p, err := vc.CreateSandbox(sandboxConfig)
p, err := vc.CreateSandbox(sandboxConfig, nil)
if err != nil {
return fmt.Errorf("Could not create sandbox: %s", err)
}

View File

@ -18,6 +18,7 @@ import (
// VCImpl is the official virtcontainers function of the same name.
type VCImpl struct {
factory Factory
}
// SetLogger implements the VC function of the same name.
@ -25,9 +26,14 @@ func (impl *VCImpl) SetLogger(logger logrus.FieldLogger) {
SetLogger(logger)
}
// SetFactory implements the VC function of the same name.
func (impl *VCImpl) SetFactory(factory Factory) {
impl.factory = factory
}
// CreateSandbox implements the VC function of the same name.
func (impl *VCImpl) CreateSandbox(sandboxConfig SandboxConfig) (VCSandbox, error) {
return CreateSandbox(sandboxConfig)
return CreateSandbox(sandboxConfig, impl.factory)
}
// DeleteSandbox implements the VC function of the same name.
@ -47,7 +53,7 @@ func (impl *VCImpl) StopSandbox(sandboxID string) (VCSandbox, error) {
// RunSandbox implements the VC function of the same name.
func (impl *VCImpl) RunSandbox(sandboxConfig SandboxConfig) (VCSandbox, error) {
return RunSandbox(sandboxConfig)
return RunSandbox(sandboxConfig, impl.factory)
}
// ListSandbox implements the VC function of the same name.

View File

@ -16,6 +16,7 @@ import (
// VC is the Virtcontainers interface
type VC interface {
SetLogger(logger logrus.FieldLogger)
SetFactory(Factory)
CreateSandbox(sandboxConfig SandboxConfig) (VCSandbox, error)
DeleteSandbox(sandboxID string) (VCSandbox, error)

View File

@ -14,7 +14,7 @@ func testCreateNoopContainer() (*Sandbox, *Container, error) {
contID := "100"
config := newTestSandboxConfigNoop()
p, err := CreateSandbox(config)
p, err := CreateSandbox(config, nil)
if err != nil {
return nil, nil, err
}

View File

@ -35,6 +35,13 @@ func (m *VCMock) SetLogger(logger logrus.FieldLogger) {
}
}
// SetFactory implements the VC function of the same name.
func (m *VCMock) SetFactory(factory vc.Factory) {
if m.SetFactoryFunc != nil {
m.SetFactoryFunc(factory)
}
}
// CreateSandbox implements the VC function of the same name.
func (m *VCMock) CreateSandbox(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
if m.CreateSandboxFunc != nil {

View File

@ -11,6 +11,7 @@ import (
"testing"
vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/factory"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
@ -20,7 +21,10 @@ const (
testContainerID = "testContainerID"
)
var loggerTriggered = 0
var (
loggerTriggered = 0
factoryTriggered = 0
)
func TestVCImplementations(t *testing.T) {
// official implementation
@ -675,3 +679,34 @@ func TestVCMockResumeContainer(t *testing.T) {
assert.Error(err)
assert.True(IsMockError(err))
}
func TestVCMockSetVMFactory(t *testing.T) {
assert := assert.New(t)
m := &VCMock{}
assert.Nil(m.SetFactoryFunc)
hyperConfig := vc.HypervisorConfig{
KernelPath: "foobar",
ImagePath: "foobar",
}
vmConfig := vc.VMConfig{
HypervisorType: vc.MockHypervisor,
AgentType: vc.NoopAgentType,
HypervisorConfig: hyperConfig,
}
f, err := factory.NewFactory(factory.Config{VMConfig: vmConfig}, false)
assert.Nil(err)
assert.Equal(factoryTriggered, 0)
m.SetFactory(f)
assert.Equal(factoryTriggered, 0)
m.SetFactoryFunc = func(factory vc.Factory) {
factoryTriggered = 1
}
m.SetFactory(f)
assert.Equal(factoryTriggered, 1)
}

View File

@ -35,7 +35,8 @@ type Container struct {
// VCMock is a type that provides an implementation of the VC interface.
// It is used for testing.
type VCMock struct {
SetLoggerFunc func(logger logrus.FieldLogger)
SetLoggerFunc func(logger logrus.FieldLogger)
SetFactoryFunc func(factory vc.Factory)
CreateSandboxFunc func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error)
DeleteSandboxFunc func(sandboxID string) (vc.VCSandbox, error)

View File

@ -440,6 +440,7 @@ type Sandbox struct {
id string
sync.Mutex
factory Factory
hypervisor hypervisor
agent agent
storage resourceStorage
@ -679,12 +680,12 @@ func createAssets(sandboxConfig *SandboxConfig) error {
// It will create and store the sandbox structure, and then ask the hypervisor
// to physically create that sandbox i.e. starts a VM for that sandbox to eventually
// be started.
func createSandbox(sandboxConfig SandboxConfig) (*Sandbox, error) {
func createSandbox(sandboxConfig SandboxConfig, factory Factory) (*Sandbox, error) {
if err := createAssets(&sandboxConfig); err != nil {
return nil, err
}
s, err := newSandbox(sandboxConfig)
s, err := newSandbox(sandboxConfig, factory)
if err != nil {
return nil, err
}
@ -718,7 +719,7 @@ func createSandbox(sandboxConfig SandboxConfig) (*Sandbox, error) {
return s, nil
}
func newSandbox(sandboxConfig SandboxConfig) (*Sandbox, error) {
func newSandbox(sandboxConfig SandboxConfig, factory Factory) (*Sandbox, error) {
if sandboxConfig.valid() == false {
return nil, fmt.Errorf("Invalid sandbox configuration")
}
@ -734,6 +735,7 @@ func newSandbox(sandboxConfig SandboxConfig) (*Sandbox, error) {
s := &Sandbox{
id: sandboxConfig.ID,
factory: factory,
hypervisor: hypervisor,
agent: agent,
storage: &filesystem{},
@ -821,7 +823,8 @@ func fetchSandbox(sandboxID string) (sandbox *Sandbox, err error) {
return nil, err
}
sandbox, err = createSandbox(config)
// fetchSandbox is not suppose to create new sandbox VM.
sandbox, err = createSandbox(config, nil)
if err != nil {
return nil, fmt.Errorf("failed to create sandbox with config %+v: %v", config, err)
}
@ -935,7 +938,28 @@ func (s *Sandbox) removeNetwork() error {
func (s *Sandbox) startVM() error {
s.Logger().Info("Starting VM")
// FIXME: This would break cached VMs. We need network hotplug and move
// oci hooks and netns handling to cli. See #273.
if err := s.network.run(s.networkNS.NetNsPath, func() error {
if s.factory != nil {
vm, err := s.factory.GetVM(VMConfig{
HypervisorType: s.config.HypervisorType,
HypervisorConfig: s.config.HypervisorConfig,
AgentType: s.config.AgentType,
AgentConfig: s.config.AgentConfig,
})
if err != nil {
return err
}
err = vm.assignSandbox(s)
if err != nil {
return err
}
// FIXME: factory vm needs network hotplug to add Nics.
s.networkNS.NetNsPath = ""
return nil
}
return s.hypervisor.startSandbox()
}); err != nil {
return err

View File

@ -52,7 +52,7 @@ func testCreateSandbox(t *testing.T, id string,
Containers: containers,
}
sandbox, err := createSandbox(sconfig)
sandbox, err := createSandbox(sconfig, nil)
if err != nil {
return nil, fmt.Errorf("Could not create sandbox: %s", err)
}