PageRenderTime 73ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/virtualbox/vbm.go

https://gitlab.com/JamesClonk/machine
Go | 90 lines | 78 code | 8 blank | 4 comment | 21 complexity | f16c1a98c61f6a3da22509870f2e96d6 MD5 | raw file
  1. package virtualbox
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. "regexp"
  10. "runtime"
  11. "strings"
  12. log "github.com/Sirupsen/logrus"
  13. )
  14. var (
  15. reVMNameUUID = regexp.MustCompile(`"(.+)" {([0-9a-f-]+)}`)
  16. reVMInfoLine = regexp.MustCompile(`(?:"(.+)"|(.+))=(?:"(.*)"|(.*))`)
  17. reColonLine = regexp.MustCompile(`(.+):\s+(.*)`)
  18. reMachineNotFound = regexp.MustCompile(`Could not find a registered machine named '(.+)'`)
  19. )
  20. var (
  21. ErrMachineExist = errors.New("machine already exists")
  22. ErrMachineNotExist = errors.New("machine does not exist")
  23. ErrVBMNotFound = errors.New("VBoxManage not found")
  24. vboxManageCmd = setVBoxManageCmd()
  25. )
  26. // detect the VBoxManage cmd's path if needed
  27. func setVBoxManageCmd() string {
  28. cmd := "VBoxManage"
  29. if path, err := exec.LookPath(cmd); err == nil {
  30. return path
  31. }
  32. if runtime.GOOS == "windows" {
  33. if p := os.Getenv("VBOX_INSTALL_PATH"); p != "" {
  34. if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil {
  35. return path
  36. }
  37. }
  38. if p := os.Getenv("VBOX_MSI_INSTALL_PATH"); p != "" {
  39. if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil {
  40. return path
  41. }
  42. }
  43. // look at HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\VirtualBox\InstallDir
  44. p := "C:\\Program Files\\Oracle\\VirtualBox"
  45. if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil {
  46. return path
  47. }
  48. }
  49. return cmd
  50. }
  51. func vbm(args ...string) error {
  52. _, _, err := vbmOutErr(args...)
  53. return err
  54. }
  55. func vbmOut(args ...string) (string, error) {
  56. stdout, _, err := vbmOutErr(args...)
  57. return stdout, err
  58. }
  59. func vbmOutErr(args ...string) (string, string, error) {
  60. cmd := exec.Command(vboxManageCmd, args...)
  61. log.Debugf("executing: %v %v", vboxManageCmd, strings.Join(args, " "))
  62. var stdout bytes.Buffer
  63. var stderr bytes.Buffer
  64. cmd.Stdout = &stdout
  65. cmd.Stderr = &stderr
  66. err := cmd.Run()
  67. stderrStr := stderr.String()
  68. log.Debugf("STDOUT: %v", stdout.String())
  69. log.Debugf("STDERR: %v", stderrStr)
  70. if err != nil {
  71. if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound {
  72. err = ErrVBMNotFound
  73. }
  74. } else {
  75. // VBoxManage will sometimes not set the return code, but has a fatal error
  76. // such as VBoxManage.exe: error: VT-x is not available. (VERR_VMX_NO_VMX)
  77. if strings.Contains(stderrStr, "error:") {
  78. err = fmt.Errorf("%v %v failed: %v", vboxManageCmd, strings.Join(args, " "), stderrStr)
  79. }
  80. }
  81. return stdout.String(), stderrStr, err
  82. }