diff --git a/go.mod b/go.mod index 6596057fc..70b4756db 100644 --- a/go.mod +++ b/go.mod @@ -96,6 +96,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-testing-interface v1.0.3 // indirect github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed + github.com/mitchellh/gox v1.0.1 // indirect github.com/mitchellh/iochan v1.0.0 github.com/mitchellh/mapstructure v1.2.3 github.com/mitchellh/panicwrap v0.0.0-20170106182340-fce601fe5557 diff --git a/go.sum b/go.sum index a4452f1e7..e64fc9fbf 100644 --- a/go.sum +++ b/go.sum @@ -351,6 +351,7 @@ github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1 github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= @@ -487,6 +488,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI= +github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= diff --git a/main.go b/main.go index 8d4c5ee38..6fb8c7c7b 100644 --- a/main.go +++ b/main.go @@ -196,6 +196,7 @@ func wrappedMain() int { Reader: os.Stdin, Writer: os.Stdout, ErrorWriter: os.Stdout, + PB: &packer.UiProgressBar{}, } ui = basicUi if !inPlugin { @@ -207,8 +208,10 @@ func wrappedMain() int { } if backgrounded { fmt.Fprint(os.Stderr, "Running in background, not using a TTY\n") + basicUi.PB = &packer.NoopProgressTracker{} } else if TTY, err := openTTY(); err != nil { fmt.Fprintf(os.Stderr, "No tty available: %s\n", err) + basicUi.PB = &packer.NoopProgressTracker{} } else { basicUi.TTY = TTY defer TTY.Close() diff --git a/packer/progressbar.go b/packer/progressbar.go index 3328ca9ce..fedc163a7 100644 --- a/packer/progressbar.go +++ b/packer/progressbar.go @@ -15,26 +15,28 @@ func ProgressBarConfig(bar *pb.ProgressBar, prefix string) { bar.Prefix(prefix) } -var defaultUiProgressBar = &uiProgressBar{} +var defaultUiProgressBar = &UiProgressBar{} -// uiProgressBar is a self managed progress bar singleton. -// decorate your struct with a *uiProgressBar to +// UiProgressBar is a self managed progress bar singleton. +// decorate your struct with a *UiProgressBar to // give it TrackProgress capabilities. -// In TrackProgress if uiProgressBar is nil +// In TrackProgress if UiProgressBar is nil // defaultUiProgressBar will be used as // the progress bar. -type uiProgressBar struct { +type UiProgressBar struct { + Noop bool lock sync.Mutex - pool *pb.Pool - - pbs int + pbs int } -func (p *uiProgressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser { +func (p *UiProgressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser { if p == nil { return defaultUiProgressBar.TrackProgress(src, currentSize, totalSize, stream) } + if p.Noop { + return stream + } p.lock.Lock() defer p.lock.Unlock() diff --git a/packer/progressbar_solaris.go b/packer/progressbar_solaris.go index 75b40ad06..868037c38 100644 --- a/packer/progressbar_solaris.go +++ b/packer/progressbar_solaris.go @@ -1,3 +1,3 @@ package packer -type uiProgressBar = NoopProgressTracker +type UiProgressBar = NoopProgressTracker diff --git a/packer/progressbar_test.go b/packer/progressbar_test.go index 5039c48a9..40928d273 100644 --- a/packer/progressbar_test.go +++ b/packer/progressbar_test.go @@ -11,7 +11,7 @@ import ( // The following tests rarelly just happen. So we run them 100 times. func TestProgressTracking_open_close(t *testing.T) { - var bar *uiProgressBar + var bar *UiProgressBar tracker := bar.TrackProgress("1,", 1, 42, ioutil.NopCloser(nil)) tracker.Close() @@ -21,7 +21,7 @@ func TestProgressTracking_open_close(t *testing.T) { } func TestProgressTracking_multi_open_close(t *testing.T) { - var bar *uiProgressBar + var bar *UiProgressBar g := errgroup.Group{} for i := 0; i < 100; i++ { @@ -36,7 +36,7 @@ func TestProgressTracking_multi_open_close(t *testing.T) { } func TestProgressTracking_races(t *testing.T) { - var bar *uiProgressBar + var bar *UiProgressBar g := errgroup.Group{} for i := 0; i < 100; i++ { diff --git a/packer/ui.go b/packer/ui.go index 5d8cb89ed..46bfbf235 100644 --- a/packer/ui.go +++ b/packer/ui.go @@ -40,11 +40,12 @@ type Ui interface { Message(string) Error(string) Machine(string, ...string) + // TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) getter.ProgressTracker } type NoopUi struct { - NoopProgressTracker + PB NoopProgressTracker } var _ Ui = new(NoopUi) @@ -54,13 +55,16 @@ func (*NoopUi) Say(string) { return } func (*NoopUi) Message(string) { return } func (*NoopUi) Error(string) { return } func (*NoopUi) Machine(string, ...string) { return } +func (u *NoopUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser { + return u.PB.TrackProgress(src, currentSize, totalSize, stream) +} // ColoredUi is a UI that is colored using terminal colors. type ColoredUi struct { Color UiColor ErrorColor UiColor Ui Ui - *uiProgressBar + PB getter.ProgressTracker } var _ Ui = new(ColoredUi) @@ -189,7 +193,7 @@ type BasicUi struct { l sync.Mutex interrupted bool TTY TTY - *uiProgressBar + PB getter.ProgressTracker } var _ Ui = new(BasicUi) @@ -304,11 +308,15 @@ func (rw *BasicUi) Machine(t string, args ...string) { log.Printf("machine readable: %s %#v", t, args) } +func (rw *BasicUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) { + return rw.PB.TrackProgress(src, currentSize, totalSize, stream) +} + // MachineReadableUi is a UI that only outputs machine-readable output // to the given Writer. type MachineReadableUi struct { Writer io.Writer - NoopProgressTracker + PB NoopProgressTracker } var _ Ui = new(MachineReadableUi) @@ -366,11 +374,15 @@ func (u *MachineReadableUi) Machine(category string, args ...string) { log.Printf("%d,%s,%s,%s\n", now.Unix(), target, category, argsString) } +func (u *MachineReadableUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) { + return u.PB.TrackProgress(src, currentSize, totalSize, stream) +} + // TimestampedUi is a UI that wraps another UI implementation and // prefixes each message with an RFC3339 timestamp type TimestampedUi struct { Ui Ui - *uiProgressBar + PB getter.ProgressTracker } var _ Ui = new(TimestampedUi) @@ -395,6 +407,10 @@ func (u *TimestampedUi) Machine(message string, args ...string) { u.Ui.Machine(message, args...) } +func (u *TimestampedUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) { + return u.Ui.TrackProgress(src, currentSize, totalSize, stream) +} + func (u *TimestampedUi) timestampLine(string string) string { return fmt.Sprintf("%v: %v", time.Now().Format(time.RFC3339), string) } @@ -404,7 +420,7 @@ func (u *TimestampedUi) timestampLine(string string) string { type SafeUi struct { Sem chan int Ui Ui - *uiProgressBar + PB getter.ProgressTracker } var _ Ui = new(SafeUi) @@ -440,3 +456,11 @@ func (u *SafeUi) Machine(t string, args ...string) { u.Ui.Machine(t, args...) <-u.Sem } + +func (u *SafeUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) { + u.Sem <- 1 + ret := u.Ui.TrackProgress(src, currentSize, totalSize, stream) + <-u.Sem + + return ret +}