use the new clistate.Locker in the local backend
Use the new StateLocker field to provide a wrapper for locking the state during terraform.Context creation. We can then remove all the state locking code from individual operations, and unlock them in one place inside the main Operation method.
This commit is contained in:
parent
d3f7edeb27
commit
0b804a9686
|
@ -13,6 +13,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/command/clistate"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/hashicorp/terraform/state"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
@ -260,12 +261,21 @@ func (b *Local) Operation(ctx context.Context, op *backend.Operation) (*backend.
|
|||
cancelCtx, cancel := context.WithCancel(context.Background())
|
||||
runningOp.Cancel = cancel
|
||||
|
||||
if op.LockState {
|
||||
op.StateLocker = clistate.NewLocker(stopCtx, op.StateLockTimeout, b.CLI, b.Colorize())
|
||||
} else {
|
||||
op.StateLocker = clistate.NewNoopLocker()
|
||||
}
|
||||
|
||||
// Do it
|
||||
go func() {
|
||||
defer done()
|
||||
defer stop()
|
||||
defer cancel()
|
||||
|
||||
// the state was locked during context creation, unlock the state when
|
||||
// the operation completes
|
||||
defer op.StateLocker.Unlock(runningOp.Err)
|
||||
defer b.opLock.Unlock()
|
||||
f(stopCtx, cancelCtx, op, runningOp)
|
||||
}()
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/command/clistate"
|
||||
"github.com/hashicorp/terraform/command/format"
|
||||
"github.com/hashicorp/terraform/config/module"
|
||||
"github.com/hashicorp/terraform/state"
|
||||
|
@ -55,20 +54,6 @@ func (b *Local) opApply(
|
|||
return
|
||||
}
|
||||
|
||||
if op.LockState {
|
||||
lockCtx, cancel := context.WithTimeout(stopCtx, op.StateLockTimeout)
|
||||
defer cancel()
|
||||
|
||||
unlock, err := clistate.Lock(lockCtx, opState, op.Type.String(), "", b.CLI, b.Colorize())
|
||||
if err != nil {
|
||||
runningOp.Err = errwrap.Wrapf("Error locking state: {{err}}", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
runningOp.Err = unlock(runningOp.Err)
|
||||
}()
|
||||
}
|
||||
|
||||
// Setup the state
|
||||
runningOp.State = tfCtx.State()
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package local
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform/command/clistate"
|
||||
"github.com/hashicorp/terraform/command/format"
|
||||
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
|
@ -20,6 +22,12 @@ func (b *Local) Context(op *backend.Operation) (*terraform.Context, state.State,
|
|||
// to ask for input/validate.
|
||||
op.Type = backend.OperationTypeInvalid
|
||||
|
||||
if op.LockState {
|
||||
op.StateLocker = clistate.NewLocker(context.Background(), op.StateLockTimeout, b.CLI, b.Colorize())
|
||||
} else {
|
||||
op.StateLocker = clistate.NewNoopLocker()
|
||||
}
|
||||
|
||||
return b.context(op)
|
||||
}
|
||||
|
||||
|
@ -30,6 +38,10 @@ func (b *Local) context(op *backend.Operation) (*terraform.Context, state.State,
|
|||
return nil, nil, errwrap.Wrapf("Error loading state: {{err}}", err)
|
||||
}
|
||||
|
||||
if err := op.StateLocker.Lock(s, op.Type.String()); err != nil {
|
||||
return nil, nil, errwrap.Wrapf("Error locking state: {{err}}", err)
|
||||
}
|
||||
|
||||
if err := s.RefreshState(); err != nil {
|
||||
return nil, nil, errwrap.Wrapf("Error loading state: {{err}}", err)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/command/clistate"
|
||||
"github.com/hashicorp/terraform/command/format"
|
||||
"github.com/hashicorp/terraform/config/module"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
@ -60,20 +59,6 @@ func (b *Local) opPlan(
|
|||
return
|
||||
}
|
||||
|
||||
if op.LockState {
|
||||
lockCtx, cancel := context.WithTimeout(stopCtx, op.StateLockTimeout)
|
||||
defer cancel()
|
||||
|
||||
unlock, err := clistate.Lock(lockCtx, opState, op.Type.String(), "", b.CLI, b.Colorize())
|
||||
if err != nil {
|
||||
runningOp.Err = errwrap.Wrapf("Error locking state: {{err}}", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
runningOp.Err = unlock(runningOp.Err)
|
||||
}()
|
||||
}
|
||||
|
||||
// Setup the state
|
||||
runningOp.State = tfCtx.State()
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/command/clistate"
|
||||
"github.com/hashicorp/terraform/config/module"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
@ -51,20 +50,6 @@ func (b *Local) opRefresh(
|
|||
return
|
||||
}
|
||||
|
||||
if op.LockState {
|
||||
lockCtx, cancel := context.WithTimeout(stopCtx, op.StateLockTimeout)
|
||||
defer cancel()
|
||||
|
||||
unlock, err := clistate.Lock(lockCtx, opState, op.Type.String(), "", b.CLI, b.Colorize())
|
||||
if err != nil {
|
||||
runningOp.Err = errwrap.Wrapf("Error locking state: {{err}}", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
runningOp.Err = unlock(runningOp.Err)
|
||||
}()
|
||||
}
|
||||
|
||||
// Set our state
|
||||
runningOp.State = opState.State()
|
||||
if runningOp.State.Empty() || !runningOp.State.HasResources() {
|
||||
|
|
Loading…
Reference in New Issue