func (m *Machine) Modify() error {
	args := []string{"modifyvm", m.Name,
		"--firmware", "bios",
		"--bioslogofadein", "off",
		"--bioslogofadeout", "off",
		"--bioslogodisplaytime", "0",
		"--biosbootmenu", "disabled",
		"--natdnshostresolver1", "off",
		"--natdnsproxy1", "off",
		"--ostype", m.OSType,
		"--cpus", fmt.Sprintf("%d", m.CPUs),
		"--memory", fmt.Sprintf("%d", m.Memory),
		"--vram", fmt.Sprintf("%d", m.VRAM),
		"--acpi", m.Flag.Get(F_acpi),
		"--ioapic", m.Flag.Get(F_ioapic),
		"--rtcuseutc", m.Flag.Get(F_rtcuseutc),
		"--cpuhotplug", m.Flag.Get(F_cpuhotplug),
		"--pae", m.Flag.Get(F_pae),
		"--longmode", m.Flag.Get(F_longmode),
		"--hpet", m.Flag.Get(F_hpet),
		"--hwvirtex", m.Flag.Get(F_hwvirtex),
		"--triplefaultreset", m.Flag.Get(F_triplefaultreset),
		"--nestedpaging", m.Flag.Get(F_nestedpaging),
		"--largepages", m.Flag.Get(F_largepages),
		"--vtxvpid", m.Flag.Get(F_vtxvpid),
		"--vtxux", m.Flag.Get(F_vtxux),
		"--accelerate3d", m.Flag.Get(F_accelerate3d),
	}
	args = append(args,
		"--uart1", "0x3F8", "4",
		"--uartmode1", "server", m.SerialFile,
	)
	for i, dev := range m.BootOrder {
		if i > 3 {
			break  
		}
		args = append(args, fmt.Sprintf("--boot%d", i+1), dev)
	}
	if err := vbm(args...); err != nil {
		return err
	}
	return m.Refresh()
}
Modify changes the settings of the machine.
package virtualbox
import (
	"archive/tar"
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"time"
	"github.com/boot2docker/boot2docker-cli/driver"
	flag "github.com/ogier/pflag"
)
type Flag int
const (
	F_acpi Flag = 1 << iota
	F_ioapic
	F_rtcuseutc
	F_cpuhotplug
	F_pae
	F_longmode
	F_hpet
	F_hwvirtex
	F_triplefaultreset
	F_nestedpaging
	F_largepages
	F_vtxvpid
	F_vtxux
	F_accelerate3d
)
type DriverCfg struct {
	VBM  string  
	VMDK string  
	shares shareSlice
}
var shareDefault string  
var (
	verbose bool  
	cfg     DriverCfg
)
func init() {
	if err := driver.Register("virtualbox", InitFunc); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to initialize driver. Error : %s", err.Error())
		os.Exit(1)
	}
	if err := driver.RegisterConfig("virtualbox", ConfigFlags); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to initialize driver config. Error : %s", err.Error())
		os.Exit(1)
	}
}
func InitFunc(mc *driver.MachineConfig) (driver.Machine, error) {
	verbose = mc.Verbose
	m, err := GetMachine(mc.VM)
	if err != nil && mc.Init {
		return CreateMachine(mc)
	}
	return m, err
}
type shareSlice map[string]string
const shareSliceSep = "="
func (s shareSlice) String() string {
	var ret []string
	for name, dir := range s {
		ret = append(ret, fmt.Sprintf("%s%s%s", dir, shareSliceSep, name))
	}
	return fmt.Sprintf("[%s]", strings.Join(ret, " "))
}
func (s *shareSlice) Set(shareDir string) error {
	var shareName string
	if i := strings.Index(shareDir, shareSliceSep); i >= 0 {
		shareName = shareDir[i+1:]
		shareDir = shareDir[:i]
	}
	if shareName == "" {
		shareName = strings.TrimLeft(shareDir, "/")
	}
	if *s == nil {
		*s = shareSlice{}
	}
	(*s)[shareName] = shareDir
	return nil
}
func ConfigFlags(B2D *driver.MachineConfig, flags *flag.FlagSet) error {
	flags.StringVar(&cfg.VMDK, "basevmdk", "", "Path to VMDK to use as base for persistent partition")
	cfg.VBM = "VBoxManage"
	if runtime.GOOS == "windows" {
		p := "C:\\Program Files\\Oracle\\VirtualBox"
		if t := os.Getenv("VBOX_INSTALL_PATH"); t != "" {
			p = t
		} else if t = os.Getenv("VBOX_MSI_INSTALL_PATH"); t != "" {
			p = t
		}
		cfg.VBM = filepath.Join(p, "VBoxManage.exe")
	}
	flags.StringVar(&cfg.VBM, "vbm", cfg.VBM, "path to VirtualBox management utility.")
	shareDefault = "disable"
	switch runtime.GOOS {
	case "darwin":
		shareDefault = "/Users" + shareSliceSep + "Users"
	case "windows":
		shareDefault = "C:\\Users" + shareSliceSep + "c/Users"
	}
	var defaultText string
	if shareDefault != "disable" {
		defaultText = "(defaults to '" + shareDefault + "' if no shares are specified; use 'disable' to explicitly prevent any shares from being created) "
	}
	flags.Var(&cfg.shares, "vbox-share", fmt.Sprintf("%sList of directories to share during 'up|start|boot' via VirtualBox Guest Additions, with optional labels", defaultText))
	return nil
}
func bool2string(b bool) string {
	if b {
		return "on"
	}
	return "off"
}
func (f Flag) Get(o Flag) string {
	return bool2string(f&o == o)
}
type Machine struct {
	Name       string
	UUID       string
	Iso        string
	State      driver.MachineState
	CPUs       uint
	Memory     uint  
	VRAM       uint  
	CfgFile    string
	BaseFolder string
	OSType     string
	Flag       Flag
	BootOrder  []string  
	DockerPort uint
	SSHPort    uint
	SerialFile string
}
func (m *Machine) Refresh() error {
	id := m.Name
	if id == "" {
		id = m.UUID
	}
	mm, err := GetMachine(id)
	if err != nil {
		return err
	}
	*m = *mm
	return nil
}
func (m *Machine) Start() error {
	switch m.State {
	case driver.Paused:
		return vbm("controlvm", m.Name, "resume")
	case driver.Poweroff, driver.Aborted:
		if err := m.setUpShares(); err != nil {
			return err
		}
		fallthrough
	case driver.Saved:
		return vbm("startvm", m.Name, "--type", "headless")
	}
	if err := m.Refresh(); err == nil {
		if m.State != driver.Running {
			return fmt.Errorf("Failed to start", m.Name)
		}
	}
	return nil
}
func (m *Machine) Save() error {
	switch m.State {
	case driver.Paused:
		if err := m.Start(); err != nil {
			return err
		}
	case driver.Poweroff, driver.Aborted, driver.Saved:
		return nil
	}
	return vbm("controlvm", m.Name, "savestate")
}
func (m *Machine) Pause() error {
	switch m.State {
	case driver.Paused, driver.Poweroff, driver.Aborted, driver.Saved:
		return nil
	}
	return vbm("controlvm", m.Name, "pause")
}
func (m *Machine) Stop() error {
	switch m.State {
	case driver.Poweroff, driver.Aborted, driver.Saved:
		return nil
	case driver.Paused:
		if err := m.Start(); err != nil {
			return err
		}
	}
	for i := 0; i < 10; i++ {
		if err := vbm("controlvm", m.Name, "acpipowerbutton"); err != nil {
			return err
		}
		time.Sleep(1 * time.Second)
		if err := m.Refresh(); err != nil {
			return err
		}
		if m.State == driver.Poweroff {
			return nil
		}
	}
	return fmt.Errorf("timed out waiting for VM to stop")
}
func (m *Machine) Poweroff() error {
	switch m.State {
	case driver.Poweroff, driver.Aborted, driver.Saved:
		return nil
	}
	return vbm("controlvm", m.Name, "poweroff")
}
func (m *Machine) Restart() error {
	switch m.State {
	case driver.Paused, driver.Saved:
		if err := m.Start(); err != nil {
			return err
		}
	}
	if err := m.Stop(); err != nil {
		return err
	}
	return m.Start()
}
func (m *Machine) Reset() error {
	switch m.State {
	case driver.Paused, driver.Saved:
		if err := m.Start(); err != nil {
			return err
		}
	}
	return vbm("controlvm", m.Name, "reset")
}
func (m *Machine) Delete() error {
	if err := m.Poweroff(); err != nil {
		return err
	}
	return vbm("unregistervm", m.Name, "--delete")
}
func (m *Machine) GetName() string {
	return m.Name
}
func (m *Machine) GetState() driver.MachineState {
	return m.State
}
func (m *Machine) GetSerialFile() string {
	return m.SerialFile
}
func (m *Machine) GetDockerPort() uint {
	return m.DockerPort
}
func (m *Machine) GetSSHPort() uint {
	return m.SSHPort
}
func GetMachine(id string) (*Machine, error) {
	stdout, stderr, err := vbmOutErr("showvminfo", id, "--machinereadable")
	if err != nil {
		if reMachineNotFound.FindString(stderr) != "" {
			return nil, driver.ErrMachineNotExist
		}
		return nil, err
	}
	s := bufio.NewScanner(strings.NewReader(stdout))
	m := &Machine{}
	for s.Scan() {
		res := reVMInfoLine.FindStringSubmatch(s.Text())
		if res == nil {
			continue
		}
		key := res[1]
		if key == "" {
			key = res[2]
		}
		val := res[3]
		if val == "" {
			val = res[4]
		}
		switch key {
		case "name":
			m.Name = val
		case "UUID":
			m.UUID = val
		case "SATA-0-0":
			m.Iso = val
		case "VMState":
			m.State = driver.MachineState(val)
		case "memory":
			n, err := strconv.ParseUint(val, 10, 32)
			if err != nil {
				return nil, err
			}
			m.Memory = uint(n)
		case "cpus":
			n, err := strconv.ParseUint(val, 10, 32)
			if err != nil {
				return nil, err
			}
			m.CPUs = uint(n)
		case "vram":
			n, err := strconv.ParseUint(val, 10, 32)
			if err != nil {
				return nil, err
			}
			m.VRAM = uint(n)
		case "CfgFile":
			m.CfgFile = val
			m.BaseFolder = filepath.Dir(val)
		case "uartmode1":
			vals := strings.Split(val, ",")
			if len(vals) >= 2 {
				m.SerialFile = vals[1]
			}
		default:
			if strings.HasPrefix(key, "Forwarding(") {
				vals := strings.Split(val, ",")
				n, err := strconv.ParseUint(vals[3], 10, 32)
				if err != nil {
					return nil, err
				}
				switch vals[0] {
				case "docker":
					m.DockerPort = uint(n)
				case "ssh":
					m.SSHPort = uint(n)
				}
			}
		}
	}
	if err := s.Err(); err != nil {
		return nil, err
	}
	return m, nil
}
func ListMachines() ([]string, error) {
	out, err := vbmOut("list", "vms")
	if err != nil {
		return nil, err
	}
	ms := []string{}
	s := bufio.NewScanner(strings.NewReader(out))
	for s.Scan() {
		res := reVMNameUUID.FindStringSubmatch(s.Text())
		if res == nil {
			continue
		}
		ms = append(ms, res[1])
	}
	if err := s.Err(); err != nil {
		return nil, err
	}
	return ms, nil
}
func CreateMachine(mc *driver.MachineConfig) (*Machine, error) {
	if mc.VM == "" {
		return nil, fmt.Errorf("machine name is empty")
	}
	machineNames, err := ListMachines()
	if err != nil {
		return nil, err
	}
	for _, m := range machineNames {
		if m == mc.VM {
			return nil, driver.ErrMachineExist
		}
	}
	args := []string{"createvm", "--name", mc.VM, "--register"}
	if err := vbm(args...); err != nil {
		return nil, err
	}
	m, err := GetMachine(mc.VM)
	if err != nil {
		return nil, err
	}
	SetExtra(mc.VM, "VBoxInternal/CPUM/EnableHVP", "1")
	m.OSType = "Linux26_64"
	if mc.CPUs > 0 {
		m.CPUs = mc.CPUs
	} else {
		m.CPUs = uint(runtime.NumCPU())
	}
	if m.CPUs > 32 {
		m.CPUs = 32
	}
	m.Memory = mc.Memory
	m.SerialFile = mc.SerialFile
	m.Flag |= F_pae
	m.Flag |= F_longmode  
	m.Flag |= F_rtcuseutc
	m.Flag |= F_acpi
	m.Flag |= F_ioapic
	m.Flag |= F_hpet
	m.Flag |= F_hwvirtex
	m.Flag |= F_vtxvpid
	m.Flag |= F_largepages
	m.Flag |= F_nestedpaging
	m.BootOrder = []string{"dvd"}
	if err := m.Modify(); err != nil {
		return m, err
	}
	m.SetNIC(1, driver.NIC{Network: driver.NICNetNAT, Hardware: driver.VirtIO})
	pfRules := map[string]driver.PFRule{
		"ssh": {Proto: driver.PFTCP, HostIP: net.ParseIP("127.0.0.1"), HostPort: mc.SSHPort, GuestPort: driver.SSHPort},
	}
	if mc.DockerPort > 0 {
		pfRules["docker"] = driver.PFRule{Proto: driver.PFTCP, HostIP: net.ParseIP("127.0.0.1"), HostPort: mc.DockerPort, GuestPort: driver.DockerPort}
	}
	for name, rule := range pfRules {
		if err := m.AddNATPF(1, name, rule); err != nil {
			return m, err
		}
	}
	hostIFName, err := getHostOnlyNetworkInterface(mc)
	if err != nil {
		return m, err
	}
	if err := m.SetNIC(2, driver.NIC{Network: driver.NICNetHostonly, Hardware: driver.VirtIO, HostonlyAdapter: hostIFName}); err != nil {
		return m, err
	}
	if err := m.AddStorageCtl("SATA", driver.StorageController{SysBus: driver.SysBusSATA, HostIOCache: true, Bootable: true, Ports: 4}); err != nil {
		return m, err
	}
	if err := m.AttachStorage("SATA", driver.StorageMedium{Port: 0, Device: 0, DriveType: driver.DriveDVD, Medium: mc.ISO}); err != nil {
		return m, err
	}
	diskImg := filepath.Join(m.BaseFolder, fmt.Sprintf("%s.vmdk", mc.VM))
	if _, err := os.Stat(diskImg); err != nil {
		if !os.IsNotExist(err) {
			return m, err
		}
		if cfg.VMDK != "" {
			if err := copyDiskImage(diskImg, cfg.VMDK); err != nil {
				return m, err
			}
		} else {
			magicString := "boot2docker, please format-me"
			buf := new(bytes.Buffer)
			tw := tar.NewWriter(buf)
			file := &tar.Header{Name: magicString, Size: int64(len(magicString))}
			if err := tw.WriteHeader(file); err != nil {
				return m, err
			}
			if _, err := tw.Write([]byte(magicString)); err != nil {
				return m, err
			}
			file = &tar.Header{Name: ".ssh", Typeflag: tar.TypeDir, Mode: 0700}
			if err := tw.WriteHeader(file); err != nil {
				return m, err
			}
			pubKey, err := ioutil.ReadFile(mc.SSHKey + ".pub")
			if err != nil {
				return m, err
			}
			file = &tar.Header{Name: ".ssh/authorized_keys", Size: int64(len(pubKey)), Mode: 0644}
			if err := tw.WriteHeader(file); err != nil {
				return m, err
			}
			if _, err := tw.Write([]byte(pubKey)); err != nil {
				return m, err
			}
			file = &tar.Header{Name: ".ssh/authorized_keys2", Size: int64(len(pubKey)), Mode: 0644}
			if err := tw.WriteHeader(file); err != nil {
				return m, err
			}
			if _, err := tw.Write([]byte(pubKey)); err != nil {
				return m, err
			}
			if err := tw.Close(); err != nil {
				return m, err
			}
			if err := makeDiskImage(diskImg, mc.DiskSize, buf.Bytes()); err != nil {
				return m, err
			}
			if verbose {
				fmt.Println("Initializing disk with ssh keys")
				fmt.Printf("WRITING: %s\n-----\n", buf)
			}
		}
	}
	if err := m.AttachStorage("SATA", driver.StorageMedium{Port: 1, Device: 0, DriveType: driver.DriveHDD, Medium: diskImg}); err != nil {
		return m, err
	}
	return m, nil
}
func (m *Machine) setUpShares() error {
	if err := vbm("guestproperty", "set", m.Name, "/VirtualBox/GuestAdd/SharedFolders/MountPrefix", "/"); err != nil {
		return err
	}
	if err := vbm("guestproperty", "set", m.Name, "/VirtualBox/GuestAdd/SharedFolders/MountDir", "/"); err != nil {
		return err
	}
	if len(cfg.shares) == 0 {
		cfg.shares.Set(shareDefault)
	}
	for shareName, shareDir := range cfg.shares {
		if shareDir == "disable" {
			continue
		}
		if _, err := os.Stat(shareDir); err != nil {
			return err
		}
		if err := vbm("sharedfolder", "add", m.Name, "--name", shareName, "--hostpath", shareDir, "--automount"); err != nil {
			return err
		}
		if err := vbm("setextradata", m.Name, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/"+shareName, "1"); err != nil {
			return err
		}
	}
	return nil
}