diff options
Diffstat (limited to 'vm/bhyve')
| -rw-r--r-- | vm/bhyve/bhyve.go | 93 |
1 files changed, 63 insertions, 30 deletions
diff --git a/vm/bhyve/bhyve.go b/vm/bhyve/bhyve.go index c3b53e053..1570b7939 100644 --- a/vm/bhyve/bhyve.go +++ b/vm/bhyve/bhyve.go @@ -25,7 +25,7 @@ func init() { } type Config struct { - Bridge string `json:"bridge"` // name of network bridge device + Bridge string `json:"bridge"` // name of network bridge device, optional Count int `json:"count"` // number of VMs to use CPU int `json:"cpu"` // number of VM vCPU HostIP string `json:"hostip"` // VM host IP address @@ -39,19 +39,21 @@ type Pool struct { } type instance struct { - cfg *Config - snapshot string - tapdev string - image string - debug bool - os string - sshkey string - sshuser string - sshhost string - merger *vmimpl.OutputMerger - vmName string - bhyve *exec.Cmd - consolew io.WriteCloser + cfg *Config + snapshot string + tapdev string + port int + forwardPort int + image string + debug bool + os string + sshkey string + sshuser string + sshhost string + merger *vmimpl.OutputMerger + vmName string + bhyve *exec.Cmd + consolew io.WriteCloser } var ipRegex = regexp.MustCompile(`bound to (([0-9]+\.){3}[0-9]+) `) @@ -129,15 +131,17 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { return nil, err } - tapdev, err := osutil.RunCmd(time.Minute, "", "ifconfig", "tap", "create") - if err != nil { - inst.Close() - return nil, err - } - inst.tapdev = tapRegex.FindString(string(tapdev)) - if _, err := osutil.RunCmd(time.Minute, "", "ifconfig", inst.cfg.Bridge, "addm", inst.tapdev); err != nil { - inst.Close() - return nil, err + if inst.cfg.Bridge != "" { + tapdev, err := osutil.RunCmd(time.Minute, "", "ifconfig", "tap", "create") + if err != nil { + inst.Close() + return nil, err + } + inst.tapdev = tapRegex.FindString(string(tapdev)) + if _, err := osutil.RunCmd(time.Minute, "", "ifconfig", inst.cfg.Bridge, "addm", inst.tapdev); err != nil { + inst.Close() + return nil, err + } } if err := inst.Boot(); err != nil { @@ -165,13 +169,22 @@ func (inst *instance) Boot() error { return err } + netdev := "" + if inst.tapdev != "" { + inst.port = 22 + netdev = inst.tapdev + } else { + inst.port = vmimpl.UnusedTCPPort() + netdev = fmt.Sprintf("slirp,hostfwd=tcp:127.0.0.1:%v-:22", inst.port) + } + bhyveArgs := []string{ "-H", "-A", "-P", "-c", fmt.Sprintf("%d", inst.cfg.CPU), "-m", inst.cfg.Mem, "-s", "0:0,hostbridge", "-s", "1:0,lpc", - "-s", fmt.Sprintf("2:0,virtio-net,%v", inst.tapdev), + "-s", fmt.Sprintf("2:0,virtio-net,%v", netdev), "-s", fmt.Sprintf("3:0,virtio-blk,%v", inst.image), "-l", "com1,stdio", inst.vmName, @@ -238,7 +251,11 @@ func (inst *instance) Boot() error { select { case ip := <-ipch: - inst.sshhost = ip + if inst.tapdev != "" { + inst.sshhost = ip + } else { + inst.sshhost = "localhost" + } case <-inst.merger.Err: bootOutputStop <- true <-bootOutputStop @@ -250,7 +267,7 @@ func (inst *instance) Boot() error { } if err := vmimpl.WaitForSSH(inst.debug, 10*time.Minute, inst.sshhost, - inst.sshkey, inst.sshuser, inst.os, 22, nil, false); err != nil { + inst.sshkey, inst.sshuser, inst.os, inst.port, nil, false); err != nil { bootOutputStop <- true <-bootOutputStop return vmimpl.MakeBootError(err, bootOutput) @@ -280,12 +297,23 @@ func (inst *instance) Close() { } func (inst *instance) Forward(port int) (string, error) { - return fmt.Sprintf("%v:%v", inst.cfg.HostIP, port), nil + if inst.tapdev != "" { + return fmt.Sprintf("%v:%v", inst.cfg.HostIP, port), nil + } else { + if port == 0 { + return "", fmt.Errorf("vm/bhyve: forward port is zero") + } + if inst.forwardPort != 0 { + return "", fmt.Errorf("vm/bhyve: forward port is already set") + } + inst.forwardPort = port + return fmt.Sprintf("localhost:%v", port), nil + } } func (inst *instance) Copy(hostSrc string) (string, error) { vmDst := filepath.Join("/root", filepath.Base(hostSrc)) - args := append(vmimpl.SCPArgs(inst.debug, inst.sshkey, 22, false), + args := append(vmimpl.SCPArgs(inst.debug, inst.sshkey, inst.port, false), hostSrc, inst.sshuser+"@"+inst.sshhost+":"+vmDst) if inst.debug { log.Logf(0, "running command: scp %#v", args) @@ -305,8 +333,13 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin } inst.merger.Add("ssh", rpipe) - args := append(vmimpl.SSHArgs(inst.debug, inst.sshkey, 22, false), - inst.sshuser+"@"+inst.sshhost, command) + sshargs := []string{} + if inst.forwardPort != 0 { + sshargs = vmimpl.SSHArgsForward(inst.debug, inst.sshkey, inst.port, inst.forwardPort, false) + } else { + sshargs = vmimpl.SSHArgs(inst.debug, inst.sshkey, inst.port, false) + } + args := append(sshargs, inst.sshuser+"@"+inst.sshhost, command) if inst.debug { log.Logf(0, "running command: ssh %#v", args) } |
