mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 09:16:29 +00:00
infrakit: Use the new HyperKit go package
Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
This commit is contained in:
parent
a6dab6e6ca
commit
dcb6f8e5f6
@ -1,34 +1,25 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
ps "github.com/mitchellh/go-ps"
|
|
||||||
"github.com/rneugeba/iso9660wrap"
|
"github.com/docker/hyperkit/go"
|
||||||
|
|
||||||
"github.com/docker/infrakit/pkg/spi/instance"
|
"github.com/docker/infrakit/pkg/spi/instance"
|
||||||
"github.com/docker/infrakit/pkg/template"
|
|
||||||
"github.com/docker/infrakit/pkg/types"
|
"github.com/docker/infrakit/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewHyperKitPlugin creates an instance plugin for hyperkit.
|
// NewHyperKitPlugin creates an instance plugin for hyperkit.
|
||||||
func NewHyperKitPlugin(vmDir, hyperkit, vpnkitSock string, thyper, tkern *template.Template) instance.Plugin {
|
func NewHyperKitPlugin(vmDir, hyperkit, vpnkitSock string) instance.Plugin {
|
||||||
return &hyperkitPlugin{VMDir: vmDir,
|
return &hyperkitPlugin{VMDir: vmDir,
|
||||||
HyperKit: hyperkit,
|
HyperKit: hyperkit,
|
||||||
VPNKitSock: vpnkitSock,
|
VPNKitSock: vpnkitSock,
|
||||||
|
|
||||||
HyperKitTmpl: thyper,
|
|
||||||
KernelTmpl: tkern,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,22 +32,15 @@ type hyperkitPlugin struct {
|
|||||||
|
|
||||||
// VPNKitSock is the path to the VPNKit Unix domain socket.
|
// VPNKitSock is the path to the VPNKit Unix domain socket.
|
||||||
VPNKitSock string
|
VPNKitSock string
|
||||||
|
|
||||||
HyperKitTmpl *template.Template
|
|
||||||
KernelTmpl *template.Template
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
hyperkitPid = "hyperkit.pid"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Validate performs local validation on a provision request.
|
// Validate performs local validation on a provision request.
|
||||||
func (v hyperkitPlugin) Validate(req *types.Any) error {
|
func (p hyperkitPlugin) Validate(req *types.Any) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provision creates a new instance.
|
// Provision creates a new instance.
|
||||||
func (v hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
func (p hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
||||||
|
|
||||||
var properties map[string]interface{}
|
var properties map[string]interface{}
|
||||||
|
|
||||||
@ -76,34 +60,39 @@ func (v hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
|||||||
properties["Memory"] = 512
|
properties["Memory"] = 512
|
||||||
}
|
}
|
||||||
if properties["Disk"] == nil {
|
if properties["Disk"] == nil {
|
||||||
properties["Disk"] = float64(256)
|
properties["Disk"] = 256
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceDir, err := ioutil.TempDir(v.VMDir, "infrakit-")
|
instanceDir, err := ioutil.TempDir(p.VMDir, "infrakit-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
id := instance.ID(path.Base(instanceDir))
|
id := instance.ID(path.Base(instanceDir))
|
||||||
|
|
||||||
// Apply parameters
|
// Start a HyperKit instance
|
||||||
params := map[string]interface{}{
|
h, err := hyperkit.New(p.HyperKit, instanceDir, p.VPNKitSock, "")
|
||||||
"VMLocation": instanceDir,
|
|
||||||
"VPNKitSock": v.VPNKitSock,
|
|
||||||
"Properties": properties,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v.execHyperKit(spec, params)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Destroy(id)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
h.Kernel = properties["Moby"].(string) + "-bzImage"
|
||||||
|
h.Initrd = properties["Moby"].(string) + "-initrd.img"
|
||||||
|
h.CPUs = int(properties["CPUs"].(float64))
|
||||||
|
h.Memory = int(properties["Memory"].(float64))
|
||||||
|
h.DiskSize = int(properties["Disk"].(float64))
|
||||||
|
h.UserData = spec.Init
|
||||||
|
h.Console = hyperkit.ConsoleFile
|
||||||
|
err = h.Start("console=ttyS0")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Info("Started new VM: ", id)
|
||||||
|
|
||||||
tagData, err := types.AnyValue(spec.Tags)
|
tagData, err := types.AnyValue(spec.Tags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(path.Join(instanceDir, "tags"), tagData.Bytes(), 0666); err != nil {
|
if err := ioutil.WriteFile(path.Join(instanceDir, "tags"), tagData.Bytes(), 0644); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +100,8 @@ func (v hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Label labels the instance
|
// Label labels the instance
|
||||||
func (v hyperkitPlugin) Label(instance instance.ID, labels map[string]string) error {
|
func (p hyperkitPlugin) Label(instance instance.ID, labels map[string]string) error {
|
||||||
instanceDir := path.Join(v.VMDir, string(instance))
|
instanceDir := path.Join(p.VMDir, string(instance))
|
||||||
tagFile := path.Join(instanceDir, "tags")
|
tagFile := path.Join(instanceDir, "tags")
|
||||||
buff, err := ioutil.ReadFile(tagFile)
|
buff, err := ioutil.ReadFile(tagFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -133,14 +122,14 @@ func (v hyperkitPlugin) Label(instance instance.ID, labels map[string]string) er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ioutil.WriteFile(tagFile, encoded.Bytes(), 0666)
|
return ioutil.WriteFile(tagFile, encoded.Bytes(), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy terminates an existing instance.
|
// Destroy terminates an existing instance.
|
||||||
func (v hyperkitPlugin) Destroy(id instance.ID) error {
|
func (p hyperkitPlugin) Destroy(id instance.ID) error {
|
||||||
fmt.Println("Destroying ", id)
|
log.Info("Destroying VM: ", id)
|
||||||
|
|
||||||
instanceDir := path.Join(v.VMDir, string(id))
|
instanceDir := path.Join(p.VMDir, string(id))
|
||||||
_, err := os.Stat(instanceDir)
|
_, err := os.Stat(instanceDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
@ -148,27 +137,24 @@ func (v hyperkitPlugin) Destroy(id instance.ID) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := getProcess(instanceDir)
|
h, err := hyperkit.FromState(instanceDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = h.Stop()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = h.Remove(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningln("Can't find processes: ", err)
|
|
||||||
} else {
|
|
||||||
err = p.Kill()
|
|
||||||
if err != nil {
|
|
||||||
log.Warningln("Can't kill processes with pid: ", p.Pid, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.RemoveAll(instanceDir); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DescribeInstances returns descriptions of all instances matching all of the provided tags.
|
// DescribeInstances returns descriptions of all instances matching all of the provided tags.
|
||||||
func (v hyperkitPlugin) DescribeInstances(tags map[string]string) ([]instance.Description, error) {
|
func (p hyperkitPlugin) DescribeInstances(tags map[string]string) ([]instance.Description, error) {
|
||||||
files, err := ioutil.ReadDir(v.VMDir)
|
files, err := ioutil.ReadDir(p.VMDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -180,7 +166,7 @@ func (v hyperkitPlugin) DescribeInstances(tags map[string]string) ([]instance.De
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceDir := path.Join(v.VMDir, file.Name())
|
instanceDir := path.Join(p.VMDir, file.Name())
|
||||||
|
|
||||||
tagData, err := ioutil.ReadFile(path.Join(instanceDir, "tags"))
|
tagData, err := ioutil.ReadFile(path.Join(instanceDir, "tags"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -209,22 +195,19 @@ func (v hyperkitPlugin) DescribeInstances(tags map[string]string) ([]instance.De
|
|||||||
var logicalID *instance.LogicalID
|
var logicalID *instance.LogicalID
|
||||||
id := instance.ID(file.Name())
|
id := instance.ID(file.Name())
|
||||||
|
|
||||||
pidData, err := ioutil.ReadFile(path.Join(instanceDir, hyperkitPid))
|
h, err := hyperkit.FromState(instanceDir)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
lid := instance.LogicalID(pidData)
|
log.Warningln("Could not get instance data. Id: ", id)
|
||||||
logicalID = &lid
|
p.Destroy(id)
|
||||||
} else {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if process is running
|
|
||||||
if _, err := getProcess(instanceDir); err != nil {
|
|
||||||
log.Warningln("Process not running: Instance ", id)
|
|
||||||
v.Destroy(id)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if !h.IsRunning() {
|
||||||
|
log.Warningln("Instance is not running. Id: ", id)
|
||||||
|
p.Destroy(id)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lid := instance.LogicalID(h.Pid)
|
||||||
|
logicalID = &lid
|
||||||
|
|
||||||
descriptions = append(descriptions, instance.Description{
|
descriptions = append(descriptions, instance.Description{
|
||||||
ID: id,
|
ID: id,
|
||||||
@ -236,183 +219,3 @@ func (v hyperkitPlugin) DescribeInstances(tags map[string]string) ([]instance.De
|
|||||||
|
|
||||||
return descriptions, nil
|
return descriptions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const hyperkitArgs = "-A -u -F {{.VMLocation}}/hyperkit.pid " +
|
|
||||||
"-c {{.Properties.CPUs}} -m {{.Properties.Memory}}M " +
|
|
||||||
"-s 0:0,hostbridge " +
|
|
||||||
"-s 1:0,virtio-vpnkit,path={{.VPNKitSock}} " +
|
|
||||||
"-s 2,virtio-blk,{{.VMLocation}}/disk.img " +
|
|
||||||
"-s 10,virtio-rnd " +
|
|
||||||
"-s 31,lpc " +
|
|
||||||
"-l com1,autopty={{.VMLocation}}/tty,log={{.VMLocation}}/console-ring"
|
|
||||||
const hyperkitKernArgs = "kexec," +
|
|
||||||
"{{.Properties.Moby}}-bzImage," +
|
|
||||||
"{{.Properties.Moby}}-initrd.img," +
|
|
||||||
"earlyprintk=serial console=ttyS0 panic=1 vsyscall=emulate page_poison=1 ntp=gateway"
|
|
||||||
|
|
||||||
func (v hyperkitPlugin) execHyperKit(spec instance.Spec, params map[string]interface{}) error {
|
|
||||||
|
|
||||||
instanceDir := params["VMLocation"].(string)
|
|
||||||
|
|
||||||
args, err := v.HyperKitTmpl.Render(params)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
kernArgs, err := v.KernelTmpl.Render(params)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Build arguments
|
|
||||||
c := []string{v.HyperKit}
|
|
||||||
c = append(c, strings.Split(args, " ")...)
|
|
||||||
c = append(c, "-f", kernArgs)
|
|
||||||
|
|
||||||
// Write command line to state
|
|
||||||
if err := ioutil.WriteFile(path.Join(instanceDir, "cmdline"), []byte(strings.Join(c, " ")), 0666); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
prop := params["Properties"].(map[string]interface{})
|
|
||||||
sz, ok := prop["Disk"].(float64)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Unable to extract Disk Size: %s", prop["Disk"])
|
|
||||||
}
|
|
||||||
err = createDisk(instanceDir, int(sz))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(spec.Init) != 0 {
|
|
||||||
err = createConfigISO(instanceDir, spec.Init)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c = append(c, "-s", "4,ahci-cd,"+path.Join(instanceDir, "config.iso"))
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command(c[0], c[1:]...)
|
|
||||||
cmd.Env = os.Environ()
|
|
||||||
|
|
||||||
stdoutChan := make(chan string)
|
|
||||||
stderrChan := make(chan string)
|
|
||||||
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
stderr, err := cmd.StderrPipe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
stream(stdout, stdoutChan)
|
|
||||||
stream(stderr, stderrChan)
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case stderrl := <-stderrChan:
|
|
||||||
log.Warning("HyperKit STDERR: ", stderrl)
|
|
||||||
case stdoutl := <-stdoutChan:
|
|
||||||
log.Info("HyperKit STDOUT: ", stdoutl)
|
|
||||||
case <-done:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
log.Infoln("Starting: ", c)
|
|
||||||
|
|
||||||
err = cmd.Start()
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func createDisk(instanceDir string, diskSz int) error {
|
|
||||||
f, err := os.Create(path.Join(instanceDir, "disk.img"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
buf := make([]byte, 1048676)
|
|
||||||
for i := 0; i < len(buf); i++ {
|
|
||||||
buf[i] = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < diskSz; i++ {
|
|
||||||
f.Write(buf)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createConfigISO(instanceDir, init string) error {
|
|
||||||
inName := path.Join(instanceDir, "config")
|
|
||||||
|
|
||||||
if err := ioutil.WriteFile(inName, []byte(init), 0666); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
outfh, err := os.OpenFile(inName+".iso", os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0666)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
infh, err := os.Open(inName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = iso9660wrap.WriteFile(outfh, infh)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("writing file failed with %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func stream(r io.ReadCloser, dest chan<- string) {
|
|
||||||
go func() {
|
|
||||||
defer r.Close()
|
|
||||||
reader := bufio.NewReader(r)
|
|
||||||
for {
|
|
||||||
line, err := reader.ReadString('\n')
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dest <- line
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getProcess(instanceDir string) (*os.Process, error) {
|
|
||||||
pidData, err := ioutil.ReadFile(path.Join(instanceDir, hyperkitPid))
|
|
||||||
if err != nil {
|
|
||||||
log.Warningln("Can't read pid file: ", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pid, err := strconv.Atoi(string(pidData[:]))
|
|
||||||
if err != nil {
|
|
||||||
log.Warningln("Can't convert pidData: ", pidData, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := os.FindProcess(pid)
|
|
||||||
if err != nil {
|
|
||||||
log.Warningln("Can't find process with pid: ", pid)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// os.FindProcess on Unix always returns a process object even
|
|
||||||
// if the process does not exists. There does not seem to be
|
|
||||||
// a call to find out if the process is running either, so we
|
|
||||||
// use another package to find out.
|
|
||||||
proc, err := ps.FindProcess(p.Pid)
|
|
||||||
if err != nil {
|
|
||||||
log.Warningln("Can't find process", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if proc == nil {
|
|
||||||
return nil, errors.New("Process not found")
|
|
||||||
}
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
@ -5,24 +5,16 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/docker/infrakit/pkg/cli"
|
"github.com/docker/infrakit/pkg/cli"
|
||||||
"github.com/docker/infrakit/pkg/discovery"
|
|
||||||
"github.com/docker/infrakit/pkg/plugin/metadata"
|
"github.com/docker/infrakit/pkg/plugin/metadata"
|
||||||
instance_plugin "github.com/docker/infrakit/pkg/rpc/instance"
|
instance_plugin "github.com/docker/infrakit/pkg/rpc/instance"
|
||||||
metadata_plugin "github.com/docker/infrakit/pkg/rpc/metadata"
|
metadata_plugin "github.com/docker/infrakit/pkg/rpc/metadata"
|
||||||
instance_spi "github.com/docker/infrakit/pkg/spi/instance"
|
instance_spi "github.com/docker/infrakit/pkg/spi/instance"
|
||||||
"github.com/docker/infrakit/pkg/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Default path when used with Docker for Mac
|
|
||||||
defaultHyperKit = "/Applications/Docker.app/Contents/MacOS/com.docker.hyperkit"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -31,9 +23,6 @@ var (
|
|||||||
|
|
||||||
// Revision is the build source control revision.
|
// Revision is the build source control revision.
|
||||||
Revision = "Unspecified"
|
Revision = "Unspecified"
|
||||||
|
|
||||||
// Default path to the VPNKit socket on Docker for Mac
|
|
||||||
defaultVPNKitSock = "Library/Containers/com.docker.docker/Data/s50"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -44,34 +33,21 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultVMDir := filepath.Join(getHome(), ".infrakit/hyperkit-vms")
|
defaultVMDir := filepath.Join(getHome(), ".infrakit/hyperkit-vms")
|
||||||
defaultVPNKitSock = path.Join(getHome(), defaultVPNKitSock)
|
|
||||||
|
|
||||||
name := cmd.Flags().String("name", "instance-hyperkit", "Plugin name to advertise for discovery")
|
name := cmd.Flags().String("name", "instance-hyperkit", "Plugin name to advertise for discovery")
|
||||||
logLevel := cmd.Flags().Int("log", cli.DefaultLogLevel, "Logging level. 0 is least verbose. Max is 5")
|
logLevel := cmd.Flags().Int("log", cli.DefaultLogLevel, "Logging level. 0 is least verbose. Max is 5")
|
||||||
|
|
||||||
vmDir := cmd.Flags().String("vm-dir", defaultVMDir, "Directory where to store VM state")
|
vmDir := cmd.Flags().String("vm-dir", defaultVMDir, "Directory where to store VM state")
|
||||||
hyperkit := cmd.Flags().String("hyperkit", defaultHyperKit, "Path to HyperKit executable")
|
hyperkit := cmd.Flags().String("hyperkit", "", "Path to HyperKit executable")
|
||||||
|
|
||||||
vpnkitSock := cmd.Flags().String("vpnkit-sock", defaultVPNKitSock, "Path to VPNKit UNIX domain socket")
|
vpnkitSock := cmd.Flags().String("vpnkit-sock", "auto", "Path to VPNKit UNIX domain socket")
|
||||||
|
|
||||||
cmd.RunE = func(c *cobra.Command, args []string) error {
|
cmd.RunE = func(c *cobra.Command, args []string) error {
|
||||||
opts := template.Options{
|
|
||||||
SocketDir: discovery.Dir(),
|
|
||||||
}
|
|
||||||
thyper, err := template.NewTemplate("str://"+hyperkitArgs, opts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tkern, err := template.NewTemplate("str://"+hyperkitKernArgs, opts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
os.MkdirAll(*vmDir, os.ModePerm)
|
os.MkdirAll(*vmDir, os.ModePerm)
|
||||||
|
|
||||||
cli.SetLogLevel(*logLevel)
|
cli.SetLogLevel(*logLevel)
|
||||||
cli.RunPlugin(*name,
|
cli.RunPlugin(*name,
|
||||||
instance_plugin.PluginServer(NewHyperKitPlugin(*vmDir, *hyperkit, *vpnkitSock, thyper, tkern)),
|
instance_plugin.PluginServer(NewHyperKitPlugin(*vmDir, *hyperkit, *vpnkitSock)),
|
||||||
metadata_plugin.PluginServer(metadata.NewPluginFromData(
|
metadata_plugin.PluginServer(metadata.NewPluginFromData(
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"version": Version,
|
"version": Version,
|
||||||
|
Loading…
Reference in New Issue
Block a user