terraform: hooks around provisioners

This commit is contained in:
Mitchell Hashimoto 2014-07-27 09:00:34 -07:00
parent 9759606989
commit 78c32ac196
6 changed files with 117 additions and 3 deletions

View File

@ -574,6 +574,11 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
delete(c.state.Tainted, r.Id)
} else {
c.state.Resources[r.Id] = rs
// We always mark the resource as tainted here in case a
// hook below during provisioning does HookActionStop. This
// way, we keep the resource tainted.
c.state.Tainted[r.Id] = struct{}{}
}
c.sl.Unlock()
@ -585,19 +590,28 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
// was an error during the provider apply.
tainted := false
if applyerr == nil && r.State.ID == "" && len(r.Provisioners) > 0 {
for _, h := range c.hooks {
handleHook(h.PreProvisionResource(r.Id, r.State))
}
if err := c.applyProvisioners(r, rs); err != nil {
errs = append(errs, err)
tainted = true
}
}
if tainted {
log.Printf("[DEBUG] %s: Marking as tainted", r.Id)
for _, h := range c.hooks {
handleHook(h.PostProvisionResource(r.Id, r.State))
}
}
c.sl.Lock()
if tainted {
log.Printf("[DEBUG] %s: Marking as tainted", r.Id)
c.state.Tainted[r.Id] = struct{}{}
c.sl.Unlock()
} else {
delete(c.state.Tainted, r.Id)
}
c.sl.Unlock()
// Update the state for the resource itself
r.State = rs
@ -671,9 +685,17 @@ func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) error {
rs.ConnInfo = overlay
// Invoke the Provisioner
for _, h := range c.hooks {
handleHook(h.PreProvision(r.Id, prov.Type))
}
if err := prov.Provisioner.Apply(rs, prov.Config); err != nil {
return err
}
for _, h := range c.hooks {
handleHook(h.PostProvision(r.Id, prov.Type))
}
}
return nil

View File

@ -864,6 +864,7 @@ func graphMapResourceProvisioners(g *depgraph.Graph,
// Save the provisioner
rn.Resource.Provisioners = append(rn.Resource.Provisioners, &ResourceProvisionerConfig{
Type: p.Type,
Provisioner: provisioner,
Config: NewResourceConfig(p.RawConfig),
RawConfig: p.RawConfig,

View File

@ -32,6 +32,12 @@ type Hook interface {
PreDiff(string, *ResourceState) (HookAction, error)
PostDiff(string, *ResourceDiff) (HookAction, error)
// Provisioning hooks
PreProvisionResource(string, *ResourceState) (HookAction, error)
PostProvisionResource(string, *ResourceState) (HookAction, error)
PreProvision(string, string) (HookAction, error)
PostProvision(string, string) (HookAction, error)
// PreRefresh and PostRefresh are called before and after a single
// resource state is refreshed, respectively.
PreRefresh(string, *ResourceState) (HookAction, error)
@ -59,6 +65,22 @@ func (*NilHook) PostDiff(string, *ResourceDiff) (HookAction, error) {
return HookActionContinue, nil
}
func (*NilHook) PreProvisionResource(string, *ResourceState) (HookAction, error) {
return HookActionContinue, nil
}
func (*NilHook) PostProvisionResource(string, *ResourceState) (HookAction, error) {
return HookActionContinue, nil
}
func (*NilHook) PreProvision(string, string) (HookAction, error) {
return HookActionContinue, nil
}
func (*NilHook) PostProvision(string, string) (HookAction, error) {
return HookActionContinue, nil
}
func (*NilHook) PreRefresh(string, *ResourceState) (HookAction, error) {
return HookActionContinue, nil
}

View File

@ -29,6 +29,30 @@ type MockHook struct {
PostDiffReturn HookAction
PostDiffError error
PreProvisionResourceCalled bool
PreProvisionResourceId string
PreProvisionResourceState *ResourceState
PreProvisionResourceReturn HookAction
PreProvisionResourceError error
PostProvisionResourceCalled bool
PostProvisionResourceId string
PostProvisionResourceState *ResourceState
PostProvisionResourceReturn HookAction
PostProvisionResourceError error
PreProvisionCalled bool
PreProvisionId string
PreProvisionProvisionerId string
PreProvisionReturn HookAction
PreProvisionError error
PostProvisionCalled bool
PostProvisionId string
PostProvisionProvisionerId string
PostProvisionReturn HookAction
PostProvisionError error
PostRefreshCalled bool
PostRefreshId string
PostRefreshState *ResourceState
@ -72,6 +96,34 @@ func (h *MockHook) PostDiff(n string, d *ResourceDiff) (HookAction, error) {
return h.PostDiffReturn, h.PostDiffError
}
func (h *MockHook) PreProvisionResource(id string, s *ResourceState) (HookAction, error) {
h.PreProvisionResourceCalled = true
h.PreProvisionResourceId = id
h.PreProvisionResourceState = s
return h.PreProvisionResourceReturn, h.PreProvisionResourceError
}
func (h *MockHook) PostProvisionResource(id string, s *ResourceState) (HookAction, error) {
h.PostProvisionResourceCalled = true
h.PostProvisionResourceId = id
h.PostProvisionResourceState = s
return h.PostProvisionResourceReturn, h.PostProvisionResourceError
}
func (h *MockHook) PreProvision(id, provId string) (HookAction, error) {
h.PreProvisionCalled = true
h.PreProvisionId = id
h.PreProvisionProvisionerId = provId
return h.PreProvisionReturn, h.PreProvisionError
}
func (h *MockHook) PostProvision(id, provId string) (HookAction, error) {
h.PostProvisionCalled = true
h.PostProvisionId = id
h.PostProvisionProvisionerId = provId
return h.PostProvisionReturn, h.PostProvisionError
}
func (h *MockHook) PreRefresh(n string, s *ResourceState) (HookAction, error) {
h.PreRefreshCalled = true
h.PreRefreshId = n

View File

@ -26,6 +26,22 @@ func (h *stopHook) PostDiff(string, *ResourceDiff) (HookAction, error) {
return h.hook()
}
func (h *stopHook) PreProvisionResource(string, *ResourceState) (HookAction, error) {
return h.hook()
}
func (h *stopHook) PostProvisionResource(string, *ResourceState) (HookAction, error) {
return h.hook()
}
func (h *stopHook) PreProvision(string, string) (HookAction, error) {
return h.hook()
}
func (h *stopHook) PostProvision(string, string) (HookAction, error) {
return h.hook()
}
func (h *stopHook) PreRefresh(string, *ResourceState) (HookAction, error) {
return h.hook()
}

View File

@ -15,6 +15,7 @@ import (
// configuration instead of instantiating a new Provisioner for each
// resource.
type ResourceProvisionerConfig struct {
Type string
Provisioner ResourceProvisioner
Config *ResourceConfig
RawConfig *config.RawConfig