command: show periodic messages about continued ops
This commit is contained in:
parent
ab14b3ad00
commit
284bc92c04
|
@ -7,6 +7,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
@ -14,6 +15,8 @@ import (
|
||||||
"github.com/mitchellh/colorstring"
|
"github.com/mitchellh/colorstring"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const periodicUiTimer = 10 * time.Second
|
||||||
|
|
||||||
type UiHook struct {
|
type UiHook struct {
|
||||||
terraform.NilHook
|
terraform.NilHook
|
||||||
|
|
||||||
|
@ -22,10 +25,17 @@ type UiHook struct {
|
||||||
|
|
||||||
l sync.Mutex
|
l sync.Mutex
|
||||||
once sync.Once
|
once sync.Once
|
||||||
resources map[string]uiResourceOp
|
resources map[string]uiResourceState
|
||||||
ui cli.Ui
|
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
|
type uiResourceOp byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -51,7 +61,10 @@ func (h *UiHook) PreApply(
|
||||||
}
|
}
|
||||||
|
|
||||||
h.l.Lock()
|
h.l.Lock()
|
||||||
h.resources[id] = op
|
h.resources[id] = uiResourceState{
|
||||||
|
Op: op,
|
||||||
|
Start: time.Now().Round(time.Second),
|
||||||
|
}
|
||||||
h.l.Unlock()
|
h.l.Unlock()
|
||||||
|
|
||||||
var operation string
|
var operation string
|
||||||
|
@ -113,9 +126,46 @@ func (h *UiHook) PreApply(
|
||||||
operation,
|
operation,
|
||||||
attrString)))
|
attrString)))
|
||||||
|
|
||||||
|
// Set a timer to show an operation is still happening
|
||||||
|
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id) })
|
||||||
|
|
||||||
return terraform.HookActionContinue, nil
|
return terraform.HookActionContinue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *UiHook) stillApplying(id string) {
|
||||||
|
// Grab the operation
|
||||||
|
h.l.Lock()
|
||||||
|
state, ok := h.resources[id]
|
||||||
|
h.l.Unlock()
|
||||||
|
|
||||||
|
// 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(
|
func (h *UiHook) PostApply(
|
||||||
n *terraform.InstanceInfo,
|
n *terraform.InstanceInfo,
|
||||||
s *terraform.InstanceState,
|
s *terraform.InstanceState,
|
||||||
|
@ -123,12 +173,12 @@ func (h *UiHook) PostApply(
|
||||||
id := n.HumanId()
|
id := n.HumanId()
|
||||||
|
|
||||||
h.l.Lock()
|
h.l.Lock()
|
||||||
op := h.resources[id]
|
state := h.resources[id]
|
||||||
delete(h.resources, id)
|
delete(h.resources, id)
|
||||||
h.l.Unlock()
|
h.l.Unlock()
|
||||||
|
|
||||||
var msg string
|
var msg string
|
||||||
switch op {
|
switch state.Op {
|
||||||
case uiResourceModify:
|
case uiResourceModify:
|
||||||
msg = "Modifications complete"
|
msg = "Modifications complete"
|
||||||
case uiResourceDestroy:
|
case uiResourceDestroy:
|
||||||
|
@ -205,7 +255,7 @@ func (h *UiHook) init() {
|
||||||
panic("colorize not given")
|
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
|
// Wrap the ui so that it is safe for concurrency regardless of the
|
||||||
// underlying reader/writer that is in place.
|
// underlying reader/writer that is in place.
|
||||||
|
|
Loading…
Reference in New Issue