terraform: add flags field

This commit is contained in:
Mitchell Hashimoto 2014-09-20 17:02:31 -07:00
parent 53c23266ca
commit 13a4818867
3 changed files with 45 additions and 57 deletions

View File

@ -616,7 +616,7 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
} }
} }
if r.Tainted && r.TaintedIndex > -1 { if r.Flags&FlagTainted != 0 {
// Update the tainted resource. // Update the tainted resource.
r.State.Tainted[r.TaintedIndex] = is r.State.Tainted[r.TaintedIndex] = is
} else { } else {
@ -667,7 +667,11 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
c.sl.Unlock() c.sl.Unlock()
// Update the state for the resource itself // Update the state for the resource itself
r.Tainted = tainted if tainted {
r.Flags &^= FlagPrimary
r.Flags &^= FlagHasTainted
r.Flags |= FlagTainted
}
for _, h := range c.hooks { for _, h := range c.hooks {
handleHook(h.PostApply(r.Id, r.State.Primary, applyerr)) handleHook(h.PostApply(r.Id, r.State.Primary, applyerr))
@ -760,7 +764,7 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
result.init() result.init()
cb := func(r *Resource) error { cb := func(r *Resource) error {
if r.Tainted && r.TaintedIndex > -1 { if r.Flags&FlagTainted != 0 {
// We don't diff tainted resources. // We don't diff tainted resources.
return nil return nil
} }
@ -773,7 +777,7 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
handleHook(h.PreDiff(r.Id, is)) handleHook(h.PreDiff(r.Id, is))
} }
if r.Config == nil { if r.Flags&FlagOrphan != 0 {
log.Printf("[DEBUG] %s: Orphan, marking for destroy", r.Id) log.Printf("[DEBUG] %s: Orphan, marking for destroy", r.Id)
// This is an orphan (no config), so we mark it to be destroyed // This is an orphan (no config), so we mark it to be destroyed
@ -788,7 +792,7 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
log.Printf("[DEBUG] %s: Executing diff", r.Id) log.Printf("[DEBUG] %s: Executing diff", r.Id)
var err error var err error
state := r.State state := r.State
if r.Tainted { if r.Flags&FlagHasTainted != 0 {
// If we're tainted, we pretend to create a new thing. // If we're tainted, we pretend to create a new thing.
state = new(ResourceState) state = new(ResourceState)
state.Type = r.State.Type state.Type = r.State.Type
@ -804,9 +808,10 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
diff = new(InstanceDiff) diff = new(InstanceDiff)
} }
if r.Tainted { if r.Flags&FlagHasTainted != 0 {
// Tainted resources must also be destroyed // This primary has a tainted resource, so just mark for
log.Printf("[DEBUG] %s: Tainted, marking for destroy", r.Id) // destroy...
log.Printf("[DEBUG] %s: Tainted children, marking for destroy", r.Id)
diff.DestroyTainted = true diff.DestroyTainted = true
} }
@ -900,7 +905,7 @@ func (c *Context) planDestroyWalkFn(result *Plan) depgraph.WalkFunc {
func (c *Context) refreshWalkFn() depgraph.WalkFunc { func (c *Context) refreshWalkFn() depgraph.WalkFunc {
cb := func(r *Resource) error { cb := func(r *Resource) error {
is := r.State.Primary is := r.State.Primary
if r.Tainted && r.TaintedIndex > -1 { if r.Flags&FlagTainted != 0 {
is = r.State.Tainted[r.TaintedIndex] is = r.State.Tainted[r.TaintedIndex]
} }
@ -922,7 +927,7 @@ func (c *Context) refreshWalkFn() depgraph.WalkFunc {
is.init() is.init()
} }
if r.Tainted { if r.Flags&FlagTainted != 0 {
r.State.Tainted[r.TaintedIndex] = is r.State.Tainted[r.TaintedIndex] = is
} else { } else {
r.State.Primary = is r.State.Primary = is
@ -965,7 +970,7 @@ func (c *Context) validateWalkFn(rws *[]string, res *[]error) depgraph.WalkFunc
} }
// Don't validate orphans since they never have a config // Don't validate orphans since they never have a config
if rn.Orphan { if rn.Resource.Flags&FlagOrphan != 0 {
return nil return nil
} }
@ -1028,24 +1033,6 @@ func (c *Context) validateWalkFn(rws *[]string, res *[]error) depgraph.WalkFunc
} }
} }
//type instanceWalkFunc func(*Resource, bool, **InstanceState) error
func instanceWalk(cb instanceWalkFunc) genericWalkFunc {
return func(r *Resource) error {
// Handle the tainted resources first
for idx := range r.State.Tainted {
if err := cb(r, true, &r.State.Tainted[idx]); err != nil {
return err
}
}
// Handle the primary resource
if r.State.Primary == nil {
r.State.init()
}
return cb(r, false, &r.State.Primary)
}
}
func (c *Context) genericWalkFn(cb genericWalkFunc) depgraph.WalkFunc { func (c *Context) genericWalkFn(cb genericWalkFunc) depgraph.WalkFunc {
// This will keep track of whether we're stopped or not // This will keep track of whether we're stopped or not
var stop uint32 = 0 var stop uint32 = 0
@ -1099,14 +1086,10 @@ func (c *Context) genericWalkFn(cb genericWalkFunc) depgraph.WalkFunc {
rn := n.Meta.(*GraphNodeResource) rn := n.Meta.(*GraphNodeResource)
// Make sure that at least some resource configuration is set // Make sure that at least some resource configuration is set
if !rn.Orphan { if rn.Config == nil {
if rn.Config == nil { rn.Resource.Config = new(ResourceConfig)
rn.Resource.Config = new(ResourceConfig)
} else {
rn.Resource.Config = NewResourceConfig(rn.Config.RawConfig)
}
} else { } else {
rn.Resource.Config = nil rn.Resource.Config = NewResourceConfig(rn.Config.RawConfig)
} }
// Handle recovery of special panic scenarios // Handle recovery of special panic scenarios

View File

@ -57,7 +57,6 @@ const GraphRootNode = "root"
type GraphNodeResource struct { type GraphNodeResource struct {
Index int Index int
Config *config.Resource Config *config.Resource
Orphan bool
Resource *Resource Resource *Resource
ResourceProviderID string ResourceProviderID string
} }
@ -263,18 +262,22 @@ func graphAddConfigResources(
} }
} }
flags := FlagPrimary
if len(state.Tainted) > 0 {
flags |= FlagHasTainted
}
resourceNouns[i] = &depgraph.Noun{ resourceNouns[i] = &depgraph.Noun{
Name: name, Name: name,
Meta: &GraphNodeResource{ Meta: &GraphNodeResource{
Index: index, Index: index,
Config: r, Config: r,
Resource: &Resource{ Resource: &Resource{
Id: name, Id: name,
Info: &InstanceInfo{Type: r.Type}, Info: &InstanceInfo{Type: r.Type},
State: state, State: state,
Config: NewResourceConfig(r.RawConfig), Config: NewResourceConfig(r.RawConfig),
Tainted: len(state.Tainted) > 0, Flags: flags,
TaintedIndex: -1,
}, },
}, },
} }
@ -337,7 +340,7 @@ func graphAddDiff(g *depgraph.Graph, d *Diff) error {
if !ok { if !ok {
continue continue
} }
if rn.Resource.Tainted && rn.Resource.TaintedIndex > -1 { if rn.Resource.Flags&FlagTainted != 0 {
continue continue
} }
@ -387,15 +390,6 @@ func graphAddDiff(g *depgraph.Graph, d *Diff) error {
Source: n, Source: n,
Target: newN, Target: newN,
}) })
// If the resource is tainted, mark the state as nil so
// that a fresh create is done.
if rn.Resource.Tainted {
rn.Resource.State = &ResourceState{
Type: rn.Resource.State.Type,
}
rn.Resource.Tainted = false
}
} }
rn.Resource.Diff = rd rn.Resource.Diff = rd
@ -606,13 +600,13 @@ func graphAddOrphans(g *depgraph.Graph, c *config.Config, s *State) {
noun := &depgraph.Noun{ noun := &depgraph.Noun{
Name: k, Name: k,
Meta: &GraphNodeResource{ Meta: &GraphNodeResource{
Index: -1, Index: -1,
Orphan: true,
Resource: &Resource{ Resource: &Resource{
Id: k, Id: k,
Info: &InstanceInfo{Type: rs.Type}, Info: &InstanceInfo{Type: rs.Type},
State: rs, State: rs,
Config: NewResourceConfig(nil), Config: NewResourceConfig(nil),
Flags: FlagOrphan,
}, },
}, },
} }
@ -822,7 +816,7 @@ func graphAddTainted(g *depgraph.Graph, s *State) {
State: rs, State: rs,
Config: NewResourceConfig(nil), Config: NewResourceConfig(nil),
Diff: &InstanceDiff{Destroy: true}, Diff: &InstanceDiff{Destroy: true},
Tainted: true, Flags: FlagTainted,
TaintedIndex: i, TaintedIndex: i,
}, },
}, },

View File

@ -33,10 +33,21 @@ type Resource struct {
Provider ResourceProvider Provider ResourceProvider
State *ResourceState State *ResourceState
Provisioners []*ResourceProvisionerConfig Provisioners []*ResourceProvisionerConfig
Tainted bool Flags ResourceFlag
TaintedIndex int TaintedIndex int
} }
// ResourceKind specifies what kind of instance we're working with, whether
// its a primary instance, a tainted instance, or an orphan.
type ResourceFlag byte
const (
FlagPrimary ResourceFlag = 1 << iota
FlagTainted
FlagOrphan
FlagHasTainted
)
// Vars returns the mapping of variables that should be replaced in // Vars returns the mapping of variables that should be replaced in
// configuration based on the attributes of this resource. // configuration based on the attributes of this resource.
func (r *Resource) Vars() map[string]string { func (r *Resource) Vars() map[string]string {