From de62c65a711ce896611eafacdfd489c0e69c1ee5 Mon Sep 17 00:00:00 2001
From: Sven Dowideit <SvenDowideit@docker.com>
Date: Wed, 11 Feb 2015 22:02:15 +1000
Subject: [PATCH] Detect vboxmanage error conditions and pass those on as
 errors

Signed-off-by: Sven Dowideit <SvenDowideit@docker.com>
---
 drivers/virtualbox/vbm.go | 41 +++++++++++++--------------------------
 1 file changed, 14 insertions(+), 27 deletions(-)

diff --git a/drivers/virtualbox/vbm.go b/drivers/virtualbox/vbm.go
index 2d0a8ad328..9f0170ead3 100644
--- a/drivers/virtualbox/vbm.go
+++ b/drivers/virtualbox/vbm.go
@@ -55,35 +55,13 @@ func setVBoxManageCmd() string {
 }
 
 func vbm(args ...string) error {
-	cmd := exec.Command(vboxManageCmd, args...)
-	if os.Getenv("DEBUG") != "" {
-		cmd.Stdout = os.Stdout
-		cmd.Stderr = os.Stderr
-	}
-	log.Debugf("executing: %v %v", vboxManageCmd, strings.Join(args, " "))
-	if err := cmd.Run(); err != nil {
-		if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound {
-			return ErrVBMNotFound
-		}
-		return fmt.Errorf("%v %v failed: %v", vboxManageCmd, strings.Join(args, " "), err)
-	}
-	return nil
+	_, _, err := vbmOutErr(args...)
+	return err
 }
 
 func vbmOut(args ...string) (string, error) {
-	cmd := exec.Command(vboxManageCmd, args...)
-	if os.Getenv("DEBUG") != "" {
-		cmd.Stderr = os.Stderr
-	}
-	log.Debugf("executing: %v %v", vboxManageCmd, strings.Join(args, " "))
-
-	b, err := cmd.Output()
-	if err != nil {
-		if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound {
-			err = ErrVBMNotFound
-		}
-	}
-	return string(b), err
+	stdout, _, err := vbmOutErr(args...)
+	return stdout, err
 }
 
 func vbmOutErr(args ...string) (string, string, error) {
@@ -94,10 +72,19 @@ func vbmOutErr(args ...string) (string, string, error) {
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
 	err := cmd.Run()
+	stderrStr := stderr.String()
+	log.Debugf("STDOUT: %v", stdout.String())
+	log.Debugf("STDERR: %v", stderrStr)
 	if err != nil {
 		if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound {
 			err = ErrVBMNotFound
 		}
+	} else {
+		// VBoxManage will sometimes not set the return code, but has a fatal error
+		// such as VBoxManage.exe: error: VT-x is not available. (VERR_VMX_NO_VMX)
+		if strings.Contains(stderrStr, "error:") {
+			err = fmt.Errorf("%v %v failed: %v", vboxManageCmd, strings.Join(args, " "), stderrStr)
+		}
 	}
-	return stdout.String(), stderr.String(), err
+	return stdout.String(), stderrStr, err
 }