diff --git a/common/progress.go b/common/progress.go index 6ab12dcd3..41b79a27f 100644 --- a/common/progress.go +++ b/common/progress.go @@ -3,11 +3,17 @@ package common import ( "fmt" "github.com/cheggaaa/pb" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/packer/rpc" "log" + "reflect" "time" ) +// This is the arrow from packer/ui.go -> TargetedUI.prefixLines +const targetedUIArrowText = "==>" + // 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. @@ -82,16 +88,19 @@ func calculateUiPrefixLength(ui packer.Ui) int { return recursiveCalculateUiPrefixLength(u.Ui, agg) case *packer.TargetedUI: - // A TargetedUI added the .Target and an arrow by default - const targetedArrowText = "==>" + // A TargetedUI adds the .Target and an arrow by default u := ui.(*packer.TargetedUI) - res := fmt.Sprintf("%s %s: ", targetedArrowText, u.Target) + res := fmt.Sprintf("%s %s: ", targetedUIArrowText, u.Target) return recursiveCalculateUiPrefixLength(u.Ui, agg+len(res)) case *packer.BasicUi: // The standard BasicUi appends only a newline return agg + len("\n") + // packer.rpc.Ui returns 0 here to trigger the hack described later + case *rpc.Ui: + return 0 + case *packer.MachineReadableUi: // MachineReadableUi doesn't emit anything...like at all return 0 @@ -103,12 +112,30 @@ func calculateUiPrefixLength(ui packer.Ui) int { return recursiveCalculateUiPrefixLength(ui, 0) } -func GetProgressBar(ui packer.Ui) ProgressBar { +func GetPackerConfigFromStateBag(state multistep.StateBag) *PackerConfig { + config := state.Get("config") + rConfig := reflect.Indirect(reflect.ValueOf(config)) + iPackerConfig := rConfig.FieldByName("PackerConfig").Interface() + packerConfig := iPackerConfig.(PackerConfig) + return &packerConfig +} + +func GetProgressBar(ui packer.Ui, config *PackerConfig) ProgressBar { + // Figure out the prefix length by quering the UI uiPrefixLength := calculateUiPrefixLength(ui) + + // hack to deal with packer.rpc.Ui courtesy of @Swampdragons + if _, ok := ui.(*rpc.Ui); uiPrefixLength == 0 && config != nil && ok { + res := fmt.Sprintf("%s %s: \n", targetedUIArrowText, config.PackerBuildName) + uiPrefixLength = len(res) + } + + // Now we can use the prefix length to calculate the progress bar width width := calculateProgressBarWidth(uiPrefixLength) log.Printf("ProgressBar: Using progress bar width: %d\n", width) + // Get a default progress bar and set some output defaults bar := GetDefaultProgressBar() bar.SetWidth(width) bar.Callback = func(message string) { diff --git a/common/step_download.go b/common/step_download.go index 52361b188..c55e12632 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -64,7 +64,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste 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 - bar := GetProgressBar(ui) + bar := GetProgressBar(ui, GetPackerConfigFromStateBag(state)) // First try to use any already downloaded file // 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) // Get a progress bar and hand it off to the download client - bar := GetProgressBar(ui) + bar := GetProgressBar(ui, GetPackerConfigFromStateBag(state)) // Create download client with config and progress bar download := NewDownloadClient(config, bar) diff --git a/provisioner/file/provisioner.go b/provisioner/file/provisioner.go index bda35bf31..13e2aa8e6 100644 --- a/provisioner/file/provisioner.go +++ b/provisioner/file/provisioner.go @@ -127,7 +127,7 @@ func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator) defer f.Close() // Get a default progress bar - pb := common.GetProgressBar(ui) + pb := common.GetProgressBar(ui, &p.config.PackerConfig) bar := pb.Start() defer bar.Finish() @@ -176,7 +176,7 @@ func (p *Provisioner) ProvisionUpload(ui packer.Ui, comm packer.Communicator) er } // Get a default progress bar - pb := common.GetProgressBar(ui) + pb := common.GetProgressBar(ui, &p.config.PackerConfig) bar := pb.Start() defer bar.Finish()