github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/graph_walk_context.go (about) 1 package terraform 2 3 import ( 4 "context" 5 "sync" 6 7 "github.com/zclconf/go-cty/cty" 8 9 "github.com/muratcelep/terraform/not-internal/addrs" 10 "github.com/muratcelep/terraform/not-internal/configs" 11 "github.com/muratcelep/terraform/not-internal/configs/configschema" 12 "github.com/muratcelep/terraform/not-internal/instances" 13 "github.com/muratcelep/terraform/not-internal/plans" 14 "github.com/muratcelep/terraform/not-internal/providers" 15 "github.com/muratcelep/terraform/not-internal/provisioners" 16 "github.com/muratcelep/terraform/not-internal/refactoring" 17 "github.com/muratcelep/terraform/not-internal/states" 18 "github.com/muratcelep/terraform/not-internal/tfdiags" 19 ) 20 21 // ContextGraphWalker is the GraphWalker implementation used with the 22 // Context struct to walk and evaluate the graph. 23 type ContextGraphWalker struct { 24 NullGraphWalker 25 26 // Configurable values 27 Context *Context 28 State *states.SyncState // Used for safe concurrent access to state 29 RefreshState *states.SyncState // Used for safe concurrent access to state 30 PrevRunState *states.SyncState // Used for safe concurrent access to state 31 Changes *plans.ChangesSync // Used for safe concurrent writes to changes 32 InstanceExpander *instances.Expander // Tracks our gradual expansion of module and resource instances 33 MoveResults refactoring.MoveResults // Read-only record of earlier processing of move statements 34 Operation walkOperation 35 StopContext context.Context 36 RootVariableValues InputValues 37 Config *configs.Config 38 39 // This is an output. Do not set this, nor read it while a graph walk 40 // is in progress. 41 NonFatalDiagnostics tfdiags.Diagnostics 42 43 once sync.Once 44 contexts map[string]*BuiltinEvalContext 45 contextLock sync.Mutex 46 variableValues map[string]map[string]cty.Value 47 variableValuesLock sync.Mutex 48 providerCache map[string]providers.Interface 49 providerSchemas map[string]*ProviderSchema 50 providerLock sync.Mutex 51 provisionerCache map[string]provisioners.Interface 52 provisionerSchemas map[string]*configschema.Block 53 provisionerLock sync.Mutex 54 } 55 56 func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext { 57 w.contextLock.Lock() 58 defer w.contextLock.Unlock() 59 60 // If we already have a context for this path cached, use that 61 key := path.String() 62 if ctx, ok := w.contexts[key]; ok { 63 return ctx 64 } 65 66 ctx := w.EvalContext().WithPath(path) 67 w.contexts[key] = ctx.(*BuiltinEvalContext) 68 return ctx 69 } 70 71 func (w *ContextGraphWalker) EvalContext() EvalContext { 72 w.once.Do(w.init) 73 74 // Our evaluator shares some locks with the main context and the walker 75 // so that we can safely run multiple evaluations at once across 76 // different modules. 77 evaluator := &Evaluator{ 78 Meta: w.Context.meta, 79 Config: w.Config, 80 Operation: w.Operation, 81 State: w.State, 82 Changes: w.Changes, 83 Plugins: w.Context.plugins, 84 VariableValues: w.variableValues, 85 VariableValuesLock: &w.variableValuesLock, 86 } 87 88 ctx := &BuiltinEvalContext{ 89 StopContext: w.StopContext, 90 Hooks: w.Context.hooks, 91 InputValue: w.Context.uiInput, 92 InstanceExpanderValue: w.InstanceExpander, 93 Plugins: w.Context.plugins, 94 MoveResultsValue: w.MoveResults, 95 ProviderCache: w.providerCache, 96 ProviderInputConfig: w.Context.providerInputConfig, 97 ProviderLock: &w.providerLock, 98 ProvisionerCache: w.provisionerCache, 99 ProvisionerLock: &w.provisionerLock, 100 ChangesValue: w.Changes, 101 StateValue: w.State, 102 RefreshStateValue: w.RefreshState, 103 PrevRunStateValue: w.PrevRunState, 104 Evaluator: evaluator, 105 VariableValues: w.variableValues, 106 VariableValuesLock: &w.variableValuesLock, 107 } 108 109 return ctx 110 } 111 112 func (w *ContextGraphWalker) init() { 113 w.contexts = make(map[string]*BuiltinEvalContext) 114 w.providerCache = make(map[string]providers.Interface) 115 w.providerSchemas = make(map[string]*ProviderSchema) 116 w.provisionerCache = make(map[string]provisioners.Interface) 117 w.provisionerSchemas = make(map[string]*configschema.Block) 118 w.variableValues = make(map[string]map[string]cty.Value) 119 120 // Populate root module variable values. Other modules will be populated 121 // during the graph walk. 122 w.variableValues[""] = make(map[string]cty.Value) 123 for k, iv := range w.RootVariableValues { 124 w.variableValues[""][k] = iv.Value 125 } 126 } 127 128 func (w *ContextGraphWalker) Execute(ctx EvalContext, n GraphNodeExecutable) tfdiags.Diagnostics { 129 // Acquire a lock on the semaphore 130 w.Context.parallelSem.Acquire() 131 defer w.Context.parallelSem.Release() 132 133 return n.Execute(ctx, w.Operation) 134 }