terraform: use a panic mechanism for handling hooks
This commit is contained in:
parent
733752122a
commit
f7bc33812e
|
@ -65,3 +65,19 @@ func (*NilHook) PreRefresh(string, *ResourceState) (HookAction, error) {
|
||||||
func (*NilHook) PostRefresh(string, *ResourceState) (HookAction, error) {
|
func (*NilHook) PostRefresh(string, *ResourceState) (HookAction, error) {
|
||||||
return HookActionContinue, nil
|
return HookActionContinue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleHook turns hook actions into panics. This lets you use the
|
||||||
|
// panic/recover mechanism in Go as a flow control mechanism for hook
|
||||||
|
// actions.
|
||||||
|
func handleHook(a HookAction, err error) {
|
||||||
|
if err != nil {
|
||||||
|
// TODO: handle errors
|
||||||
|
}
|
||||||
|
|
||||||
|
switch a {
|
||||||
|
case HookActionContinue:
|
||||||
|
return
|
||||||
|
case HookActionHalt:
|
||||||
|
panic(HookActionHalt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -24,10 +23,6 @@ type Terraform struct {
|
||||||
// tree internally on the Terraform structure.
|
// tree internally on the Terraform structure.
|
||||||
type genericWalkFunc func(*Resource) (map[string]string, error)
|
type genericWalkFunc func(*Resource) (map[string]string, error)
|
||||||
|
|
||||||
// genericWalkStop is a special return value that can be returned from a
|
|
||||||
// genericWalkFunc that causes the walk to cease immediately.
|
|
||||||
var genericWalkStop error
|
|
||||||
|
|
||||||
// Config is the configuration that must be given to instantiate
|
// Config is the configuration that must be given to instantiate
|
||||||
// a Terraform structure.
|
// a Terraform structure.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -35,10 +30,6 @@ type Config struct {
|
||||||
Providers map[string]ResourceProviderFactory
|
Providers map[string]ResourceProviderFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
genericWalkStop = errors.New("genericWalkStop")
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Terraform structure, initializes resource providers
|
// New creates a new Terraform structure, initializes resource providers
|
||||||
// for the given configuration, etc.
|
// for the given configuration, etc.
|
||||||
//
|
//
|
||||||
|
@ -183,8 +174,7 @@ func (t *Terraform) refreshWalkFn(result *State) depgraph.WalkFunc {
|
||||||
|
|
||||||
cb := func(r *Resource) (map[string]string, error) {
|
cb := func(r *Resource) (map[string]string, error) {
|
||||||
for _, h := range t.hooks {
|
for _, h := range t.hooks {
|
||||||
// TODO: return value
|
handleHook(h.PreRefresh(r.Id, r.State))
|
||||||
h.PreRefresh(r.Id, r.State)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rs, err := r.Provider.Refresh(r.State)
|
rs, err := r.Provider.Refresh(r.State)
|
||||||
|
@ -203,8 +193,7 @@ func (t *Terraform) refreshWalkFn(result *State) depgraph.WalkFunc {
|
||||||
l.Unlock()
|
l.Unlock()
|
||||||
|
|
||||||
for _, h := range t.hooks {
|
for _, h := range t.hooks {
|
||||||
// TODO: return value
|
handleHook(h.PostRefresh(r.Id, rs))
|
||||||
h.PostRefresh(r.Id, rs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -239,15 +228,7 @@ func (t *Terraform) applyWalkFn(
|
||||||
// anything and that the diff has no computed values (pre-computed)
|
// anything and that the diff has no computed values (pre-computed)
|
||||||
|
|
||||||
for _, h := range t.hooks {
|
for _, h := range t.hooks {
|
||||||
a, err := h.PreApply(r.Id, r.State, diff)
|
handleHook(h.PreApply(r.Id, r.State, diff))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch a {
|
|
||||||
case HookActionHalt:
|
|
||||||
return nil, genericWalkStop
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// With the completed diff, apply!
|
// With the completed diff, apply!
|
||||||
|
@ -291,15 +272,7 @@ func (t *Terraform) applyWalkFn(
|
||||||
r.State = rs
|
r.State = rs
|
||||||
|
|
||||||
for _, h := range t.hooks {
|
for _, h := range t.hooks {
|
||||||
a, err := h.PostApply(r.Id, r.State)
|
handleHook(h.PostApply(r.Id, r.State))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch a {
|
|
||||||
case HookActionHalt:
|
|
||||||
return nil, genericWalkStop
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the new state and update variables
|
// Determine the new state and update variables
|
||||||
|
@ -324,8 +297,7 @@ func (t *Terraform) planWalkFn(result *Plan, opts *PlanOpts) depgraph.WalkFunc {
|
||||||
var diff *ResourceDiff
|
var diff *ResourceDiff
|
||||||
|
|
||||||
for _, h := range t.hooks {
|
for _, h := range t.hooks {
|
||||||
// TODO: return value
|
handleHook(h.PreDiff(r.Id, r.State))
|
||||||
h.PreDiff(r.Id, r.State)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Destroy {
|
if opts.Destroy {
|
||||||
|
@ -358,8 +330,7 @@ func (t *Terraform) planWalkFn(result *Plan, opts *PlanOpts) depgraph.WalkFunc {
|
||||||
l.Unlock()
|
l.Unlock()
|
||||||
|
|
||||||
for _, h := range t.hooks {
|
for _, h := range t.hooks {
|
||||||
// TODO: return value
|
handleHook(h.PostDiff(r.Id, diff))
|
||||||
h.PostDiff(r.Id, diff)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the new state and update variables
|
// Determine the new state and update variables
|
||||||
|
@ -446,15 +417,21 @@ func (t *Terraform) genericWalkFn(
|
||||||
rn.Resource.Config = nil
|
rn.Resource.Config = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle recovery of special panic scenarios
|
||||||
|
defer func() {
|
||||||
|
if v := recover(); v != nil {
|
||||||
|
if v == HookActionHalt {
|
||||||
|
atomic.StoreUint32(&stop, 1)
|
||||||
|
} else {
|
||||||
|
panic(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// Call the callack
|
// Call the callack
|
||||||
log.Printf("[INFO] Walking: %s", rn.Resource.Id)
|
log.Printf("[INFO] Walking: %s", rn.Resource.Id)
|
||||||
newVars, err := cb(rn.Resource)
|
newVars, err := cb(rn.Resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == genericWalkStop {
|
|
||||||
atomic.StoreUint32(&stop, 1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue