Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

command: show periodic messages about continued ops #6163

Merged
merged 2 commits into from
Apr 13, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions command/hook_ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import (
"sort"
"strings"
"sync"
"time"
"unicode"

"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli"
"github.com/mitchellh/colorstring"
)

const periodicUiTimer = 10 * time.Second

type UiHook struct {
terraform.NilHook

Expand All @@ -22,10 +25,17 @@ type UiHook struct {

l sync.Mutex
once sync.Once
resources map[string]uiResourceOp
resources map[string]uiResourceState
ui cli.Ui
}

// uiResourceState tracks the state of a single resource
type uiResourceState struct {
Op uiResourceOp
Start time.Time
}

// uiResourceOp is an enum for operations on a resource
type uiResourceOp byte

const (
Expand All @@ -51,7 +61,10 @@ func (h *UiHook) PreApply(
}

h.l.Lock()
h.resources[id] = op
h.resources[id] = uiResourceState{
Op: op,
Start: time.Now().Round(time.Second),
}
h.l.Unlock()

var operation string
Expand Down Expand Up @@ -113,22 +126,60 @@ func (h *UiHook) PreApply(
operation,
attrString)))

// Set a timer to show an operation is still happening
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id) })

return terraform.HookActionContinue, nil
}

func (h *UiHook) stillApplying(id string) {
// Grab the operation. We defer the lock here to avoid the "still..."
// message showing up after a completion message.
h.l.Lock()
defer h.l.Unlock()
state, ok := h.resources[id]

// If the resource is out of the map it means we're done with it
if !ok {
return
}

var msg string
switch state.Op {
case uiResourceModify:
msg = "Still modifying..."
case uiResourceDestroy:
msg = "Still destroying..."
case uiResourceCreate:
msg = "Still creating..."
case uiResourceUnknown:
return
}

h.ui.Output(h.Colorize.Color(fmt.Sprintf(
"[reset][bold]%s: %s (%s elapsed)[reset_bold]",
id,
msg,
time.Now().Round(time.Second).Sub(state.Start),
)))

// Reschedule
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id) })
}

func (h *UiHook) PostApply(
n *terraform.InstanceInfo,
s *terraform.InstanceState,
applyerr error) (terraform.HookAction, error) {
id := n.HumanId()

h.l.Lock()
op := h.resources[id]
state := h.resources[id]
delete(h.resources, id)
h.l.Unlock()

var msg string
switch op {
switch state.Op {
case uiResourceModify:
msg = "Modifications complete"
case uiResourceDestroy:
Expand Down Expand Up @@ -205,7 +256,7 @@ func (h *UiHook) init() {
panic("colorize not given")
}

h.resources = make(map[string]uiResourceOp)
h.resources = make(map[string]uiResourceState)

// Wrap the ui so that it is safe for concurrency regardless of the
// underlying reader/writer that is in place.
Expand Down