Merge pull request #27787 from hashicorp/alisdair/command-views-state-locker
clistate: Update clistate.Locker for command views
This commit is contained in:
commit
6375c6ce6b
|
@ -10,7 +10,6 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
@ -216,17 +215,13 @@ type Operation struct {
|
||||||
// ShowDiagnostics prints diagnostic messages to the UI.
|
// ShowDiagnostics prints diagnostic messages to the UI.
|
||||||
ShowDiagnostics func(vals ...interface{})
|
ShowDiagnostics func(vals ...interface{})
|
||||||
|
|
||||||
// If LockState is true, the Operation must Lock any
|
|
||||||
// statemgr.Lockers for its duration, and Unlock when complete.
|
|
||||||
LockState bool
|
|
||||||
|
|
||||||
// StateLocker is used to lock the state while providing UI feedback to the
|
// StateLocker is used to lock the state while providing UI feedback to the
|
||||||
// user. This will be supplied by the Backend itself.
|
// user. This will be replaced by the Backend to update the context.
|
||||||
|
//
|
||||||
|
// If state locking is not necessary, this should be set to a no-op
|
||||||
|
// implementation of clistate.Locker.
|
||||||
StateLocker clistate.Locker
|
StateLocker clistate.Locker
|
||||||
|
|
||||||
// The duration to retry obtaining a State lock.
|
|
||||||
StateLockTimeout time.Duration
|
|
||||||
|
|
||||||
// Workspace is the name of the workspace that this operation should run
|
// Workspace is the name of the workspace that this operation should run
|
||||||
// in, which controls which named state is used.
|
// in, which controls which named state is used.
|
||||||
Workspace string
|
Workspace string
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
"github.com/hashicorp/terraform/internal/terminal"
|
"github.com/hashicorp/terraform/internal/terminal"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
|
@ -326,11 +325,7 @@ func (b *Local) Operation(ctx context.Context, op *backend.Operation) (*backend.
|
||||||
cancelCtx, cancel := context.WithCancel(context.Background())
|
cancelCtx, cancel := context.WithCancel(context.Background())
|
||||||
runningOp.Cancel = cancel
|
runningOp.Cancel = cancel
|
||||||
|
|
||||||
if op.LockState {
|
op.StateLocker = op.StateLocker.WithContext(stopCtx)
|
||||||
op.StateLocker = clistate.NewLocker(stopCtx, op.StateLockTimeout, b.CLI, b.Colorize())
|
|
||||||
} else {
|
|
||||||
op.StateLocker = clistate.NewNoopLocker()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do it
|
// Do it
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -52,9 +52,9 @@ func (b *Local) opApply(
|
||||||
// the state was locked during succesfull context creation; unlock the state
|
// the state was locked during succesfull context creation; unlock the state
|
||||||
// when the operation completes
|
// when the operation completes
|
||||||
defer func() {
|
defer func() {
|
||||||
err := op.StateLocker.Unlock(nil)
|
diags := op.StateLocker.Unlock()
|
||||||
if err != nil {
|
if diags.HasErrors() {
|
||||||
op.ShowDiagnostics(err)
|
op.ShowDiagnostics(diags)
|
||||||
runningOp.Result = backend.OperationFailure
|
runningOp.Result = backend.OperationFailure
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
"github.com/hashicorp/terraform/internal/initwd"
|
"github.com/hashicorp/terraform/internal/initwd"
|
||||||
"github.com/hashicorp/terraform/providers"
|
"github.com/hashicorp/terraform/providers"
|
||||||
|
@ -293,6 +294,7 @@ func testOperationApply(t *testing.T, configDir string) (*backend.Operation, fun
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
ShowDiagnostics: testLogDiagnostics(t),
|
ShowDiagnostics: testLogDiagnostics(t),
|
||||||
|
StateLocker: clistate.NewNoopLocker(),
|
||||||
}, configCleanup
|
}, configCleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/configs/configload"
|
"github.com/hashicorp/terraform/configs/configload"
|
||||||
"github.com/hashicorp/terraform/plans/planfile"
|
"github.com/hashicorp/terraform/plans/planfile"
|
||||||
|
@ -24,11 +23,7 @@ func (b *Local) Context(op *backend.Operation) (*terraform.Context, statemgr.Ful
|
||||||
// to ask for input/validate.
|
// to ask for input/validate.
|
||||||
op.Type = backend.OperationTypeInvalid
|
op.Type = backend.OperationTypeInvalid
|
||||||
|
|
||||||
if op.LockState {
|
op.StateLocker = op.StateLocker.WithContext(context.Background())
|
||||||
op.StateLocker = clistate.NewLocker(context.Background(), op.StateLockTimeout, b.CLI, b.Colorize())
|
|
||||||
} else {
|
|
||||||
op.StateLocker = clistate.NewNoopLocker()
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, _, stateMgr, diags := b.context(op)
|
ctx, _, stateMgr, diags := b.context(op)
|
||||||
return ctx, stateMgr, diags
|
return ctx, stateMgr, diags
|
||||||
|
@ -45,8 +40,7 @@ func (b *Local) context(op *backend.Operation) (*terraform.Context, *configload.
|
||||||
return nil, nil, nil, diags
|
return nil, nil, nil, diags
|
||||||
}
|
}
|
||||||
log.Printf("[TRACE] backend/local: requesting state lock for workspace %q", op.Workspace)
|
log.Printf("[TRACE] backend/local: requesting state lock for workspace %q", op.Workspace)
|
||||||
if err := op.StateLocker.Lock(s, op.Type.String()); err != nil {
|
if diags := op.StateLocker.Lock(s, op.Type.String()); diags.HasErrors() {
|
||||||
diags = diags.Append(errwrap.Wrapf("Error locking state: {{err}}", err))
|
|
||||||
return nil, nil, nil, diags
|
return nil, nil, nil, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,10 +48,7 @@ func (b *Local) context(op *backend.Operation) (*terraform.Context, *configload.
|
||||||
// If we're returning with errors, and thus not producing a valid
|
// If we're returning with errors, and thus not producing a valid
|
||||||
// context, we'll want to avoid leaving the workspace locked.
|
// context, we'll want to avoid leaving the workspace locked.
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
err := op.StateLocker.Unlock(nil)
|
diags = diags.Append(op.StateLocker.Unlock())
|
||||||
if err != nil {
|
|
||||||
diags = diags.Append(errwrap.Wrapf("Error unlocking state: {{err}}", err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/internal/initwd"
|
"github.com/hashicorp/terraform/internal/initwd"
|
||||||
|
"github.com/hashicorp/terraform/internal/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLocalContext(t *testing.T) {
|
func TestLocalContext(t *testing.T) {
|
||||||
|
@ -15,11 +19,15 @@ func TestLocalContext(t *testing.T) {
|
||||||
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
||||||
defer configCleanup()
|
defer configCleanup()
|
||||||
|
|
||||||
|
streams, _ := terminal.StreamsForTesting(t)
|
||||||
|
view := views.NewView(streams)
|
||||||
|
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
|
||||||
|
|
||||||
op := &backend.Operation{
|
op := &backend.Operation{
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
Workspace: backend.DefaultStateName,
|
Workspace: backend.DefaultStateName,
|
||||||
LockState: true,
|
StateLocker: stateLocker,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, diags := b.Context(op)
|
_, _, diags := b.Context(op)
|
||||||
|
@ -39,11 +47,15 @@ func TestLocalContext_error(t *testing.T) {
|
||||||
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
||||||
defer configCleanup()
|
defer configCleanup()
|
||||||
|
|
||||||
|
streams, _ := terminal.StreamsForTesting(t)
|
||||||
|
view := views.NewView(streams)
|
||||||
|
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
|
||||||
|
|
||||||
op := &backend.Operation{
|
op := &backend.Operation{
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
Workspace: backend.DefaultStateName,
|
Workspace: backend.DefaultStateName,
|
||||||
LockState: true,
|
StateLocker: stateLocker,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, diags := b.Context(op)
|
_, _, diags := b.Context(op)
|
||||||
|
@ -53,5 +65,4 @@ func TestLocalContext_error(t *testing.T) {
|
||||||
|
|
||||||
// Context() unlocks the state on failure
|
// Context() unlocks the state on failure
|
||||||
assertBackendStateUnlocked(t, b)
|
assertBackendStateUnlocked(t, b)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,9 +73,9 @@ func (b *Local) opPlan(
|
||||||
// the state was locked during succesfull context creation; unlock the state
|
// the state was locked during succesfull context creation; unlock the state
|
||||||
// when the operation completes
|
// when the operation completes
|
||||||
defer func() {
|
defer func() {
|
||||||
err := op.StateLocker.Unlock(nil)
|
diags := op.StateLocker.Unlock()
|
||||||
if err != nil {
|
if diags.HasErrors() {
|
||||||
op.ShowDiagnostics(err)
|
op.ShowDiagnostics(diags)
|
||||||
runningOp.Result = backend.OperationFailure
|
runningOp.Result = backend.OperationFailure
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
"github.com/hashicorp/terraform/internal/initwd"
|
"github.com/hashicorp/terraform/internal/initwd"
|
||||||
"github.com/hashicorp/terraform/plans"
|
"github.com/hashicorp/terraform/plans"
|
||||||
|
@ -740,6 +741,7 @@ func testOperationPlan(t *testing.T, configDir string) (*backend.Operation, func
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
ShowDiagnostics: testLogDiagnostics(t),
|
ShowDiagnostics: testLogDiagnostics(t),
|
||||||
|
StateLocker: clistate.NewNoopLocker(),
|
||||||
}, configCleanup
|
}, configCleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,9 +55,9 @@ func (b *Local) opRefresh(
|
||||||
// the state was locked during succesfull context creation; unlock the state
|
// the state was locked during succesfull context creation; unlock the state
|
||||||
// when the operation completes
|
// when the operation completes
|
||||||
defer func() {
|
defer func() {
|
||||||
err := op.StateLocker.Unlock(nil)
|
diags := op.StateLocker.Unlock()
|
||||||
if err != nil {
|
if diags.HasErrors() {
|
||||||
op.ShowDiagnostics(err)
|
op.ShowDiagnostics(diags)
|
||||||
runningOp.Result = backend.OperationFailure
|
runningOp.Result = backend.OperationFailure
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
"github.com/hashicorp/terraform/internal/initwd"
|
"github.com/hashicorp/terraform/internal/initwd"
|
||||||
"github.com/hashicorp/terraform/providers"
|
"github.com/hashicorp/terraform/providers"
|
||||||
|
@ -260,8 +261,8 @@ func testOperationRefresh(t *testing.T, configDir string) (*backend.Operation, f
|
||||||
Type: backend.OperationTypeRefresh,
|
Type: backend.OperationTypeRefresh,
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
LockState: true,
|
|
||||||
ShowDiagnostics: testLogDiagnostics(t),
|
ShowDiagnostics: testLogDiagnostics(t),
|
||||||
|
StateLocker: clistate.NewNoopLocker(),
|
||||||
}, configCleanup
|
}, configCleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,11 @@ import (
|
||||||
version "github.com/hashicorp/go-version"
|
version "github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/internal/initwd"
|
"github.com/hashicorp/terraform/internal/initwd"
|
||||||
|
"github.com/hashicorp/terraform/internal/terminal"
|
||||||
"github.com/hashicorp/terraform/plans/planfile"
|
"github.com/hashicorp/terraform/plans/planfile"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
@ -26,14 +30,24 @@ import (
|
||||||
func testOperationApply(t *testing.T, configDir string) (*backend.Operation, func()) {
|
func testOperationApply(t *testing.T, configDir string) (*backend.Operation, func()) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
return testOperationApplyWithTimeout(t, configDir, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testOperationApplyWithTimeout(t *testing.T, configDir string, timeout time.Duration) (*backend.Operation, func()) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
||||||
|
|
||||||
|
streams, _ := terminal.StreamsForTesting(t)
|
||||||
|
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))
|
||||||
|
|
||||||
return &backend.Operation{
|
return &backend.Operation{
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
Parallelism: defaultParallelism,
|
Parallelism: defaultParallelism,
|
||||||
PlanRefresh: true,
|
PlanRefresh: true,
|
||||||
ShowDiagnostics: testLogDiagnostics(t),
|
ShowDiagnostics: testLogDiagnostics(t),
|
||||||
|
StateLocker: clistate.NewLocker(timeout, view),
|
||||||
Type: backend.OperationTypeApply,
|
Type: backend.OperationTypeApply,
|
||||||
}, configCleanup
|
}, configCleanup
|
||||||
}
|
}
|
||||||
|
@ -878,7 +892,7 @@ func TestRemote_applyLockTimeout(t *testing.T) {
|
||||||
t.Fatalf("error creating pending run: %v", err)
|
t.Fatalf("error creating pending run: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
op, configCleanup := testOperationApply(t, "./testdata/apply")
|
op, configCleanup := testOperationApplyWithTimeout(t, "./testdata/apply", 50*time.Millisecond)
|
||||||
defer configCleanup()
|
defer configCleanup()
|
||||||
|
|
||||||
input := testInput(t, map[string]string{
|
input := testInput(t, map[string]string{
|
||||||
|
@ -886,7 +900,6 @@ func TestRemote_applyLockTimeout(t *testing.T) {
|
||||||
"approve": "yes",
|
"approve": "yes",
|
||||||
})
|
})
|
||||||
|
|
||||||
op.StateLockTimeout = 50 * time.Millisecond
|
|
||||||
op.UIIn = input
|
op.UIIn = input
|
||||||
op.UIOut = b.CLI
|
op.UIOut = b.CLI
|
||||||
op.Workspace = backend.DefaultStateName
|
op.Workspace = backend.DefaultStateName
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
@ -23,11 +22,7 @@ import (
|
||||||
func (b *Remote) Context(op *backend.Operation) (*terraform.Context, statemgr.Full, tfdiags.Diagnostics) {
|
func (b *Remote) Context(op *backend.Operation) (*terraform.Context, statemgr.Full, tfdiags.Diagnostics) {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
if op.LockState {
|
op.StateLocker = op.StateLocker.WithContext(context.Background())
|
||||||
op.StateLocker = clistate.NewLocker(context.Background(), op.StateLockTimeout, b.CLI, b.cliColorize())
|
|
||||||
} else {
|
|
||||||
op.StateLocker = clistate.NewNoopLocker()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the remote workspace name.
|
// Get the remote workspace name.
|
||||||
remoteWorkspaceName := b.getRemoteWorkspaceName(op.Workspace)
|
remoteWorkspaceName := b.getRemoteWorkspaceName(op.Workspace)
|
||||||
|
@ -41,8 +36,7 @@ func (b *Remote) Context(op *backend.Operation) (*terraform.Context, statemgr.Fu
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[TRACE] backend/remote: requesting state lock for workspace %q", remoteWorkspaceName)
|
log.Printf("[TRACE] backend/remote: requesting state lock for workspace %q", remoteWorkspaceName)
|
||||||
if err := op.StateLocker.Lock(stateMgr, op.Type.String()); err != nil {
|
if diags := op.StateLocker.Lock(stateMgr, op.Type.String()); diags.HasErrors() {
|
||||||
diags = diags.Append(errwrap.Wrapf("Error locking state: {{err}}", err))
|
|
||||||
return nil, nil, diags
|
return nil, nil, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,10 +44,7 @@ func (b *Remote) Context(op *backend.Operation) (*terraform.Context, statemgr.Fu
|
||||||
// If we're returning with errors, and thus not producing a valid
|
// If we're returning with errors, and thus not producing a valid
|
||||||
// context, we'll want to avoid leaving the remote workspace locked.
|
// context, we'll want to avoid leaving the remote workspace locked.
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
err := op.StateLocker.Unlock(nil)
|
diags = diags.Append(op.StateLocker.Unlock())
|
||||||
if err != nil {
|
|
||||||
diags = diags.Append(errwrap.Wrapf("Error unlocking state: {{err}}", err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,12 @@ import (
|
||||||
|
|
||||||
tfe "github.com/hashicorp/go-tfe"
|
tfe "github.com/hashicorp/go-tfe"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/internal/initwd"
|
"github.com/hashicorp/terraform/internal/initwd"
|
||||||
|
"github.com/hashicorp/terraform/internal/terminal"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
@ -183,11 +187,14 @@ func TestRemoteContextWithVars(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
streams, _ := terminal.StreamsForTesting(t)
|
||||||
|
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))
|
||||||
|
|
||||||
op := &backend.Operation{
|
op := &backend.Operation{
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
|
StateLocker: clistate.NewLocker(0, view),
|
||||||
Workspace: backend.DefaultStateName,
|
Workspace: backend.DefaultStateName,
|
||||||
LockState: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v := test.Opts
|
v := test.Opts
|
||||||
|
|
|
@ -260,15 +260,16 @@ in order to capture the filesystem context the remote workspace expects:
|
||||||
return r, generalError("Failed to create run", err)
|
return r, generalError("Failed to create run", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the lock timeout is set,
|
// When the lock timeout is set, if the run is still pending and
|
||||||
if op.StateLockTimeout > 0 {
|
// cancellable after that period, we attempt to cancel it.
|
||||||
|
if lockTimeout := op.StateLocker.Timeout(); lockTimeout > 0 {
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-stopCtx.Done():
|
case <-stopCtx.Done():
|
||||||
return
|
return
|
||||||
case <-cancelCtx.Done():
|
case <-cancelCtx.Done():
|
||||||
return
|
return
|
||||||
case <-time.After(op.StateLockTimeout):
|
case <-time.After(lockTimeout):
|
||||||
// Retrieve the run to get its current status.
|
// Retrieve the run to get its current status.
|
||||||
r, err := b.client.Runs.Read(cancelCtx, r.ID)
|
r, err := b.client.Runs.Read(cancelCtx, r.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -13,7 +13,11 @@ import (
|
||||||
tfe "github.com/hashicorp/go-tfe"
|
tfe "github.com/hashicorp/go-tfe"
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/internal/initwd"
|
"github.com/hashicorp/terraform/internal/initwd"
|
||||||
|
"github.com/hashicorp/terraform/internal/terminal"
|
||||||
"github.com/hashicorp/terraform/plans/planfile"
|
"github.com/hashicorp/terraform/plans/planfile"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
@ -24,14 +28,24 @@ import (
|
||||||
func testOperationPlan(t *testing.T, configDir string) (*backend.Operation, func()) {
|
func testOperationPlan(t *testing.T, configDir string) (*backend.Operation, func()) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
return testOperationPlanWithTimeout(t, configDir, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testOperationPlanWithTimeout(t *testing.T, configDir string, timeout time.Duration) (*backend.Operation, func()) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
||||||
|
|
||||||
|
streams, _ := terminal.StreamsForTesting(t)
|
||||||
|
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))
|
||||||
|
|
||||||
return &backend.Operation{
|
return &backend.Operation{
|
||||||
ConfigDir: configDir,
|
ConfigDir: configDir,
|
||||||
ConfigLoader: configLoader,
|
ConfigLoader: configLoader,
|
||||||
Parallelism: defaultParallelism,
|
Parallelism: defaultParallelism,
|
||||||
PlanRefresh: true,
|
PlanRefresh: true,
|
||||||
ShowDiagnostics: testLogDiagnostics(t),
|
ShowDiagnostics: testLogDiagnostics(t),
|
||||||
|
StateLocker: clistate.NewLocker(timeout, view),
|
||||||
Type: backend.OperationTypePlan,
|
Type: backend.OperationTypePlan,
|
||||||
}, configCleanup
|
}, configCleanup
|
||||||
}
|
}
|
||||||
|
@ -625,7 +639,7 @@ func TestRemote_planLockTimeout(t *testing.T) {
|
||||||
t.Fatalf("error creating pending run: %v", err)
|
t.Fatalf("error creating pending run: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
op, configCleanup := testOperationPlan(t, "./testdata/plan")
|
op, configCleanup := testOperationPlanWithTimeout(t, "./testdata/plan", 50)
|
||||||
defer configCleanup()
|
defer configCleanup()
|
||||||
|
|
||||||
input := testInput(t, map[string]string{
|
input := testInput(t, map[string]string{
|
||||||
|
@ -633,7 +647,6 @@ func TestRemote_planLockTimeout(t *testing.T) {
|
||||||
"approve": "yes",
|
"approve": "yes",
|
||||||
})
|
})
|
||||||
|
|
||||||
op.StateLockTimeout = 50 * time.Millisecond
|
|
||||||
op.UIIn = input
|
op.UIIn = input
|
||||||
op.UIOut = b.CLI
|
op.UIOut = b.CLI
|
||||||
op.Workspace = backend.DefaultStateName
|
op.Workspace = backend.DefaultStateName
|
||||||
|
|
|
@ -940,6 +940,7 @@ func TestApply_planNoModuleFiles(t *testing.T) {
|
||||||
|
|
||||||
p := applyFixtureProvider()
|
p := applyFixtureProvider()
|
||||||
planPath := applyFixturePlanFile(t)
|
planPath := applyFixturePlanFile(t)
|
||||||
|
view, _ := testView(t)
|
||||||
|
|
||||||
view, _ := testView(t)
|
view, _ := testView(t)
|
||||||
apply := &ApplyCommand{
|
apply := &ApplyCommand{
|
||||||
|
|
|
@ -7,33 +7,25 @@ package clistate
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/terraform/command/views"
|
||||||
multierror "github.com/hashicorp/go-multierror"
|
|
||||||
"github.com/hashicorp/terraform/internal/helper/slowmessage"
|
"github.com/hashicorp/terraform/internal/helper/slowmessage"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/mitchellh/colorstring"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LockThreshold = 400 * time.Millisecond
|
LockThreshold = 400 * time.Millisecond
|
||||||
LockMessage = "Acquiring state lock. This may take a few moments..."
|
LockErrorMessage = `Error message: %s
|
||||||
LockErrorMessage = `Error acquiring the state lock: {{err}}
|
|
||||||
|
|
||||||
Terraform acquires a state lock to protect the state from being written
|
Terraform acquires a state lock to protect the state from being written
|
||||||
by multiple users at the same time. Please resolve the issue above and try
|
by multiple users at the same time. Please resolve the issue above and try
|
||||||
again. For most commands, you can disable locking with the "-lock=false"
|
again. For most commands, you can disable locking with the "-lock=false"
|
||||||
flag, but this is not recommended.`
|
flag, but this is not recommended.`
|
||||||
|
|
||||||
UnlockMessage = "Releasing state lock. This may take a few moments..."
|
UnlockErrorMessage = `Error message: %s
|
||||||
UnlockErrorMessage = `
|
|
||||||
[reset][bold][red]Error releasing the state lock![reset][red]
|
|
||||||
|
|
||||||
Error message: %s
|
|
||||||
|
|
||||||
Terraform acquires a lock when accessing your state to prevent others
|
Terraform acquires a lock when accessing your state to prevent others
|
||||||
running Terraform to potentially modify the state at the same time. An
|
running Terraform to potentially modify the state at the same time. An
|
||||||
|
@ -46,8 +38,7 @@ In this scenario, please call the "force-unlock" command to unlock the
|
||||||
state manually. This is a very dangerous operation since if it is done
|
state manually. This is a very dangerous operation since if it is done
|
||||||
erroneously it could result in two people modifying state at the same time.
|
erroneously it could result in two people modifying state at the same time.
|
||||||
Only call this command if you're certain that the unlock above failed and
|
Only call this command if you're certain that the unlock above failed and
|
||||||
that no one else is holding a lock.
|
that no one else is holding a lock.`
|
||||||
`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Locker allows for more convenient usage of the lower-level statemgr.Locker
|
// Locker allows for more convenient usage of the lower-level statemgr.Locker
|
||||||
|
@ -60,12 +51,17 @@ that no one else is holding a lock.
|
||||||
// Unlock, which is at a minimum the LockID string returned by the
|
// Unlock, which is at a minimum the LockID string returned by the
|
||||||
// statemgr.Locker.
|
// statemgr.Locker.
|
||||||
type Locker interface {
|
type Locker interface {
|
||||||
|
// Returns a shallow copy of the locker with its context changed to ctx.
|
||||||
|
WithContext(ctx context.Context) Locker
|
||||||
|
|
||||||
// Lock the provided state manager, storing the reason string in the LockInfo.
|
// Lock the provided state manager, storing the reason string in the LockInfo.
|
||||||
Lock(s statemgr.Locker, reason string) error
|
Lock(s statemgr.Locker, reason string) tfdiags.Diagnostics
|
||||||
|
|
||||||
// Unlock the previously locked state.
|
// Unlock the previously locked state.
|
||||||
// An optional error can be passed in, and will be combined with any error
|
Unlock() tfdiags.Diagnostics
|
||||||
// from the Unlock operation.
|
|
||||||
Unlock(error) error
|
// Timeout returns the configured timeout duration
|
||||||
|
Timeout() time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type locker struct {
|
type locker struct {
|
||||||
|
@ -73,34 +69,43 @@ type locker struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
state statemgr.Locker
|
state statemgr.Locker
|
||||||
ui cli.Ui
|
view views.StateLocker
|
||||||
color *colorstring.Colorize
|
|
||||||
lockID string
|
lockID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ Locker = (*locker)(nil)
|
||||||
|
|
||||||
// Create a new Locker.
|
// Create a new Locker.
|
||||||
// This Locker uses state.LockWithContext to retry the lock until the provided
|
// This Locker uses state.LockWithContext to retry the lock until the provided
|
||||||
// timeout is reached, or the context is canceled. Lock progress will be be
|
// timeout is reached, or the context is canceled. Lock progress will be be
|
||||||
// reported to the user through the provided UI.
|
// reported to the user through the provided UI.
|
||||||
func NewLocker(
|
func NewLocker(timeout time.Duration, view views.StateLocker) Locker {
|
||||||
ctx context.Context,
|
return &locker{
|
||||||
timeout time.Duration,
|
ctx: context.Background(),
|
||||||
ui cli.Ui,
|
|
||||||
color *colorstring.Colorize) Locker {
|
|
||||||
|
|
||||||
l := &locker{
|
|
||||||
ctx: ctx,
|
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
ui: ui,
|
view: view,
|
||||||
color: color,
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithContext returns a new Locker with the specified context, copying the
|
||||||
|
// timeout and view parameters from the original Locker.
|
||||||
|
func (l *locker) WithContext(ctx context.Context) Locker {
|
||||||
|
if ctx == nil {
|
||||||
|
panic("nil context")
|
||||||
|
}
|
||||||
|
return &locker{
|
||||||
|
ctx: ctx,
|
||||||
|
timeout: l.timeout,
|
||||||
|
view: l.view,
|
||||||
}
|
}
|
||||||
return l
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locker locks the given state and outputs to the user if locking is taking
|
// Locker locks the given state and outputs to the user if locking is taking
|
||||||
// longer than the threshold. The lock is retried until the context is
|
// longer than the threshold. The lock is retried until the context is
|
||||||
// cancelled.
|
// cancelled.
|
||||||
func (l *locker) Lock(s statemgr.Locker, reason string) error {
|
func (l *locker) Lock(s statemgr.Locker, reason string) tfdiags.Diagnostics {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
defer l.mu.Unlock()
|
defer l.mu.Unlock()
|
||||||
|
|
||||||
|
@ -116,46 +121,49 @@ func (l *locker) Lock(s statemgr.Locker, reason string) error {
|
||||||
id, err := statemgr.LockWithContext(ctx, s, lockInfo)
|
id, err := statemgr.LockWithContext(ctx, s, lockInfo)
|
||||||
l.lockID = id
|
l.lockID = id
|
||||||
return err
|
return err
|
||||||
}, func() {
|
}, l.view.Locking)
|
||||||
if l.ui != nil {
|
|
||||||
l.ui.Output(l.color.Color(LockMessage))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errwrap.Wrapf(strings.TrimSpace(LockErrorMessage), err)
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
|
tfdiags.Error,
|
||||||
|
"Error acquiring the state lock",
|
||||||
|
fmt.Sprintf(LockErrorMessage, err),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *locker) Unlock(parentErr error) error {
|
func (l *locker) Unlock() tfdiags.Diagnostics {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
defer l.mu.Unlock()
|
defer l.mu.Unlock()
|
||||||
|
|
||||||
if l.lockID == "" {
|
if l.lockID == "" {
|
||||||
return parentErr
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
err := slowmessage.Do(LockThreshold, func() error {
|
err := slowmessage.Do(LockThreshold, func() error {
|
||||||
return l.state.Unlock(l.lockID)
|
return l.state.Unlock(l.lockID)
|
||||||
}, func() {
|
}, l.view.Unlocking)
|
||||||
if l.ui != nil {
|
|
||||||
l.ui.Output(l.color.Color(UnlockMessage))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.ui.Output(l.color.Color(fmt.Sprintf(
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
"\n"+strings.TrimSpace(UnlockErrorMessage)+"\n", err)))
|
tfdiags.Error,
|
||||||
|
"Error releasing the state lock",
|
||||||
parentErr = multierror.Append(parentErr, err)
|
fmt.Sprintf(UnlockErrorMessage, err),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
return parentErr
|
return diags
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *locker) Timeout() time.Duration {
|
||||||
|
return l.timeout
|
||||||
|
}
|
||||||
|
|
||||||
type noopLocker struct{}
|
type noopLocker struct{}
|
||||||
|
|
||||||
// NewNoopLocker returns a valid Locker that does nothing.
|
// NewNoopLocker returns a valid Locker that does nothing.
|
||||||
|
@ -163,10 +171,20 @@ func NewNoopLocker() Locker {
|
||||||
return noopLocker{}
|
return noopLocker{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l noopLocker) Lock(statemgr.Locker, string) error {
|
var _ Locker = noopLocker{}
|
||||||
|
|
||||||
|
func (l noopLocker) WithContext(ctx context.Context) Locker {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l noopLocker) Lock(statemgr.Locker, string) tfdiags.Diagnostics {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l noopLocker) Unlock(err error) error {
|
func (l noopLocker) Unlock() tfdiags.Diagnostics {
|
||||||
return err
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l noopLocker) Timeout() time.Duration {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
package clistate
|
package clistate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
|
"github.com/hashicorp/terraform/internal/terminal"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/mitchellh/cli"
|
|
||||||
"github.com/mitchellh/colorstring"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUnlock(t *testing.T) {
|
func TestUnlock(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
streams, _ := terminal.StreamsForTesting(t)
|
||||||
|
view := views.NewView(streams)
|
||||||
|
|
||||||
l := NewLocker(context.Background(), 0, ui, &colorstring.Colorize{Disable: true})
|
l := NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
|
||||||
l.Lock(statemgr.NewUnlockErrorFull(nil, nil), "test-lock")
|
l.Lock(statemgr.NewUnlockErrorFull(nil, nil), "test-lock")
|
||||||
|
|
||||||
err := l.Unlock(nil)
|
diags := l.Unlock()
|
||||||
if err != nil {
|
if diags.HasErrors() {
|
||||||
t.Log(err.Error())
|
t.Log(diags.Err().Error())
|
||||||
} else {
|
} else {
|
||||||
t.Error("expected error")
|
t.Error("expected error")
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,9 +104,9 @@ func (c *ConsoleCommand) Run(args []string) int {
|
||||||
|
|
||||||
// Successfully creating the context can result in a lock, so ensure we release it
|
// Successfully creating the context can result in a lock, so ensure we release it
|
||||||
defer func() {
|
defer func() {
|
||||||
err := opReq.StateLocker.Unlock(nil)
|
diags := opReq.StateLocker.Unlock()
|
||||||
if err != nil {
|
if diags.HasErrors() {
|
||||||
c.Ui.Error(err.Error())
|
c.showDiagnostics(diags)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,12 @@ func TestConsole_basic(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ConsoleCommand{
|
c := &ConsoleCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,10 +78,12 @@ func TestConsole_tfvars(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ConsoleCommand{
|
c := &ConsoleCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,10 +131,12 @@ func TestConsole_unsetRequiredVars(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ConsoleCommand{
|
c := &ConsoleCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,10 +165,12 @@ func TestConsole_variables(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ConsoleCommand{
|
c := &ConsoleCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,11 +208,13 @@ func TestConsole_modules(t *testing.T) {
|
||||||
|
|
||||||
p := applyFixtureProvider()
|
p := applyFixtureProvider()
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
|
|
||||||
c := &ConsoleCommand{
|
c := &ConsoleCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,9 +218,9 @@ func (c *ImportCommand) Run(args []string) int {
|
||||||
|
|
||||||
// Successfully creating the context can result in a lock, so ensure we release it
|
// Successfully creating the context can result in a lock, so ensure we release it
|
||||||
defer func() {
|
defer func() {
|
||||||
err := opReq.StateLocker.Unlock(nil)
|
diags := opReq.StateLocker.Unlock()
|
||||||
if err != nil {
|
if diags.HasErrors() {
|
||||||
c.Ui.Error(err.Error())
|
c.showDiagnostics(diags)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,12 @@ func TestInit_empty(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +58,12 @@ func TestInit_multipleArgs(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +84,12 @@ func TestInit_fromModule_cwdDest(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +136,12 @@ func TestInit_fromModule_dstInSrc(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,10 +165,12 @@ func TestInit_get(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,10 +194,12 @@ func TestInit_getUpgradeModules(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,10 +226,12 @@ func TestInit_backend(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,10 +256,12 @@ func TestInit_backendUnset(t *testing.T) {
|
||||||
log.Printf("[TRACE] TestInit_backendUnset: beginning first init")
|
log.Printf("[TRACE] TestInit_backendUnset: beginning first init")
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,10 +288,12 @@ func TestInit_backendUnset(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,10 +321,12 @@ func TestInit_backendConfigFile(t *testing.T) {
|
||||||
|
|
||||||
t.Run("good-config-file", func(t *testing.T) {
|
t.Run("good-config-file", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
args := []string{"-backend-config", "input.config"}
|
args := []string{"-backend-config", "input.config"}
|
||||||
|
@ -324,10 +344,12 @@ func TestInit_backendConfigFile(t *testing.T) {
|
||||||
// the backend config file must not be a full terraform block
|
// the backend config file must not be a full terraform block
|
||||||
t.Run("full-backend-config-file", func(t *testing.T) {
|
t.Run("full-backend-config-file", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
args := []string{"-backend-config", "backend.config"}
|
args := []string{"-backend-config", "backend.config"}
|
||||||
|
@ -342,10 +364,12 @@ func TestInit_backendConfigFile(t *testing.T) {
|
||||||
// the backend config file must match the schema for the backend
|
// the backend config file must match the schema for the backend
|
||||||
t.Run("invalid-config-file", func(t *testing.T) {
|
t.Run("invalid-config-file", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
args := []string{"-backend-config", "invalid.config"}
|
args := []string{"-backend-config", "invalid.config"}
|
||||||
|
@ -360,10 +384,12 @@ func TestInit_backendConfigFile(t *testing.T) {
|
||||||
// missing file is an error
|
// missing file is an error
|
||||||
t.Run("missing-config-file", func(t *testing.T) {
|
t.Run("missing-config-file", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
args := []string{"-backend-config", "missing.config"}
|
args := []string{"-backend-config", "missing.config"}
|
||||||
|
@ -378,10 +404,12 @@ func TestInit_backendConfigFile(t *testing.T) {
|
||||||
// blank filename clears the backend config
|
// blank filename clears the backend config
|
||||||
t.Run("blank-config-file", func(t *testing.T) {
|
t.Run("blank-config-file", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
args := []string{"-backend-config="}
|
args := []string{"-backend-config="}
|
||||||
|
@ -429,10 +457,12 @@ func TestInit_backendConfigFilePowershellConfusion(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,10 +498,12 @@ func TestInit_backendConfigFileChange(t *testing.T) {
|
||||||
})()
|
})()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,10 +527,12 @@ func TestInit_backendConfigKV(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,10 +556,12 @@ func TestInit_backendConfigKVReInit(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,6 +575,7 @@ func TestInit_backendConfigKVReInit(t *testing.T) {
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,10 +620,12 @@ func TestInit_backendConfigKVReInitWithConfigDiff(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,6 +639,7 @@ func TestInit_backendConfigKVReInitWithConfigDiff(t *testing.T) {
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,10 +669,12 @@ func TestInit_backendCli_no_config_block(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,10 +709,12 @@ func TestInit_backendReinitWithExtra(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,10 +754,12 @@ func TestInit_backendReinitConfigToExtra(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,6 +787,7 @@ func TestInit_backendReinitConfigToExtra(t *testing.T) {
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,10 +813,12 @@ func TestInit_inputFalse(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,6 +854,7 @@ func TestInit_inputFalse(t *testing.T) {
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,6 +873,7 @@ func TestInit_inputFalse(t *testing.T) {
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,6 +893,7 @@ func TestInit_getProvider(t *testing.T) {
|
||||||
|
|
||||||
overrides := metaOverridesForProvider(testProvider())
|
overrides := metaOverridesForProvider(testProvider())
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||||
// looking for an exact version
|
// looking for an exact version
|
||||||
"exact": {"1.2.3"},
|
"exact": {"1.2.3"},
|
||||||
|
@ -854,6 +906,7 @@ func TestInit_getProvider(t *testing.T) {
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: overrides,
|
testingOverrides: overrides,
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,7 +972,9 @@ func TestInit_getProvider(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m.Ui = ui
|
m.Ui = ui
|
||||||
|
m.View = view
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: m,
|
Meta: m,
|
||||||
}
|
}
|
||||||
|
@ -944,6 +999,7 @@ func TestInit_getProviderSource(t *testing.T) {
|
||||||
|
|
||||||
overrides := metaOverridesForProvider(testProvider())
|
overrides := metaOverridesForProvider(testProvider())
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||||
// looking for an exact version
|
// looking for an exact version
|
||||||
"acme/alpha": {"1.2.3"},
|
"acme/alpha": {"1.2.3"},
|
||||||
|
@ -955,6 +1011,7 @@ func TestInit_getProviderSource(t *testing.T) {
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: overrides,
|
testingOverrides: overrides,
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,6 +1050,7 @@ func TestInit_getProviderLegacyFromState(t *testing.T) {
|
||||||
|
|
||||||
overrides := metaOverridesForProvider(testProvider())
|
overrides := metaOverridesForProvider(testProvider())
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||||
"acme/alpha": {"1.2.3"},
|
"acme/alpha": {"1.2.3"},
|
||||||
})
|
})
|
||||||
|
@ -1000,6 +1058,7 @@ func TestInit_getProviderLegacyFromState(t *testing.T) {
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: overrides,
|
testingOverrides: overrides,
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,6 +1092,7 @@ func TestInit_getProviderInvalidPackage(t *testing.T) {
|
||||||
|
|
||||||
overrides := metaOverridesForProvider(testProvider())
|
overrides := metaOverridesForProvider(testProvider())
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
|
|
||||||
// create a provider source which allows installing an invalid package
|
// create a provider source which allows installing an invalid package
|
||||||
addr := addrs.MustParseProviderSourceString("invalid/package")
|
addr := addrs.MustParseProviderSourceString("invalid/package")
|
||||||
|
@ -1053,6 +1113,7 @@ func TestInit_getProviderInvalidPackage(t *testing.T) {
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: overrides,
|
testingOverrides: overrides,
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,8 +1170,10 @@ func TestInit_getProviderDetectedLegacy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: multiSource,
|
ProviderSource: multiSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1166,9 +1229,11 @@ func TestInit_providerSource(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1277,9 +1342,11 @@ func TestInit_cancel(t *testing.T) {
|
||||||
close(shutdownCh)
|
close(shutdownCh)
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
ShutdownCh: shutdownCh,
|
ShutdownCh: shutdownCh,
|
||||||
}
|
}
|
||||||
|
@ -1320,9 +1387,11 @@ func TestInit_getUpgradePlugins(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1444,9 +1513,11 @@ func TestInit_getProviderMissing(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1472,10 +1543,12 @@ func TestInit_checkRequiredVersion(t *testing.T) {
|
||||||
defer testChdir(t, td)()
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1505,9 +1578,11 @@ func TestInit_providerLockFile(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1555,10 +1630,12 @@ func TestInit_pluginDirReset(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1591,6 +1668,7 @@ func TestInit_pluginDirReset(t *testing.T) {
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource, // still empty
|
ProviderSource: providerSource, // still empty
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1623,9 +1701,11 @@ func TestInit_pluginDirProviders(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1723,9 +1803,11 @@ func TestInit_pluginDirProvidersDoesNotGet(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1795,9 +1877,11 @@ func TestInit_pluginDirWithBuiltIn(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1832,9 +1916,11 @@ func TestInit_invalidBuiltInProviders(t *testing.T) {
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,9 @@ import (
|
||||||
"github.com/hashicorp/hcl/v2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
remoteBackend "github.com/hashicorp/terraform/backend/remote"
|
remoteBackend "github.com/hashicorp/terraform/backend/remote"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/plans"
|
"github.com/hashicorp/terraform/plans"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
|
@ -341,6 +343,12 @@ func (m *Meta) Operation(b backend.Backend) *backend.Operation {
|
||||||
panic(fmt.Sprintf("failed to encode backend configuration for plan: %s", err))
|
panic(fmt.Sprintf("failed to encode backend configuration for plan: %s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stateLocker := clistate.NewNoopLocker()
|
||||||
|
if m.stateLock {
|
||||||
|
view := views.NewStateLocker(arguments.ViewHuman, m.View)
|
||||||
|
stateLocker = clistate.NewLocker(m.stateLockTimeout, view)
|
||||||
|
}
|
||||||
|
|
||||||
return &backend.Operation{
|
return &backend.Operation{
|
||||||
PlanOutBackend: planOutBackend,
|
PlanOutBackend: planOutBackend,
|
||||||
Parallelism: m.parallelism,
|
Parallelism: m.parallelism,
|
||||||
|
@ -348,8 +356,7 @@ func (m *Meta) Operation(b backend.Backend) *backend.Operation {
|
||||||
UIIn: m.UIInput(),
|
UIIn: m.UIInput(),
|
||||||
UIOut: m.Ui,
|
UIOut: m.Ui,
|
||||||
Workspace: workspace,
|
Workspace: workspace,
|
||||||
LockState: m.stateLock,
|
StateLocker: stateLocker,
|
||||||
StateLockTimeout: m.stateLockTimeout,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,12 +809,13 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.stateLock {
|
if m.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), m.stateLockTimeout, m.Ui, m.Colorize())
|
view := views.NewStateLocker(arguments.ViewHuman, m.View)
|
||||||
|
stateLocker := clistate.NewLocker(m.stateLockTimeout, view)
|
||||||
if err := stateLocker.Lock(sMgr, "backend from plan"); err != nil {
|
if err := stateLocker.Lock(sMgr, "backend from plan"); err != nil {
|
||||||
diags = diags.Append(fmt.Errorf("Error locking state: %s", err))
|
diags = diags.Append(fmt.Errorf("Error locking state: %s", err))
|
||||||
return nil, diags
|
return nil, diags
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer stateLocker.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema().ImpliedType())
|
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema().ImpliedType())
|
||||||
|
@ -886,12 +894,13 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clista
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.stateLock {
|
if m.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), m.stateLockTimeout, m.Ui, m.Colorize())
|
view := views.NewStateLocker(arguments.ViewHuman, m.View)
|
||||||
|
stateLocker := clistate.NewLocker(m.stateLockTimeout, view)
|
||||||
if err := stateLocker.Lock(sMgr, "backend from plan"); err != nil {
|
if err := stateLocker.Lock(sMgr, "backend from plan"); err != nil {
|
||||||
diags = diags.Append(fmt.Errorf("Error locking state: %s", err))
|
diags = diags.Append(fmt.Errorf("Error locking state: %s", err))
|
||||||
return nil, diags
|
return nil, diags
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer stateLocker.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema().ImpliedType())
|
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema().ImpliedType())
|
||||||
|
|
|
@ -12,7 +12,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
@ -325,17 +327,20 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error {
|
||||||
if m.stateLock {
|
if m.stateLock {
|
||||||
lockCtx := context.Background()
|
lockCtx := context.Background()
|
||||||
|
|
||||||
lockerOne := clistate.NewLocker(lockCtx, m.stateLockTimeout, m.Ui, m.Colorize())
|
view := views.NewStateLocker(arguments.ViewHuman, m.View)
|
||||||
if err := lockerOne.Lock(stateOne, "migration source state"); err != nil {
|
locker := clistate.NewLocker(m.stateLockTimeout, view)
|
||||||
return fmt.Errorf("Error locking source state: %s", err)
|
|
||||||
}
|
|
||||||
defer lockerOne.Unlock(nil)
|
|
||||||
|
|
||||||
lockerTwo := clistate.NewLocker(lockCtx, m.stateLockTimeout, m.Ui, m.Colorize())
|
lockerOne := locker.WithContext(lockCtx)
|
||||||
if err := lockerTwo.Lock(stateTwo, "migration destination state"); err != nil {
|
if diags := lockerOne.Lock(stateOne, "migration source state"); diags.HasErrors() {
|
||||||
return fmt.Errorf("Error locking destination state: %s", err)
|
return diags.Err()
|
||||||
}
|
}
|
||||||
defer lockerTwo.Unlock(nil)
|
defer lockerOne.Unlock()
|
||||||
|
|
||||||
|
lockerTwo := locker.WithContext(lockCtx)
|
||||||
|
if diags := lockerTwo.Lock(stateTwo, "migration destination state"); diags.HasErrors() {
|
||||||
|
return diags.Err()
|
||||||
|
}
|
||||||
|
defer lockerTwo.Unlock()
|
||||||
|
|
||||||
// We now own a lock, so double check that we have the version
|
// We now own a lock, so double check that we have the version
|
||||||
// corresponding to the lock.
|
// corresponding to the lock.
|
||||||
|
|
|
@ -1876,6 +1876,8 @@ func TestBackendFromState(t *testing.T) {
|
||||||
func testMetaBackend(t *testing.T, args []string) *Meta {
|
func testMetaBackend(t *testing.T, args []string) *Meta {
|
||||||
var m Meta
|
var m Meta
|
||||||
m.Ui = new(cli.MockUi)
|
m.Ui = new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
|
m.View = view
|
||||||
m.process(args)
|
m.process(args)
|
||||||
f := m.extendedFlagSet("test")
|
f := m.extendedFlagSet("test")
|
||||||
if err := f.Parse(args); err != nil {
|
if err := f.Parse(args); err != nil {
|
||||||
|
|
|
@ -22,10 +22,12 @@ import (
|
||||||
|
|
||||||
func TestShow(t *testing.T) {
|
func TestShow(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +48,12 @@ func TestShow_noArgs(t *testing.T) {
|
||||||
defer testChdir(t, stateDir)()
|
defer testChdir(t, stateDir)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,10 +97,12 @@ func TestShow_aliasedProvider(t *testing.T) {
|
||||||
defer testChdir(t, stateDir)()
|
defer testChdir(t, stateDir)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,10 +127,12 @@ func TestShow_noArgsNoState(t *testing.T) {
|
||||||
defer testChdir(t, stateDir)()
|
defer testChdir(t, stateDir)()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,10 +147,12 @@ func TestShow_plan(t *testing.T) {
|
||||||
planPath := testPlanFileNoop(t)
|
planPath := testPlanFileNoop(t)
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,10 +174,12 @@ func TestShow_planWithChanges(t *testing.T) {
|
||||||
planPathWithChanges := showFixturePlanFile(t, plans.DeleteThenCreate)
|
planPathWithChanges := showFixturePlanFile(t, plans.DeleteThenCreate)
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(showFixtureProvider()),
|
testingOverrides: metaOverridesForProvider(showFixtureProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,10 +202,12 @@ func TestShow_plan_json(t *testing.T) {
|
||||||
planPath := showFixturePlanFile(t, plans.Create)
|
planPath := showFixturePlanFile(t, plans.Create)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(showFixtureProvider()),
|
testingOverrides: metaOverridesForProvider(showFixtureProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,10 +226,12 @@ func TestShow_state(t *testing.T) {
|
||||||
defer os.RemoveAll(filepath.Dir(statePath))
|
defer os.RemoveAll(filepath.Dir(statePath))
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &ShowCommand{
|
c := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,9 +370,11 @@ func TestShow_json_output_state(t *testing.T) {
|
||||||
|
|
||||||
p := showFixtureProvider()
|
p := showFixtureProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
m := Meta{
|
m := Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
ProviderSource: providerSource,
|
ProviderSource: providerSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
|
@ -49,12 +50,16 @@ func (c *StateMvCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.stateLock {
|
if c.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateFromMgr, "state-mv"); err != nil {
|
if diags := stateLocker.Lock(stateFromMgr, "state-mv"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking source state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := stateFromMgr.RefreshState(); err != nil {
|
if err := stateFromMgr.RefreshState(); err != nil {
|
||||||
|
@ -83,12 +88,16 @@ func (c *StateMvCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.stateLock {
|
if c.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateToMgr, "state-mv"); err != nil {
|
if diags := stateLocker.Lock(stateToMgr, "state-mv"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking destination state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := stateToMgr.RefreshState(); err != nil {
|
if err := stateToMgr.RefreshState(); err != nil {
|
||||||
|
|
|
@ -58,11 +58,13 @@ func TestStateMv(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -204,11 +206,13 @@ func TestStateMv_resourceToInstance(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -277,12 +281,14 @@ func TestStateMv_resourceToInstanceErr(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
|
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -344,11 +350,13 @@ func TestStateMv_resourceToInstanceErrInAutomation(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
RunningInAutomation: true,
|
RunningInAutomation: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -416,11 +424,13 @@ func TestStateMv_instanceToResource(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -489,11 +499,13 @@ func TestStateMv_instanceToNewResource(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -560,11 +572,13 @@ func TestStateMv_differentResourceTypes(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -636,10 +650,12 @@ func TestStateMv_explicitWithBackend(t *testing.T) {
|
||||||
|
|
||||||
// init our backend
|
// init our backend
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
ic := &InitCommand{
|
ic := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,6 +672,7 @@ func TestStateMv_explicitWithBackend(t *testing.T) {
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -713,11 +730,13 @@ func TestStateMv_backupExplicit(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -762,11 +781,13 @@ func TestStateMv_stateOutNew(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -834,11 +855,13 @@ func TestStateMv_stateOutExisting(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -877,11 +900,13 @@ func TestStateMv_noState(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -945,11 +970,13 @@ func TestStateMv_stateOutNew_count(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1019,11 +1046,13 @@ func TestStateMv_stateOutNew_largeCount(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1089,11 +1118,13 @@ func TestStateMv_stateOutNew_nestedModule(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1145,11 +1176,13 @@ func TestStateMv_toNewModule(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1244,11 +1277,13 @@ func TestStateMv_withinBackend(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1314,11 +1349,13 @@ func TestStateMv_fromBackendToLocal(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1365,11 +1402,13 @@ func TestStateMv_onlyResourceInModule(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateMvCommand{
|
c := &StateMvCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/states/statefile"
|
"github.com/hashicorp/terraform/states/statefile"
|
||||||
"github.com/hashicorp/terraform/states/statemgr"
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
|
@ -93,12 +94,16 @@ func (c *StatePushCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.stateLock {
|
if c.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateMgr, "state-push"); err != nil {
|
if diags := stateLocker.Lock(stateMgr, "state-push"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := stateMgr.RefreshState(); err != nil {
|
if err := stateMgr.RefreshState(); err != nil {
|
||||||
|
|
|
@ -23,10 +23,12 @@ func TestStatePush_empty(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,10 +52,12 @@ func TestStatePush_lockedState(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +87,12 @@ func TestStatePush_replaceMatch(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,10 +125,12 @@ func TestStatePush_replaceMatchStdin(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,10 +156,12 @@ func TestStatePush_lineageMismatch(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,10 +187,12 @@ func TestStatePush_serialNewer(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,10 +218,12 @@ func TestStatePush_serialOlder(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,8 +250,9 @@ func TestStatePush_forceRemoteState(t *testing.T) {
|
||||||
|
|
||||||
// init the backend
|
// init the backend
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
initCmd := &InitCommand{
|
initCmd := &InitCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
if code := initCmd.Run([]string{}); code != 0 {
|
if code := initCmd.Run([]string{}); code != 0 {
|
||||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||||
|
@ -246,7 +261,7 @@ func TestStatePush_forceRemoteState(t *testing.T) {
|
||||||
// create a new workspace
|
// create a new workspace
|
||||||
ui = new(cli.MockUi)
|
ui = new(cli.MockUi)
|
||||||
newCmd := &WorkspaceNewCommand{
|
newCmd := &WorkspaceNewCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
if code := newCmd.Run([]string{"test"}); code != 0 {
|
if code := newCmd.Run([]string{"test"}); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
|
@ -268,7 +283,7 @@ func TestStatePush_forceRemoteState(t *testing.T) {
|
||||||
// push our local state to that new workspace
|
// push our local state to that new workspace
|
||||||
ui = new(cli.MockUi)
|
ui = new(cli.MockUi)
|
||||||
c := &StatePushCommand{
|
c := &StatePushCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
|
|
||||||
args := []string{"-force", statePath}
|
args := []string{"-force", statePath}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
|
@ -74,12 +75,16 @@ func (c *StateReplaceProviderCommand) Run(args []string) int {
|
||||||
|
|
||||||
// Acquire lock if requested
|
// Acquire lock if requested
|
||||||
if c.stateLock {
|
if c.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateMgr, "state-replace-provider"); err != nil {
|
if diags := stateLocker.Lock(stateMgr, "state-replace-provider"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking source state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh and load state
|
// Refresh and load state
|
||||||
|
|
|
@ -65,10 +65,12 @@ func TestStateReplaceProvider(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateReplaceProviderCommand{
|
c := &StateReplaceProviderCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -99,10 +101,12 @@ func TestStateReplaceProvider(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateReplaceProviderCommand{
|
c := &StateReplaceProviderCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -133,10 +137,12 @@ func TestStateReplaceProvider(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateReplaceProviderCommand{
|
c := &StateReplaceProviderCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -166,10 +172,12 @@ func TestStateReplaceProvider(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateReplaceProviderCommand{
|
c := &StateReplaceProviderCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -193,10 +201,12 @@ func TestStateReplaceProvider(t *testing.T) {
|
||||||
|
|
||||||
t.Run("invalid flags", func(t *testing.T) {
|
t.Run("invalid flags", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateReplaceProviderCommand{
|
c := &StateReplaceProviderCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -217,10 +227,12 @@ func TestStateReplaceProvider(t *testing.T) {
|
||||||
|
|
||||||
t.Run("wrong number of arguments", func(t *testing.T) {
|
t.Run("wrong number of arguments", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateReplaceProviderCommand{
|
c := &StateReplaceProviderCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -237,10 +249,12 @@ func TestStateReplaceProvider(t *testing.T) {
|
||||||
|
|
||||||
t.Run("invalid provider strings", func(t *testing.T) {
|
t.Run("invalid provider strings", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateReplaceProviderCommand{
|
c := &StateReplaceProviderCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
@ -44,12 +45,16 @@ func (c *StateRmCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.stateLock {
|
if c.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateMgr, "state-rm"); err != nil {
|
if diags := stateLocker.Lock(stateMgr, "state-rm"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := stateMgr.RefreshState(); err != nil {
|
if err := stateMgr.RefreshState(); err != nil {
|
||||||
|
|
|
@ -49,11 +49,13 @@ func TestStateRm(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -117,11 +119,13 @@ func TestStateRmNotChildModule(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -203,11 +207,13 @@ func TestStateRmNoArgs(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -262,11 +268,13 @@ func TestStateRmNonExist(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -318,11 +326,13 @@ func TestStateRm_backupExplicit(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -349,11 +359,13 @@ func TestStateRm_noState(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -372,11 +384,13 @@ func TestStateRm_needsInit(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -446,11 +460,13 @@ func TestStateRm_backendState(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &StateRmCommand{
|
c := &StateRmCommand{
|
||||||
StateMeta{
|
StateMeta{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
|
@ -116,12 +117,16 @@ func (c *TaintCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.stateLock {
|
if c.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateMgr, "taint"); err != nil {
|
if diags := stateLocker.Lock(stateMgr, "taint"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := stateMgr.RefreshState(); err != nil {
|
if err := stateMgr.RefreshState(); err != nil {
|
||||||
|
|
|
@ -33,9 +33,11 @@ func TestTaint(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,9 +78,11 @@ func TestTaint_lockedState(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer unlock()
|
defer unlock()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,9 +126,11 @@ func TestTaint_backup(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,9 +171,11 @@ func TestTaint_backupDisable(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +196,11 @@ func TestTaint_backupDisable(t *testing.T) {
|
||||||
|
|
||||||
func TestTaint_badState(t *testing.T) {
|
func TestTaint_badState(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,9 +239,11 @@ func TestTaint_defaultState(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +283,8 @@ func TestTaint_defaultWorkspaceState(t *testing.T) {
|
||||||
path := testStateFileWorkspaceDefault(t, testWorkspace, state)
|
path := testStateFileWorkspaceDefault(t, testWorkspace, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
meta := Meta{Ui: ui}
|
view, _ := testView(t)
|
||||||
|
meta := Meta{Ui: ui, View: view}
|
||||||
meta.SetWorkspace(testWorkspace)
|
meta.SetWorkspace(testWorkspace)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: meta,
|
Meta: meta,
|
||||||
|
@ -308,9 +321,11 @@ func TestTaint_missing(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,9 +359,11 @@ func TestTaint_missingAllow(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,9 +416,11 @@ func TestTaint_stateOut(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,9 +472,11 @@ func TestTaint_module(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,10 +519,12 @@ func TestTaint_checkRequiredVersion(t *testing.T) {
|
||||||
path := testStateFile(t, state)
|
path := testStateFile(t, state)
|
||||||
|
|
||||||
ui := cli.NewMockUi()
|
ui := cli.NewMockUi()
|
||||||
|
view, _ := testView(t)
|
||||||
c := &TaintCommand{
|
c := &TaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,12 @@ func TestUnlock(t *testing.T) {
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UnlockCommand{
|
c := &UnlockCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,9 +74,11 @@ func TestUnlock_inmemBackend(t *testing.T) {
|
||||||
|
|
||||||
// init backend
|
// init backend
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
ci := &InitCommand{
|
ci := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if code := ci.Run(nil); code != 0 {
|
if code := ci.Run(nil); code != 0 {
|
||||||
|
@ -85,6 +89,7 @@ func TestUnlock_inmemBackend(t *testing.T) {
|
||||||
c := &UnlockCommand{
|
c := &UnlockCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +107,7 @@ func TestUnlock_inmemBackend(t *testing.T) {
|
||||||
c = &UnlockCommand{
|
c = &UnlockCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
)
|
)
|
||||||
|
@ -81,12 +82,16 @@ func (c *UntaintCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.stateLock {
|
if c.stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateMgr, "untaint"); err != nil {
|
if diags := stateLocker.Lock(stateMgr, "untaint"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := stateMgr.RefreshState(); err != nil {
|
if err := stateMgr.RefreshState(); err != nil {
|
||||||
|
|
|
@ -32,9 +32,11 @@ func TestUntaint(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +82,11 @@ func TestUntaint_lockedState(t *testing.T) {
|
||||||
defer unlock()
|
defer unlock()
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,9 +130,11 @@ func TestUntaint_backup(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,9 +186,11 @@ func TestUntaint_backupDisable(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,9 +215,11 @@ test_instance.foo:
|
||||||
|
|
||||||
func TestUntaint_badState(t *testing.T) {
|
func TestUntaint_badState(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,9 +258,11 @@ func TestUntaint_defaultState(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +307,8 @@ func TestUntaint_defaultWorkspaceState(t *testing.T) {
|
||||||
path := testStateFileWorkspaceDefault(t, testWorkspace, state)
|
path := testStateFileWorkspaceDefault(t, testWorkspace, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
meta := Meta{Ui: ui}
|
view, _ := testView(t)
|
||||||
|
meta := Meta{Ui: ui, View: view}
|
||||||
meta.SetWorkspace(testWorkspace)
|
meta.SetWorkspace(testWorkspace)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: meta,
|
Meta: meta,
|
||||||
|
@ -336,9 +349,11 @@ func TestUntaint_missing(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,9 +387,11 @@ func TestUntaint_missingAllow(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,9 +444,11 @@ func TestUntaint_stateOut(t *testing.T) {
|
||||||
testStateFileDefault(t, state)
|
testStateFileDefault(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,9 +508,11 @@ func TestUntaint_module(t *testing.T) {
|
||||||
statePath := testStateFile(t, state)
|
statePath := testStateFile(t, state)
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
c := &UntaintCommand{
|
c := &UntaintCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
|
View: view,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package views
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The StateLocker view is used to display locking/unlocking status messages
|
||||||
|
// if the state lock process takes longer than expected.
|
||||||
|
type StateLocker interface {
|
||||||
|
Locking()
|
||||||
|
Unlocking()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStateLocker returns an initialized StateLocker implementation for the given ViewType.
|
||||||
|
func NewStateLocker(vt arguments.ViewType, view *View) StateLocker {
|
||||||
|
switch vt {
|
||||||
|
case arguments.ViewHuman:
|
||||||
|
return &StateLockerHuman{View: *view}
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unknown view type %v", vt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateLockerHuman is an implementation of StateLocker which prints status to
|
||||||
|
// a terminal.
|
||||||
|
type StateLockerHuman struct {
|
||||||
|
View
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ StateLocker = (*StateLockerHuman)(nil)
|
||||||
|
|
||||||
|
func (v *StateLockerHuman) Locking() {
|
||||||
|
v.streams.Println("Acquiring state lock. This may take a few moments...")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *StateLockerHuman) Unlocking() {
|
||||||
|
v.streams.Println("Releasing state lock. This may take a few moments...")
|
||||||
|
}
|
|
@ -34,7 +34,8 @@ func TestWorkspace_createAndChange(t *testing.T) {
|
||||||
|
|
||||||
args := []string{"test"}
|
args := []string{"test"}
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
newCmd.Meta = Meta{Ui: ui}
|
view, _ := testView(t)
|
||||||
|
newCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
if code := newCmd.Run(args); code != 0 {
|
if code := newCmd.Run(args); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
|
@ -47,7 +48,7 @@ func TestWorkspace_createAndChange(t *testing.T) {
|
||||||
selCmd := &WorkspaceSelectCommand{}
|
selCmd := &WorkspaceSelectCommand{}
|
||||||
args = []string{backend.DefaultStateName}
|
args = []string{backend.DefaultStateName}
|
||||||
ui = new(cli.MockUi)
|
ui = new(cli.MockUi)
|
||||||
selCmd.Meta = Meta{Ui: ui}
|
selCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
if code := selCmd.Run(args); code != 0 {
|
if code := selCmd.Run(args); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
|
@ -83,8 +84,9 @@ func TestWorkspace_createAndList(t *testing.T) {
|
||||||
// create multiple workspaces
|
// create multiple workspaces
|
||||||
for _, env := range envs {
|
for _, env := range envs {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
newCmd := &WorkspaceNewCommand{
|
newCmd := &WorkspaceNewCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
if code := newCmd.Run([]string{env}); code != 0 {
|
if code := newCmd.Run([]string{env}); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
|
@ -93,7 +95,8 @@ func TestWorkspace_createAndList(t *testing.T) {
|
||||||
|
|
||||||
listCmd := &WorkspaceListCommand{}
|
listCmd := &WorkspaceListCommand{}
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
listCmd.Meta = Meta{Ui: ui}
|
view, _ := testView(t)
|
||||||
|
listCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
|
|
||||||
if code := listCmd.Run(nil); code != 0 {
|
if code := listCmd.Run(nil); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
|
@ -128,7 +131,8 @@ func TestWorkspace_createAndShow(t *testing.T) {
|
||||||
// make sure current workspace show outputs "default"
|
// make sure current workspace show outputs "default"
|
||||||
showCmd := &WorkspaceShowCommand{}
|
showCmd := &WorkspaceShowCommand{}
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
showCmd.Meta = Meta{Ui: ui}
|
view, _ := testView(t)
|
||||||
|
showCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
|
|
||||||
if code := showCmd.Run(nil); code != 0 {
|
if code := showCmd.Run(nil); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
|
@ -147,21 +151,21 @@ func TestWorkspace_createAndShow(t *testing.T) {
|
||||||
|
|
||||||
// create test_a workspace
|
// create test_a workspace
|
||||||
ui = new(cli.MockUi)
|
ui = new(cli.MockUi)
|
||||||
newCmd.Meta = Meta{Ui: ui}
|
newCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
if code := newCmd.Run(env); code != 0 {
|
if code := newCmd.Run(env); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
selCmd := &WorkspaceSelectCommand{}
|
selCmd := &WorkspaceSelectCommand{}
|
||||||
ui = new(cli.MockUi)
|
ui = new(cli.MockUi)
|
||||||
selCmd.Meta = Meta{Ui: ui}
|
selCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
if code := selCmd.Run(env); code != 0 {
|
if code := selCmd.Run(env); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
showCmd = &WorkspaceShowCommand{}
|
showCmd = &WorkspaceShowCommand{}
|
||||||
ui = new(cli.MockUi)
|
ui = new(cli.MockUi)
|
||||||
showCmd.Meta = Meta{Ui: ui}
|
showCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
|
|
||||||
if code := showCmd.Run(nil); code != 0 {
|
if code := showCmd.Run(nil); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
|
@ -188,8 +192,9 @@ func TestWorkspace_createInvalid(t *testing.T) {
|
||||||
// create multiple workspaces
|
// create multiple workspaces
|
||||||
for _, env := range envs {
|
for _, env := range envs {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
newCmd := &WorkspaceNewCommand{
|
newCmd := &WorkspaceNewCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
if code := newCmd.Run([]string{env}); code == 0 {
|
if code := newCmd.Run([]string{env}); code == 0 {
|
||||||
t.Fatalf("expected failure: \n%s", ui.OutputWriter)
|
t.Fatalf("expected failure: \n%s", ui.OutputWriter)
|
||||||
|
@ -199,7 +204,8 @@ func TestWorkspace_createInvalid(t *testing.T) {
|
||||||
// list workspaces to make sure none were created
|
// list workspaces to make sure none were created
|
||||||
listCmd := &WorkspaceListCommand{}
|
listCmd := &WorkspaceListCommand{}
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
listCmd.Meta = Meta{Ui: ui}
|
view, _ := testView(t)
|
||||||
|
listCmd.Meta = Meta{Ui: ui, View: view}
|
||||||
|
|
||||||
if code := listCmd.Run(nil); code != 0 {
|
if code := listCmd.Run(nil); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
|
@ -222,8 +228,9 @@ func TestWorkspace_createWithState(t *testing.T) {
|
||||||
|
|
||||||
// init the backend
|
// init the backend
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
initCmd := &InitCommand{
|
initCmd := &InitCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
if code := initCmd.Run([]string{}); code != 0 {
|
if code := initCmd.Run([]string{}); code != 0 {
|
||||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||||
|
@ -257,7 +264,7 @@ func TestWorkspace_createWithState(t *testing.T) {
|
||||||
args := []string{"-state", "test.tfstate", workspace}
|
args := []string{"-state", "test.tfstate", workspace}
|
||||||
ui = new(cli.MockUi)
|
ui = new(cli.MockUi)
|
||||||
newCmd := &WorkspaceNewCommand{
|
newCmd := &WorkspaceNewCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
if code := newCmd.Run(args); code != 0 {
|
if code := newCmd.Run(args); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
|
@ -303,8 +310,9 @@ func TestWorkspace_delete(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
delCmd := &WorkspaceDeleteCommand{
|
delCmd := &WorkspaceDeleteCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
|
|
||||||
current, _ := delCmd.Workspace()
|
current, _ := delCmd.Workspace()
|
||||||
|
@ -352,8 +360,9 @@ func TestWorkspace_deleteInvalid(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
delCmd := &WorkspaceDeleteCommand{
|
delCmd := &WorkspaceDeleteCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the workspace
|
// delete the workspace
|
||||||
|
@ -406,8 +415,9 @@ func TestWorkspace_deleteWithState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
view, _ := testView(t)
|
||||||
delCmd := &WorkspaceDeleteCommand{
|
delCmd := &WorkspaceDeleteCommand{
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui, View: view},
|
||||||
}
|
}
|
||||||
args := []string{"test"}
|
args := []string{"test"}
|
||||||
if code := delCmd.Run(args); code == 0 {
|
if code := delCmd.Run(args); code == 0 {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/posener/complete"
|
"github.com/posener/complete"
|
||||||
|
@ -107,9 +108,9 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
||||||
|
|
||||||
var stateLocker clistate.Locker
|
var stateLocker clistate.Locker
|
||||||
if stateLock {
|
if stateLock {
|
||||||
stateLocker = clistate.NewLocker(context.Background(), stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker = clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateMgr, "workspace_delete"); err != nil {
|
if diags := stateLocker.Lock(stateMgr, "state-replace-provider"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -118,7 +119,7 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
||||||
|
|
||||||
if err := stateMgr.RefreshState(); err != nil {
|
if err := stateMgr.RefreshState(); err != nil {
|
||||||
// We need to release the lock before exit
|
// We need to release the lock before exit
|
||||||
stateLocker.Unlock(nil)
|
stateLocker.Unlock()
|
||||||
c.Ui.Error(err.Error())
|
c.Ui.Error(err.Error())
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -127,7 +128,7 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
||||||
|
|
||||||
if hasResources && !force {
|
if hasResources && !force {
|
||||||
// We need to release the lock before exit
|
// We need to release the lock before exit
|
||||||
stateLocker.Unlock(nil)
|
stateLocker.Unlock()
|
||||||
c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envNotEmpty), workspace))
|
c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envNotEmpty), workspace))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -141,7 +142,7 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
||||||
// state deletion, i.e. in a CI environment. Adding Delete() as a
|
// state deletion, i.e. in a CI environment. Adding Delete() as a
|
||||||
// required method of States would allow the removal of the resource to
|
// required method of States would allow the removal of the resource to
|
||||||
// be delegated from the Backend to the State itself.
|
// be delegated from the Backend to the State itself.
|
||||||
stateLocker.Unlock(nil)
|
stateLocker.Unlock()
|
||||||
|
|
||||||
err = b.DeleteWorkspace(workspace)
|
err = b.DeleteWorkspace(workspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/command/arguments"
|
||||||
"github.com/hashicorp/terraform/command/clistate"
|
"github.com/hashicorp/terraform/command/clistate"
|
||||||
|
"github.com/hashicorp/terraform/command/views"
|
||||||
"github.com/hashicorp/terraform/states/statefile"
|
"github.com/hashicorp/terraform/states/statefile"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
|
@ -124,12 +125,16 @@ func (c *WorkspaceNewCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if stateLock {
|
if stateLock {
|
||||||
stateLocker := clistate.NewLocker(context.Background(), stateLockTimeout, c.Ui, c.Colorize())
|
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
|
||||||
if err := stateLocker.Lock(stateMgr, "workspace_new"); err != nil {
|
if diags := stateLocker.Lock(stateMgr, "workspace-new"); diags.HasErrors() {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.showDiagnostics(diags)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer stateLocker.Unlock(nil)
|
defer func() {
|
||||||
|
if diags := stateLocker.Unlock(); diags.HasErrors() {
|
||||||
|
c.showDiagnostics(diags)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the existing state file
|
// read the existing state file
|
||||||
|
|
Loading…
Reference in New Issue