2015-02-04 17:44:23 -06:00
|
|
|
package terraform
|
|
|
|
|
|
|
|
import (
|
2016-12-22 13:33:26 -06:00
|
|
|
"context"
|
2015-02-13 18:27:23 -06:00
|
|
|
"fmt"
|
2015-02-16 21:04:05 -06:00
|
|
|
"log"
|
2020-10-29 15:39:38 -05:00
|
|
|
"strings"
|
2015-02-04 17:44:23 -06:00
|
|
|
"sync"
|
|
|
|
|
2020-10-29 15:39:38 -05:00
|
|
|
"github.com/apparentlymart/go-versions/versions"
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
|
|
"github.com/hashicorp/terraform/configs"
|
2019-11-21 18:21:41 -06:00
|
|
|
"github.com/hashicorp/terraform/instances"
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
"github.com/hashicorp/terraform/lang"
|
|
|
|
"github.com/hashicorp/terraform/plans"
|
2018-08-16 10:40:08 -05:00
|
|
|
"github.com/hashicorp/terraform/providers"
|
2018-08-17 11:42:07 -05:00
|
|
|
"github.com/hashicorp/terraform/provisioners"
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
"github.com/hashicorp/terraform/states"
|
2017-11-21 17:08:00 -06:00
|
|
|
"github.com/hashicorp/terraform/tfdiags"
|
2019-08-07 16:50:59 -05:00
|
|
|
"github.com/zclconf/go-cty/cty"
|
2016-09-14 22:59:02 -05:00
|
|
|
|
2020-10-29 15:39:38 -05:00
|
|
|
"github.com/hashicorp/terraform/internal/depsfile"
|
|
|
|
"github.com/hashicorp/terraform/internal/getproviders"
|
2020-10-18 09:01:48 -05:00
|
|
|
_ "github.com/hashicorp/terraform/internal/logging"
|
|
|
|
)
|
2020-10-17 08:38:18 -05:00
|
|
|
|
2016-10-19 15:41:30 -05:00
|
|
|
// InputMode defines what sort of input will be asked for when Input
|
|
|
|
// is called on Context.
|
|
|
|
type InputMode byte
|
|
|
|
|
2015-02-13 19:29:38 -06:00
|
|
|
const (
|
|
|
|
// InputModeProvider asks for provider variables
|
2019-10-08 14:08:27 -05:00
|
|
|
InputModeProvider InputMode = 1 << iota
|
2015-02-13 19:29:38 -06:00
|
|
|
|
|
|
|
// InputModeStd is the standard operating mode and asks for both variables
|
|
|
|
// and providers.
|
2019-10-08 14:08:27 -05:00
|
|
|
InputModeStd = InputModeProvider
|
2015-02-13 19:29:38 -06:00
|
|
|
)
|
|
|
|
|
2015-02-04 17:44:23 -06:00
|
|
|
// ContextOpts are the user-configurable options to create a context with
|
|
|
|
// NewContext.
|
|
|
|
type ContextOpts struct {
|
2020-09-23 10:04:27 -05:00
|
|
|
Config *configs.Config
|
|
|
|
Changes *plans.Changes
|
|
|
|
State *states.State
|
|
|
|
Targets []addrs.Targetable
|
|
|
|
Variables InputValues
|
|
|
|
Meta *ContextMeta
|
|
|
|
Destroy bool
|
|
|
|
SkipRefresh bool
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
|
2020-03-30 17:30:56 -05:00
|
|
|
Hooks []Hook
|
|
|
|
Parallelism int
|
|
|
|
Providers map[addrs.Provider]providers.Factory
|
|
|
|
Provisioners map[string]provisioners.Factory
|
2015-02-04 17:44:23 -06:00
|
|
|
|
2017-05-24 18:33:26 -05:00
|
|
|
// If non-nil, will apply as additional constraints on the provider
|
|
|
|
// plugins that will be requested from the provider resolver.
|
2020-09-07 14:16:18 -05:00
|
|
|
ProviderSHA256s map[string][]byte
|
2017-05-24 18:33:26 -05:00
|
|
|
|
2020-10-29 15:39:38 -05:00
|
|
|
// If non-nil, will be verified to ensure that provider requirements from
|
|
|
|
// configuration can be satisfied by the set of locked dependencies.
|
|
|
|
LockedDependencies *depsfile.Locks
|
|
|
|
|
|
|
|
// Set of providers to exclude from the requirements check process, as they
|
|
|
|
// are marked as in local development.
|
|
|
|
ProvidersInDevelopment map[addrs.Provider]struct{}
|
|
|
|
|
2015-02-04 17:44:23 -06:00
|
|
|
UIInput UIInput
|
|
|
|
}
|
|
|
|
|
2017-03-13 18:14:27 -05:00
|
|
|
// ContextMeta is metadata about the running context. This is information
|
|
|
|
// that this package or structure cannot determine on its own but exposes
|
|
|
|
// into Terraform in various ways. This must be provided by the Context
|
|
|
|
// initializer.
|
|
|
|
type ContextMeta struct {
|
|
|
|
Env string // Env is the state environment
|
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-01 17:45:12 -05:00
|
|
|
|
|
|
|
// OriginalWorkingDir is the working directory where the Terraform CLI
|
|
|
|
// was run from, which may no longer actually be the current working
|
|
|
|
// directory if the user included the -chdir=... option.
|
|
|
|
//
|
|
|
|
// If this string is empty then the original working directory is the same
|
|
|
|
// as the current working directory.
|
|
|
|
//
|
|
|
|
// In most cases we should respect the user's override by ignoring this
|
|
|
|
// path and just using the current working directory, but this is here
|
|
|
|
// for some exceptional cases where the original working directory is
|
|
|
|
// needed.
|
|
|
|
OriginalWorkingDir string
|
2017-03-13 18:14:27 -05:00
|
|
|
}
|
|
|
|
|
2015-02-04 17:44:23 -06:00
|
|
|
// Context represents all the context that Terraform needs in order to
|
|
|
|
// perform operations on infrastructure. This structure is built using
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
// NewContext.
|
2015-02-13 20:15:36 -06:00
|
|
|
type Context struct {
|
2020-09-04 15:51:11 -05:00
|
|
|
config *configs.Config
|
|
|
|
changes *plans.Changes
|
|
|
|
state *states.State
|
|
|
|
refreshState *states.State
|
2020-09-23 10:04:27 -05:00
|
|
|
skipRefresh bool
|
2020-09-04 15:51:11 -05:00
|
|
|
targets []addrs.Targetable
|
|
|
|
variables InputValues
|
|
|
|
meta *ContextMeta
|
|
|
|
destroy bool
|
2016-10-03 02:01:11 -05:00
|
|
|
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
hooks []Hook
|
2016-10-03 20:23:37 -05:00
|
|
|
components contextComponentFactory
|
2018-05-31 14:39:45 -05:00
|
|
|
schemas *Schemas
|
2016-10-03 20:23:37 -05:00
|
|
|
sh *stopHook
|
|
|
|
uiInput UIInput
|
2015-02-13 11:05:09 -06:00
|
|
|
|
2015-02-13 19:59:54 -06:00
|
|
|
l sync.Mutex // Lock acquired during any task
|
2015-02-16 22:27:29 -06:00
|
|
|
parallelSem Semaphore
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
providerInputConfig map[string]map[string]cty.Value
|
2017-06-05 19:08:02 -05:00
|
|
|
providerSHA256s map[string][]byte
|
2016-12-27 19:16:14 -06:00
|
|
|
runCond *sync.Cond
|
2016-12-22 13:33:26 -06:00
|
|
|
runContext context.Context
|
|
|
|
runContextCancel context.CancelFunc
|
2015-02-04 17:44:23 -06:00
|
|
|
}
|
|
|
|
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
// (additional methods on Context can be found in context_*.go files.)
|
|
|
|
|
2015-02-04 17:44:23 -06:00
|
|
|
// NewContext creates a new Context structure.
|
|
|
|
//
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
// Once a Context is created, the caller must not access or mutate any of
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
// the objects referenced (directly or indirectly) by the ContextOpts fields.
|
|
|
|
//
|
|
|
|
// If the returned diagnostics contains errors then the resulting context is
|
|
|
|
// invalid and must not be used.
|
|
|
|
func NewContext(opts *ContextOpts) (*Context, tfdiags.Diagnostics) {
|
2018-10-11 18:36:09 -05:00
|
|
|
log.Printf("[TRACE] terraform.NewContext: starting")
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
diags := CheckCoreVersionRequirements(opts.Config)
|
|
|
|
// If version constraints are not met then we'll bail early since otherwise
|
|
|
|
// we're likely to just see a bunch of other errors related to
|
|
|
|
// incompatibilities, which could be overwhelming for the user.
|
|
|
|
if diags.HasErrors() {
|
|
|
|
return nil, diags
|
2016-11-12 18:50:26 -06:00
|
|
|
}
|
|
|
|
|
2015-02-13 11:05:09 -06:00
|
|
|
// Copy all the hooks and add our stop hook. We don't append directly
|
|
|
|
// to the Config so that we're not modifying that in-place.
|
|
|
|
sh := new(stopHook)
|
|
|
|
hooks := make([]Hook, len(opts.Hooks)+1)
|
|
|
|
copy(hooks, opts.Hooks)
|
|
|
|
hooks[len(opts.Hooks)] = sh
|
|
|
|
|
2015-02-11 17:22:03 -06:00
|
|
|
state := opts.State
|
|
|
|
if state == nil {
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
state = states.NewState()
|
2016-03-11 13:07:54 -06:00
|
|
|
}
|
|
|
|
|
2015-02-16 22:27:29 -06:00
|
|
|
// Determine parallelism, default to 10. We do this both to limit
|
|
|
|
// CPU pressure but also to have an extra guard against rate throttling
|
|
|
|
// from providers.
|
2020-02-12 09:10:52 -06:00
|
|
|
// We throw an error in case of negative parallelism
|
2015-02-16 22:27:29 -06:00
|
|
|
par := opts.Parallelism
|
2020-02-12 09:10:52 -06:00
|
|
|
if par < 0 {
|
|
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
|
|
tfdiags.Error,
|
|
|
|
"Invalid parallelism value",
|
|
|
|
fmt.Sprintf("The parallelism must be a positive value. Not %d.", par),
|
|
|
|
))
|
|
|
|
return nil, diags
|
|
|
|
}
|
|
|
|
|
2015-02-16 22:27:29 -06:00
|
|
|
if par == 0 {
|
|
|
|
par = 10
|
|
|
|
}
|
|
|
|
|
core: Allow lists and maps as variable overrides
Terraform 0.7 introduces lists and maps as first-class values for
variables, in addition to string values which were previously available.
However, there was previously no way to override the default value of a
list or map, and the functionality for overriding specific map keys was
broken.
Using the environment variable method for setting variable values, there
was previously no way to give a variable a value of a list or map. These
now support HCL for individual values - specifying:
TF_VAR_test='["Hello", "World"]'
will set the variable `test` to a two-element list containing "Hello"
and "World". Specifying
TF_VAR_test_map='{"Hello = "World", "Foo" = "bar"}'
will set the variable `test_map` to a two-element map with keys "Hello"
and "Foo", and values "World" and "bar" respectively.
The same logic is applied to `-var` flags, and the file parsed by
`-var-files` ("autoVariables").
Note that care must be taken to not run into shell expansion for `-var-`
flags and environment variables.
We also merge map keys where appropriate. The override syntax has
changed (to be noted in CHANGELOG as a breaking change), so several
tests needed their syntax updating from the old `amis.us-east-1 =
"newValue"` style to `amis = "{ "us-east-1" = "newValue"}"` style as
defined in TF-002.
In order to continue supporting the `-var "foo=bar"` type of variable
flag (which is not valid HCL), a special case error is checked after HCL
parsing fails, and the old code path runs instead.
2016-07-20 20:38:26 -05:00
|
|
|
// Set up the variables in the following sequence:
|
|
|
|
// 0 - Take default values from the configuration
|
|
|
|
// 1 - Take values from TF_VAR_x environment variables
|
|
|
|
// 2 - Take values specified in -var flags, overriding values
|
|
|
|
// set by environment variables if necessary. This includes
|
|
|
|
// values taken from -var-file in addition.
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
var variables InputValues
|
|
|
|
if opts.Config != nil {
|
|
|
|
// Default variables from the configuration seed our map.
|
|
|
|
variables = DefaultVariableValues(opts.Config.Module.Variables)
|
2015-05-14 11:58:30 -05:00
|
|
|
}
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
// Variables provided by the caller (from CLI, environment, etc) can
|
|
|
|
// override the defaults.
|
|
|
|
variables = variables.Override(opts.Variables)
|
2015-05-13 22:09:05 -05:00
|
|
|
|
2018-05-31 14:39:45 -05:00
|
|
|
components := &basicComponentFactory{
|
2020-03-30 17:30:56 -05:00
|
|
|
providers: opts.Providers,
|
2018-05-31 14:39:45 -05:00
|
|
|
provisioners: opts.Provisioners,
|
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:09 -05:00
|
|
|
log.Printf("[TRACE] terraform.NewContext: loading provider schemas")
|
2018-05-31 14:39:45 -05:00
|
|
|
schemas, err := LoadSchemas(opts.Config, opts.State, components)
|
|
|
|
if err != nil {
|
2020-04-21 15:29:27 -05:00
|
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
|
|
tfdiags.Error,
|
|
|
|
"Could not load plugin",
|
|
|
|
fmt.Sprintf(errPluginInit, err),
|
|
|
|
))
|
2018-05-31 14:39:45 -05:00
|
|
|
return nil, diags
|
|
|
|
}
|
|
|
|
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
changes := opts.Changes
|
|
|
|
if changes == nil {
|
|
|
|
changes = plans.NewChanges()
|
|
|
|
}
|
|
|
|
|
|
|
|
config := opts.Config
|
|
|
|
if config == nil {
|
|
|
|
config = configs.NewEmptyConfig()
|
2016-12-02 09:53:29 -06:00
|
|
|
}
|
|
|
|
|
2020-10-29 15:39:38 -05:00
|
|
|
// If we have a configuration and a set of locked dependencies, verify that
|
|
|
|
// the provider requirements from the configuration can be satisfied by the
|
|
|
|
// locked dependencies.
|
|
|
|
if opts.LockedDependencies != nil {
|
|
|
|
reqs, providerDiags := config.ProviderRequirements()
|
|
|
|
diags = diags.Append(providerDiags)
|
|
|
|
|
|
|
|
locked := opts.LockedDependencies.AllProviders()
|
|
|
|
unmetReqs := make(getproviders.Requirements)
|
|
|
|
for provider, versionConstraints := range reqs {
|
|
|
|
// Builtin providers are not listed in the locks file
|
|
|
|
if provider.IsBuiltIn() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// Development providers must be excluded from this check
|
|
|
|
if _, ok := opts.ProvidersInDevelopment[provider]; ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// If the required provider doesn't exist in the lock, or the
|
|
|
|
// locked version doesn't meet the constraints, mark the
|
|
|
|
// requirement unmet
|
|
|
|
acceptable := versions.MeetingConstraints(versionConstraints)
|
|
|
|
if lock, ok := locked[provider]; !ok || !acceptable.Has(lock.Version()) {
|
|
|
|
unmetReqs[provider] = versionConstraints
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(unmetReqs) > 0 {
|
|
|
|
var buf strings.Builder
|
|
|
|
for provider, versionConstraints := range unmetReqs {
|
|
|
|
fmt.Fprintf(&buf, "\n- %s", provider)
|
|
|
|
if len(versionConstraints) > 0 {
|
|
|
|
fmt.Fprintf(&buf, " (%s)", getproviders.VersionConstraintsString(versionConstraints))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
|
|
tfdiags.Error,
|
|
|
|
"Provider requirements cannot be satisfied by locked dependencies",
|
|
|
|
fmt.Sprintf("The following required providers are not installed:\n%s\n\nPlease run \"terraform init\".", buf.String()),
|
|
|
|
))
|
|
|
|
return nil, diags
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:09 -05:00
|
|
|
log.Printf("[TRACE] terraform.NewContext: complete")
|
|
|
|
|
2019-10-07 17:24:16 -05:00
|
|
|
// By the time we get here, we should have values defined for all of
|
|
|
|
// the root module variables, even if some of them are "unknown". It's the
|
|
|
|
// caller's responsibility to have already handled the decoding of these
|
|
|
|
// from the various ways the CLI allows them to be set and to produce
|
|
|
|
// user-friendly error messages if they are not all present, and so
|
|
|
|
// the error message from checkInputVariables should never be seen and
|
|
|
|
// includes language asking the user to report a bug.
|
|
|
|
if config != nil {
|
|
|
|
varDiags := checkInputVariables(config.Module.Variables, variables)
|
|
|
|
diags = diags.Append(varDiags)
|
|
|
|
}
|
|
|
|
|
2015-02-13 20:15:36 -06:00
|
|
|
return &Context{
|
2020-09-04 15:51:11 -05:00
|
|
|
components: components,
|
|
|
|
schemas: schemas,
|
|
|
|
destroy: opts.Destroy,
|
|
|
|
changes: changes,
|
|
|
|
hooks: hooks,
|
|
|
|
meta: opts.Meta,
|
|
|
|
config: config,
|
|
|
|
state: state,
|
|
|
|
refreshState: state.DeepCopy(),
|
2020-09-23 10:04:27 -05:00
|
|
|
skipRefresh: opts.SkipRefresh,
|
2020-09-04 15:51:11 -05:00
|
|
|
targets: opts.Targets,
|
|
|
|
uiInput: opts.UIInput,
|
|
|
|
variables: variables,
|
2015-02-16 22:27:29 -06:00
|
|
|
|
|
|
|
parallelSem: NewSemaphore(par),
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
providerInputConfig: make(map[string]map[string]cty.Value),
|
2017-06-05 19:08:02 -05:00
|
|
|
providerSHA256s: opts.ProviderSHA256s,
|
2015-02-13 19:59:54 -06:00
|
|
|
sh: sh,
|
2019-10-07 17:24:16 -05:00
|
|
|
}, diags
|
2015-02-04 17:44:23 -06:00
|
|
|
}
|
|
|
|
|
2018-08-29 14:12:18 -05:00
|
|
|
func (c *Context) Schemas() *Schemas {
|
|
|
|
return c.schemas
|
|
|
|
}
|
|
|
|
|
2015-04-23 10:52:31 -05:00
|
|
|
type ContextGraphOpts struct {
|
2016-12-02 21:38:49 -06:00
|
|
|
// If true, validates the graph structure (checks for cycles).
|
2015-04-23 10:52:31 -05:00
|
|
|
Validate bool
|
2016-12-02 21:38:49 -06:00
|
|
|
|
|
|
|
// Legacy graphs only: won't prune the graph
|
|
|
|
Verbose bool
|
2015-04-23 10:52:31 -05:00
|
|
|
}
|
|
|
|
|
2016-12-02 21:38:49 -06:00
|
|
|
// Graph returns the graph used for the given operation type.
|
|
|
|
//
|
|
|
|
// The most extensive or complex graph type is GraphTypePlan.
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
func (c *Context) Graph(typ GraphType, opts *ContextGraphOpts) (*Graph, tfdiags.Diagnostics) {
|
2016-12-02 21:38:49 -06:00
|
|
|
if opts == nil {
|
|
|
|
opts = &ContextGraphOpts{Validate: true}
|
|
|
|
}
|
|
|
|
|
2017-02-21 22:35:36 -06:00
|
|
|
log.Printf("[INFO] terraform: building graph: %s", typ)
|
2016-12-02 21:38:49 -06:00
|
|
|
switch typ {
|
|
|
|
case GraphTypeApply:
|
|
|
|
return (&ApplyGraphBuilder{
|
2018-05-02 22:16:22 -05:00
|
|
|
Config: c.config,
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
Changes: c.changes,
|
2018-05-02 22:16:22 -05:00
|
|
|
State: c.state,
|
|
|
|
Components: c.components,
|
2018-05-31 14:39:45 -05:00
|
|
|
Schemas: c.schemas,
|
2018-05-02 22:16:22 -05:00
|
|
|
Targets: c.targets,
|
|
|
|
Validate: opts.Validate,
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
}).Build(addrs.RootModuleInstance)
|
2016-12-02 21:38:49 -06:00
|
|
|
|
2017-01-25 14:24:48 -06:00
|
|
|
case GraphTypeValidate:
|
2020-08-31 14:45:39 -05:00
|
|
|
// The validate graph is just a slightly modified plan graph: an empty
|
|
|
|
// state is substituted in for Validate.
|
|
|
|
return ValidateGraphBuilder(&PlanGraphBuilder{
|
|
|
|
Config: c.config,
|
|
|
|
Components: c.components,
|
|
|
|
Schemas: c.schemas,
|
|
|
|
Targets: c.targets,
|
|
|
|
Validate: opts.Validate,
|
|
|
|
State: states.NewState(),
|
|
|
|
}).Build(addrs.RootModuleInstance)
|
|
|
|
|
2016-12-02 21:38:49 -06:00
|
|
|
case GraphTypePlan:
|
2017-01-25 14:24:48 -06:00
|
|
|
// Create the plan graph builder
|
2020-08-31 14:45:39 -05:00
|
|
|
return (&PlanGraphBuilder{
|
2020-09-23 10:04:27 -05:00
|
|
|
Config: c.config,
|
|
|
|
State: c.state,
|
|
|
|
Components: c.components,
|
|
|
|
Schemas: c.schemas,
|
|
|
|
Targets: c.targets,
|
|
|
|
Validate: opts.Validate,
|
|
|
|
skipRefresh: c.skipRefresh,
|
2020-08-31 14:45:39 -05:00
|
|
|
}).Build(addrs.RootModuleInstance)
|
2016-12-02 21:38:49 -06:00
|
|
|
|
|
|
|
case GraphTypePlanDestroy:
|
|
|
|
return (&DestroyPlanGraphBuilder{
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
Config: c.config,
|
|
|
|
State: c.state,
|
|
|
|
Components: c.components,
|
|
|
|
Schemas: c.schemas,
|
|
|
|
Targets: c.targets,
|
|
|
|
Validate: opts.Validate,
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
}).Build(addrs.RootModuleInstance)
|
2016-12-02 21:38:49 -06:00
|
|
|
|
2018-05-03 22:41:46 -05:00
|
|
|
case GraphTypeEval:
|
|
|
|
return (&EvalGraphBuilder{
|
|
|
|
Config: c.config,
|
|
|
|
State: c.state,
|
|
|
|
Components: c.components,
|
2018-05-31 14:39:45 -05:00
|
|
|
Schemas: c.schemas,
|
2018-05-03 22:41:46 -05:00
|
|
|
}).Build(addrs.RootModuleInstance)
|
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
default:
|
|
|
|
// Should never happen, because the above is exhaustive for all graph types.
|
|
|
|
panic(fmt.Errorf("unsupported graph type %s", typ))
|
|
|
|
}
|
2015-02-13 20:22:08 -06:00
|
|
|
}
|
|
|
|
|
2017-01-18 22:50:57 -06:00
|
|
|
// State returns a copy of the current state associated with this context.
|
|
|
|
//
|
|
|
|
// This cannot safely be called in parallel with any other Context function.
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
func (c *Context) State() *states.State {
|
2017-01-18 22:50:57 -06:00
|
|
|
return c.state.DeepCopy()
|
|
|
|
}
|
|
|
|
|
2018-05-03 22:41:46 -05:00
|
|
|
// Eval produces a scope in which expressions can be evaluated for
|
|
|
|
// the given module path.
|
|
|
|
//
|
|
|
|
// This method must first evaluate any ephemeral values (input variables, local
|
|
|
|
// values, and output values) in the configuration. These ephemeral values are
|
|
|
|
// not included in the persisted state, so they must be re-computed using other
|
|
|
|
// values in the state before they can be properly evaluated. The updated
|
|
|
|
// values are retained in the main state associated with the receiving context.
|
|
|
|
//
|
|
|
|
// This function takes no action against remote APIs but it does need access
|
|
|
|
// to all provider and provisioner instances in order to obtain their schemas
|
|
|
|
// for type checking.
|
|
|
|
//
|
|
|
|
// The result is an evaluation scope that can be used to resolve references
|
|
|
|
// against the root module. If the returned diagnostics contains errors then
|
|
|
|
// the returned scope may be nil. If it is not nil then it may still be used
|
|
|
|
// to attempt expression evaluation or other analysis, but some expressions
|
|
|
|
// may not behave as expected.
|
|
|
|
func (c *Context) Eval(path addrs.ModuleInstance) (*lang.Scope, tfdiags.Diagnostics) {
|
|
|
|
// This is intended for external callers such as the "terraform console"
|
|
|
|
// command. Internally, we create an evaluator in c.walk before walking
|
|
|
|
// the graph, and create scopes in ContextGraphWalker.
|
|
|
|
|
|
|
|
var diags tfdiags.Diagnostics
|
|
|
|
defer c.acquireRun("eval")()
|
|
|
|
|
|
|
|
// Start with a copy of state so that we don't affect any instances
|
|
|
|
// that other methods may have already returned.
|
|
|
|
c.state = c.state.DeepCopy()
|
|
|
|
var walker *ContextGraphWalker
|
|
|
|
|
|
|
|
graph, graphDiags := c.Graph(GraphTypeEval, nil)
|
|
|
|
diags = diags.Append(graphDiags)
|
|
|
|
if !diags.HasErrors() {
|
|
|
|
var walkDiags tfdiags.Diagnostics
|
|
|
|
walker, walkDiags = c.walk(graph, walkEval)
|
|
|
|
diags = diags.Append(walker.NonFatalDiagnostics)
|
|
|
|
diags = diags.Append(walkDiags)
|
|
|
|
}
|
|
|
|
|
|
|
|
if walker == nil {
|
|
|
|
// If we skipped walking the graph (due to errors) then we'll just
|
|
|
|
// use a placeholder graph walker here, which'll refer to the
|
|
|
|
// unmodified state.
|
|
|
|
walker = c.graphWalker(walkEval)
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is a bit weird since we don't normally evaluate outside of
|
|
|
|
// the context of a walk, but we'll "re-enter" our desired path here
|
|
|
|
// just to get hold of an EvalContext for it. GraphContextBuiltin
|
|
|
|
// caches its contexts, so we should get hold of the context that was
|
|
|
|
// previously used for evaluation here, unless we skipped walking.
|
|
|
|
evalCtx := walker.EnterPath(path)
|
2018-06-22 15:04:19 -05:00
|
|
|
return evalCtx.EvaluationScope(nil, EvalDataForNoInstanceKey), diags
|
2016-11-14 00:04:11 -06:00
|
|
|
}
|
|
|
|
|
2015-02-12 16:46:22 -06:00
|
|
|
// Apply applies the changes represented by this context and returns
|
|
|
|
// the resulting state.
|
|
|
|
//
|
2017-04-14 09:53:08 -05:00
|
|
|
// Even in the case an error is returned, the state may be returned and will
|
|
|
|
// potentially be partially updated. In addition to returning the resulting
|
|
|
|
// state, this context is updated with the latest state.
|
|
|
|
//
|
|
|
|
// If the state is required after an error, the caller should call
|
|
|
|
// Context.State, rather than rely on the return value.
|
|
|
|
//
|
|
|
|
// TODO: Apply and Refresh should either always return a state, or rely on the
|
|
|
|
// State() method. Currently the helper/resource testing framework relies
|
|
|
|
// on the absence of a returned state to determine if Destroy can be
|
|
|
|
// called, so that will need to be refactored before this can be changed.
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
func (c *Context) Apply() (*states.State, tfdiags.Diagnostics) {
|
2016-12-22 13:33:26 -06:00
|
|
|
defer c.acquireRun("apply")()
|
2015-02-13 11:05:09 -06:00
|
|
|
|
2015-02-12 16:46:22 -06:00
|
|
|
// Copy our own state
|
2015-02-23 23:32:27 -06:00
|
|
|
c.state = c.state.DeepCopy()
|
2015-02-12 16:46:22 -06:00
|
|
|
|
2016-11-10 09:54:39 -06:00
|
|
|
// Build the graph.
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
graph, diags := c.Graph(GraphTypeApply, nil)
|
|
|
|
if diags.HasErrors() {
|
|
|
|
return nil, diags
|
2015-04-23 10:52:31 -05:00
|
|
|
}
|
|
|
|
|
2016-10-19 16:17:12 -05:00
|
|
|
// Determine the operation
|
|
|
|
operation := walkApply
|
|
|
|
if c.destroy {
|
|
|
|
operation = walkDestroy
|
|
|
|
}
|
|
|
|
|
|
|
|
// Walk the graph
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
walker, walkDiags := c.walk(graph, operation)
|
|
|
|
diags = diags.Append(walker.NonFatalDiagnostics)
|
|
|
|
diags = diags.Append(walkDiags)
|
2015-02-12 16:46:22 -06:00
|
|
|
|
2018-09-30 10:51:47 -05:00
|
|
|
if c.destroy && !diags.HasErrors() {
|
|
|
|
// If we know we were trying to destroy objects anyway, and we
|
|
|
|
// completed without any errors, then we'll also prune out any
|
|
|
|
// leftover empty resource husks (left after all of the instances
|
|
|
|
// of a resource with "count" or "for_each" are destroyed) to
|
|
|
|
// help ensure we end up with an _actually_ empty state, assuming
|
|
|
|
// we weren't destroying with -target here.
|
|
|
|
//
|
|
|
|
// (This doesn't actually take into account -target, but that should
|
|
|
|
// be okay because it doesn't throw away anything we can't recompute
|
|
|
|
// on a subsequent "terraform plan" run, if the resources are still
|
|
|
|
// present in the configuration. However, this _will_ cause "count = 0"
|
|
|
|
// resources to read as unknown during the next refresh walk, which
|
|
|
|
// may cause some additional churn if used in a data resource or
|
|
|
|
// provider block, until we remove refreshing as a separate walk and
|
|
|
|
// just do it as part of the plan walk.)
|
|
|
|
c.state.PruneResourceHusks()
|
|
|
|
}
|
|
|
|
|
2019-09-12 14:11:54 -05:00
|
|
|
if len(c.targets) > 0 {
|
|
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
|
|
tfdiags.Warning,
|
|
|
|
"Applied changes may be incomplete",
|
|
|
|
`The plan was created with the -target option in effect, so some changes requested in the configuration may have been ignored and the output values may not be fully updated. Run the following command to verify that no other changes are pending:
|
|
|
|
terraform plan
|
|
|
|
|
|
|
|
Note that the -target option is not suitable for routine use, and is provided only for exceptional situations such as recovering from errors or mistakes, or when Terraform specifically suggests to use it as part of an error message.`,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2020-09-11 16:27:12 -05:00
|
|
|
// This isn't technically needed, but don't leave an old refreshed state
|
|
|
|
// around in case we re-use the context in internal tests.
|
|
|
|
c.refreshState = c.state.DeepCopy()
|
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
return c.state, diags
|
2015-02-12 16:46:22 -06:00
|
|
|
}
|
|
|
|
|
2020-09-04 15:51:11 -05:00
|
|
|
// Plan generates an execution plan for the given context, and returns the
|
|
|
|
// refreshed state.
|
2015-02-11 17:22:03 -06:00
|
|
|
//
|
|
|
|
// The execution plan encapsulates the context and can be stored
|
|
|
|
// in order to reinstantiate a context later for Apply.
|
|
|
|
//
|
|
|
|
// Plan also updates the diff of this context to be the diff generated
|
|
|
|
// by the plan, so Apply can be called after.
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
func (c *Context) Plan() (*plans.Plan, tfdiags.Diagnostics) {
|
2016-12-22 13:33:26 -06:00
|
|
|
defer c.acquireRun("plan")()
|
2018-10-15 20:08:01 -05:00
|
|
|
c.changes = plans.NewChanges()
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
var diags tfdiags.Diagnostics
|
2017-06-05 19:08:02 -05:00
|
|
|
|
2019-09-12 14:11:54 -05:00
|
|
|
if len(c.targets) > 0 {
|
|
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
|
|
tfdiags.Warning,
|
|
|
|
"Resource targeting is in effect",
|
|
|
|
`You are creating a plan with the -target option, which means that the result of this plan may not represent all of the changes requested by the current configuration.
|
|
|
|
|
|
|
|
The -target option is not for routine use, and is provided only for exceptional situations such as recovering from errors or mistakes, or when Terraform specifically suggests to use it as part of an error message.`,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
varVals := make(map[string]plans.DynamicValue, len(c.variables))
|
|
|
|
for k, iv := range c.variables {
|
|
|
|
// We use cty.DynamicPseudoType here so that we'll save both the
|
|
|
|
// value _and_ its dynamic type in the plan, so we can recover
|
|
|
|
// exactly the same value later.
|
|
|
|
dv, err := plans.NewDynamicValue(iv.Value, cty.DynamicPseudoType)
|
|
|
|
if err != nil {
|
|
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
|
|
tfdiags.Error,
|
|
|
|
"Failed to prepare variable value for plan",
|
|
|
|
fmt.Sprintf("The value for variable %q could not be serialized to store in the plan: %s.", k, err),
|
|
|
|
))
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
varVals[k] = dv
|
|
|
|
}
|
|
|
|
|
|
|
|
p := &plans.Plan{
|
|
|
|
VariableValues: varVals,
|
|
|
|
TargetAddrs: c.targets,
|
|
|
|
ProviderSHA256s: c.providerSHA256s,
|
2015-02-11 17:22:03 -06:00
|
|
|
}
|
|
|
|
|
2020-09-04 17:09:47 -05:00
|
|
|
operation := walkPlan
|
2017-01-26 17:18:42 -06:00
|
|
|
graphType := GraphTypePlan
|
|
|
|
if c.destroy {
|
2020-09-04 17:09:47 -05:00
|
|
|
operation = walkPlanDestroy
|
2017-01-26 17:18:42 -06:00
|
|
|
graphType = GraphTypePlanDestroy
|
2016-10-19 02:59:56 -05:00
|
|
|
}
|
2020-09-04 17:09:47 -05:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
graph, graphDiags := c.Graph(graphType, nil)
|
|
|
|
diags = diags.Append(graphDiags)
|
|
|
|
if graphDiags.HasErrors() {
|
|
|
|
return nil, diags
|
2015-04-23 10:52:31 -05:00
|
|
|
}
|
|
|
|
|
2015-02-11 17:22:03 -06:00
|
|
|
// Do the walk
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
walker, walkDiags := c.walk(graph, operation)
|
|
|
|
diags = diags.Append(walker.NonFatalDiagnostics)
|
|
|
|
diags = diags.Append(walkDiags)
|
|
|
|
if walkDiags.HasErrors() {
|
|
|
|
return nil, diags
|
2015-02-11 19:01:08 -06:00
|
|
|
}
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
p.Changes = c.changes
|
2016-10-01 23:30:09 -05:00
|
|
|
|
2020-09-18 15:45:39 -05:00
|
|
|
c.refreshState.SyncWrapper().RemovePlannedResourceInstanceObjects()
|
2020-09-30 11:13:22 -05:00
|
|
|
|
|
|
|
refreshedState := c.refreshState.DeepCopy()
|
|
|
|
p.State = refreshedState
|
2020-09-04 15:51:11 -05:00
|
|
|
|
2020-09-04 17:09:47 -05:00
|
|
|
// replace the working state with the updated state, so that immediate calls
|
|
|
|
// to Apply work as expected.
|
2020-09-30 11:13:22 -05:00
|
|
|
c.state = refreshedState
|
2020-09-04 17:09:47 -05:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
return p, diags
|
2015-02-11 17:22:03 -06:00
|
|
|
}
|
|
|
|
|
2015-02-10 10:58:14 -06:00
|
|
|
// Refresh goes through all the resources in the state and refreshes them
|
2020-09-21 14:56:07 -05:00
|
|
|
// to their latest state. This is done by executing a plan, and retaining the
|
|
|
|
// state while discarding the change set.
|
2015-02-10 10:58:14 -06:00
|
|
|
//
|
2020-09-21 14:56:07 -05:00
|
|
|
// In the case of an error, there is no state returned.
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
|
|
|
func (c *Context) Refresh() (*states.State, tfdiags.Diagnostics) {
|
2020-09-21 14:56:07 -05:00
|
|
|
p, diags := c.Plan()
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
if diags.HasErrors() {
|
|
|
|
return nil, diags
|
2015-04-23 10:52:31 -05:00
|
|
|
}
|
|
|
|
|
2020-09-21 14:56:07 -05:00
|
|
|
return p.State, diags
|
2015-02-10 10:58:14 -06:00
|
|
|
}
|
|
|
|
|
2015-02-13 11:05:09 -06:00
|
|
|
// Stop stops the running task.
|
|
|
|
//
|
|
|
|
// Stop will block until the task completes.
|
2015-02-13 20:15:36 -06:00
|
|
|
func (c *Context) Stop() {
|
2016-12-26 18:29:44 -06:00
|
|
|
log.Printf("[WARN] terraform: Stop called, initiating interrupt sequence")
|
|
|
|
|
2015-02-13 11:05:09 -06:00
|
|
|
c.l.Lock()
|
2017-01-30 10:35:10 -06:00
|
|
|
defer c.l.Unlock()
|
2015-02-13 11:05:09 -06:00
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
// If we're running, then stop
|
|
|
|
if c.runContextCancel != nil {
|
2016-12-26 18:29:44 -06:00
|
|
|
log.Printf("[WARN] terraform: run context exists, stopping")
|
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
// Tell the hook we want to stop
|
|
|
|
c.sh.Stop()
|
2015-02-13 11:05:09 -06:00
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
// Stop the context
|
|
|
|
c.runContextCancel()
|
|
|
|
c.runContextCancel = nil
|
|
|
|
}
|
2015-02-13 11:05:09 -06:00
|
|
|
|
2016-12-27 19:16:14 -06:00
|
|
|
// Grab the condition var before we exit
|
|
|
|
if cond := c.runCond; cond != nil {
|
2018-09-25 17:11:15 -05:00
|
|
|
log.Printf("[INFO] terraform: waiting for graceful stop to complete")
|
2016-12-27 19:16:14 -06:00
|
|
|
cond.Wait()
|
2016-12-22 13:33:26 -06:00
|
|
|
}
|
2016-10-23 19:55:45 -05:00
|
|
|
|
2016-12-26 18:29:44 -06:00
|
|
|
log.Printf("[WARN] terraform: stop complete")
|
2015-02-13 11:05:09 -06:00
|
|
|
}
|
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
// Validate performs semantic validation of the configuration, and returning
|
|
|
|
// any warnings or errors.
|
|
|
|
//
|
|
|
|
// Syntax and structural checks are performed by the configuration loader,
|
|
|
|
// and so are not repeated here.
|
2017-11-21 17:08:00 -06:00
|
|
|
func (c *Context) Validate() tfdiags.Diagnostics {
|
2016-12-22 13:33:26 -06:00
|
|
|
defer c.acquireRun("validate")()
|
2015-02-13 11:05:09 -06:00
|
|
|
|
2017-11-21 17:08:00 -06:00
|
|
|
var diags tfdiags.Diagnostics
|
2015-02-04 19:02:18 -06:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
// If we have errors at this point then we probably won't be able to
|
|
|
|
// construct a graph without producing redundant errors, so we'll halt early.
|
2017-11-21 17:08:00 -06:00
|
|
|
if diags.HasErrors() {
|
|
|
|
return diags
|
2015-06-25 00:43:55 -05:00
|
|
|
}
|
|
|
|
|
2015-05-05 17:24:44 -05:00
|
|
|
// Build the graph so we can walk it and run Validate on nodes.
|
|
|
|
// We also validate the graph generated here, but this graph doesn't
|
|
|
|
// necessarily match the graph that Plan will generate, so we'll validate the
|
|
|
|
// graph again later after Planning.
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
graph, graphDiags := c.Graph(GraphTypeValidate, nil)
|
|
|
|
diags = diags.Append(graphDiags)
|
|
|
|
if graphDiags.HasErrors() {
|
2017-11-21 17:08:00 -06:00
|
|
|
return diags
|
2015-04-23 10:52:31 -05:00
|
|
|
}
|
|
|
|
|
2015-02-10 10:58:14 -06:00
|
|
|
// Walk
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
walker, walkDiags := c.walk(graph, walkValidate)
|
|
|
|
diags = diags.Append(walker.NonFatalDiagnostics)
|
|
|
|
diags = diags.Append(walkDiags)
|
|
|
|
if walkDiags.HasErrors() {
|
|
|
|
return diags
|
2017-11-21 17:08:00 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return diags
|
2015-02-04 17:44:23 -06:00
|
|
|
}
|
2015-02-10 10:58:14 -06:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
// Config returns the configuration tree associated with this context.
|
|
|
|
func (c *Context) Config() *configs.Config {
|
|
|
|
return c.config
|
2015-03-06 17:12:39 -06:00
|
|
|
}
|
|
|
|
|
2015-03-06 17:04:12 -06:00
|
|
|
// Variables will return the mapping of variables that were defined
|
|
|
|
// for this Context. If Input was called, this mapping may be different
|
|
|
|
// than what was given.
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
func (c *Context) Variables() InputValues {
|
2015-03-06 17:04:12 -06:00
|
|
|
return c.variables
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetVariable sets a variable after a context has already been built.
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
func (c *Context) SetVariable(k string, v cty.Value) {
|
|
|
|
c.variables[k] = &InputValue{
|
|
|
|
Value: v,
|
|
|
|
SourceType: ValueFromCaller,
|
|
|
|
}
|
2015-03-06 17:04:12 -06:00
|
|
|
}
|
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
func (c *Context) acquireRun(phase string) func() {
|
|
|
|
// With the run lock held, grab the context lock to make changes
|
|
|
|
// to the run context.
|
2015-02-13 11:05:09 -06:00
|
|
|
c.l.Lock()
|
|
|
|
defer c.l.Unlock()
|
|
|
|
|
2016-12-27 19:16:14 -06:00
|
|
|
// Wait until we're no longer running
|
|
|
|
for c.runCond != nil {
|
|
|
|
c.runCond.Wait()
|
2015-02-13 11:05:09 -06:00
|
|
|
}
|
|
|
|
|
2016-12-27 19:16:14 -06:00
|
|
|
// Build our lock
|
|
|
|
c.runCond = sync.NewCond(&c.l)
|
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
// Create a new run context
|
|
|
|
c.runContext, c.runContextCancel = context.WithCancel(context.Background())
|
2016-10-23 19:55:45 -05:00
|
|
|
|
2016-10-06 13:00:28 -05:00
|
|
|
// Reset the stop hook so we're not stopped
|
|
|
|
c.sh.Reset()
|
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
return c.releaseRun
|
2015-02-13 11:05:09 -06:00
|
|
|
}
|
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
func (c *Context) releaseRun() {
|
|
|
|
// Grab the context lock so that we can make modifications to fields
|
2015-02-13 11:05:09 -06:00
|
|
|
c.l.Lock()
|
|
|
|
defer c.l.Unlock()
|
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
// End our run. We check if runContext is non-nil because it can be
|
|
|
|
// set to nil if it was cancelled via Stop()
|
|
|
|
if c.runContextCancel != nil {
|
|
|
|
c.runContextCancel()
|
|
|
|
}
|
|
|
|
|
2016-12-27 19:16:14 -06:00
|
|
|
// Unlock all waiting our condition
|
|
|
|
cond := c.runCond
|
|
|
|
c.runCond = nil
|
|
|
|
cond.Broadcast()
|
|
|
|
|
2016-12-22 13:33:26 -06:00
|
|
|
// Unset the context
|
|
|
|
c.runContext = nil
|
2015-02-13 11:05:09 -06:00
|
|
|
}
|
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
func (c *Context) walk(graph *Graph, operation walkOperation) (*ContextGraphWalker, tfdiags.Diagnostics) {
|
2016-10-06 12:49:52 -05:00
|
|
|
log.Printf("[DEBUG] Starting graph walk: %s", operation.String())
|
2016-11-04 10:30:51 -05:00
|
|
|
|
2018-05-03 22:41:46 -05:00
|
|
|
walker := c.graphWalker(operation)
|
2016-10-01 18:51:00 -05:00
|
|
|
|
2016-10-23 19:55:45 -05:00
|
|
|
// Watch for a stop so we can call the provider Stop() API.
|
2017-03-08 13:43:31 -06:00
|
|
|
watchStop, watchWait := c.watchStop(walker)
|
2016-10-23 19:55:45 -05:00
|
|
|
|
2016-10-06 12:49:52 -05:00
|
|
|
// Walk the real graph, this will block until it completes
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
diags := graph.Walk(walker)
|
2016-10-06 12:49:52 -05:00
|
|
|
|
2017-03-08 13:43:31 -06:00
|
|
|
// Close the channel so the watcher stops, and wait for it to return.
|
|
|
|
close(watchStop)
|
|
|
|
<-watchWait
|
2016-10-23 19:55:45 -05:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
return walker, diags
|
2015-02-10 10:58:14 -06:00
|
|
|
}
|
core: Allow lists and maps as variable overrides
Terraform 0.7 introduces lists and maps as first-class values for
variables, in addition to string values which were previously available.
However, there was previously no way to override the default value of a
list or map, and the functionality for overriding specific map keys was
broken.
Using the environment variable method for setting variable values, there
was previously no way to give a variable a value of a list or map. These
now support HCL for individual values - specifying:
TF_VAR_test='["Hello", "World"]'
will set the variable `test` to a two-element list containing "Hello"
and "World". Specifying
TF_VAR_test_map='{"Hello = "World", "Foo" = "bar"}'
will set the variable `test_map` to a two-element map with keys "Hello"
and "Foo", and values "World" and "bar" respectively.
The same logic is applied to `-var` flags, and the file parsed by
`-var-files` ("autoVariables").
Note that care must be taken to not run into shell expansion for `-var-`
flags and environment variables.
We also merge map keys where appropriate. The override syntax has
changed (to be noted in CHANGELOG as a breaking change), so several
tests needed their syntax updating from the old `amis.us-east-1 =
"newValue"` style to `amis = "{ "us-east-1" = "newValue"}"` style as
defined in TF-002.
In order to continue supporting the `-var "foo=bar"` type of variable
flag (which is not valid HCL), a special case error is checked after HCL
parsing fails, and the old code path runs instead.
2016-07-20 20:38:26 -05:00
|
|
|
|
2018-05-03 22:41:46 -05:00
|
|
|
func (c *Context) graphWalker(operation walkOperation) *ContextGraphWalker {
|
2020-09-04 14:59:22 -05:00
|
|
|
var state *states.SyncState
|
|
|
|
var refreshState *states.SyncState
|
|
|
|
|
|
|
|
switch operation {
|
|
|
|
case walkValidate:
|
|
|
|
// validate should not use any state
|
2020-09-30 10:49:04 -05:00
|
|
|
state = states.NewState().SyncWrapper()
|
2020-09-04 14:59:22 -05:00
|
|
|
|
|
|
|
// validate currently uses the plan graph, so we have to populate the
|
|
|
|
// refreshState.
|
2020-09-30 10:49:04 -05:00
|
|
|
refreshState = states.NewState().SyncWrapper()
|
2020-09-04 14:59:22 -05:00
|
|
|
|
|
|
|
case walkPlan:
|
|
|
|
state = c.state.SyncWrapper()
|
2020-09-04 15:51:11 -05:00
|
|
|
refreshState = c.refreshState.SyncWrapper()
|
2020-09-04 14:59:22 -05:00
|
|
|
|
|
|
|
default:
|
|
|
|
state = c.state.SyncWrapper()
|
2020-08-31 14:45:39 -05:00
|
|
|
}
|
2020-09-04 14:59:22 -05:00
|
|
|
|
2018-05-03 22:41:46 -05:00
|
|
|
return &ContextGraphWalker{
|
|
|
|
Context: c,
|
2020-09-04 14:59:22 -05:00
|
|
|
State: state,
|
|
|
|
RefreshState: refreshState,
|
2018-08-27 16:33:08 -05:00
|
|
|
Changes: c.changes.SyncWrapper(),
|
2019-11-21 18:21:41 -06:00
|
|
|
InstanceExpander: instances.NewExpander(),
|
2018-05-03 22:41:46 -05:00
|
|
|
Operation: operation,
|
|
|
|
StopContext: c.runContext,
|
|
|
|
RootVariableValues: c.variables,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-08 13:43:31 -06:00
|
|
|
// watchStop immediately returns a `stop` and a `wait` chan after dispatching
|
|
|
|
// the watchStop goroutine. This will watch the runContext for cancellation and
|
|
|
|
// stop the providers accordingly. When the watch is no longer needed, the
|
|
|
|
// `stop` chan should be closed before waiting on the `wait` chan.
|
|
|
|
// The `wait` chan is important, because without synchronizing with the end of
|
|
|
|
// the watchStop goroutine, the runContext may also be closed during the select
|
|
|
|
// incorrectly causing providers to be stopped. Even if the graph walk is done
|
|
|
|
// at that point, stopping a provider permanently cancels its StopContext which
|
|
|
|
// can cause later actions to fail.
|
|
|
|
func (c *Context) watchStop(walker *ContextGraphWalker) (chan struct{}, <-chan struct{}) {
|
|
|
|
stop := make(chan struct{})
|
|
|
|
wait := make(chan struct{})
|
|
|
|
|
|
|
|
// get the runContext cancellation channel now, because releaseRun will
|
|
|
|
// write to the runContext field.
|
|
|
|
done := c.runContext.Done()
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer close(wait)
|
|
|
|
// Wait for a stop or completion
|
|
|
|
select {
|
|
|
|
case <-done:
|
|
|
|
// done means the context was canceled, so we need to try and stop
|
|
|
|
// providers.
|
|
|
|
case <-stop:
|
|
|
|
// our own stop channel was closed.
|
|
|
|
return
|
2016-12-22 13:33:26 -06:00
|
|
|
}
|
|
|
|
|
2017-03-08 13:43:31 -06:00
|
|
|
// If we're here, we're stopped, trigger the call.
|
2018-09-25 17:11:15 -05:00
|
|
|
log.Printf("[TRACE] Context: requesting providers and provisioners to gracefully stop")
|
2016-10-23 19:55:45 -05:00
|
|
|
|
2017-03-08 13:43:31 -06:00
|
|
|
{
|
|
|
|
// Copy the providers so that a misbehaved blocking Stop doesn't
|
|
|
|
// completely hang Terraform.
|
|
|
|
walker.providerLock.Lock()
|
2018-08-16 10:40:08 -05:00
|
|
|
ps := make([]providers.Interface, 0, len(walker.providerCache))
|
2017-03-08 13:43:31 -06:00
|
|
|
for _, p := range walker.providerCache {
|
|
|
|
ps = append(ps, p)
|
|
|
|
}
|
|
|
|
defer walker.providerLock.Unlock()
|
|
|
|
|
|
|
|
for _, p := range ps {
|
|
|
|
// We ignore the error for now since there isn't any reasonable
|
|
|
|
// action to take if there is an error here, since the stop is still
|
|
|
|
// advisory: Terraform will exit once the graph node completes.
|
|
|
|
p.Stop()
|
|
|
|
}
|
2016-12-22 13:33:26 -06:00
|
|
|
}
|
|
|
|
|
2017-03-08 13:43:31 -06:00
|
|
|
{
|
|
|
|
// Call stop on all the provisioners
|
|
|
|
walker.provisionerLock.Lock()
|
2018-08-17 11:42:07 -05:00
|
|
|
ps := make([]provisioners.Interface, 0, len(walker.provisionerCache))
|
2017-03-08 13:43:31 -06:00
|
|
|
for _, p := range walker.provisionerCache {
|
|
|
|
ps = append(ps, p)
|
|
|
|
}
|
|
|
|
defer walker.provisionerLock.Unlock()
|
|
|
|
|
|
|
|
for _, p := range ps {
|
|
|
|
// We ignore the error for now since there isn't any reasonable
|
|
|
|
// action to take if there is an error here, since the stop is still
|
|
|
|
// advisory: Terraform will exit once the graph node completes.
|
|
|
|
p.Stop()
|
|
|
|
}
|
2016-12-22 13:33:26 -06:00
|
|
|
}
|
2017-03-08 13:43:31 -06:00
|
|
|
}()
|
|
|
|
|
|
|
|
return stop, wait
|
2016-10-23 19:55:45 -05:00
|
|
|
}
|