WIP
This commit is contained in:
parent
08283f077b
commit
17c9a403f2
|
@ -4,6 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -50,6 +51,7 @@ func (h *UiHook) PreApply(
|
||||||
n *terraform.InstanceInfo,
|
n *terraform.InstanceInfo,
|
||||||
s *terraform.InstanceState,
|
s *terraform.InstanceState,
|
||||||
d *terraform.InstanceDiff) (terraform.HookAction, error) {
|
d *terraform.InstanceDiff) (terraform.HookAction, error) {
|
||||||
|
log.Printf("[DEBUG] PreApply arguments:\n%#v\n%#v\n%#v", n, s, d)
|
||||||
h.once.Do(h.init)
|
h.once.Do(h.init)
|
||||||
|
|
||||||
id := n.HumanId()
|
id := n.HumanId()
|
||||||
|
@ -129,9 +131,8 @@ func (h *UiHook) PreApply(
|
||||||
attrString = "\n " + attrString
|
attrString = "\n " + attrString
|
||||||
}
|
}
|
||||||
|
|
||||||
var stateId, stateIdSuffix string
|
var stateIdSuffix string
|
||||||
if s != nil && s.ID != "" {
|
if s != nil && s.ID != "" {
|
||||||
stateId = s.ID
|
|
||||||
stateIdSuffix = fmt.Sprintf(" (ID: %s)", truncateId(s.ID, maxIdLen))
|
stateIdSuffix = fmt.Sprintf(" (ID: %s)", truncateId(s.ID, maxIdLen))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,12 +144,12 @@ func (h *UiHook) PreApply(
|
||||||
attrString)))
|
attrString)))
|
||||||
|
|
||||||
// Set a timer to show an operation is still happening
|
// Set a timer to show an operation is still happening
|
||||||
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id, stateId) })
|
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id, s) })
|
||||||
|
|
||||||
return terraform.HookActionContinue, nil
|
return terraform.HookActionContinue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UiHook) stillApplying(id, stateId string) {
|
func (h *UiHook) stillApplying(id string, s *terraform.InstanceState) {
|
||||||
// Grab the operation. We defer the lock here to avoid the "still..."
|
// Grab the operation. We defer the lock here to avoid the "still..."
|
||||||
// message showing up after a completion message.
|
// message showing up after a completion message.
|
||||||
h.l.Lock()
|
h.l.Lock()
|
||||||
|
@ -173,8 +174,8 @@ func (h *UiHook) stillApplying(id, stateId string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var stateIdSuffix string
|
var stateIdSuffix string
|
||||||
if stateId != "" {
|
if s != nil && s.ID != "" {
|
||||||
stateIdSuffix = fmt.Sprintf("ID: %s, ", truncateId(stateId, maxIdLen))
|
stateIdSuffix = fmt.Sprintf("ID: %s, ", truncateId(s.ID, maxIdLen))
|
||||||
}
|
}
|
||||||
|
|
||||||
h.ui.Output(h.Colorize.Color(fmt.Sprintf(
|
h.ui.Output(h.Colorize.Color(fmt.Sprintf(
|
||||||
|
@ -186,13 +187,15 @@ func (h *UiHook) stillApplying(id, stateId string) {
|
||||||
)))
|
)))
|
||||||
|
|
||||||
// Reschedule
|
// Reschedule
|
||||||
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id, stateId) })
|
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id, s) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UiHook) PostApply(
|
func (h *UiHook) PostApply(
|
||||||
n *terraform.InstanceInfo,
|
n *terraform.InstanceInfo,
|
||||||
s *terraform.InstanceState,
|
s *terraform.InstanceState,
|
||||||
applyerr error) (terraform.HookAction, error) {
|
applyerr error) (terraform.HookAction, error) {
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] PostApply arguments:\n%#v\n%#v\n%#v", n, s, applyerr)
|
||||||
id := n.HumanId()
|
id := n.HumanId()
|
||||||
|
|
||||||
h.l.Lock()
|
h.l.Lock()
|
||||||
|
@ -221,10 +224,13 @@ func (h *UiHook) PostApply(
|
||||||
// Errors are collected and printed in ApplyCommand, no need to duplicate
|
// Errors are collected and printed in ApplyCommand, no need to duplicate
|
||||||
return terraform.HookActionContinue, nil
|
return terraform.HookActionContinue, nil
|
||||||
}
|
}
|
||||||
|
log.Printf("[DEBUG] Printing out output: %#v", msg)
|
||||||
|
|
||||||
h.ui.Output(h.Colorize.Color(fmt.Sprintf(
|
colorized := h.Colorize.Color(fmt.Sprintf(
|
||||||
"[reset][bold]%s: %s%s[reset]",
|
"[reset][bold]%s: %s%s[reset]",
|
||||||
id, msg, stateIdSuffix)))
|
id, msg, stateIdSuffix))
|
||||||
|
|
||||||
|
h.ui.Output(colorized)
|
||||||
|
|
||||||
return terraform.HookActionContinue, nil
|
return terraform.HookActionContinue, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,72 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
"github.com/mitchellh/cli"
|
||||||
|
"github.com/mitchellh/colorstring"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestUiHookPostApply_emptyState(t *testing.T) {
|
||||||
|
colorize := &colorstring.Colorize{
|
||||||
|
Colors: colorstring.DefaultColors,
|
||||||
|
Disable: true,
|
||||||
|
Reset: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
ir := bytes.NewReader([]byte{})
|
||||||
|
errBuf := bytes.NewBuffer([]byte{})
|
||||||
|
outBuf := bytes.NewBuffer([]byte{})
|
||||||
|
ui := cli.MockUi{
|
||||||
|
InputReader: ir,
|
||||||
|
ErrorWriter: errBuf,
|
||||||
|
OutputWriter: outBuf,
|
||||||
|
}
|
||||||
|
h := &UiHook{
|
||||||
|
Colorize: colorize,
|
||||||
|
Ui: &ui,
|
||||||
|
}
|
||||||
|
h.init()
|
||||||
|
h.resources = map[string]uiResourceState{
|
||||||
|
"data.google_compute_zones.available": uiResourceState{
|
||||||
|
Op: uiResourceDestroy,
|
||||||
|
Start: time.Now(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mock := &terraform.MockInstanceInfo{
|
||||||
|
terraform.InstanceInfo{
|
||||||
|
Id: "data.google_compute_zones.available",
|
||||||
|
ModulePath: []string{"root"},
|
||||||
|
Type: "google_compute_zones",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
n := mock.WithUniqueExtra("destroy")
|
||||||
|
action, err := h.PostApply(n, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if action != terraform.HookActionContinue {
|
||||||
|
t.Fatal("Expected hook to continue, given: %#v", action)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := ""
|
||||||
|
output := outBuf.String()
|
||||||
|
if output != expectedOutput {
|
||||||
|
t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedErrOutput := ""
|
||||||
|
errOutput := errBuf.String()
|
||||||
|
if errOutput != expectedErrOutput {
|
||||||
|
t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTruncateId(t *testing.T) {
|
func TestTruncateId(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Input string
|
Input string
|
||||||
|
|
|
@ -72,6 +72,19 @@ type InstanceInfo struct {
|
||||||
uniqueExtra string
|
uniqueExtra string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MockInstanceInfo struct {
|
||||||
|
InstanceInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockInstanceInfo) WithUniqueExtra(extra string) *InstanceInfo {
|
||||||
|
return &InstanceInfo{
|
||||||
|
Id: m.Id,
|
||||||
|
ModulePath: m.ModulePath,
|
||||||
|
Type: m.Type,
|
||||||
|
uniqueExtra: extra,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HumanId is a unique Id that is human-friendly and useful for UI elements.
|
// HumanId is a unique Id that is human-friendly and useful for UI elements.
|
||||||
func (i *InstanceInfo) HumanId() string {
|
func (i *InstanceInfo) HumanId() string {
|
||||||
if i == nil {
|
if i == nil {
|
||||||
|
|
Loading…
Reference in New Issue