github.com/tonnydourado/packer@v0.6.1-0.20140701134019-5d0cd9676a37/builder/virtualbox/common/driver_4_2.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"os/exec"
     8  	"regexp"
     9  	"strings"
    10  	"time"
    11  )
    12  
    13  type VBox42Driver struct {
    14  	// This is the path to the "VBoxManage" application.
    15  	VBoxManagePath string
    16  }
    17  
    18  func (d *VBox42Driver) CreateSATAController(vmName string, name string) error {
    19  	version, err := d.Version()
    20  	if err != nil {
    21  		return err
    22  	}
    23  
    24  	portCountArg := "--sataportcount"
    25  	if strings.HasPrefix(version, "4.3") {
    26  		portCountArg = "--portcount"
    27  	}
    28  
    29  	command := []string{
    30  		"storagectl", vmName,
    31  		"--name", name,
    32  		"--add", "sata",
    33  		portCountArg, "1",
    34  	}
    35  
    36  	return d.VBoxManage(command...)
    37  }
    38  
    39  func (d *VBox42Driver) Delete(name string) error {
    40  	return d.VBoxManage("unregistervm", name, "--delete")
    41  }
    42  
    43  func (d *VBox42Driver) Iso() (string, error) {
    44  	var stdout bytes.Buffer
    45  
    46  	cmd := exec.Command(d.VBoxManagePath, "list", "systemproperties")
    47  	cmd.Stdout = &stdout
    48  	if err := cmd.Run(); err != nil {
    49  		return "", err
    50  	}
    51  
    52  	DefaultGuestAdditionsRe := regexp.MustCompile("Default Guest Additions ISO:(.*)")
    53  
    54  	for _, line := range strings.Split(stdout.String(), "\n") {
    55  		// Need to trim off CR character when running in windows
    56  		line = strings.TrimRight(line, "\r")
    57  
    58  		matches := DefaultGuestAdditionsRe.FindStringSubmatch(line)
    59  		if matches == nil {
    60  			continue
    61  		}
    62  
    63  		isoname := strings.Trim(matches[1], " \r\n")
    64  		log.Printf("Found Default Guest Additions ISO: %s", isoname)
    65  
    66  		return isoname, nil
    67  	}
    68  
    69  	return "", fmt.Errorf("Cannot find \"Default Guest Additions ISO\" in vboxmanage output")
    70  }
    71  
    72  func (d *VBox42Driver) Import(name, path, opts string) error {
    73  	args := []string{
    74  		"import", path,
    75  		"--vsys", "0",
    76  		"--vmname", name,
    77  		"--options", opts,
    78  	}
    79  
    80  	return d.VBoxManage(args...)
    81  }
    82  
    83  func (d *VBox42Driver) IsRunning(name string) (bool, error) {
    84  	var stdout bytes.Buffer
    85  
    86  	cmd := exec.Command(d.VBoxManagePath, "showvminfo", name, "--machinereadable")
    87  	cmd.Stdout = &stdout
    88  	if err := cmd.Run(); err != nil {
    89  		return false, err
    90  	}
    91  
    92  	for _, line := range strings.Split(stdout.String(), "\n") {
    93  		// Need to trim off CR character when running in windows
    94  		line = strings.TrimRight(line, "\r")
    95  
    96  		if line == `VMState="running"` {
    97  			return true, nil
    98  		}
    99  
   100  		// We consider "stopping" to still be running. We wait for it to
   101  		// be completely stopped or some other state.
   102  		if line == `VMState="stopping"` {
   103  			return true, nil
   104  		}
   105  
   106  		// We consider "paused" to still be running. We wait for it to
   107  		// be completely stopped or some other state.
   108  		if line == `VMState="paused"` {
   109  			return true, nil
   110  		}
   111  	}
   112  
   113  	return false, nil
   114  }
   115  
   116  func (d *VBox42Driver) Stop(name string) error {
   117  	if err := d.VBoxManage("controlvm", name, "poweroff"); err != nil {
   118  		return err
   119  	}
   120  
   121  	// We sleep here for a little bit to let the session "unlock"
   122  	time.Sleep(2 * time.Second)
   123  
   124  	return nil
   125  }
   126  
   127  func (d *VBox42Driver) SuppressMessages() error {
   128  	extraData := map[string]string{
   129  		"GUI/RegistrationData": "triesLeft=0",
   130  		"GUI/SuppressMessages": "confirmInputCapture,remindAboutAutoCapture,remindAboutMouseIntegrationOff,remindAboutMouseIntegrationOn,remindAboutWrongColorDepth",
   131  		"GUI/UpdateDate":       fmt.Sprintf("1 d, %d-01-01, stable", time.Now().Year()+1),
   132  		"GUI/UpdateCheckCount": "60",
   133  	}
   134  
   135  	for k, v := range extraData {
   136  		if err := d.VBoxManage("setextradata", "global", k, v); err != nil {
   137  			return err
   138  		}
   139  	}
   140  
   141  	return nil
   142  }
   143  
   144  func (d *VBox42Driver) VBoxManage(args ...string) error {
   145  	var stdout, stderr bytes.Buffer
   146  
   147  	log.Printf("Executing VBoxManage: %#v", args)
   148  	cmd := exec.Command(d.VBoxManagePath, args...)
   149  	cmd.Stdout = &stdout
   150  	cmd.Stderr = &stderr
   151  	err := cmd.Run()
   152  
   153  	stdoutString := strings.TrimSpace(stdout.String())
   154  	stderrString := strings.TrimSpace(stderr.String())
   155  
   156  	if _, ok := err.(*exec.ExitError); ok {
   157  		err = fmt.Errorf("VBoxManage error: %s", stderrString)
   158  	}
   159  
   160  	log.Printf("stdout: %s", stdoutString)
   161  	log.Printf("stderr: %s", stderrString)
   162  
   163  	return err
   164  }
   165  
   166  func (d *VBox42Driver) Verify() error {
   167  	return nil
   168  }
   169  
   170  func (d *VBox42Driver) Version() (string, error) {
   171  	var stdout bytes.Buffer
   172  
   173  	cmd := exec.Command(d.VBoxManagePath, "--version")
   174  	cmd.Stdout = &stdout
   175  	if err := cmd.Run(); err != nil {
   176  		return "", err
   177  	}
   178  
   179  	versionOutput := strings.TrimSpace(stdout.String())
   180  	log.Printf("VBoxManage --version output: %s", versionOutput)
   181  
   182  	// If the "--version" output contains vboxdrv, then this is indicative
   183  	// of problems with the VirtualBox setup and we shouldn't really continue,
   184  	// whether or not we can read the version.
   185  	if strings.Contains(versionOutput, "vboxdrv") {
   186  		return "", fmt.Errorf("VirtualBox is not properly setup: %s", versionOutput)
   187  	}
   188  
   189  	versionRe := regexp.MustCompile("[^.0-9]")
   190  	matches := versionRe.Split(versionOutput, 2)
   191  	if len(matches) == 0 || matches[0] == "" {
   192  		return "", fmt.Errorf("No version found: %s", versionOutput)
   193  	}
   194  
   195  	log.Printf("VirtualBox version: %s", matches[0])
   196  	return matches[0], nil
   197  }