From 89ca0b50de2d7f118273bb468f289189a62a2ab9 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sun, 11 Jun 2017 22:15:42 +0800 Subject: [PATCH] use hypervisor.BootConfig for factories' arguements make it easier to pass pc-lite, dax, tempalte, vsocks configurations to the hypervisor driver(qemu/libvirt...). Signed-off-by: Lai Jiangshan --- containerd/containerd.go | 11 +++++-- factory/direct/direct.go | 9 +----- factory/factory.go | 16 +++++----- factory/multi/multi.go | 3 +- factory/single/single.go | 21 +++++++------ factory/template/template.go | 6 ++-- manage.go | 9 +++++- template/template.go | 59 +++++++++++++----------------------- 8 files changed, 64 insertions(+), 70 deletions(-) diff --git a/containerd/containerd.go b/containerd/containerd.go index dd351270..4ce76363 100644 --- a/containerd/containerd.go +++ b/containerd/containerd.go @@ -104,8 +104,8 @@ var ContainerdCommand = cli.Command{ f.Close() if (driver != "" && driver != tconfig.Driver) || - (kernel != "" && kernel != tconfig.Kernel) || - (initrd != "" && initrd != tconfig.Initrd) { + (kernel != "" && kernel != tconfig.Config.Kernel) || + (initrd != "" && initrd != tconfig.Config.Initrd) { glog.Warningf("template config is not match the driver, kernel or initrd argument, disable template") template = "" } else if driver == "" { @@ -127,7 +127,12 @@ var ContainerdCommand = cli.Command{ if template != "" { f = singlefactory.New(templatefactory.NewFromExisted(tconfig)) } else { - f = factory.NewFromConfigs(kernel, initrd, vsock, nil) + bootConfig := hypervisor.BootConfig{ + Kernel: kernel, + Initrd: initrd, + EnableVsock: vsock, + } + f = singlefactory.Dummy(bootConfig) } sv, err := supervisor.New(stateDir, containerdDir, f, context.GlobalInt("default_cpus"), context.GlobalInt("default_memory")) diff --git a/factory/direct/direct.go b/factory/direct/direct.go index 7ad92318..633b4a9f 100644 --- a/factory/direct/direct.go +++ b/factory/direct/direct.go @@ -10,14 +10,7 @@ type directFactory struct { config hypervisor.BootConfig } -func New(cpu, mem int, kernel, initrd string, vsock bool) base.Factory { - b := hypervisor.BootConfig{ - CPU: cpu, - Memory: mem, - EnableVsock: vsock, - Kernel: kernel, - Initrd: initrd, - } +func New(b hypervisor.BootConfig) base.Factory { return &directFactory{config: b} } diff --git a/factory/factory.go b/factory/factory.go index f0a862f5..c180fa45 100644 --- a/factory/factory.go +++ b/factory/factory.go @@ -30,21 +30,23 @@ type FactoryConfig struct { Memory int `json:"memory"` } -func NewFromConfigs(kernel, initrd string, vsock bool, configs []FactoryConfig) Factory { +func NewFromConfigs(bootConfig hypervisor.BootConfig, configs []FactoryConfig) Factory { bases := make([]base.Factory, len(configs)) for i, c := range configs { var b base.Factory + boot := bootConfig + boot.CPU = c.Cpu + boot.Memory = c.Memory if c.Template { - b = template.New(filepath.Join(hypervisor.BaseDir, "template"), c.Cpu, c.Memory, kernel, initrd, vsock) + b = template.New(filepath.Join(hypervisor.BaseDir, "template"), boot) } else { - b = direct.New(c.Cpu, c.Memory, kernel, initrd, vsock) + b = direct.New(boot) } bases[i] = cache.New(c.Cache, b) } if len(bases) == 0 { - // skip GetVm from the base factory - return single.New(direct.New(1000000, 1000000, kernel, initrd, vsock)) + return single.Dummy(bootConfig) } else if len(bases) == 1 { return single.New(bases[0]) } else { @@ -54,12 +56,12 @@ func NewFromConfigs(kernel, initrd string, vsock bool, configs []FactoryConfig) // vmFactoryPolicy = [FactoryConfig,]*FactoryConfig // FactoryConfig = {["cache":NUMBER,]["template":true|false,]"cpu":NUMBER,"memory":NUMBER} -func NewFromPolicy(kernel, initrd string, vsock bool, policy string) Factory { +func NewFromPolicy(bootConfig hypervisor.BootConfig, policy string) Factory { var configs []FactoryConfig jsonString := "[" + policy + "]" err := json.Unmarshal([]byte(jsonString), &configs) if err != nil && policy != "none" { glog.Errorf("Incorrect policy: %s", policy) } - return NewFromConfigs(kernel, initrd, vsock, configs) + return NewFromConfigs(bootConfig, configs) } diff --git a/factory/multi/multi.go b/factory/multi/multi.go index 6d72062d..0b2e1b28 100644 --- a/factory/multi/multi.go +++ b/factory/multi/multi.go @@ -17,7 +17,8 @@ func (f Factory) GetVm(cpu, mem int) (*hypervisor.Vm, error) { return single.New(b).GetVm(cpu, mem) } } - return single.New(f[0]).GetVm(cpu, mem) + boot := *f[0].Config() + return single.Dummy(boot).GetVm(cpu, mem) } func (f Factory) CloseFactory() { diff --git a/factory/single/single.go b/factory/single/single.go index c0487f3e..1977f9f6 100644 --- a/factory/single/single.go +++ b/factory/single/single.go @@ -16,15 +16,8 @@ func (f Factory) GetVm(cpu, mem int) (*hypervisor.Vm, error) { // check if match the base config := f.Config() if config.CPU > cpu || config.Memory > mem { - // also strip unrelated option from @config - boot := &hypervisor.BootConfig{ - CPU: cpu, - Memory: mem, - Kernel: config.Kernel, - Initrd: config.Initrd, - EnableVsock: config.EnableVsock, - } - return hypervisor.GetVm("", boot, false) + boot := *config + return Dummy(boot).GetVm(cpu, mem) } vm, err := f.GetBaseVm() @@ -59,3 +52,13 @@ func (f Factory) GetVm(cpu, mem int) (*hypervisor.Vm, error) { } return vm, err } + +type Dummy hypervisor.BootConfig + +func (f Dummy) GetVm(cpu, mem int) (*hypervisor.Vm, error) { + config := hypervisor.BootConfig(f) + config.CPU = cpu + config.Memory = mem + return hypervisor.GetVm("", &config, false) +} +func (f Dummy) CloseFactory() {} diff --git a/factory/template/template.go b/factory/template/template.go index ecea281e..425cf03e 100644 --- a/factory/template/template.go +++ b/factory/template/template.go @@ -17,7 +17,7 @@ type templateFactory struct { s *template.TemplateVmConfig } -func New(templateRoot string, cpu, mem int, kernel, initrd string, vsock bool) base.Factory { +func New(templateRoot string, b hypervisor.BootConfig) base.Factory { var vmName string for { @@ -26,11 +26,11 @@ func New(templateRoot string, cpu, mem int, kernel, initrd string, vsock bool) b break } } - s, err := template.CreateTemplateVM(filepath.Join(templateRoot, vmName), vmName, cpu, mem, kernel, initrd, vsock) + s, err := template.CreateTemplateVM(filepath.Join(templateRoot, vmName), vmName, b) if err != nil { glog.Errorf("failed to create template factory: %v", err) glog.V(3).Infof("use direct factory instead") - return direct.New(cpu, mem, kernel, initrd, vsock) + return direct.New(b) } return &templateFactory{s: s} } diff --git a/manage.go b/manage.go index a89c31a6..744c10fb 100644 --- a/manage.go +++ b/manage.go @@ -80,7 +80,14 @@ var createTemplateCommand = cli.Command{ os.Exit(-1) } - if _, err := templatecore.CreateTemplateVM(template, "", context.Int("cpu"), context.Int("mem"), kernel, initrd, context.GlobalBool("vsock")); err != nil { + boot := hypervisor.BootConfig{ + CPU: context.Int("cpu"), + Memory: context.Int("mem"), + Kernel: kernel, + Initrd: initrd, + EnableVsock: context.GlobalBool("vsock"), + } + if _, err := templatecore.CreateTemplateVM(template, "", boot); err != nil { fmt.Printf("Failed to create the template: %v\n", err) os.Exit(-1) } diff --git a/template/template.go b/template/template.go index 21c3117e..2b952b71 100644 --- a/template/template.go +++ b/template/template.go @@ -26,16 +26,26 @@ import ( type TemplateVmConfig struct { StatePath string `json:"statepath"` Driver string `json:"driver"` - Cpu int `json:"cpu"` - Memory int `json:"memory"` - Kernel string `json:"kernel"` - Initrd string `json:"initrd"` + Config hypervisor.BootConfig } -func CreateTemplateVM(statePath, vmName string, cpu, mem int, kernel, initrd string, vsock bool) (t *TemplateVmConfig, err error) { +func CreateTemplateVM(statePath, vmName string, b hypervisor.BootConfig) (t *TemplateVmConfig, err error) { + if b.BootToBeTemplate || b.BootFromTemplate || b.MemoryPath != "" || b.DevicesStatePath != "" { + return nil, fmt.Errorf("Error boot config for template") + } + b.MemoryPath = statePath + "/memory" + b.DevicesStatePath = statePath + "/state" + + config := &TemplateVmConfig{ + StatePath: statePath, + Driver: hypervisor.HDriver.Name(), + Config: b, + } + config.Config.BootFromTemplate = true + defer func() { if err != nil { - (&TemplateVmConfig{StatePath: statePath}).Destroy() + config.Destroy() } }() @@ -45,7 +55,7 @@ func CreateTemplateVM(statePath, vmName string, cpu, mem int, kernel, initrd str return nil, err } flags := uintptr(syscall.MS_NOSUID | syscall.MS_NODEV) - opts := fmt.Sprintf("size=%dM", mem+8) + opts := fmt.Sprintf("size=%dM", b.Memory+8) if err = syscall.Mount("tmpfs", statePath, "tmpfs", flags, opts); err != nil { glog.Infof("mount template state path failed: %v", err) return nil, err @@ -58,18 +68,8 @@ func CreateTemplateVM(statePath, vmName string, cpu, mem int, kernel, initrd str } // launch vm - b := &hypervisor.BootConfig{ - CPU: cpu, - Memory: mem, - BootToBeTemplate: true, - BootFromTemplate: false, - EnableVsock: vsock, - MemoryPath: statePath + "/memory", - DevicesStatePath: statePath + "/state", - Kernel: kernel, - Initrd: initrd, - } - vm, err := hypervisor.GetVm(vmName, b, true) + b.BootToBeTemplate = true + vm, err := hypervisor.GetVm(vmName, &b, true) if err != nil { return nil, err } @@ -89,15 +89,6 @@ func CreateTemplateVM(statePath, vmName string, cpu, mem int, kernel, initrd str // so we wait here. We should fix it in the qemu driver side. time.Sleep(1 * time.Second) - config := &TemplateVmConfig{ - StatePath: statePath, - Driver: hypervisor.HDriver.Name(), - Cpu: cpu, - Memory: mem, - Kernel: kernel, - Initrd: initrd, - } - configData, err := json.MarshalIndent(config, "", "\t") if err != nil { glog.V(1).Infof("%s\n", err.Error()) @@ -114,16 +105,8 @@ func CreateTemplateVM(statePath, vmName string, cpu, mem int, kernel, initrd str } func (t *TemplateVmConfig) BootConfigFromTemplate() *hypervisor.BootConfig { - return &hypervisor.BootConfig{ - CPU: t.Cpu, - Memory: t.Memory, - BootToBeTemplate: false, - BootFromTemplate: true, - MemoryPath: t.StatePath + "/memory", - DevicesStatePath: t.StatePath + "/state", - Kernel: t.Kernel, - Initrd: t.Initrd, - } + b := t.Config + return &b } // boot vm from template, the returned vm is paused