Skip to content

Commit

Permalink
Merge pull request #13665 from hashicorp/jbardin/context-return-state
Browse files Browse the repository at this point in the history
context Refresh and Apply sometimes return nil
  • Loading branch information
jbardin authored Apr 14, 2017
2 parents 7b32ad2 + 928e606 commit 1771ba1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
4 changes: 3 additions & 1 deletion backend/local/backend_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ func (b *Local) opApply(
doneCh := make(chan struct{})
go func() {
defer close(doneCh)
applyState, applyErr = tfCtx.Apply()
_, applyErr = tfCtx.Apply()
// we always want the state, even if apply failed
applyState = tfCtx.State()

/*
// Record any shadow errors for later
Expand Down
15 changes: 12 additions & 3 deletions terraform/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,17 @@ func (c *Context) Input(mode InputMode) error {
// Apply applies the changes represented by this context and returns
// the resulting state.
//
// In addition to returning the resulting state, this context is updated
// with the latest state.
// 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.
func (c *Context) Apply() (*State, error) {
defer c.acquireRun("apply")()

Expand Down Expand Up @@ -580,7 +589,7 @@ func (c *Context) Plan() (*Plan, error) {
// to their latest state. This will update the state that this context
// works with, along with returning it.
//
// Even in the case an error is returned, the state will be returned and
// Even in the case an error is returned, the state may be returned and
// will potentially be partially updated.
func (c *Context) Refresh() (*State, error) {
defer c.acquireRun("refresh")()
Expand Down
21 changes: 13 additions & 8 deletions terraform/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -1960,12 +1960,12 @@ func ReadStateV2(jsonBytes []byte) (*State, error) {
}
}

// Sort it
state.sort()

// catch any unitialized fields in the state
state.init()

// Sort it
state.sort()

return state, nil
}

Expand Down Expand Up @@ -1995,12 +1995,12 @@ func ReadStateV3(jsonBytes []byte) (*State, error) {
}
}

// Sort it
state.sort()

// catch any unitialized fields in the state
state.init()

// Sort it
state.sort()

// Now we write the state back out to detect any changes in normaliztion.
// If our state is now written out differently, bump the serial number to
// prevent conflicts.
Expand All @@ -2020,12 +2020,17 @@ func ReadStateV3(jsonBytes []byte) (*State, error) {

// WriteState writes a state somewhere in a binary format.
func WriteState(d *State, dst io.Writer) error {
// Make sure it is sorted
d.sort()
// writing a nil state is a noop.
if d == nil {
return nil
}

// make sure we have no uninitialized fields
d.init()

// Make sure it is sorted
d.sort()

// Ensure the version is set
d.Version = StateVersion

Expand Down

0 comments on commit 1771ba1

Please sign in to comment.