mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-03 18:47:03 +00:00
cli: add vm factory management subcommand
Add enable_template option to the config file. When it is set, enable the vm template factory. cache factory cannot be used by kata cli directly because it requires a running daemon to maintain the cache VMs. `kata-runtime factory init` would initialize the vm factory and `kata-runtime factory destroy` would destroy the vm factory. When configured, a vm factory is loaded before creating new sandboxes. Signed-off-by: Peng Tao <bergwolf@gmail.com>
This commit is contained in:
parent
a7d888febc
commit
0309e59cf8
@ -62,6 +62,11 @@ type tomlConfig struct {
|
|||||||
Shim map[string]shim
|
Shim map[string]shim
|
||||||
Agent map[string]agent
|
Agent map[string]agent
|
||||||
Runtime runtime
|
Runtime runtime
|
||||||
|
Factory factory
|
||||||
|
}
|
||||||
|
|
||||||
|
type factory struct {
|
||||||
|
Template bool `toml:"enable_template"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type hypervisor struct {
|
type hypervisor struct {
|
||||||
@ -353,6 +358,10 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newFactoryConfig(f factory) (oci.FactoryConfig, error) {
|
||||||
|
return oci.FactoryConfig{Template: f.Template}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newShimConfig(s shim) (vc.ShimConfig, error) {
|
func newShimConfig(s shim) (vc.ShimConfig, error) {
|
||||||
path, err := s.path()
|
path, err := s.path()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -423,6 +432,12 @@ func updateRuntimeConfig(configPath string, tomlConf tomlConfig, config *oci.Run
|
|||||||
config.ShimConfig = shConfig
|
config.ShimConfig = shConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fConfig, err := newFactoryConfig(tomlConf.Factory)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%v: %v", configPath, err)
|
||||||
|
}
|
||||||
|
config.FactoryConfig = fConfig
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +134,18 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
|||||||
# used for 9p packet payload.
|
# used for 9p packet payload.
|
||||||
#msize_9p = @DEFMSIZE9P@
|
#msize_9p = @DEFMSIZE9P@
|
||||||
|
|
||||||
|
[factory]
|
||||||
|
# VM templating support. Once enabled, new VMs are created from template
|
||||||
|
# using vm cloning. They will share the same initial kernel, initramfs and
|
||||||
|
# agent memory by mapping it readonly. It helps speeding up new container
|
||||||
|
# creation and saves a lot of memory if there are many kata containers running
|
||||||
|
# on the same host.
|
||||||
|
#
|
||||||
|
# When disabled, new VMs are created from scratch.
|
||||||
|
#
|
||||||
|
# Default false
|
||||||
|
#enable_template = true
|
||||||
|
|
||||||
[proxy.@PROJECT_TYPE@]
|
[proxy.@PROJECT_TYPE@]
|
||||||
path = "@PROXYPATH@"
|
path = "@PROXYPATH@"
|
||||||
|
|
||||||
|
@ -1146,3 +1146,19 @@ func TestUpdateRuntimeConfigurationVMConfig(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(expectedVMConfig, config.VMConfig)
|
assert.Equal(expectedVMConfig, config.VMConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateRuntimeConfigurationFactoryConfig(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
config := oci.RuntimeConfig{}
|
||||||
|
expectedFactoryConfig := oci.FactoryConfig{
|
||||||
|
Template: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
tomlConf := tomlConfig{Factory: factory{Template: true}}
|
||||||
|
|
||||||
|
err := updateRuntimeConfig("", tomlConf, &config)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
assert.Equal(expectedFactoryConfig, config.FactoryConfig)
|
||||||
|
}
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
|
vf "github.com/kata-containers/runtime/virtcontainers/factory"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -106,6 +107,25 @@ func create(containerID, bundlePath, console, pidFilePath string, detach bool,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if runtimeConfig.FactoryConfig.Template {
|
||||||
|
factoryConfig := vf.Config{
|
||||||
|
Template: true,
|
||||||
|
VMConfig: vc.VMConfig{
|
||||||
|
HypervisorType: runtimeConfig.HypervisorType,
|
||||||
|
HypervisorConfig: runtimeConfig.HypervisorConfig,
|
||||||
|
AgentType: runtimeConfig.AgentType,
|
||||||
|
AgentConfig: runtimeConfig.AgentConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
kataLog.WithField("factory", factoryConfig).Info("load vm factory")
|
||||||
|
f, err := vf.NewFactory(factoryConfig, true)
|
||||||
|
if err != nil {
|
||||||
|
kataLog.WithError(err).Info("load vm factory failed")
|
||||||
|
} else {
|
||||||
|
vci.SetFactory(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
disableOutput := noNeedForOutput(detach, ociSpec.Process.Terminal)
|
disableOutput := noNeedForOutput(detach, ociSpec.Process.Terminal)
|
||||||
|
|
||||||
var process vc.Process
|
var process vc.Process
|
||||||
|
98
cli/factory.go
Normal file
98
cli/factory.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Copyright (c) 2018 HyperHQ Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
|
vf "github.com/kata-containers/runtime/virtcontainers/factory"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var factorySubCmds = []cli.Command{
|
||||||
|
initFactoryCommand,
|
||||||
|
destroyFactoryCommand,
|
||||||
|
}
|
||||||
|
|
||||||
|
var factoryCLICommand = cli.Command{
|
||||||
|
Name: "factory",
|
||||||
|
Usage: "manage vm factory",
|
||||||
|
Subcommands: factorySubCmds,
|
||||||
|
Action: func(context *cli.Context) {
|
||||||
|
cli.ShowSubcommandHelp(context)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var initFactoryCommand = cli.Command{
|
||||||
|
Name: "init",
|
||||||
|
Usage: "initialize a VM factory based on kata-runtime configuration",
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
runtimeConfig, ok := context.App.Metadata["runtimeConfig"].(oci.RuntimeConfig)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid runtime config")
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtimeConfig.FactoryConfig.Template {
|
||||||
|
factoryConfig := vf.Config{
|
||||||
|
Template: true,
|
||||||
|
VMConfig: vc.VMConfig{
|
||||||
|
HypervisorType: runtimeConfig.HypervisorType,
|
||||||
|
HypervisorConfig: runtimeConfig.HypervisorConfig,
|
||||||
|
AgentType: runtimeConfig.AgentType,
|
||||||
|
AgentConfig: runtimeConfig.AgentConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
kataLog.WithField("factory", factoryConfig).Info("create vm factory")
|
||||||
|
_, err := vf.NewFactory(factoryConfig, false)
|
||||||
|
if err != nil {
|
||||||
|
kataLog.WithError(err).Error("create vm factory failed")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("vm factory initialized")
|
||||||
|
} else {
|
||||||
|
kataLog.Error("vm factory is not enabled")
|
||||||
|
fmt.Println("vm factory is not enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var destroyFactoryCommand = cli.Command{
|
||||||
|
Name: "destroy",
|
||||||
|
Usage: "destroy the VM factory",
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
runtimeConfig, ok := context.App.Metadata["runtimeConfig"].(oci.RuntimeConfig)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid runtime config")
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtimeConfig.FactoryConfig.Template {
|
||||||
|
factoryConfig := vf.Config{
|
||||||
|
Template: true,
|
||||||
|
VMConfig: vc.VMConfig{
|
||||||
|
HypervisorType: runtimeConfig.HypervisorType,
|
||||||
|
HypervisorConfig: runtimeConfig.HypervisorConfig,
|
||||||
|
AgentType: runtimeConfig.AgentType,
|
||||||
|
AgentConfig: runtimeConfig.AgentConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
kataLog.WithField("factory", factoryConfig).Info("load vm factory")
|
||||||
|
f, err := vf.NewFactory(factoryConfig, true)
|
||||||
|
if err != nil {
|
||||||
|
kataLog.WithError(err).Error("load vm factory failed")
|
||||||
|
// ignore error
|
||||||
|
} else {
|
||||||
|
f.CloseFactory()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("vm factory destroyed")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
117
cli/factory_test.go
Normal file
117
cli/factory_test.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) 2018 HyperHQ Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFactoryCLIFunctionNoRuntimeConfig(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
app := cli.NewApp()
|
||||||
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
app.Name = "foo"
|
||||||
|
ctx.App.Metadata = map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
fn, ok := initFactoryCommand.Action.(func(context *cli.Context) error)
|
||||||
|
assert.True(ok)
|
||||||
|
err := fn(ctx)
|
||||||
|
// no runtime config in the Metadata
|
||||||
|
assert.Error(err)
|
||||||
|
|
||||||
|
fn, ok = destroyFactoryCommand.Action.(func(context *cli.Context) error)
|
||||||
|
assert.True(ok)
|
||||||
|
err = fn(ctx)
|
||||||
|
// no runtime config in the Metadata
|
||||||
|
assert.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFactoryCLIFunctionInit(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tmpdir, err := ioutil.TempDir("", "")
|
||||||
|
assert.NoError(err)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
set := flag.NewFlagSet("", 0)
|
||||||
|
|
||||||
|
set.String("console-socket", "", "")
|
||||||
|
|
||||||
|
app := cli.NewApp()
|
||||||
|
ctx := cli.NewContext(app, set, nil)
|
||||||
|
app.Name = "foo"
|
||||||
|
|
||||||
|
// No template
|
||||||
|
ctx.App.Metadata = map[string]interface{}{
|
||||||
|
"runtimeConfig": runtimeConfig,
|
||||||
|
}
|
||||||
|
fn, ok := initFactoryCommand.Action.(func(context *cli.Context) error)
|
||||||
|
assert.True(ok)
|
||||||
|
err = fn(ctx)
|
||||||
|
assert.Nil(err)
|
||||||
|
|
||||||
|
// With template
|
||||||
|
runtimeConfig.FactoryConfig.Template = true
|
||||||
|
runtimeConfig.HypervisorType = vc.MockHypervisor
|
||||||
|
runtimeConfig.AgentType = vc.NoopAgentType
|
||||||
|
ctx.App.Metadata["runtimeConfig"] = runtimeConfig
|
||||||
|
fn, ok = initFactoryCommand.Action.(func(context *cli.Context) error)
|
||||||
|
assert.True(ok)
|
||||||
|
err = fn(ctx)
|
||||||
|
assert.Nil(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFactoryCLIFunctionDestroy(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tmpdir, err := ioutil.TempDir("", "")
|
||||||
|
assert.NoError(err)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
set := flag.NewFlagSet("", 0)
|
||||||
|
|
||||||
|
set.String("console-socket", "", "")
|
||||||
|
|
||||||
|
app := cli.NewApp()
|
||||||
|
ctx := cli.NewContext(app, set, nil)
|
||||||
|
app.Name = "foo"
|
||||||
|
|
||||||
|
// No template
|
||||||
|
ctx.App.Metadata = map[string]interface{}{
|
||||||
|
"runtimeConfig": runtimeConfig,
|
||||||
|
}
|
||||||
|
fn, ok := destroyFactoryCommand.Action.(func(context *cli.Context) error)
|
||||||
|
assert.True(ok)
|
||||||
|
err = fn(ctx)
|
||||||
|
assert.Nil(err)
|
||||||
|
|
||||||
|
// With template
|
||||||
|
runtimeConfig.FactoryConfig.Template = true
|
||||||
|
runtimeConfig.HypervisorType = vc.MockHypervisor
|
||||||
|
runtimeConfig.AgentType = vc.NoopAgentType
|
||||||
|
ctx.App.Metadata["runtimeConfig"] = runtimeConfig
|
||||||
|
fn, ok = destroyFactoryCommand.Action.(func(context *cli.Context) error)
|
||||||
|
assert.True(ok)
|
||||||
|
err = fn(ctx)
|
||||||
|
assert.Nil(err)
|
||||||
|
}
|
@ -123,6 +123,7 @@ var runtimeCommands = []cli.Command{
|
|||||||
// Kata Containers specific extensions
|
// Kata Containers specific extensions
|
||||||
kataCheckCLICommand,
|
kataCheckCLICommand,
|
||||||
kataEnvCLICommand,
|
kataEnvCLICommand,
|
||||||
|
factoryCLICommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeBeforeSubcommands is the function to run before command-line
|
// runtimeBeforeSubcommands is the function to run before command-line
|
||||||
|
@ -91,6 +91,12 @@ type CompatOCISpec struct {
|
|||||||
Process *CompatOCIProcess `json:"process,omitempty"`
|
Process *CompatOCIProcess `json:"process,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FactoryConfig is a structure to set the VM factory configuration.
|
||||||
|
type FactoryConfig struct {
|
||||||
|
// Template enables VM templating support in VM factory.
|
||||||
|
Template bool
|
||||||
|
}
|
||||||
|
|
||||||
// RuntimeConfig aggregates all runtime specific settings
|
// RuntimeConfig aggregates all runtime specific settings
|
||||||
type RuntimeConfig struct {
|
type RuntimeConfig struct {
|
||||||
VMConfig vc.Resources
|
VMConfig vc.Resources
|
||||||
@ -98,6 +104,8 @@ type RuntimeConfig struct {
|
|||||||
HypervisorType vc.HypervisorType
|
HypervisorType vc.HypervisorType
|
||||||
HypervisorConfig vc.HypervisorConfig
|
HypervisorConfig vc.HypervisorConfig
|
||||||
|
|
||||||
|
FactoryConfig FactoryConfig
|
||||||
|
|
||||||
AgentType vc.AgentType
|
AgentType vc.AgentType
|
||||||
AgentConfig interface{}
|
AgentConfig interface{}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user