terraform: PostProvision hook gets the error from the provision step

This commit is contained in:
Mitchell Hashimoto 2017-01-20 20:21:12 -08:00
parent b56ee1a169
commit f40fdde708
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
5 changed files with 56 additions and 12 deletions

View File

@ -4043,6 +4043,46 @@ aws_instance.foo:
} }
} }
// Verify that a normal provisioner with on_failure "continue" records
// the error with the hook.
func TestContext2Apply_provisionerFailContinueHook(t *testing.T) {
h := new(MockHook)
m := testModule(t, "apply-provisioner-fail-continue")
p := testProvider("aws")
pr := testProvisioner()
p.ApplyFn = testApplyFn
p.DiffFn = testDiffFn
pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
return fmt.Errorf("provisioner error")
}
ctx := testContext2(t, &ContextOpts{
Module: m,
Hooks: []Hook{h},
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Provisioners: map[string]ResourceProvisionerFactory{
"shell": testProvisionerFuncFixed(pr),
},
})
if _, err := ctx.Plan(); err != nil {
t.Fatalf("err: %s", err)
}
if _, err := ctx.Apply(); err != nil {
t.Fatalf("err: %s", err)
}
if !h.PostProvisionCalled {
t.Fatal("PostProvision not called")
}
if h.PostProvisionErrorArg == nil {
t.Fatal("should have error")
}
}
func TestContext2Apply_provisionerDestroy(t *testing.T) { func TestContext2Apply_provisionerDestroy(t *testing.T) {
m := testModule(t, "apply-provisioner-destroy") m := testModule(t, "apply-provisioner-destroy")
p := testProvider("aws") p := testProvider("aws")

View File

@ -307,6 +307,13 @@ func (n *EvalApplyProvisioners) apply(ctx EvalContext, provs []*config.Provision
// Invoke the Provisioner // Invoke the Provisioner
output := CallbackUIOutput{OutputFn: outputFn} output := CallbackUIOutput{OutputFn: outputFn}
applyErr := provisioner.Apply(&output, state, provConfig) applyErr := provisioner.Apply(&output, state, provConfig)
// Call post hook
hookErr := ctx.Hook(func(h Hook) (HookAction, error) {
return h.PostProvision(n.Info, prov.Type, applyErr)
})
// Handle the error before we deal with the hook
if applyErr != nil { if applyErr != nil {
// Determine failure behavior // Determine failure behavior
switch prov.OnFailure { switch prov.OnFailure {
@ -320,14 +327,9 @@ func (n *EvalApplyProvisioners) apply(ctx EvalContext, provs []*config.Provision
} }
} }
{ // Deal with the hook
// Call post hook if hookErr != nil {
err := ctx.Hook(func(h Hook) (HookAction, error) { return hookErr
return h.PostProvision(n.Info, prov.Type)
})
if err != nil {
return err
}
} }
} }

View File

@ -42,7 +42,7 @@ type Hook interface {
PreProvisionResource(*InstanceInfo, *InstanceState) (HookAction, error) PreProvisionResource(*InstanceInfo, *InstanceState) (HookAction, error)
PostProvisionResource(*InstanceInfo, *InstanceState) (HookAction, error) PostProvisionResource(*InstanceInfo, *InstanceState) (HookAction, error)
PreProvision(*InstanceInfo, string) (HookAction, error) PreProvision(*InstanceInfo, string) (HookAction, error)
PostProvision(*InstanceInfo, string) (HookAction, error) PostProvision(*InstanceInfo, string, error) (HookAction, error)
ProvisionOutput(*InstanceInfo, string, string) ProvisionOutput(*InstanceInfo, string, string)
// PreRefresh and PostRefresh are called before and after a single // PreRefresh and PostRefresh are called before and after a single
@ -92,7 +92,7 @@ func (*NilHook) PreProvision(*InstanceInfo, string) (HookAction, error) {
return HookActionContinue, nil return HookActionContinue, nil
} }
func (*NilHook) PostProvision(*InstanceInfo, string) (HookAction, error) { func (*NilHook) PostProvision(*InstanceInfo, string, error) (HookAction, error) {
return HookActionContinue, nil return HookActionContinue, nil
} }

View File

@ -55,6 +55,7 @@ type MockHook struct {
PostProvisionCalled bool PostProvisionCalled bool
PostProvisionInfo *InstanceInfo PostProvisionInfo *InstanceInfo
PostProvisionProvisionerId string PostProvisionProvisionerId string
PostProvisionErrorArg error
PostProvisionReturn HookAction PostProvisionReturn HookAction
PostProvisionError error PostProvisionError error
@ -170,13 +171,14 @@ func (h *MockHook) PreProvision(n *InstanceInfo, provId string) (HookAction, err
return h.PreProvisionReturn, h.PreProvisionError return h.PreProvisionReturn, h.PreProvisionError
} }
func (h *MockHook) PostProvision(n *InstanceInfo, provId string) (HookAction, error) { func (h *MockHook) PostProvision(n *InstanceInfo, provId string, err error) (HookAction, error) {
h.Lock() h.Lock()
defer h.Unlock() defer h.Unlock()
h.PostProvisionCalled = true h.PostProvisionCalled = true
h.PostProvisionInfo = n h.PostProvisionInfo = n
h.PostProvisionProvisionerId = provId h.PostProvisionProvisionerId = provId
h.PostProvisionErrorArg = err
return h.PostProvisionReturn, h.PostProvisionError return h.PostProvisionReturn, h.PostProvisionError
} }

View File

@ -38,7 +38,7 @@ func (h *stopHook) PreProvision(*InstanceInfo, string) (HookAction, error) {
return h.hook() return h.hook()
} }
func (h *stopHook) PostProvision(*InstanceInfo, string) (HookAction, error) { func (h *stopHook) PostProvision(*InstanceInfo, string, error) (HookAction, error) {
return h.hook() return h.hook()
} }