mirror of https://github.com/docker/docs.git
Check that VT-X/AMD-v is enabled
Signed-off-by: David Gageot <david@gageot.net>
This commit is contained in:
parent
6cac8cc95f
commit
4a33fabe8b
|
@ -2,6 +2,7 @@ package virtualbox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -18,6 +19,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/docker/machine/libmachine/drivers"
|
"github.com/docker/machine/libmachine/drivers"
|
||||||
"github.com/docker/machine/libmachine/log"
|
"github.com/docker/machine/libmachine/log"
|
||||||
"github.com/docker/machine/libmachine/mcnflag"
|
"github.com/docker/machine/libmachine/mcnflag"
|
||||||
|
@ -41,6 +44,7 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrUnableToGenerateRandomIP = errors.New("unable to generate random IP")
|
ErrUnableToGenerateRandomIP = errors.New("unable to generate random IP")
|
||||||
|
ErrMustEnableVTX = errors.New("This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory.")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Driver struct {
|
type Driver struct {
|
||||||
|
@ -174,23 +178,71 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
|
||||||
|
|
||||||
func (d *Driver) PreCreateCheck() error {
|
func (d *Driver) PreCreateCheck() error {
|
||||||
// Check that VBoxManage exists and works
|
// Check that VBoxManage exists and works
|
||||||
if err := vbm(); err != nil {
|
return vbm()
|
||||||
return err
|
}
|
||||||
|
|
||||||
|
// IsVTXDisabled checks if VT-X is disabled in the BIOS. If it is, the vm will fail to start.
|
||||||
|
// If we can't be sure it is disabled, we carry on and will check the vm logs after it's started.
|
||||||
|
func (d *Driver) IsVTXDisabled() bool {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
output, err := cmdOutput("wmic", "cpu", "get", "VirtualizationFirmwareEnabled")
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("Couldn't check that VT-X/AMD-v is enabled. Will check that the vm is properly created: %v", err)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
disabled := strings.Contains(output, "FALSE")
|
||||||
|
return disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: linux and OSX
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// cmdOutput runs a shell command and returns its output.
|
||||||
|
func cmdOutput(name string, args ...string) (string, error) {
|
||||||
|
cmd := exec.Command(name, args...)
|
||||||
|
log.Debugf("COMMAND: %v %v", name, strings.Join(args, " "))
|
||||||
|
|
||||||
|
stdout, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("STDOUT:\n{\n%v}", string(stdout))
|
||||||
|
|
||||||
|
return string(stdout), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsVTXDisabledInTheVM checks if VT-X is disabled in the started vm.
|
||||||
|
func (d *Driver) IsVTXDisabledInTheVM() (bool, error) {
|
||||||
|
file, err := os.Open(path.Join(d.ResolveStorePath(d.MachineName), "Logs", "VBox.log"))
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
if strings.Contains(scanner.Text(), "VT-x is disabled") {
|
||||||
|
return true, ErrMustEnableVTX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Create() error {
|
func (d *Driver) Create() error {
|
||||||
if err := vbm("--version"); err != nil {
|
|
||||||
return fmt.Errorf("Checking VirtualBox version failed: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
b2dutils := mcnutils.NewB2dUtils("", "", d.StorePath)
|
b2dutils := mcnutils.NewB2dUtils("", "", d.StorePath)
|
||||||
if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil {
|
if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.IsVTXDisabled() {
|
||||||
|
return ErrMustEnableVTX
|
||||||
|
}
|
||||||
|
|
||||||
log.Infof("Creating VirtualBox VM...")
|
log.Infof("Creating VirtualBox VM...")
|
||||||
|
|
||||||
// import b2d VM if requested
|
// import b2d VM if requested
|
||||||
|
@ -364,11 +416,7 @@ func (d *Driver) Create() error {
|
||||||
|
|
||||||
log.Infof("Starting VirtualBox VM...")
|
log.Infof("Starting VirtualBox VM...")
|
||||||
|
|
||||||
if err := d.Start(); err != nil {
|
return d.Start()
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) hostOnlyIpAvailable() bool {
|
func (d *Driver) hostOnlyIpAvailable() bool {
|
||||||
|
@ -417,6 +465,16 @@ func (d *Driver) Start() error {
|
||||||
log.Infof("VM not in restartable state")
|
log.Infof("VM not in restartable state")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that VT-X is not disabled in the started VM
|
||||||
|
disabled, err := d.IsVTXDisabledInTheVM()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Checking if hardware virtualization is enabled failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if disabled {
|
||||||
|
return ErrMustEnableVTX
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for SSH over NAT to be available before returning to user
|
// Wait for SSH over NAT to be available before returning to user
|
||||||
if err := drivers.WaitForSSH(d); err != nil {
|
if err := drivers.WaitForSSH(d); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue