Commit Graph

25 Commits

Author SHA1 Message Date
James Bardin a84b4a669a use the open state file for refresh when possible
Only open a new file descriptor for RefreshState if we haven't written a
state, and don't have the correct state open already. This prevents
windows from failing to refresh a locked state.
2018-03-19 18:17:43 -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 4866f35645 add mutexes to Local, Backup, and InmemState 2017-05-25 11:20:52 -04:00
James Bardin a4283d23f6 fix windows locking
Don't create a new windows handle for the lock.
2017-02-17 13:29:48 -05:00
James Bardin ec00564be6 Clean up LockInfo and LockError and use them
Gove LockInfo a Marshal method for easy serialization, and a String
method for more readable output.

Have the state.Locker implementations use LockError when possible to
return LockInfo and an error.
2017-02-15 14:44:43 -05:00
James Bardin 08cff7cc13 have LocalState check Lock ID on Unlock
Have LocalState store and check the lock ID, and strictly enforce
unlocking with the correct ID.

This isn't required for local lock correctness, as we track the file
descriptor to unlock, but it does provide a varification that locking
and unlocking is done correctly throughout terraform.
2017-02-15 14:41:55 -05:00
James Bardin 4f0c465187 make command tests pass with new state.Locker 2017-02-15 14:41:55 -05:00
James Bardin 200c8de4e9 Update the state.Locker interface
Remove CacheState rather than update it, since it's no longer used.
2017-02-15 14:41:55 -05:00
Mitchell Hashimoto a7cfb8062b
state: just style changes in the code itself (newlines, moving methods) 2017-02-14 08:51:20 -08:00
James Bardin 0c1b138719 Add state locking during backend init
During backend initialization, especially during a migration, there is a
chance that an existing state could be overwritten.

Attempt to get a locks when writing the new state. It would be nice to
always have a lock when reading the states, but the recursive structure
of the Meta.Backend config functions makes that quite complex.
2017-02-09 15:47:27 -05:00
James Bardin 14d965722e Use single state.LockInfo struct
Remove redundant structures
2017-02-08 11:34:31 -05:00
James Bardin e92559f518 Cleanup state file during Unlock
Close and remove the file descriptor from LocalState if we Unlock the
state. Also remove an empty state file if we created it and it was never
written to. This is mostly to clean up after tests, but doesn't hurt to
not leave empty files around.
2017-02-03 18:58:18 -05:00
James Bardin a2b5811f50 Remove "expires" from lock info.
We are not going to handle lock expiration, at least at this time, so
remove the Expires fields to avoid any confusion.
2017-02-03 14:55:21 -05:00
James Bardin 1646310e68 Allow a non-existent state file
A missing state file was allowed, and treated as an empty state.
2017-01-30 17:16:57 -05:00
James Bardin 3fdcbda3aa Switch from Path to PathOut on LocalState.written
After LocalState writes to a state file, we will refresh off the new
state file rather than the original Path argument.
2017-01-30 17:16:57 -05:00
James Bardin 8f7f1917f2 Remove state file data when writing a nil state
The old behavior in this situation was to simply delete the file. Since
we now have a lock on this file we don't want to close or delete it, so
instead truncate the file at offset 0.

Fix a number of related tests
2017-01-30 17:16:57 -05:00
James Bardin 10f6d7f30f Add locking for s3 state
Use a DynamoDB table to coodinate state locking in S3.

We use a simple strategy here, defining a key containing the value of
the bucket/key of the state file as the lock. If the keys exists, the
locks fails.

TODO: decide if locks should automatically be expired, or require manual
intervention.
2017-01-30 17:16:57 -05:00
James Bardin 6162cde6ff Add basic local state locking
Add the LockUnlock methods to LocalState and BackupState.

The implementation for LocalState will be platform specific. We will use
OS-native locking on the state files, speficially locking whichever
state file we intend to write to.
2017-01-30 17:16:57 -05:00
Mitchell Hashimoto cc8e6b6331 state: deep copies are required 2015-02-23 21:36:58 -08:00
Mitchell Hashimoto c2bf600603 state: only change serial if changed 2015-02-23 21:26:33 -08:00
Mitchell Hashimoto 3bf59183b8 state: InmemState 2015-02-23 15:13:55 -08:00
Mitchell Hashimoto 4ec63bc2ef command: deal with plan states 2015-02-23 15:13:54 -08:00
Mitchell Hashimoto 5c356f35b9 state: LocalState supports alternate output path 2015-02-23 15:13:54 -08:00
Mitchell Hashimoto 34864a64a5 state: LocalState allows file to not exist 2015-02-23 15:13:54 -08:00
Mitchell Hashimoto 1f7ddc30fe state: a bunch of state stuff 2015-02-23 15:13:53 -08:00