terraform: Fixing up context
This commit is contained in:
parent
9cbd71b88d
commit
3963b42625
|
@ -505,6 +505,9 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Ensure the state is initialized
|
||||
r.State.init()
|
||||
|
||||
if !diff.Destroy {
|
||||
// Since we need the configuration, interpolate the variables
|
||||
if err := r.Config.interpolate(c); err != nil {
|
||||
|
@ -543,11 +546,6 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
}
|
||||
}
|
||||
|
||||
// If we do not have any connection info, initialize
|
||||
if r.State.Primary.Ephemeral.ConnInfo == nil {
|
||||
r.State.Primary.Ephemeral.init()
|
||||
}
|
||||
|
||||
// Remove any output values from the diff
|
||||
for k, ad := range diff.Attributes {
|
||||
if ad.Type == DiffAttrOutput {
|
||||
|
@ -571,42 +569,36 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
// Make sure the result is instantiated
|
||||
if rs == nil {
|
||||
rs = new(ResourceState)
|
||||
rs.init()
|
||||
}
|
||||
|
||||
// Force the resource state type to be our type
|
||||
rs.Type = r.State.Type
|
||||
|
||||
// Force the "id" attribute to be our ID
|
||||
if rs.ID != "" {
|
||||
if rs.Attributes == nil {
|
||||
rs.Attributes = make(map[string]string)
|
||||
}
|
||||
|
||||
rs.Attributes["id"] = rs.ID
|
||||
if rs.Primary.ID != "" {
|
||||
rs.Primary.Attributes["id"] = rs.Primary.ID
|
||||
}
|
||||
|
||||
for ak, av := range rs.Attributes {
|
||||
for ak, av := range rs.Primary.Attributes {
|
||||
// If the value is the unknown variable value, then it is an error.
|
||||
// In this case we record the error and remove it from the state
|
||||
if av == config.UnknownVariableValue {
|
||||
errs = append(errs, fmt.Errorf(
|
||||
"Attribute with unknown value: %s", ak))
|
||||
delete(rs.Attributes, ak)
|
||||
delete(rs.Primary.Attributes, ak)
|
||||
}
|
||||
}
|
||||
|
||||
// Update the resulting diff
|
||||
c.sl.Lock()
|
||||
if rs.ID == "" {
|
||||
delete(c.state.Resources, r.Id)
|
||||
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{}{}
|
||||
// TODO: Get other modules
|
||||
mod := c.state.RootModule()
|
||||
if rs.Primary.ID == "" && len(rs.Tainted) == 0 {
|
||||
delete(mod.Resources, r.Id)
|
||||
} else {
|
||||
mod.Resources[r.Id] = rs
|
||||
}
|
||||
c.sl.Unlock()
|
||||
|
||||
|
@ -617,7 +609,7 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
// Additionally, we need to be careful to not run this if there
|
||||
// was an error during the provider apply.
|
||||
tainted := false
|
||||
if applyerr == nil && r.State.ID == "" && len(r.Provisioners) > 0 {
|
||||
if applyerr == nil && r.State.Primary.ID == "" && len(r.Provisioners) > 0 {
|
||||
for _, h := range c.hooks {
|
||||
handleHook(h.PreProvisionResource(r.Id, r.State))
|
||||
}
|
||||
|
@ -635,9 +627,8 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
c.sl.Lock()
|
||||
if tainted {
|
||||
log.Printf("[DEBUG] %s: Marking as tainted", r.Id)
|
||||
c.state.Tainted[r.Id] = struct{}{}
|
||||
} else {
|
||||
delete(c.state.Tainted, r.Id)
|
||||
rs.Tainted = append(rs.Tainted, rs.Primary)
|
||||
rs.Primary = nil
|
||||
}
|
||||
c.sl.Unlock()
|
||||
|
||||
|
@ -665,9 +656,9 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
// defined after the resource creation has already completed.
|
||||
func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) error {
|
||||
// Store the original connection info, restore later
|
||||
origConnInfo := rs.ConnInfo
|
||||
origConnInfo := rs.Primary.Ephemeral.ConnInfo
|
||||
defer func() {
|
||||
rs.ConnInfo = origConnInfo
|
||||
rs.Primary.Ephemeral.ConnInfo = origConnInfo
|
||||
}()
|
||||
|
||||
for _, prov := range r.Provisioners {
|
||||
|
@ -710,7 +701,7 @@ func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) error {
|
|||
overlay[k] = fmt.Sprintf("%v", vt)
|
||||
}
|
||||
}
|
||||
rs.ConnInfo = overlay
|
||||
rs.Primary.Ephemeral.ConnInfo = overlay
|
||||
|
||||
// Invoke the Provisioner
|
||||
for _, h := range c.hooks {
|
||||
|
@ -778,16 +769,16 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
|
|||
diff.Destroy = true
|
||||
}
|
||||
|
||||
if diff.RequiresNew() && r.State.ID != "" {
|
||||
if diff.RequiresNew() && r.State.Primary.ID != "" {
|
||||
// This will also require a destroy
|
||||
diff.Destroy = true
|
||||
}
|
||||
|
||||
if diff.RequiresNew() || r.State.ID == "" {
|
||||
if diff.RequiresNew() || r.State.Primary.ID == "" {
|
||||
// Add diff to compute new ID
|
||||
diff.init()
|
||||
diff.Attributes["id"] = &ResourceAttrDiff{
|
||||
Old: r.State.Attributes["id"],
|
||||
Old: r.State.Primary.Attributes["id"],
|
||||
NewComputed: true,
|
||||
RequiresNew: true,
|
||||
Type: DiffAttrOutput,
|
||||
|
@ -812,7 +803,10 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
|
|||
// Update our internal state so that variable computation works
|
||||
c.sl.Lock()
|
||||
defer c.sl.Unlock()
|
||||
c.state.Resources[r.Id] = r.State
|
||||
|
||||
// TODO: Handle other modules
|
||||
mod := c.state.RootModule()
|
||||
mod.Resources[r.Id] = r.State
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -833,7 +827,7 @@ func (c *Context) planDestroyWalkFn(result *Plan) depgraph.WalkFunc {
|
|||
}
|
||||
|
||||
r := rn.Resource
|
||||
if r.State.ID != "" {
|
||||
if r.State.Primary.ID != "" {
|
||||
log.Printf("[DEBUG] %s: Making for destroy", r.Id)
|
||||
|
||||
l.Lock()
|
||||
|
@ -849,7 +843,7 @@ func (c *Context) planDestroyWalkFn(result *Plan) depgraph.WalkFunc {
|
|||
|
||||
func (c *Context) refreshWalkFn() depgraph.WalkFunc {
|
||||
cb := func(r *Resource) error {
|
||||
if r.State.ID == "" {
|
||||
if r.State.Primary.ID == "" {
|
||||
log.Printf("[DEBUG] %s: Not refreshing, ID is empty", r.Id)
|
||||
return nil
|
||||
}
|
||||
|
@ -870,10 +864,13 @@ func (c *Context) refreshWalkFn() depgraph.WalkFunc {
|
|||
rs.Type = r.State.Type
|
||||
|
||||
c.sl.Lock()
|
||||
if rs.ID == "" {
|
||||
delete(c.state.Resources, r.Id)
|
||||
|
||||
// TODO: Handle other moduels
|
||||
mod := c.state.RootModule()
|
||||
if rs.Primary.ID == "" {
|
||||
delete(mod.Resources, r.Id)
|
||||
} else {
|
||||
c.state.Resources[r.Id] = rs
|
||||
mod.Resources[r.Id] = rs
|
||||
}
|
||||
c.sl.Unlock()
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
)
|
||||
|
||||
// rootModulePath is the path of the root module
|
||||
|
@ -82,6 +84,15 @@ type ModuleState struct {
|
|||
Resources map[string]*ResourceState `json:"resources"`
|
||||
}
|
||||
|
||||
func (m *ModuleState) init() {
|
||||
if m.Outputs == nil {
|
||||
m.Outputs = make(map[string]stirng)
|
||||
}
|
||||
if m.Resources == nil {
|
||||
m.Resources = make(map[string]*ResourceState)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ModuleState) deepcopy() *ModuleState {
|
||||
n := &ModuleState{
|
||||
Path: make([]string, len(m.Path)),
|
||||
|
@ -154,6 +165,13 @@ type ResourceState struct {
|
|||
Tainted []*InstanceState `json:"tainted,omitempty"`
|
||||
}
|
||||
|
||||
func (r *ResourceState) init() {
|
||||
if i.Primary == nil {
|
||||
i.Primary = &InstanceState{}
|
||||
i.Primary.init()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ResourceState) deepcopy() *ResourceState {
|
||||
n := &ResourceState{
|
||||
Type: r.Type,
|
||||
|
@ -181,6 +199,44 @@ func (r *ResourceState) prune() {
|
|||
r.Instances = r.Instances[:n]
|
||||
}
|
||||
|
||||
// MergeDiff takes a ResourceDiff and merges the attributes into
|
||||
// this resource state in order to generate a new state. This new
|
||||
// state can be used to provide updated attribute lookups for
|
||||
// variable interpolation.
|
||||
//
|
||||
// If the diff attribute requires computing the value, and hence
|
||||
// won't be available until apply, the value is replaced with the
|
||||
// computeID.
|
||||
func (s *ResourceState) MergeDiff(d *ResourceDiff) *ResourceState {
|
||||
var result ResourceState
|
||||
if s != nil {
|
||||
result = *s
|
||||
}
|
||||
result.init()
|
||||
|
||||
if s != nil {
|
||||
for k, v := range s.Primary.Attributes {
|
||||
result.Primary.Attributes[k] = v
|
||||
}
|
||||
}
|
||||
if d != nil {
|
||||
for k, diff := range d.Attributes {
|
||||
if diff.NewRemoved {
|
||||
delete(result.Primary.Attributes, k)
|
||||
continue
|
||||
}
|
||||
if diff.NewComputed {
|
||||
result.Primary.Attributes[k] = config.UnknownVariableValue
|
||||
continue
|
||||
}
|
||||
|
||||
result.Primary.Attributes[k] = diff.New
|
||||
}
|
||||
}
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
// InstanceState is used to track the unique state information belonging
|
||||
// to a given instance.
|
||||
type InstanceState struct {
|
||||
|
@ -204,6 +260,13 @@ type InstanceState struct {
|
|||
Ephemeral EphemeralState `json:"-"`
|
||||
}
|
||||
|
||||
func (i *InstanceState) init() {
|
||||
if i.Attributes == nil {
|
||||
i.Attributes = make(map[string]string)
|
||||
}
|
||||
i.Ephemeral.init()
|
||||
}
|
||||
|
||||
func (i *InstanceState) deepcopy() *InstanceState {
|
||||
n := &InstanceState{
|
||||
ID: i.ID,
|
||||
|
|
Loading…
Reference in New Issue