Moved the progress bar out of packer.Ui and unlinked it out of all the packer.Ui implementations. Split up the terminal-related functions into a separate terminal.go and calculate the progress bar width by traversing through packer.Ui to avoid the issue with github.com/ugorji/go/codec serializing private members (or unsafe pointers) of structs. Shuffled some arguments around in getConsoleScreenBufferInfo in common/terminal_windows.go so that the interface forces the user to correctly declare a _CONSOLE_SCREEN_BUFFER_INFO type.
This commit is contained in:
parent
dc2088318e
commit
5726927cba
@ -18,11 +18,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// required import for progress-bar
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/packer/packer"
|
|
||||||
)
|
|
||||||
|
|
||||||
// imports related to each Downloader implementation
|
// imports related to each Downloader implementation
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@ -86,12 +81,12 @@ func HashForType(t string) hash.Hash {
|
|||||||
|
|
||||||
// NewDownloadClient returns a new DownloadClient for the given
|
// NewDownloadClient returns a new DownloadClient for the given
|
||||||
// configuration.
|
// configuration.
|
||||||
func NewDownloadClient(c *DownloadConfig, bar packer.ProgressBar) *DownloadClient {
|
func NewDownloadClient(c *DownloadConfig, bar ProgressBar) *DownloadClient {
|
||||||
const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */
|
const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */
|
||||||
|
|
||||||
// If bar is nil, then use a dummy progress bar that doesn't do anything
|
// If bar is nil, then use a dummy progress bar that doesn't do anything
|
||||||
if bar == nil {
|
if bar == nil {
|
||||||
bar = packer.GetDummyProgressBar()
|
bar = GetDummyProgressBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create downloader map if it hasn't been specified already.
|
// Create downloader map if it hasn't been specified already.
|
||||||
@ -242,7 +237,7 @@ type HTTPDownloader struct {
|
|||||||
total uint64
|
total uint64
|
||||||
userAgent string
|
userAgent string
|
||||||
|
|
||||||
progress packer.ProgressBar
|
progress ProgressBar
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *HTTPDownloader) Cancel() {
|
func (d *HTTPDownloader) Cancel() {
|
||||||
@ -336,7 +331,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error {
|
|||||||
d.total = d.current + uint64(resp.ContentLength)
|
d.total = d.current + uint64(resp.ContentLength)
|
||||||
|
|
||||||
bar := d.progress
|
bar := d.progress
|
||||||
bar.Total = int64(d.total)
|
bar.SetTotal64(int64(d.total))
|
||||||
progressBar := bar.Start()
|
progressBar := bar.Start()
|
||||||
progressBar.Set64(int64(d.current))
|
progressBar.Set64(int64(d.current))
|
||||||
|
|
||||||
@ -379,7 +374,7 @@ type FileDownloader struct {
|
|||||||
current uint64
|
current uint64
|
||||||
total uint64
|
total uint64
|
||||||
|
|
||||||
progress packer.ProgressBar
|
progress ProgressBar
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *FileDownloader) Progress() uint64 {
|
func (d *FileDownloader) Progress() uint64 {
|
||||||
@ -471,7 +466,7 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error {
|
|||||||
d.total = uint64(fi.Size())
|
d.total = uint64(fi.Size())
|
||||||
|
|
||||||
bar := d.progress
|
bar := d.progress
|
||||||
bar.Total = int64(d.total)
|
bar.SetTotal64(int64(d.total))
|
||||||
progressBar := bar.Start()
|
progressBar := bar.Start()
|
||||||
progressBar.Set64(int64(d.current))
|
progressBar.Set64(int64(d.current))
|
||||||
|
|
||||||
@ -518,7 +513,7 @@ type SMBDownloader struct {
|
|||||||
current uint64
|
current uint64
|
||||||
total uint64
|
total uint64
|
||||||
|
|
||||||
progress packer.ProgressBar
|
progress ProgressBar
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *SMBDownloader) Progress() uint64 {
|
func (d *SMBDownloader) Progress() uint64 {
|
||||||
@ -592,7 +587,7 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error {
|
|||||||
d.total = uint64(fi.Size())
|
d.total = uint64(fi.Size())
|
||||||
|
|
||||||
bar := d.progress
|
bar := d.progress
|
||||||
bar.Total = int64(d.total)
|
bar.SetTotal64(int64(d.total))
|
||||||
progressBar := bar.Start()
|
progressBar := bar.Start()
|
||||||
progressBar.Set64(int64(d.current))
|
progressBar.Set64(int64(d.current))
|
||||||
|
|
||||||
|
@ -12,8 +12,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/cheggaaa/pb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDownloadClientVerifyChecksum(t *testing.T) {
|
func TestDownloadClientVerifyChecksum(t *testing.T) {
|
||||||
@ -38,7 +36,7 @@ func TestDownloadClientVerifyChecksum(t *testing.T) {
|
|||||||
Checksum: checksum,
|
Checksum: checksum,
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDownloadClient(config, *pb.New64(0))
|
d := NewDownloadClient(config, nil)
|
||||||
result, err := d.VerifyChecksum(tf.Name())
|
result, err := d.VerifyChecksum(tf.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Verify err: %s", err)
|
t.Fatalf("Verify err: %s", err)
|
||||||
@ -61,7 +59,7 @@ func TestDownloadClient_basic(t *testing.T) {
|
|||||||
Url: ts.URL + "/basic.txt",
|
Url: ts.URL + "/basic.txt",
|
||||||
TargetPath: tf.Name(),
|
TargetPath: tf.Name(),
|
||||||
CopyFile: true,
|
CopyFile: true,
|
||||||
}, *pb.New64(0))
|
}, nil)
|
||||||
|
|
||||||
path, err := client.Get()
|
path, err := client.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -97,7 +95,7 @@ func TestDownloadClient_checksumBad(t *testing.T) {
|
|||||||
Hash: HashForType("md5"),
|
Hash: HashForType("md5"),
|
||||||
Checksum: checksum,
|
Checksum: checksum,
|
||||||
CopyFile: true,
|
CopyFile: true,
|
||||||
}, *pb.New64(0))
|
}, nil)
|
||||||
|
|
||||||
if _, err := client.Get(); err == nil {
|
if _, err := client.Get(); err == nil {
|
||||||
t.Fatal("should error")
|
t.Fatal("should error")
|
||||||
@ -123,7 +121,7 @@ func TestDownloadClient_checksumGood(t *testing.T) {
|
|||||||
Hash: HashForType("md5"),
|
Hash: HashForType("md5"),
|
||||||
Checksum: checksum,
|
Checksum: checksum,
|
||||||
CopyFile: true,
|
CopyFile: true,
|
||||||
}, *pb.New64(0))
|
}, nil)
|
||||||
|
|
||||||
path, err := client.Get()
|
path, err := client.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -155,8 +153,7 @@ func TestDownloadClient_checksumNoDownload(t *testing.T) {
|
|||||||
Hash: HashForType("md5"),
|
Hash: HashForType("md5"),
|
||||||
Checksum: checksum,
|
Checksum: checksum,
|
||||||
CopyFile: true,
|
CopyFile: true,
|
||||||
}, *pb.New64(0))
|
}, nil)
|
||||||
|
|
||||||
path, err := client.Get()
|
path, err := client.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
@ -186,7 +183,7 @@ func TestDownloadClient_notFound(t *testing.T) {
|
|||||||
client := NewDownloadClient(&DownloadConfig{
|
client := NewDownloadClient(&DownloadConfig{
|
||||||
Url: ts.URL + "/not-found.txt",
|
Url: ts.URL + "/not-found.txt",
|
||||||
TargetPath: tf.Name(),
|
TargetPath: tf.Name(),
|
||||||
}, *pb.New64(0))
|
}, nil)
|
||||||
|
|
||||||
if _, err := client.Get(); err == nil {
|
if _, err := client.Get(); err == nil {
|
||||||
t.Fatal("should error")
|
t.Fatal("should error")
|
||||||
@ -214,7 +211,7 @@ func TestDownloadClient_resume(t *testing.T) {
|
|||||||
Url: ts.URL,
|
Url: ts.URL,
|
||||||
TargetPath: tf.Name(),
|
TargetPath: tf.Name(),
|
||||||
CopyFile: true,
|
CopyFile: true,
|
||||||
}, *pb.New64(0))
|
}, nil)
|
||||||
|
|
||||||
path, err := client.Get()
|
path, err := client.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -276,7 +273,7 @@ func TestDownloadClient_usesDefaultUserAgent(t *testing.T) {
|
|||||||
CopyFile: true,
|
CopyFile: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewDownloadClient(config, *pb.New64(0))
|
client := NewDownloadClient(config, nil)
|
||||||
_, err = client.Get()
|
_, err = client.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -309,7 +306,7 @@ func TestDownloadClient_setsUserAgent(t *testing.T) {
|
|||||||
CopyFile: true,
|
CopyFile: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewDownloadClient(config, *pb.New64(0))
|
client := NewDownloadClient(config, nil)
|
||||||
_, err = client.Get()
|
_, err = client.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -408,7 +405,7 @@ func TestDownloadFileUrl(t *testing.T) {
|
|||||||
CopyFile: false,
|
CopyFile: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewDownloadClient(config, *pb.New64(0))
|
client := NewDownloadClient(config, nil)
|
||||||
|
|
||||||
// Verify that we fail to match the checksum
|
// Verify that we fail to match the checksum
|
||||||
_, err = client.Get()
|
_, err = client.Get()
|
||||||
@ -439,7 +436,7 @@ func SimulateFileUriDownload(t *testing.T, uri string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// go go go
|
// go go go
|
||||||
client := NewDownloadClient(config, *pb.New64(0))
|
client := NewDownloadClient(config, nil)
|
||||||
path, err := client.Get()
|
path, err := client.Get()
|
||||||
|
|
||||||
// ignore any non-important checksum errors if it's not a unc path
|
// ignore any non-important checksum errors if it's not a unc path
|
||||||
|
118
common/progress.go
Normal file
118
common/progress.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/cheggaaa/pb"
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The ProgressBar interface is used for abstracting cheggaaa's progress-
|
||||||
|
// bar, or any other progress bar. If a UI does not support a progress-
|
||||||
|
// bar, then it must return a null progress bar.
|
||||||
|
const (
|
||||||
|
DefaultProgressBarWidth = 80
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProgressBar = *pb.ProgressBar
|
||||||
|
|
||||||
|
// Figure out the terminal dimensions and use it to calculate the available rendering space
|
||||||
|
func calculateProgressBarWidth(length int) int {
|
||||||
|
// If the UI's width is signed, then this is an interface that doesn't really benefit from a progress bar
|
||||||
|
if length < 0 {
|
||||||
|
log.Println("Refusing to render progress-bar for unsupported UI.")
|
||||||
|
return length
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out the terminal width if possible
|
||||||
|
width, _, err := GetTerminalDimensions()
|
||||||
|
if err != nil {
|
||||||
|
newerr := fmt.Errorf("Unable to determine terminal dimensions: %v", err)
|
||||||
|
log.Printf("Using default width (%d) for progress-bar due to error: %s", DefaultProgressBarWidth, newerr)
|
||||||
|
return DefaultProgressBarWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the terminal width is smaller than the requested length, then complain
|
||||||
|
if width < length {
|
||||||
|
newerr := fmt.Errorf("Terminal width (%d) is smaller than UI message width (%d).", width, length)
|
||||||
|
log.Printf("Using default width (%d) for progress-bar due to error: %s", DefaultProgressBarWidth, newerr)
|
||||||
|
return DefaultProgressBarWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise subtract the minimum length and return it
|
||||||
|
return width - length
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a progress bar with the default appearance
|
||||||
|
func GetDefaultProgressBar() ProgressBar {
|
||||||
|
bar := pb.New64(0)
|
||||||
|
bar.ShowPercent = true
|
||||||
|
bar.ShowCounters = true
|
||||||
|
bar.ShowSpeed = false
|
||||||
|
bar.ShowBar = true
|
||||||
|
bar.ShowTimeLeft = false
|
||||||
|
bar.ShowFinalTime = false
|
||||||
|
bar.SetUnits(pb.U_BYTES)
|
||||||
|
bar.Format("[=>-]")
|
||||||
|
bar.SetRefreshRate(1 * time.Second)
|
||||||
|
return bar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a dummy progress bar that doesn't do anything
|
||||||
|
func GetDummyProgressBar() ProgressBar {
|
||||||
|
bar := pb.New64(0)
|
||||||
|
bar.ManualUpdate = true
|
||||||
|
return bar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a packer.Ui, calculate the number of characters that a packer.Ui will
|
||||||
|
// prefix a message with. Then we can use this to calculate the progress bar's width.
|
||||||
|
func calculateUiPrefixLength(ui packer.Ui) int {
|
||||||
|
var recursiveCalculateUiPrefixLength func(packer.Ui, int) int
|
||||||
|
|
||||||
|
// Define a recursive closure that traverses through all the known packer.Ui types
|
||||||
|
// and aggregates the length of the message prefix from each particular type
|
||||||
|
recursiveCalculateUiPrefixLength = func(ui packer.Ui, agg int) int {
|
||||||
|
switch ui.(type) {
|
||||||
|
|
||||||
|
case *packer.ColoredUi:
|
||||||
|
// packer.ColoredUi is simply a wrapper around .Ui
|
||||||
|
u := ui.(*packer.ColoredUi)
|
||||||
|
return recursiveCalculateUiPrefixLength(u.Ui, agg)
|
||||||
|
|
||||||
|
case *packer.TargetedUI:
|
||||||
|
// A TargetedUI added the .Target and an arrow by default
|
||||||
|
const targetedArrowText = "==>"
|
||||||
|
u := ui.(*packer.TargetedUI)
|
||||||
|
res := fmt.Sprintf("%s %s: ", targetedArrowText, u.Target)
|
||||||
|
return recursiveCalculateUiPrefixLength(u.Ui, agg+len(res))
|
||||||
|
|
||||||
|
case *packer.BasicUi:
|
||||||
|
// The standard BasicUi appends only a newline
|
||||||
|
return agg + len("\n")
|
||||||
|
|
||||||
|
case *packer.MachineReadableUi:
|
||||||
|
// MachineReadableUi doesn't emit anything...like at all
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Calculating the message prefix length for packer.Ui type (%T) is not implemented. Using the current aggregated length of %d.", ui, agg)
|
||||||
|
return agg
|
||||||
|
}
|
||||||
|
return recursiveCalculateUiPrefixLength(ui, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProgressBar(ui packer.Ui) ProgressBar {
|
||||||
|
uiPrefixLength := calculateUiPrefixLength(ui)
|
||||||
|
width := calculateProgressBarWidth(uiPrefixLength)
|
||||||
|
|
||||||
|
log.Printf("ProgressBar: Using progress bar width: %d\n", width)
|
||||||
|
|
||||||
|
bar := GetDefaultProgressBar()
|
||||||
|
bar.SetWidth(width)
|
||||||
|
bar.Callback = func(message string) {
|
||||||
|
ui.Message(message)
|
||||||
|
}
|
||||||
|
return bar
|
||||||
|
}
|
142
common/progress_test.go
Normal file
142
common/progress_test.go
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// test packer.Ui implementation to verify that progress bar is being written
|
||||||
|
type testProgressBarUi struct {
|
||||||
|
messageCalled bool
|
||||||
|
messageMessage string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *testProgressBarUi) Say(string) {}
|
||||||
|
func (u *testProgressBarUi) Error(string) {}
|
||||||
|
func (u *testProgressBarUi) Machine(string, ...string) {}
|
||||||
|
|
||||||
|
func (u *testProgressBarUi) Ask(string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
func (u *testProgressBarUi) Message(message string) {
|
||||||
|
u.messageCalled = true
|
||||||
|
u.messageMessage = message
|
||||||
|
}
|
||||||
|
|
||||||
|
// ..and now let's begin our actual tests
|
||||||
|
func TestCalculateUiPrefixLength_Unknown(t *testing.T) {
|
||||||
|
ui := &testProgressBarUi{}
|
||||||
|
|
||||||
|
expected := 0
|
||||||
|
if res := calculateUiPrefixLength(ui); res != expected {
|
||||||
|
t.Fatalf("calculateUiPrefixLength should have returned a length of %d", expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateUiPrefixLength_BasicUi(t *testing.T) {
|
||||||
|
ui := &packer.BasicUi{}
|
||||||
|
|
||||||
|
expected := 1
|
||||||
|
if res := calculateUiPrefixLength(ui); res != expected {
|
||||||
|
t.Fatalf("calculateUiPrefixLength should have returned a length of %d", expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateUiPrefixLength_TargetedUI(t *testing.T) {
|
||||||
|
ui := &packer.TargetedUI{}
|
||||||
|
ui.Target = "TestTarget"
|
||||||
|
arrowText := "==>"
|
||||||
|
|
||||||
|
expected := len(arrowText + " " + ui.Target + ": ")
|
||||||
|
if res := calculateUiPrefixLength(ui); res != expected {
|
||||||
|
t.Fatalf("calculateUiPrefixLength should have returned a length of %d", expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateUiPrefixLength_TargetedUIWrappingBasicUi(t *testing.T) {
|
||||||
|
ui := &packer.TargetedUI{}
|
||||||
|
ui.Target = "TestTarget"
|
||||||
|
ui.Ui = &packer.BasicUi{}
|
||||||
|
arrowText := "==>"
|
||||||
|
|
||||||
|
expected := len(arrowText + " " + ui.Target + ": " + "\n")
|
||||||
|
if res := calculateUiPrefixLength(ui); res != expected {
|
||||||
|
t.Fatalf("calculateUiPrefixLength should have returned a length of %d", expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateUiPrefixLength_TargetedUIWrappingMachineUi(t *testing.T) {
|
||||||
|
ui := &packer.TargetedUI{}
|
||||||
|
ui.Target = "TestTarget"
|
||||||
|
ui.Ui = &packer.MachineReadableUi{}
|
||||||
|
|
||||||
|
expected := 0
|
||||||
|
if res := calculateUiPrefixLength(ui); res != expected {
|
||||||
|
t.Fatalf("calculateUiPrefixLength should have returned a length of %d", expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestDefaultProgressBar(t *testing.T) {
|
||||||
|
var callbackCalled bool
|
||||||
|
|
||||||
|
// Initialize the default progress bar
|
||||||
|
bar := GetDefaultProgressBar()
|
||||||
|
bar.Callback = func(state string) {
|
||||||
|
callbackCalled = true
|
||||||
|
t.Logf("TestDefaultProgressBar emitted %#v", state)
|
||||||
|
}
|
||||||
|
bar.SetTotal64(1)
|
||||||
|
|
||||||
|
// Set it off
|
||||||
|
progressBar := bar.Start()
|
||||||
|
progressBar.Set64(1)
|
||||||
|
|
||||||
|
// Check to see that the callback was hit
|
||||||
|
if !callbackCalled {
|
||||||
|
t.Fatalf("TestDefaultProgressBar.Callback should be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDummyProgressBar(t *testing.T) {
|
||||||
|
var callbackCalled bool
|
||||||
|
|
||||||
|
// Initialize the dummy progress bar
|
||||||
|
bar := GetDummyProgressBar()
|
||||||
|
bar.Callback = func(state string) {
|
||||||
|
callbackCalled = true
|
||||||
|
t.Logf("TestDummyProgressBar emitted %#v", state)
|
||||||
|
}
|
||||||
|
bar.SetTotal64(1)
|
||||||
|
|
||||||
|
// Now we can go
|
||||||
|
progressBar := bar.Start()
|
||||||
|
progressBar.Set64(1)
|
||||||
|
|
||||||
|
// Check to see that the callback was hit
|
||||||
|
if callbackCalled {
|
||||||
|
t.Fatalf("TestDummyProgressBar.Callback should not be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUiProgressBar(t *testing.T) {
|
||||||
|
|
||||||
|
ui := &testProgressBarUi{}
|
||||||
|
|
||||||
|
// Initialize the Ui progress bar
|
||||||
|
bar := GetProgressBar(ui, nil)
|
||||||
|
bar.SetTotal64(1)
|
||||||
|
|
||||||
|
// Ensure that callback has been set to something
|
||||||
|
if bar.Callback == nil {
|
||||||
|
t.Fatalf("TestUiProgressBar.Callback should be initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we can go
|
||||||
|
progressBar := bar.Start()
|
||||||
|
progressBar.Set64(1)
|
||||||
|
|
||||||
|
// Check to see that the callback was hit
|
||||||
|
if !ui.messageCalled {
|
||||||
|
t.Fatalf("TestUiProgressBar.messageCalled should be called")
|
||||||
|
}
|
||||||
|
t.Logf("TestUiProgressBar emitted %#v", ui.messageMessage)
|
||||||
|
}
|
@ -64,7 +64,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste
|
|||||||
ui.Say(fmt.Sprintf("Retrieving %s", s.Description))
|
ui.Say(fmt.Sprintf("Retrieving %s", s.Description))
|
||||||
|
|
||||||
// Get a progress bar from the ui so we can hand it off to the download client
|
// Get a progress bar from the ui so we can hand it off to the download client
|
||||||
bar := ui.GetProgressBar()
|
bar := GetProgressBar(ui)
|
||||||
|
|
||||||
// First try to use any already downloaded file
|
// First try to use any already downloaded file
|
||||||
// If it fails, proceed to regular download logic
|
// If it fails, proceed to regular download logic
|
||||||
@ -144,7 +144,7 @@ func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag
|
|||||||
ui := state.Get("ui").(packer.Ui)
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
|
||||||
// Get a progress bar and hand it off to the download client
|
// Get a progress bar and hand it off to the download client
|
||||||
bar := ui.GetProgressBar()
|
bar := GetProgressBar(ui)
|
||||||
|
|
||||||
// Create download client with config and progress bar
|
// Create download client with config and progress bar
|
||||||
download := NewDownloadClient(config, bar)
|
download := NewDownloadClient(config, bar)
|
||||||
|
6
common/terminal.go
Normal file
6
common/terminal.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
// call into one of the platform-specific implementations to get the current terminal dimensions
|
||||||
|
func GetTerminalDimensions() (width, height int, err error) {
|
||||||
|
return platformGetTerminalDimensions()
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package packer
|
package common
|
||||||
|
|
||||||
// Imports for determining terminal information across platforms
|
// Imports for determining terminal information across platforms
|
||||||
import (
|
import (
|
||||||
@ -9,7 +9,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// posix api
|
// posix api
|
||||||
func GetTerminalDimensions() (width, height int, err error) {
|
func platformGetTerminalDimensions() (width, height int, err error) {
|
||||||
|
|
||||||
|
// grab the handle to stdin
|
||||||
|
// XXX: in some cases, packer closes stdin, so the following can't be guaranteed
|
||||||
|
/*
|
||||||
|
tty := os.Stdin
|
||||||
|
*/
|
||||||
|
|
||||||
// open up a handle to the current tty
|
// open up a handle to the current tty
|
||||||
tty, err := os.Open("/dev/tty")
|
tty, err := os.Open("/dev/tty")
|
9
common/terminal_test.go
Normal file
9
common/terminal_test.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGetTerminalDimensions(t *testing.T) {
|
||||||
|
if _, _, err := GetTerminalDimensions(); err != nil {
|
||||||
|
t.Fatalf("Unable to get terminal dimensions: %s", err)
|
||||||
|
}
|
||||||
|
}
|
86
common/terminal_windows.go
Normal file
86
common/terminal_windows.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// windows constants and structures pulled from msdn
|
||||||
|
const (
|
||||||
|
_STD_INPUT_HANDLE = -10
|
||||||
|
_STD_OUTPUT_HANDLE = -11
|
||||||
|
_STD_ERROR_HANDLE = -12
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_SHORT int16
|
||||||
|
_WORD uint16
|
||||||
|
|
||||||
|
_SMALL_RECT struct {
|
||||||
|
Left, Top, Right, Bottom _SHORT
|
||||||
|
}
|
||||||
|
_COORD struct {
|
||||||
|
X, Y _SHORT
|
||||||
|
}
|
||||||
|
_CONSOLE_SCREEN_BUFFER_INFO struct {
|
||||||
|
dwSize, dwCursorPosition _COORD
|
||||||
|
wAttributes _WORD
|
||||||
|
srWindow _SMALL_RECT
|
||||||
|
dwMaximumWindowSize _COORD
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Low-level functions that call into Windows API for getting console info
|
||||||
|
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
var kernel32_GetStdHandleProc = kernel32.NewProc("GetStdHandle")
|
||||||
|
var kernel32_GetConsoleScreenBufferInfoProc = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||||
|
|
||||||
|
func kernel32_GetStdHandle(nStdHandle int32) (syscall.Handle, error) {
|
||||||
|
res, _, err := kernel32_GetStdHandleProc.Call(uintptr(nStdHandle))
|
||||||
|
if res == uintptr(syscall.InvalidHandle) {
|
||||||
|
return syscall.InvalidHandle, error(err)
|
||||||
|
}
|
||||||
|
return syscall.Handle(res), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func kernel32_GetConsoleScreenBufferInfo(hConsoleOutput syscall.Handle, info *_CONSOLE_SCREEN_BUFFER_INFO) error {
|
||||||
|
ok, _, err := kernel32_GetConsoleScreenBufferInfoProc.Call(uintptr(hConsoleOutput), uintptr(unsafe.Pointer(info)))
|
||||||
|
if int(ok) == 0 {
|
||||||
|
return error(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// windows api to get the console screen buffer info
|
||||||
|
func getConsoleScreenBufferInfo(csbi *_CONSOLE_SCREEN_BUFFER_INFO) (err error) {
|
||||||
|
var (
|
||||||
|
bi _CONSOLE_SCREEN_BUFFER_INFO
|
||||||
|
fd syscall.Handle
|
||||||
|
)
|
||||||
|
|
||||||
|
// Re-open CONOUT$ as in some instances, stdout may be closed and guaranteed an stdout
|
||||||
|
if fd, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
|
// grab the dimensions for the console
|
||||||
|
if err = kernel32_GetConsoleScreenBufferInfo(fd, &bi); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*csbi = bi
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func platformGetTerminalDimensions() (width, height int, err error) {
|
||||||
|
var csbi _CONSOLE_SCREEN_BUFFER_INFO
|
||||||
|
|
||||||
|
if err = getConsoleScreenBufferInfo(&csbi); err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(csbi.dwSize.X), int(csbi.dwSize.Y), nil
|
||||||
|
}
|
@ -60,13 +60,6 @@ func (u *Ui) Say(message string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Ui) GetProgressBar() (result packer.ProgressBar) {
|
|
||||||
if err := u.client.Call("Ui.GetProgressBar", nil, &result); err != nil {
|
|
||||||
log.Printf("Error in Ui RPC call: %s", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UiServer) Ask(query string, reply *string) (err error) {
|
func (u *UiServer) Ask(query string, reply *string) (err error) {
|
||||||
*reply, err = u.ui.Ask(query)
|
*reply, err = u.ui.Ask(query)
|
||||||
return
|
return
|
||||||
@ -98,9 +91,3 @@ func (u *UiServer) Say(message *string, reply *interface{}) error {
|
|||||||
*reply = nil
|
*reply = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UiServer) GetProgressBar(noargs *interface{}, reply *packer.ProgressBar) error {
|
|
||||||
res := u.ui.GetProgressBar()
|
|
||||||
*reply = res
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/packer/packer"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testUi struct {
|
type testUi struct {
|
||||||
askCalled bool
|
askCalled bool
|
||||||
askQuery string
|
askQuery string
|
||||||
errorCalled bool
|
errorCalled bool
|
||||||
errorMessage string
|
errorMessage string
|
||||||
machineCalled bool
|
machineCalled bool
|
||||||
machineType string
|
machineType string
|
||||||
machineArgs []string
|
machineArgs []string
|
||||||
messageCalled bool
|
messageCalled bool
|
||||||
messageMessage string
|
messageMessage string
|
||||||
sayCalled bool
|
sayCalled bool
|
||||||
sayMessage string
|
sayMessage string
|
||||||
getProgressBarCalled bool
|
|
||||||
getProgressBarValue packer.ProgressBar
|
|
||||||
progessBarCallbackWasCalled bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *testUi) Ask(query string) (string, error) {
|
func (u *testUi) Ask(query string) (string, error) {
|
||||||
@ -50,15 +46,6 @@ func (u *testUi) Say(message string) {
|
|||||||
u.sayMessage = message
|
u.sayMessage = message
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *testUi) GetProgressBar() packer.ProgressBar {
|
|
||||||
u.getProgressBarCalled = true
|
|
||||||
u.getProgressBarValue = packer.GetDummyProgressBar()
|
|
||||||
u.getProgressBarValue.Callback = func(string) {
|
|
||||||
u.progessBarCallbackWasCalled = true
|
|
||||||
}
|
|
||||||
return u.getProgressBarValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUiRPC(t *testing.T) {
|
func TestUiRPC(t *testing.T) {
|
||||||
// Create the UI to test
|
// Create the UI to test
|
||||||
ui := new(testUi)
|
ui := new(testUi)
|
||||||
@ -106,19 +93,6 @@ func TestUiRPC(t *testing.T) {
|
|||||||
t.Fatal("machine should be called")
|
t.Fatal("machine should be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
bar := uiClient.GetProgressBar()
|
|
||||||
if !ui.getProgressBarCalled {
|
|
||||||
t.Fatal("getprogressbar should be called")
|
|
||||||
}
|
|
||||||
|
|
||||||
if bar.Callback == nil {
|
|
||||||
t.Fatal("getprogressbar returned a bar with an empty callback")
|
|
||||||
}
|
|
||||||
bar.Callback("test")
|
|
||||||
if !ui.progessBarCallbackWasCalled {
|
|
||||||
t.Fatal("progressbarcallback should be called")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ui.machineType != "foo" {
|
if ui.machineType != "foo" {
|
||||||
t.Fatalf("bad type: %#v", ui.machineType)
|
t.Fatalf("bad type: %#v", ui.machineType)
|
||||||
}
|
}
|
||||||
|
92
packer/ui.go
92
packer/ui.go
@ -15,8 +15,6 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/cheggaaa/pb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type UiColor uint
|
type UiColor uint
|
||||||
@ -30,15 +28,6 @@ const (
|
|||||||
UiColorCyan = 36
|
UiColorCyan = 36
|
||||||
)
|
)
|
||||||
|
|
||||||
// The ProgressBar interface is used for abstracting cheggaaa's progress-
|
|
||||||
// bar, or any other progress bar. If a UI does not support a progress-
|
|
||||||
// bar, then it must return a null progress bar.
|
|
||||||
const (
|
|
||||||
DefaultProgressBarWidth = 80
|
|
||||||
)
|
|
||||||
|
|
||||||
type ProgressBar = *pb.ProgressBar
|
|
||||||
|
|
||||||
// The Ui interface handles all communication for Packer with the outside
|
// The Ui interface handles all communication for Packer with the outside
|
||||||
// world. This sort of control allows us to strictly control how output
|
// world. This sort of control allows us to strictly control how output
|
||||||
// is formatted and various levels of output.
|
// is formatted and various levels of output.
|
||||||
@ -48,7 +37,6 @@ type Ui interface {
|
|||||||
Message(string)
|
Message(string)
|
||||||
Error(string)
|
Error(string)
|
||||||
Machine(string, ...string)
|
Machine(string, ...string)
|
||||||
GetProgressBar() ProgressBar
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColoredUi is a UI that is colored using terminal colors.
|
// ColoredUi is a UI that is colored using terminal colors.
|
||||||
@ -144,11 +132,6 @@ func (u *ColoredUi) supportsColors() bool {
|
|||||||
return cygwin
|
return cygwin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ColoredUi) GetProgressBar() ProgressBar {
|
|
||||||
log.Printf("ColoredUi: Using wrapped UI for progress bar.\n")
|
|
||||||
return u.Ui.GetProgressBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *TargetedUI) Ask(query string) (string, error) {
|
func (u *TargetedUI) Ask(query string) (string, error) {
|
||||||
return u.Ui.Ask(u.prefixLines(true, query))
|
return u.Ui.Ask(u.prefixLines(true, query))
|
||||||
}
|
}
|
||||||
@ -185,11 +168,6 @@ func (u *TargetedUI) prefixLines(arrow bool, message string) string {
|
|||||||
return strings.TrimRightFunc(result.String(), unicode.IsSpace)
|
return strings.TrimRightFunc(result.String(), unicode.IsSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *TargetedUI) GetProgressBar() ProgressBar {
|
|
||||||
log.Printf("TargetedUI: Using wrapped UI for progress bar.\n")
|
|
||||||
return u.Ui.GetProgressBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rw *BasicUi) Ask(query string) (string, error) {
|
func (rw *BasicUi) Ask(query string) (string, error) {
|
||||||
rw.l.Lock()
|
rw.l.Lock()
|
||||||
defer rw.l.Unlock()
|
defer rw.l.Unlock()
|
||||||
@ -282,23 +260,6 @@ func (rw *BasicUi) Machine(t string, args ...string) {
|
|||||||
log.Printf("machine readable: %s %#v", t, args)
|
log.Printf("machine readable: %s %#v", t, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rw *BasicUi) GetProgressBar() ProgressBar {
|
|
||||||
width := calculateProgressBarWidth(0)
|
|
||||||
|
|
||||||
log.Printf("BasicUi: Using progress bar width: %d\n", width)
|
|
||||||
|
|
||||||
bar := GetDefaultProgressBar()
|
|
||||||
bar.SetWidth(width)
|
|
||||||
bar.Callback = func(message string) {
|
|
||||||
rw.l.Lock()
|
|
||||||
defer rw.l.Unlock()
|
|
||||||
|
|
||||||
// Discard the error here so we don't emit an error everytime the progress-bar fails to update
|
|
||||||
fmt.Fprint(rw.Writer, message)
|
|
||||||
}
|
|
||||||
return bar
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *MachineReadableUi) Ask(query string) (string, error) {
|
func (u *MachineReadableUi) Ask(query string) (string, error) {
|
||||||
return "", errors.New("machine-readable UI can't ask")
|
return "", errors.New("machine-readable UI can't ask")
|
||||||
}
|
}
|
||||||
@ -344,56 +305,3 @@ func (u *MachineReadableUi) Machine(category string, args ...string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *MachineReadableUi) GetProgressBar() ProgressBar {
|
|
||||||
log.Printf("MachineReadableUi: Using dummy progress bar.\n")
|
|
||||||
bar := GetDummyProgressBar()
|
|
||||||
return bar
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a dummy progress bar that doesn't do anything
|
|
||||||
func GetDummyProgressBar() *pb.ProgressBar {
|
|
||||||
return pb.New64(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a progress bar with the default appearance
|
|
||||||
func GetDefaultProgressBar() *pb.ProgressBar {
|
|
||||||
bar := pb.New64(0)
|
|
||||||
bar.ShowPercent = true
|
|
||||||
bar.ShowCounters = true
|
|
||||||
bar.ShowSpeed = false
|
|
||||||
bar.ShowBar = true
|
|
||||||
bar.ShowTimeLeft = false
|
|
||||||
bar.ShowFinalTime = false
|
|
||||||
bar.SetUnits(pb.U_BYTES)
|
|
||||||
bar.Format("[=>-]")
|
|
||||||
bar.SetRefreshRate(1 * time.Second)
|
|
||||||
return bar
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out the terminal dimensions and use it to calculate the available rendering space
|
|
||||||
func calculateProgressBarWidth(length int) int {
|
|
||||||
// If the UI's width is signed, then this is an interface that doesn't really benefit from a progress bar
|
|
||||||
if length < 0 {
|
|
||||||
log.Println("Refusing to render progress-bar for unsupported UI.")
|
|
||||||
return length
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out the terminal width if possible
|
|
||||||
width, _, err := GetTerminalDimensions()
|
|
||||||
if err != nil {
|
|
||||||
newerr := fmt.Errorf("Unable to determine terminal dimensions: %v", err)
|
|
||||||
log.Printf("Using default width (%d) for progress-bar due to error: %s", DefaultProgressBarWidth, newerr)
|
|
||||||
return DefaultProgressBarWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the terminal width is smaller than the requested length, then complain
|
|
||||||
if width < length {
|
|
||||||
newerr := fmt.Errorf("Terminal width (%d) is smaller than UI message width (%d).", width, length)
|
|
||||||
log.Printf("Using default width (%d) for progress-bar due to error: %s", DefaultProgressBarWidth, newerr)
|
|
||||||
return DefaultProgressBarWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise subtract the minimum length and return it
|
|
||||||
return width - length
|
|
||||||
}
|
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
// +build windows
|
|
||||||
|
|
||||||
package packer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// windows constants and structures pulled from msdn
|
|
||||||
const (
|
|
||||||
STD_INPUT_HANDLE = -10
|
|
||||||
STD_OUTPUT_HANDLE = -11
|
|
||||||
STD_ERROR_HANDLE = -12
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
SHORT int16
|
|
||||||
WORD uint16
|
|
||||||
|
|
||||||
SMALL_RECT struct {
|
|
||||||
Left, Top, Right, Bottom SHORT
|
|
||||||
}
|
|
||||||
COORD struct {
|
|
||||||
X, Y SHORT
|
|
||||||
}
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO struct {
|
|
||||||
dwSize, dwCursorPosition COORD
|
|
||||||
wAttributes WORD
|
|
||||||
srWindow SMALL_RECT
|
|
||||||
dwMaximumWindowSize COORD
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Low-level functions that call into Windows API for getting console info
|
|
||||||
var KERNEL32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
var KERNEL32_GetStdHandleProc = KERNEL32.NewProc("GetStdHandle")
|
|
||||||
var KERNEL32_GetConsoleScreenBufferInfoProc = KERNEL32.NewProc("GetConsoleScreenBufferInfo")
|
|
||||||
|
|
||||||
func KERNEL32_GetStdHandle(nStdHandle int32) (syscall.Handle, error) {
|
|
||||||
res, _, err := KERNEL32_GetStdHandleProc.Call(uintptr(nStdHandle))
|
|
||||||
if res == uintptr(syscall.InvalidHandle) {
|
|
||||||
return syscall.InvalidHandle, error(err)
|
|
||||||
}
|
|
||||||
return syscall.Handle(res), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func KERNEL32_GetConsoleScreenBufferInfo(hConsoleOutput syscall.Handle, info *CONSOLE_SCREEN_BUFFER_INFO) error {
|
|
||||||
ok, _, err := KERNEL32_GetConsoleScreenBufferInfoProc.Call(uintptr(hConsoleOutput), uintptr(unsafe.Pointer(info)))
|
|
||||||
if int(ok) == 0 {
|
|
||||||
return error(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// windows api
|
|
||||||
func GetTerminalDimensions() (width, height int, err error) {
|
|
||||||
var (
|
|
||||||
fd syscall.Handle
|
|
||||||
csbi CONSOLE_SCREEN_BUFFER_INFO
|
|
||||||
)
|
|
||||||
|
|
||||||
// grab the handle for stdout
|
|
||||||
/*
|
|
||||||
if fd, err = KERNEL32_GetStdHandle(STD_OUTPUT_HANDLE); err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if fd, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0); err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
defer syscall.Close(fd)
|
|
||||||
|
|
||||||
// grab the dimensions for the console
|
|
||||||
if err = KERNEL32_GetConsoleScreenBufferInfo(fd, &csbi); err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// whee...
|
|
||||||
return int(csbi.dwSize.X), int(csbi.dwSize.Y), nil
|
|
||||||
}
|
|
@ -1,7 +1,5 @@
|
|||||||
package ansiblelocal
|
package ansiblelocal
|
||||||
|
|
||||||
import "github.com/hashicorp/packer/packer"
|
|
||||||
|
|
||||||
type uiStub struct{}
|
type uiStub struct{}
|
||||||
|
|
||||||
func (su *uiStub) Ask(string) (string, error) {
|
func (su *uiStub) Ask(string) (string, error) {
|
||||||
@ -15,6 +13,3 @@ func (su *uiStub) Machine(string, ...string) {}
|
|||||||
func (su *uiStub) Message(string) {}
|
func (su *uiStub) Message(string) {}
|
||||||
|
|
||||||
func (su *uiStub) Say(msg string) {}
|
func (su *uiStub) Say(msg string) {}
|
||||||
func (su *uiStub) GetProcessBar() packer.ProgressBar {
|
|
||||||
return packer.GetDummyProgressBar()
|
|
||||||
}
|
|
||||||
|
@ -123,10 +123,6 @@ func (u *ui) Machine(s1 string, s2 ...string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) GetProgressBar() packer.ProgressBar {
|
|
||||||
return packer.GetDummyProgressBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
type communicator struct{}
|
type communicator struct{}
|
||||||
|
|
||||||
func (c communicator) Start(*packer.RemoteCmd) error {
|
func (c communicator) Start(*packer.RemoteCmd) error {
|
||||||
|
@ -599,7 +599,3 @@ func (ui *Ui) Machine(t string, args ...string) {
|
|||||||
ui.ui.Machine(t, args...)
|
ui.ui.Machine(t, args...)
|
||||||
<-ui.sem
|
<-ui.sem
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *Ui) GetProgressBar() packer.ProgressBar {
|
|
||||||
return packer.GetDummyProgressBar()
|
|
||||||
}
|
|
||||||
|
@ -127,7 +127,7 @@ func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator)
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
// Get a default progress bar
|
// Get a default progress bar
|
||||||
pb := ui.GetProgressBar()
|
pb := common.GetProgressBar(ui)
|
||||||
bar := pb.Start()
|
bar := pb.Start()
|
||||||
defer bar.Finish()
|
defer bar.Finish()
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ func (p *Provisioner) ProvisionUpload(ui packer.Ui, comm packer.Communicator) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get a default progress bar
|
// Get a default progress bar
|
||||||
pb := ui.GetProgressBar()
|
pb := common.GetProgressBar(ui)
|
||||||
bar := pb.Start()
|
bar := pb.Start()
|
||||||
defer bar.Finish()
|
defer bar.Finish()
|
||||||
|
|
||||||
|
@ -120,10 +120,6 @@ func (su *stubUi) Say(msg string) {
|
|||||||
su.sayMessages += msg
|
su.sayMessages += msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (su *stubUi) GetProgressBar() packer.ProgressBar {
|
|
||||||
return packer.GetDummyProgressBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestProvisionerProvision_SendsFile(t *testing.T) {
|
func TestProvisionerProvision_SendsFile(t *testing.T) {
|
||||||
var p Provisioner
|
var p Provisioner
|
||||||
tf, err := ioutil.TempFile("", "packer")
|
tf, err := ioutil.TempFile("", "packer")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user