Merge pull request #8607 from hashicorp/fix_vagrant_crash
Fix a crash in the vagrant driver
This commit is contained in:
commit
ecf0e5794a
|
@ -1,6 +1,7 @@
|
||||||
package vagrant
|
package vagrant
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
@ -8,7 +9,6 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
)
|
)
|
||||||
|
@ -190,16 +190,47 @@ func (d *Vagrant_2_2_Driver) Version() (string, error) {
|
||||||
return version, nil
|
return version, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Vagrant_2_2_Driver) vagrantCmd(args ...string) (string, string, error) {
|
// Copied and modified from Bufio; this will return data that contains a
|
||||||
var stdout, stderr bytes.Buffer
|
// carriage return, not just data that contains a newline.
|
||||||
|
// This allows us to stream progress output from vagrant that would otherwise
|
||||||
|
// be smothered. It is a bit noisy, but probably prefereable to suppressing
|
||||||
|
// the output in a way that looks like Packer has hung.
|
||||||
|
func ScanLinesInclCR(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||||
|
if atEOF && len(data) == 0 {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
if i := bytes.IndexByte(data, '\n'); i >= 0 {
|
||||||
|
// We have a full newline-terminated line.
|
||||||
|
return i + 1, data[0:i], nil
|
||||||
|
}
|
||||||
|
if i := bytes.IndexByte(data, '\r'); i >= 0 {
|
||||||
|
// We have a CR-terminated line.
|
||||||
|
return i + 1, data[0:i], nil
|
||||||
|
}
|
||||||
|
// If we're at EOF, we have a final, non-terminated line. Return it.
|
||||||
|
if atEOF {
|
||||||
|
return len(data), data, nil
|
||||||
|
}
|
||||||
|
// Request more data.
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Vagrant_2_2_Driver) vagrantCmd(args ...string) (string, string, error) {
|
||||||
log.Printf("Calling Vagrant CLI: %#v", args)
|
log.Printf("Calling Vagrant CLI: %#v", args)
|
||||||
cmd := exec.Command(d.vagrantBinary, args...)
|
cmd := exec.Command(d.vagrantBinary, args...)
|
||||||
cmd.Env = append(os.Environ(), fmt.Sprintf("VAGRANT_CWD=%s", d.VagrantCWD))
|
cmd.Env = append(os.Environ(), fmt.Sprintf("VAGRANT_CWD=%s", d.VagrantCWD))
|
||||||
cmd.Stdout = &stdout
|
|
||||||
cmd.Stderr = &stderr
|
|
||||||
|
|
||||||
err := cmd.Start()
|
stderr, err := cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error getting err pipe")
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error getting out pipe")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("Error starting vagrant command with args: %q",
|
return "", "", fmt.Errorf("Error starting vagrant command with args: %q",
|
||||||
strings.Join(args, " "))
|
strings.Join(args, " "))
|
||||||
|
@ -208,43 +239,24 @@ func (d *Vagrant_2_2_Driver) vagrantCmd(args ...string) (string, string, error)
|
||||||
stdoutString := ""
|
stdoutString := ""
|
||||||
stderrString := ""
|
stderrString := ""
|
||||||
|
|
||||||
donech := make(chan bool)
|
scanOut := bufio.NewScanner(stdout)
|
||||||
|
scanOut.Split(ScanLinesInclCR)
|
||||||
|
scanErr := bufio.NewScanner(stderr)
|
||||||
|
scanErr.Split(ScanLinesInclCR)
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for scanErr.Scan() {
|
||||||
select {
|
line := scanErr.Text()
|
||||||
case <-donech:
|
|
||||||
line := stdout.String()
|
|
||||||
if line != "" {
|
|
||||||
log.Printf("[vagrant driver] stdout: %s", line)
|
|
||||||
}
|
|
||||||
stdoutString += line
|
|
||||||
line = stderr.String()
|
|
||||||
if line != "" {
|
|
||||||
log.Printf("[vagrant driver] stderr: %s", line)
|
log.Printf("[vagrant driver] stderr: %s", line)
|
||||||
}
|
stderrString += line + "\n"
|
||||||
stderrString += line
|
|
||||||
default:
|
|
||||||
line, _ := stdout.ReadString('\n')
|
|
||||||
if line != "" {
|
|
||||||
log.Printf("[vagrant driver] stdout: %s", line)
|
|
||||||
stdoutString += line
|
|
||||||
|
|
||||||
}
|
|
||||||
line, _ = stderr.ReadString('\n')
|
|
||||||
if line != "" {
|
|
||||||
log.Printf("[vagrant driver] stderr: %s", line)
|
|
||||||
stderrString += line
|
|
||||||
|
|
||||||
}
|
|
||||||
time.Sleep(500)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = cmd.Wait()
|
for scanOut.Scan() {
|
||||||
|
line := scanOut.Text()
|
||||||
donech <- true
|
log.Printf("[vagrant driver] stdout: %s", line)
|
||||||
|
stdoutString += line + "\n"
|
||||||
|
}
|
||||||
|
cmd.Wait()
|
||||||
|
|
||||||
if _, ok := err.(*exec.ExitError); ok {
|
if _, ok := err.(*exec.ExitError); ok {
|
||||||
err = fmt.Errorf("Vagrant error: %s", stderrString)
|
err = fmt.Errorf("Vagrant error: %s", stderrString)
|
||||||
|
|
|
@ -82,7 +82,8 @@ func (s *StepAddBox) Run(ctx context.Context, state multistep.StateBag) multiste
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Say("Adding box using vagrant box add..")
|
ui.Say("Adding box using vagrant box add ...")
|
||||||
|
ui.Message("(this can take some time if we need to download the box)")
|
||||||
addArgs := s.generateAddArgs()
|
addArgs := s.generateAddArgs()
|
||||||
|
|
||||||
log.Printf("[vagrant] Calling box add with following args %s", strings.Join(addArgs, " "))
|
log.Printf("[vagrant] Calling box add with following args %s", strings.Join(addArgs, " "))
|
||||||
|
|
Loading…
Reference in New Issue