terraform: no longer require uiOutput, do it auto in Hook

This commit is contained in:
Mitchell Hashimoto 2014-10-04 16:24:07 -07:00
parent d7a1f3dc0e
commit 76f5f1057e
9 changed files with 77 additions and 45 deletions

View File

@ -34,7 +34,6 @@ type Context struct {
provisioners map[string]ResourceProvisionerFactory
variables map[string]string
uiInput UIInput
uiOutput UIOutput
l sync.Mutex // Lock acquired during any task
parCh chan struct{} // Semaphore used to limit parallelism
@ -56,7 +55,6 @@ type ContextOpts struct {
Variables map[string]string
UIInput UIInput
UIOutput UIOutput
}
// NewContext creates a new context.
@ -90,7 +88,6 @@ func NewContext(opts *ContextOpts) *Context {
provisioners: opts.Provisioners,
variables: opts.Variables,
uiInput: opts.UIInput,
uiOutput: opts.UIOutput,
parCh: parCh,
sh: sh,
@ -1313,9 +1310,10 @@ func (c *walkContext) applyProvisioners(r *Resource, is *InstanceState) error {
handleHook(h.PreProvision(r.Info, prov.Type))
}
output := PrefixUIOutput{
Prefix: r.Id + ": ",
UIOutput: c.Context.uiOutput,
output := ProvisionerUIOutput{
Info: r.Info,
Type: prov.Type,
Hooks: c.Context.hooks,
}
err := prov.Provisioner.Apply(&output, is, prov.Config)
if err != nil {

View File

@ -37,6 +37,7 @@ type Hook interface {
PostProvisionResource(*InstanceInfo, *InstanceState) (HookAction, error)
PreProvision(*InstanceInfo, string) (HookAction, error)
PostProvision(*InstanceInfo, string) (HookAction, error)
ProvisionOutput(*InstanceInfo, string, string)
// PreRefresh and PostRefresh are called before and after a single
// resource state is refreshed, respectively.
@ -81,6 +82,10 @@ func (*NilHook) PostProvision(*InstanceInfo, string) (HookAction, error) {
return HookActionContinue, nil
}
func (*NilHook) ProvisionOutput(
*InstanceInfo, string, string) {
}
func (*NilHook) PreRefresh(*InstanceInfo, *InstanceState) (HookAction, error) {
return HookActionContinue, nil
}

View File

@ -53,6 +53,11 @@ type MockHook struct {
PostProvisionReturn HookAction
PostProvisionError error
ProvisionOutputCalled bool
ProvisionOutputInfo *InstanceInfo
ProvisionOutputProvisionerId string
ProvisionOutputMessage string
PostRefreshCalled bool
PostRefreshInfo *InstanceInfo
PostRefreshState *InstanceState
@ -124,6 +129,16 @@ func (h *MockHook) PostProvision(n *InstanceInfo, provId string) (HookAction, er
return h.PostProvisionReturn, h.PostProvisionError
}
func (h *MockHook) ProvisionOutput(
n *InstanceInfo,
provId string,
msg string) {
h.ProvisionOutputCalled = true
h.ProvisionOutputInfo = n
h.ProvisionOutputProvisionerId = provId
h.ProvisionOutputMessage = msg
}
func (h *MockHook) PreRefresh(n *InstanceInfo, s *InstanceState) (HookAction, error) {
h.PreRefreshCalled = true
h.PreRefreshInfo = n

View File

@ -42,6 +42,9 @@ func (h *stopHook) PostProvision(*InstanceInfo, string) (HookAction, error) {
return h.hook()
}
func (h *stopHook) ProvisionOutput(*InstanceInfo, string, string) {
}
func (h *stopHook) PreRefresh(*InstanceInfo, *InstanceState) (HookAction, error) {
return h.hook()
}

View File

@ -0,0 +1,5 @@
package terraform
type CallbackUIOutput struct {
OutputFun func(string)
}

View File

@ -1,17 +0,0 @@
package terraform
import (
"fmt"
)
// PrefixUIOutput is an implementation of UIOutput that prefixes the output
// with a string.
type PrefixUIOutput struct {
Prefix string
UIOutput UIOutput
}
func (i *PrefixUIOutput) Output(v string) {
v = fmt.Sprintf("%s%s", i.Prefix, v)
i.UIOutput.Output(v)
}

View File

@ -1,22 +0,0 @@
package terraform
import (
"testing"
)
func TestPrefixUIOutput_impl(t *testing.T) {
var _ UIOutput = new(PrefixUIOutput)
}
func testPrefixUIOutput(t *testing.T) {
output := new(MockUIOutput)
prefix := &PrefixUIOutput{
Prefix: "foo",
UIOutput: output,
}
prefix.Output("foo")
if output.OutputMessage != "foofoo" {
t.Fatalf("bad: %#v", output)
}
}

View File

@ -0,0 +1,15 @@
package terraform
// ProvisionerUIOutput is an implementation of UIOutput that calls a hook
// for the output so that the hooks can handle it.
type ProvisionerUIOutput struct {
Info *InstanceInfo
Type string
Hooks []Hook
}
func (o *ProvisionerUIOutput) Output(msg string) {
for _, h := range o.Hooks {
h.ProvisionOutput(o.Info, o.Type, msg)
}
}

View File

@ -0,0 +1,30 @@
package terraform
import (
"testing"
)
func TestProvisionerUIOutput_impl(t *testing.T) {
var _ UIOutput = new(ProvisionerUIOutput)
}
func TestProvisionerUIOutputOutput(t *testing.T) {
hook := new(MockHook)
output := &ProvisionerUIOutput{
Info: nil,
Type: "foo",
Hooks: []Hook{hook},
}
output.Output("bar")
if !hook.ProvisionOutputCalled {
t.Fatal("should be called")
}
if hook.ProvisionOutputProvisionerId != "foo" {
t.Fatalf("bad: %#v", hook.ProvisionOutputProvisionerId)
}
if hook.ProvisionOutputMessage != "bar" {
t.Fatalf("bad: %#v", hook.ProvisionOutputMessage)
}
}