From 13a4818867281e8194b48c255763a4528844444f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 20 Sep 2014 17:02:31 -0700 Subject: [PATCH] terraform: add flags field --- terraform/context.go | 55 +++++++++++++++---------------------------- terraform/graph.go | 34 +++++++++++--------------- terraform/resource.go | 13 +++++++++- 3 files changed, 45 insertions(+), 57 deletions(-) diff --git a/terraform/context.go b/terraform/context.go index 29d23ee21..f9ed271b8 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -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. r.State.Tainted[r.TaintedIndex] = is } else { @@ -667,7 +667,11 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc { c.sl.Unlock() // 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 { handleHook(h.PostApply(r.Id, r.State.Primary, applyerr)) @@ -760,7 +764,7 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc { result.init() cb := func(r *Resource) error { - if r.Tainted && r.TaintedIndex > -1 { + if r.Flags&FlagTainted != 0 { // We don't diff tainted resources. return nil } @@ -773,7 +777,7 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc { 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) // 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) var err error state := r.State - if r.Tainted { + if r.Flags&FlagHasTainted != 0 { // If we're tainted, we pretend to create a new thing. state = new(ResourceState) state.Type = r.State.Type @@ -804,9 +808,10 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc { diff = new(InstanceDiff) } - if r.Tainted { - // Tainted resources must also be destroyed - log.Printf("[DEBUG] %s: Tainted, marking for destroy", r.Id) + if r.Flags&FlagHasTainted != 0 { + // This primary has a tainted resource, so just mark for + // destroy... + log.Printf("[DEBUG] %s: Tainted children, marking for destroy", r.Id) diff.DestroyTainted = true } @@ -900,7 +905,7 @@ func (c *Context) planDestroyWalkFn(result *Plan) depgraph.WalkFunc { func (c *Context) refreshWalkFn() depgraph.WalkFunc { cb := func(r *Resource) error { is := r.State.Primary - if r.Tainted && r.TaintedIndex > -1 { + if r.Flags&FlagTainted != 0 { is = r.State.Tainted[r.TaintedIndex] } @@ -922,7 +927,7 @@ func (c *Context) refreshWalkFn() depgraph.WalkFunc { is.init() } - if r.Tainted { + if r.Flags&FlagTainted != 0 { r.State.Tainted[r.TaintedIndex] = is } else { 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 - if rn.Orphan { + if rn.Resource.Flags&FlagOrphan != 0 { 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 { // This will keep track of whether we're stopped or not var stop uint32 = 0 @@ -1099,14 +1086,10 @@ func (c *Context) genericWalkFn(cb genericWalkFunc) depgraph.WalkFunc { rn := n.Meta.(*GraphNodeResource) // Make sure that at least some resource configuration is set - if !rn.Orphan { - if rn.Config == nil { - rn.Resource.Config = new(ResourceConfig) - } else { - rn.Resource.Config = NewResourceConfig(rn.Config.RawConfig) - } + if rn.Config == nil { + rn.Resource.Config = new(ResourceConfig) } else { - rn.Resource.Config = nil + rn.Resource.Config = NewResourceConfig(rn.Config.RawConfig) } // Handle recovery of special panic scenarios diff --git a/terraform/graph.go b/terraform/graph.go index 4af03a315..8911a5c9b 100644 --- a/terraform/graph.go +++ b/terraform/graph.go @@ -57,7 +57,6 @@ const GraphRootNode = "root" type GraphNodeResource struct { Index int Config *config.Resource - Orphan bool Resource *Resource ResourceProviderID string } @@ -263,18 +262,22 @@ func graphAddConfigResources( } } + flags := FlagPrimary + if len(state.Tainted) > 0 { + flags |= FlagHasTainted + } + resourceNouns[i] = &depgraph.Noun{ Name: name, Meta: &GraphNodeResource{ Index: index, Config: r, Resource: &Resource{ - Id: name, - Info: &InstanceInfo{Type: r.Type}, - State: state, - Config: NewResourceConfig(r.RawConfig), - Tainted: len(state.Tainted) > 0, - TaintedIndex: -1, + Id: name, + Info: &InstanceInfo{Type: r.Type}, + State: state, + Config: NewResourceConfig(r.RawConfig), + Flags: flags, }, }, } @@ -337,7 +340,7 @@ func graphAddDiff(g *depgraph.Graph, d *Diff) error { if !ok { continue } - if rn.Resource.Tainted && rn.Resource.TaintedIndex > -1 { + if rn.Resource.Flags&FlagTainted != 0 { continue } @@ -387,15 +390,6 @@ func graphAddDiff(g *depgraph.Graph, d *Diff) error { Source: n, 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 @@ -606,13 +600,13 @@ func graphAddOrphans(g *depgraph.Graph, c *config.Config, s *State) { noun := &depgraph.Noun{ Name: k, Meta: &GraphNodeResource{ - Index: -1, - Orphan: true, + Index: -1, Resource: &Resource{ Id: k, Info: &InstanceInfo{Type: rs.Type}, State: rs, Config: NewResourceConfig(nil), + Flags: FlagOrphan, }, }, } @@ -822,7 +816,7 @@ func graphAddTainted(g *depgraph.Graph, s *State) { State: rs, Config: NewResourceConfig(nil), Diff: &InstanceDiff{Destroy: true}, - Tainted: true, + Flags: FlagTainted, TaintedIndex: i, }, }, diff --git a/terraform/resource.go b/terraform/resource.go index a625b5732..2962e3491 100644 --- a/terraform/resource.go +++ b/terraform/resource.go @@ -33,10 +33,21 @@ type Resource struct { Provider ResourceProvider State *ResourceState Provisioners []*ResourceProvisionerConfig - Tainted bool + Flags ResourceFlag 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 // configuration based on the attributes of this resource. func (r *Resource) Vars() map[string]string {