terraform: share graph walker's variables lock w/ interpolater

The ContextGraphWalker struct includes a lock that's passed down to
BuiltinEvalContext and guards access to interpolation variables as
they're written using SetVariables.

The likely problem being expressed in #5733 is that the same map
reference is also passed down to the Interpolater.Variables field, which
is used for variable lookup.

Here, we plumb the same lock we're using to guard access for writes down
and acquire it before doing variable reads as well. It's not as fine
grained as perhaps it could be, but all the context tests pass and I
believe this should address #5733.
This commit is contained in:
Paul Hinze 2016-03-21 18:17:18 -05:00
parent 293c6ca68c
commit 024dcc9d32
2 changed files with 14 additions and 10 deletions

View File

@ -81,11 +81,12 @@ func (w *ContextGraphWalker) EnterPath(path []string) EvalContext {
StateValue: w.Context.state,
StateLock: &w.Context.stateLock,
Interpolater: &Interpolater{
Operation: w.Operation,
Module: w.Context.module,
State: w.Context.state,
StateLock: &w.Context.stateLock,
Variables: variables,
Operation: w.Operation,
Module: w.Context.module,
State: w.Context.state,
StateLock: &w.Context.stateLock,
Variables: variables,
VariablesLock: &w.interpolaterVarLock,
},
InterpolaterVars: w.interpolaterVars,
InterpolaterVarLock: &w.interpolaterVarLock,

View File

@ -23,11 +23,12 @@ const (
// Interpolater is the structure responsible for determining the values
// for interpolations such as `aws_instance.foo.bar`.
type Interpolater struct {
Operation walkOperation
Module *module.Tree
State *State
StateLock *sync.RWMutex
Variables map[string]string
Operation walkOperation
Module *module.Tree
State *State
StateLock *sync.RWMutex
Variables map[string]string
VariablesLock *sync.Mutex
}
// InterpolationScope is the current scope of execution. This is required
@ -273,6 +274,8 @@ func (i *Interpolater) valueUserVar(
n string,
v *config.UserVariable,
result map[string]ast.Variable) error {
i.VariablesLock.Lock()
defer i.VariablesLock.Unlock()
val, ok := i.Variables[v.Name]
if ok {
result[n] = ast.Variable{