terraform: copy RawConfigs

This commit is contained in:
Mitchell Hashimoto 2015-04-09 09:21:38 -07:00
parent f0004186cf
commit b201983304
2 changed files with 30 additions and 4 deletions

View File

@ -3,6 +3,7 @@ package config
import ( import (
"bytes" "bytes"
"encoding/gob" "encoding/gob"
"sync"
"github.com/hashicorp/terraform/config/lang" "github.com/hashicorp/terraform/config/lang"
"github.com/hashicorp/terraform/config/lang/ast" "github.com/hashicorp/terraform/config/lang/ast"
@ -31,6 +32,7 @@ type RawConfig struct {
Interpolations []ast.Node Interpolations []ast.Node
Variables map[string]InterpolatedVariable Variables map[string]InterpolatedVariable
lock sync.Mutex
config map[string]interface{} config map[string]interface{}
unknownKeys []string unknownKeys []string
} }
@ -46,6 +48,19 @@ func NewRawConfig(raw map[string]interface{}) (*RawConfig, error) {
return result, nil return result, nil
} }
// Copy returns a copy of this RawConfig, uninterpolated.
func (r *RawConfig) Copy() *RawConfig {
r.lock.Lock()
defer r.lock.Unlock()
result, err := NewRawConfig(r.Raw)
if err != nil {
panic("copy failed: " + err.Error())
}
return result
}
// Value returns the value of the configuration if this configuration // Value returns the value of the configuration if this configuration
// has a Key set. If this does not have a Key set, nil will be returned. // has a Key set. If this does not have a Key set, nil will be returned.
func (r *RawConfig) Value() interface{} { func (r *RawConfig) Value() interface{} {
@ -55,6 +70,8 @@ func (r *RawConfig) Value() interface{} {
} }
} }
r.lock.Lock()
defer r.lock.Unlock()
return r.Raw[r.Key] return r.Raw[r.Key]
} }
@ -81,6 +98,9 @@ func (r *RawConfig) Config() map[string]interface{} {
// //
// If a variable key is missing, this will panic. // If a variable key is missing, this will panic.
func (r *RawConfig) Interpolate(vs map[string]ast.Variable) error { func (r *RawConfig) Interpolate(vs map[string]ast.Variable) error {
r.lock.Lock()
defer r.lock.Unlock()
config := langEvalConfig(vs) config := langEvalConfig(vs)
return r.interpolate(func(root ast.Node) (string, error) { return r.interpolate(func(root ast.Node) (string, error) {
// We detect the variables again and check if the value of any // We detect the variables again and check if the value of any
@ -119,6 +139,9 @@ func (r *RawConfig) Interpolate(vs map[string]ast.Variable) error {
// values in this config) and returns a new config. The original config // values in this config) and returns a new config. The original config
// is not modified. // is not modified.
func (r *RawConfig) Merge(other *RawConfig) *RawConfig { func (r *RawConfig) Merge(other *RawConfig) *RawConfig {
r.lock.Lock()
defer r.lock.Unlock()
// Merge the raw configurations // Merge the raw configurations
raw := make(map[string]interface{}) raw := make(map[string]interface{})
for k, v := range r.Raw { for k, v := range r.Raw {
@ -252,6 +275,9 @@ func (r *RawConfig) GobDecode(b []byte) error {
// tree of interpolated variables is recomputed on decode, since it is // tree of interpolated variables is recomputed on decode, since it is
// referentially transparent. // referentially transparent.
func (r *RawConfig) GobEncode() ([]byte, error) { func (r *RawConfig) GobEncode() ([]byte, error) {
r.lock.Lock()
defer r.lock.Unlock()
data := gobRawConfig{ data := gobRawConfig{
Key: r.Key, Key: r.Key,
Raw: r.Raw, Raw: r.Raw,

View File

@ -171,7 +171,7 @@ func (n *graphNodeExpandedResource) EvalTree() EvalNode {
Output: &provider, Output: &provider,
}) })
vseq.Nodes = append(vseq.Nodes, &EvalInterpolate{ vseq.Nodes = append(vseq.Nodes, &EvalInterpolate{
Config: n.Resource.RawConfig, Config: n.Resource.RawConfig.Copy(),
Resource: resource, Resource: resource,
Output: &resourceConfig, Output: &resourceConfig,
}) })
@ -189,7 +189,7 @@ func (n *graphNodeExpandedResource) EvalTree() EvalNode {
Name: p.Type, Name: p.Type,
Output: &provisioner, Output: &provisioner,
}, &EvalInterpolate{ }, &EvalInterpolate{
Config: p.RawConfig, Config: p.RawConfig.Copy(),
Resource: resource, Resource: resource,
Output: &resourceConfig, Output: &resourceConfig,
}, &EvalValidateProvisioner{ }, &EvalValidateProvisioner{
@ -243,7 +243,7 @@ func (n *graphNodeExpandedResource) EvalTree() EvalNode {
Node: &EvalSequence{ Node: &EvalSequence{
Nodes: []EvalNode{ Nodes: []EvalNode{
&EvalInterpolate{ &EvalInterpolate{
Config: n.Resource.RawConfig, Config: n.Resource.RawConfig.Copy(),
Resource: resource, Resource: resource,
Output: &resourceConfig, Output: &resourceConfig,
}, },
@ -354,7 +354,7 @@ func (n *graphNodeExpandedResource) EvalTree() EvalNode {
}, },
&EvalInterpolate{ &EvalInterpolate{
Config: n.Resource.RawConfig, Config: n.Resource.RawConfig.Copy(),
Resource: resource, Resource: resource,
Output: &resourceConfig, Output: &resourceConfig,
}, },