* PSS: Ensure experimental backend codepath is isolated + gated correctly
* Update init_run.go
Co-authored-by: Sarah French <15078782+SarahFrench@users.noreply.github.com>
---------
Co-authored-by: Sarah French <15078782+SarahFrench@users.noreply.github.com>
* Minor fixes in diagnostics
This can only be done once modules have been parsed and the required providers data is available. There are multiple places where config is parsed, into either Config or Module structs, so this needs to be implemented in multiple places.
* Rename test to make it specific to use of backend block in config
* Update initBackend to accept whole initArgs collection
* Only process --backend-config data, when setting up a `backend`, if that data isn't empty
* Simplify how mock provider factories are made in tests
* Update mock provider's default logic to track and manage existing workspaces
* Add `ProviderSchema` method to `Pluggable` structs. This allows calling code to access the provider schema when using provider configuration data.
* Add function for converting a providerreqs.Version to a hashicorp/go-version Version.
This is needed for using locks when creating the backend state file.
* Implement initial version of init new working directories using `stateStore_C_s`. Default to creating the default workspace if no workspaces exist.
* Update test fixtures to match the hashicorp/test mock provider used in PSS tests
* Allow tests to obtain locks that include `testingOverrides` providers.
The `testingOverrides` field will only be set in tests, so this should not impact end users.
* Add tests showing TF can initialize a working directory for the first time (and do the same when forced by -reconfigure flag). Remove replaced tests.
* Add -create-default-workspace flag, to be used to disable creating the default workspace by default when -input=false (i.e for use in CI). Refactor creation of default workspace logic. Add tests.
* Allow reattached providers to be used during init for PSS
* Rename variable to `backendHash` so relation to `backend` is clearer
* Allow `(m *Meta) Backend` to return warning diagnostics
* Protect against nil testingOverrides in providerFactoriesFromLocks
* Add test case seeing what happens if default workspace selected, doesn't exist, but other workspaces do exist.
The consequences here are due to using `selectWorkspace` in `stateStore_C_s`, matching what's done in `backend_C_r_s`.
* Address code consistency check failure on PR
* Refactor use of mock in test that's experiencing EOF error...
* Remove test that requires test to supply input for user prompt
This test passes when run in isolation but fails when run alongside other tests, even when skipping all other tests using `testStdinPipe`. I don't think the value of this test is great enough to start changing how we test stdin input.
* Allow -create-default-workspace to be used regardless of whether input is enabled or disabled
* Add TF_SKIP_CREATE_DEFAULT_WORKSPACE environment variable
* Responses to feedback, including making testStdinPipe helper log details of errors copying data to stdin.
Note: We cannot call t.Fatal from a non-test goroutine.
* Use Errorf instead
* Allow backend state files to not include version data when a builtin or reattached provider is in use.
* Add clarifying comment about re-attached providers when finding the matching entry in required_providers
* Report that the default workspace was created to the view
* Refactor: use error comparison via `errors.Is` to identify when no workspaces exist.
* Move handling of TF_ENABLE_PLUGGABLE_STATE_STORAGE into init's ParseInit func.
* Validate that PSS-related flags can only be used when experiments are enabled, enforce coupling of PSS-related flags when in use.
* Slight rewording of output message about default workspace
* Update test to assert new output about default workspace
* Add method to allow accessing factories from locks that are in memory
* Create new getStateStoreProviderFactory method for accessing a factory from config
* Update getStateStoreProviderFactory to use in memory locks instead of reading them from the deps lock file. Update calling code to accommodate this.
* Add tests for getStateStoreProviderFactory, improve errors returned from method
* Update test following schema change in simple providers
* Move test case into e2etest package, so we protect against environments where building binaries isn't possible
* Fix issues with running test in e2etest package
* Update code comments
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
---------
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* Add forked version of `run` logic that's only used if experiments are enabled
* Reorder actions in experimental init - load in full config before configuring the backend.
* Add getProvidersFromConfig method, initially as an exact copy of getProviders
* Make getProvidersFromConfig not use state to get providers
* Add `appendLockedDependencies` method to `Meta` to allow multi-phase saving to the dep locks file
* Update experimental init to use new getProvidersFromConfig method
* Add new getProvidersFromState method that only accepts state information as input for getting providers. Use in experimental init and append values to existing deps lock file
* Update messages sent to view about provider download phases
* Change init to save updates to the deps lock file only once
* Make Terraform output report that a lock file _will_ be made after providers are determined from config
* Remove use of `ProviderDownloadOutcome`s
* Move repeated code into separate method
* Change provider download approach: determine if locks changed at point of attempting to update the lockfile, keep record of incomplete providers inside init command struct
* Refactor `mergeLockedDependencies` and update test
* Add comments to provider download methods
* Fix issue where incorrect message ouput to view when downloading providers
* Update `mergeLockedDependencies` method to be more generic
* Update `getProvidersFromState` method to receive in-progress config locks and merge those with any locks on file. This allows re-use of providers downloaded by `getProvidersFromConfig` in the same init command
* Fix config for `TestInit_stateStoreBlockIsExperimental`
* Improve testing of mergeLockedDependencies; state locks are always missing version constraints
* Add tests for 2 phase provider download
* Add test case to cover use of the `-upgrade` flag
* Change the message shown when a provider is reused during the second provider download step.
When downloading providers described only in the state then the provider may already be downloaded from a previous init (i.e. is recorded in the deps lock file) or downloaded during step 1 of provider download. The message here needs to cover both potential scenarios.
* Update mergeLockedDependencies comment
* fix: completely remove use of upgrade flag in getProvidersFromState
* Fix: avoid nil pointer errors by returning an empty collection of locks when there is no state
* Fix: use state store data only in diagnostic
* Change how we make PSS experimental - avoid relying on a package level variable that causes tests to interact.
* Remove full-stop in view message, update tests
* Update span names to be unique
* Re-add lost early returns
* Remove unused view messages
* Add comments to new view messages
* Pull `init` `Run` method into new method in a separate file, in preparation for adding experimental fork.
* Add license header
* Allow init args to be accessed before calling separate init run logic
* Add -enable-pss flag to the init command, to be used for accessing experimental init logic
* Fix- put call to `run` in else block!
* Make flag name more explicit
* Add an environment variable alternative to the CLI flag
* Make the panic text more user-friendly
* go fmt
* Allow backend or state_store config to be passed via BackendOpts from calling code
* Update messages sent to view: make message specific to state storage mechanism in use
* Add nil pointer check
* Fix typos
* Pivot to `Len` method approach of nil check
* Pivot to the point of pirouetting
* Update comments to distinguish between operations and state-storage backends more clearly
* Rename `BackendOpts` field `Config` to more specific `BackendConfig`
Some updates to staticcheck were catching more errors. Most of these
were format functions without a format string, but rather than adding
more exceptions I just fixed them all. This did also catch some
incorrectly wrapped errors.
On a default provider install failure we can always suggest running
`terraform providers` to help in cases where it's not apparent to the
user how to proceed. This would most commonly be encountered by
conflicting provider requirements, but if we find there are other common
situations we may want to generate a more precise error type for better
diagnostics.
Several times over the years we've considered adding tracing
instrumentation to Terraform, since even when running in isolation as a
CLI program it has a "distributed system-like" structure, with lots of
concurrent internal work and also some work delegated to provider plugins
that are essentially temporarily-running microservices.
However, it's always felt a bit overwhelming to do it because much of
Terraform predates the Go context.Context idiom and so it's tough to get
a clean chain of context.Context values all the way down the stack without
disturbing a lot of existing APIs.
This commit aims to just get that process started by establishing how a
context can propagate from "package main" into the command package,
focusing initially on "terraform init" and some other commands that share
some underlying functions with that command.
OpenTelemetry has emerged as a de-facto industry standard and so this uses
its API directly, without any attempt to hide it behind an abstraction.
The OpenTelemetry API is itself already an adapter layer, so we should be
able to swap in any backend that uses comparable concepts. For now we just
discard the tracing reports by default, and allow users to opt in to
delivering traces over OTLP by setting an environment variable when
running Terraform (the environment variable was established in an earlier
commit, so this commit builds on that.)
When tracing collection is enabled, every Terraform CLI run will generate
at least one overall span representing the command that was run. Some
commands might also create child spans, but most currently do not.
* [testing framework] prepare for beta phase of development
* [Testing Framework] Add module block to test run blocks
* [testing framework] allow tests to define and override providers
* cloud: assert import block compatibility
* check for import <> TFC compatibility during init
* imports are not in alphabetical order 🙃
---------
Co-authored-by: CJ Horton <cjhorton@hashicorp.com>
As explained by the deleted comments, this package was used to identify situations where the `terraform 0.12upgrade` command can help migrate 0.11 syntax. Current versions of terraform don't include this command, and it's not likely that users are attempting upgrades from 0.11 to 1.4+
The replacement init swaps the order of the module and backend initialization in order to prepare for the next commit.
Config initialization now takes the following approach:
1. Load the root module, but withhold diagnostic errors until after version check
2. Initialize the backend, but withhold diagnostic errors until after version check
3. Get modules
4. Load all config (root and modules)
5. Check terraform version requirements (this can be defined by nested modules) and display any errors. It's important to show these first because prior errors could be the result of a newer terraform version syntax
6. Finally, show any errors related to backed init or config loading
There are no good options for inserting diagnostics into the backend
lookup, or creating a backend which reports it's removal because none of
the init or GetSchema functions return any errors.
Keep a registry of the removed backend so that we can at least notify
users that a backend was removed vs an invalid name.
Some of the wording here needed adjusting with the change that backends
largely reflect state snapshot storage (removing 'enhanced'
designation), and that a 'backend' is not necessarily always present.
This fixes an issue where a user could not disable initialization of the
'cloud' configuration block (As is possible with -backend=false), as
well as add some syntactic sugar around -backend by adding a mutually
exclusive -cloud alias.
There are a few command line options for "terraform init" which are only
relevant when working with traditional backends, with the Cloud
integration previously just mostly ignoring them, or sometimes misbehaving
slightly due to them creating an unreasonable situation.
Now we'll catch these and return explicit errors, in order to be clear
that these options are not needed nor supported in Cloud mode.
Error diags from c.installModules() no longer cause getModules() to exit early.
Whether installModules completed successfully, errored, or was cancelled, we
try to update the manifest as best we can, preferring incomplete information
to none.
Earlier work to make "terraform init" interruptible made the getproviders
package context-aware in order to allow provider installation to be cancelled.
Here we make a similar change for module installation, which is now also
cancellable with SIGINT. This involves plumbing context through initwd and
getmodules. Functions which can make network requests now include a context
parameter whose cancellation cancels those requests.
Since the module installation code is shared, "terraform get" is now
also interruptible during module installation.
With the alternative block introduced in 7bf9b2c7b, this removes the
ability to explicitly declare the 'cloud' backend. The literal backend
interface is an implementation detail and no longer a user-level
concept when using Terraform Cloud.
This is a replacement declaration for using Terraform Cloud as a remote
backend, leaving the literal backend as an implementation detail and not
a user-level concept.
The init command needs to initialize a backend, in order to access
state, in turn to derive provider requirements from state. The backend
initialization step requires building provider factories, which
previously would fail if a lockfile was present without a corresponding
local provider cache.
This commit ensures that in this situation only, errors with the
provider factories are temporarily ignored. This allows us to continue
to initialize the backend, fetch providers, and then report any errors
as necessary.
The -lock and -lock-timeout flags were removed prior to the release of
1.0 as they were thought to have no effect. This is not true in the case
of state migrations when changing backends. This commit restores these
flags, and adds test coverage for locking during backend state
migration.
Also update the help output describing other boolean flags, showing the
argument as the user would type it rather than the default behavior.
We must ensure that the terraform required_version is checked as early
as possible, so that new configuration constructs don't cause init to
fail without indicating the version is incompatible.
The loadConfig call before the earlyconfig parsing seems to be unneeded,
and we can delay that to de-tangle it from installing the modules which
may have their own constraints.
TODO: it seems that loadConfig should be able to handle returning the
version constraints in the same manner as loadSingleModule.