Commit Graph

11 Commits

Author SHA1 Message Date
James Bardin 32ae05c342 fix strict remote.State lineage check
We can't check lineage in the remote state instance, because we may need
to overwrite a state with a new lineage. Whil it's tempting to add an
optional interface for this, like OverwriteState(), optional interfaces
are never _really_ optional, and will have to be implemented by any
wrapper types as well.

Another solution may be to add a State.Supersedes field to indicate that
we intend to replace an existing state, but that may not be worth the
extra check either.
2017-08-01 19:34:22 -04:00
Martin Atkins 4d53eaa6df state: more robust handling of state Serial
Previously we relied on a constellation of coincidences for everything to
work out correctly with state serials. In particular, callers needed to
be very careful about mutating states (or not) because many different bits
of code shared pointers to the same objects.

Here we move to a model where all of the state managers always use
distinct instances of state, copied when WriteState is called. This means
that they are truly a snapshot of the state as it was at that call, even
if the caller goes on mutating the state that was passed.

We also adjust the handling of serials so that the state managers ignore
any serials in incoming states and instead just treat each Persist as
the next version after what was most recently Refreshed.

(An exception exists for when nothing has been refreshed, e.g. because
we are writing a state to a location for the first time. In that case
we _do_ trust the caller, since the given state is either a new state
or it's a copy of something we're migrating from elsewhere with its
state and lineage intact.)

The intent here is to allow the rest of Terraform to not worry about
serials and state identity, and instead just treat the state as a mutable
structure. We'll just snapshot it occasionally, when WriteState is called,
and deal with serials _only_ at persist time.

This is intended as a more robust version of #15423, which was a quick
hotfix to an issue that resulted from our previous slopping handling
of state serials but arguably makes the problem worse by depending on
an additional coincidental behavior of the local backend's apply
implementation.
2017-07-05 12:34:30 -07:00
James Bardin f0f2220abb add mutexes to remote.State 2017-05-25 11:20:52 -04:00
Mitchell Hashimoto efe754183b
state/remote: export ClientLocker, test for implementation
This adds unit tests (that will fail at compile time) if various structs
don't implement the right interfaces for locking
2017-02-15 14:20:59 -08:00
James Bardin 35307d5a60 Add remote state locking
In order to provide lockign for remote states, the Cache state,
remote.State need to expose Lock and Unlock methods. The actual locking
will be done by the remote.Client, which can implement the same
state.Locker methods.
2017-01-30 17:16:57 -05:00
James Bardin 3622bfddd6 Revert #7464 and allow an empty state
Revert back to using a nil state. The external usage of the state shoudl
always check the Empty() method.
2016-07-07 16:19:58 -04:00
James Bardin 24f6d3fe98 Return an error when there's no remote state
When refreshing remote state, indicate when no state file was found with
an ErrRemoteStateNotFound error. This prevents us from inadvertantly
getting a nil state into a terraform.State where we assume there's
always a root module.
2016-07-01 18:44:23 -04:00
Mitchell Hashimoto cc8e6b6331 state: deep copies are required 2015-02-23 21:36:58 -08:00
Mitchell Hashimoto ed6128aa6e state/remote: increment serial properly 2015-02-23 21:30:59 -08:00
Mitchell Hashimoto 1eec77378b state/remote: can handle nil payloads 2015-02-23 15:13:53 -08:00
Mitchell Hashimoto 1f7ddc30fe state: a bunch of state stuff 2015-02-23 15:13:53 -08:00