Move views.StateLocker to arguments.ViewOptions

Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
Christian Mesh
2025-12-18 07:41:54 -05:00
parent 98ab59f92c
commit 272a0a8327
28 changed files with 117 additions and 78 deletions

View File

@@ -40,7 +40,7 @@ func TestLocalRun(t *testing.T) {
streams, _ := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view))
op := &backend.Operation{
ConfigDir: configDir,
@@ -70,7 +70,7 @@ func TestLocalRun_error(t *testing.T) {
streams, _ := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view))
op := &backend.Operation{
ConfigDir: configDir,
@@ -103,7 +103,7 @@ func TestLocalRun_cloudPlan(t *testing.T) {
streams, _ := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view))
op := &backend.Operation{
ConfigDir: configDir,
@@ -188,7 +188,7 @@ func TestLocalRun_stalePlan(t *testing.T) {
streams, _ := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
stateLocker := clistate.NewLocker(0, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view))
op := &backend.Operation{
ConfigDir: configDir,

View File

@@ -49,7 +49,7 @@ func testOperationApplyWithTimeout(t *testing.T, configDir string, timeout time.
streams, done := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLockerView := views.NewStateLocker(arguments.ViewHuman, view)
stateLockerView := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view)
operationView := views.NewOperation(arguments.ViewHuman, false, view)
// Many of our tests use an overridden "null" provider that's just in-memory

View File

@@ -196,7 +196,7 @@ func TestRemoteContextWithVars(t *testing.T) {
}
streams, _ := terminal.StreamsForTesting(t)
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))
view := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, views.NewView(streams))
op := &backend.Operation{
ConfigDir: configDir,
@@ -421,7 +421,7 @@ func TestRemoteVariablesDoNotOverride(t *testing.T) {
}
streams, _ := terminal.StreamsForTesting(t)
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))
view := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, views.NewView(streams))
op := &backend.Operation{
ConfigDir: configDir,

View File

@@ -47,7 +47,7 @@ func testOperationPlanWithTimeout(t *testing.T, configDir string, timeout time.D
streams, done := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLockerView := views.NewStateLocker(arguments.ViewHuman, view)
stateLockerView := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view)
operationView := views.NewOperation(arguments.ViewHuman, false, view)
// Many of our tests use an overridden "null" provider that's just in-memory

View File

@@ -52,7 +52,7 @@ func testOperationApplyWithTimeout(t *testing.T, configDir string, timeout time.
streams, done := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLockerView := views.NewStateLocker(arguments.ViewHuman, view)
stateLockerView := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view)
operationView := views.NewOperation(arguments.ViewHuman, false, view)
// Many of our tests use an overridden "null" provider that's just in-memory

View File

@@ -195,7 +195,7 @@ func TestRemoteContextWithVars(t *testing.T) {
}
streams, _ := terminal.StreamsForTesting(t)
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))
view := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, views.NewView(streams))
op := &backend.Operation{
ConfigDir: configDir,
@@ -420,7 +420,7 @@ func TestRemoteVariablesDoNotOverride(t *testing.T) {
}
streams, _ := terminal.StreamsForTesting(t)
view := views.NewStateLocker(arguments.ViewHuman, views.NewView(streams))
view := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, views.NewView(streams))
op := &backend.Operation{
ConfigDir: configDir,

View File

@@ -49,7 +49,7 @@ func testOperationPlanWithTimeout(t *testing.T, configDir string, timeout time.D
streams, done := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLockerView := views.NewStateLocker(arguments.ViewHuman, view)
stateLockerView := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view)
operationView := views.NewOperation(arguments.ViewHuman, false, view)
// Many of our tests use an overridden "null" provider that's just in-memory

View File

@@ -36,7 +36,7 @@ func testOperationRefreshWithTimeout(t *testing.T, configDir string, timeout tim
streams, done := terminal.StreamsForTesting(t)
view := views.NewView(streams)
stateLockerView := views.NewStateLocker(arguments.ViewHuman, view)
stateLockerView := views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view)
operationView := views.NewOperation(arguments.ViewHuman, false, view)
return &backend.Operation{

View File

@@ -104,7 +104,7 @@ func (c *ApplyCommand) Run(rawArgs []string) int {
// Prepare the backend, passing the plan file if present, and the
// backend-specific arguments
be, beDiags := c.PrepareBackend(ctx, planFile, args.State, args.ViewOptions.ViewType, enc.State())
be, beDiags := c.PrepareBackend(ctx, planFile, args.State, args.ViewOptions, enc.State())
diags = diags.Append(beDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
@@ -197,7 +197,7 @@ func (c *ApplyCommand) LoadPlanFile(path string, enc encryption.Encryption) (*pl
return planFile, diags
}
func (c *ApplyCommand) PrepareBackend(ctx context.Context, planFile *planfile.WrappedPlanFile, args *arguments.State, viewType arguments.ViewType, enc encryption.StateEncryption) (backend.Enhanced, tfdiags.Diagnostics) {
func (c *ApplyCommand) PrepareBackend(ctx context.Context, planFile *planfile.WrappedPlanFile, args *arguments.State, viewOptions arguments.ViewOptions, enc encryption.StateEncryption) (backend.Enhanced, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// FIXME: we need to apply the state arguments to the meta object here
@@ -238,8 +238,8 @@ func (c *ApplyCommand) PrepareBackend(ctx context.Context, planFile *planfile.Wr
}
be, beDiags = c.Backend(ctx, &BackendOpts{
Config: backendConfig,
ViewType: viewType,
Config: backendConfig,
ViewOptions: viewOptions,
}, enc)
}
@@ -266,7 +266,7 @@ func (c *ApplyCommand) OperationRequest(
diags = diags.Append(c.providerDevOverrideRuntimeWarnings())
// Build the operation
opReq := c.Operation(ctx, be, applyArgs.ViewOptions.ViewType, enc)
opReq := c.Operation(ctx, be, applyArgs.ViewOptions, enc)
opReq.AutoApprove = applyArgs.AutoApprove
opReq.SuppressForgetErrorsDuringDestroy = applyArgs.SuppressForgetErrorsDuringDestroy
opReq.ConfigDir = "."

View File

@@ -18,7 +18,7 @@ func TestUnlock(t *testing.T) {
streams, _ := terminal.StreamsForTesting(t)
view := views.NewView(streams)
l := NewLocker(0, views.NewStateLocker(arguments.ViewHuman, view))
l := NewLocker(0, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, view))
l.Lock(statemgr.NewUnlockErrorFull(nil, nil), "test-lock")
diags := l.Unlock()

View File

@@ -91,7 +91,7 @@ func (c *ConsoleCommand) Run(args []string) int {
c.ignoreRemoteVersionConflict(b)
// Build the operation
opReq := c.Operation(ctx, b, arguments.ViewHuman, enc)
opReq := c.Operation(ctx, b, arguments.ViewOptions{ViewType: arguments.ViewHuman}, enc)
opReq.ConfigDir = configPath
opReq.ConfigLoader, err = c.initConfigLoader()
opReq.AllowUnsetVariables = true // we'll just evaluate them as unknown

View File

@@ -139,7 +139,7 @@ func (c *GraphCommand) Run(args []string) int {
c.ignoreRemoteVersionConflict(b)
// Build the operation
opReq := c.Operation(ctx, b, arguments.ViewHuman, enc)
opReq := c.Operation(ctx, b, arguments.ViewOptions{ViewType: arguments.ViewHuman}, enc)
opReq.ConfigDir = configPath
opReq.ConfigLoader, err = c.initConfigLoader()
opReq.PlanFile = planFile

View File

@@ -206,7 +206,7 @@ func (c *ImportCommand) Run(args []string) int {
}
// Build the operation
opReq := c.Operation(ctx, b, arguments.ViewHuman, enc)
opReq := c.Operation(ctx, b, arguments.ViewOptions{ViewType: arguments.ViewHuman}, enc)
opReq.ConfigDir = configPath
opReq.ConfigLoader, err = c.initConfigLoader()
if err != nil {

View File

@@ -61,9 +61,9 @@ type BackendOpts struct {
// You probably don't want to set this.
ForceLocal bool
// ViewType will set console output format for the
// ViewOptions will set console output format for the
// initialization operation (JSON or human-readable).
ViewType arguments.ViewType
ViewOptions arguments.ViewOptions
}
// BackendWithRemoteTerraformVersion is a shared interface between the 'remote' and 'cloud' backends
@@ -426,7 +426,7 @@ func (m *Meta) backendCLIOpts(ctx context.Context) (*backend.CLIOpts, error) {
// This prepares the operation. After calling this, the caller is expected
// to modify fields of the operation such as Sequence to specify what will
// be called.
func (m *Meta) Operation(ctx context.Context, b backend.Backend, vt arguments.ViewType, enc encryption.Encryption) *backend.Operation {
func (m *Meta) Operation(ctx context.Context, b backend.Backend, vt arguments.ViewOptions, enc encryption.Encryption) *backend.Operation {
schema := b.ConfigSchema()
workspace, err := m.Workspace(ctx)
if err != nil {
@@ -920,11 +920,14 @@ func (m *Meta) backend_c_r_S(
var diags tfdiags.Diagnostics
vt := arguments.ViewJSON
var viewOptions arguments.ViewOptions
if opts != nil {
viewOptions = opts.ViewOptions
}
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
if viewOptions.ViewType != arguments.ViewHuman && viewOptions.ViewType != arguments.ViewJSON {
viewOptions.ViewType = arguments.ViewHuman
}
s := sMgr.State()
@@ -964,7 +967,7 @@ func (m *Meta) backend_c_r_S(
DestinationType: "local",
Source: b,
Destination: localB,
ViewType: vt,
ViewOptions: viewOptions,
})
if err != nil {
diags = diags.Append(err)
@@ -996,11 +999,14 @@ func (m *Meta) backend_c_r_S(
func (m *Meta) backend_C_r_s(ctx context.Context, c *configs.Backend, cHash int, sMgr *clistate.LocalState, opts *BackendOpts, enc encryption.StateEncryption) (backend.Backend, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
vt := arguments.ViewJSON
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
viewOptions := arguments.ViewOptions{ViewType: arguments.ViewHuman}
if opts != nil {
viewOptions = opts.ViewOptions
if viewOptions.ViewType != arguments.ViewHuman && viewOptions.ViewType != arguments.ViewJSON {
viewOptions.ViewType = arguments.ViewHuman
}
}
// Grab a purely local backend to get the local state if it exists
@@ -1057,7 +1063,7 @@ func (m *Meta) backend_C_r_s(ctx context.Context, c *configs.Backend, cHash int,
DestinationType: c.Type,
Source: localB,
Destination: b,
ViewType: vt,
ViewOptions: viewOptions,
})
if err != nil {
diags = diags.Append(err)
@@ -1095,7 +1101,7 @@ func (m *Meta) backend_C_r_s(ctx context.Context, c *configs.Backend, cHash int,
}
if m.stateLock {
view := views.NewStateLocker(vt, m.View)
view := views.NewStateLocker(viewOptions, m.View)
stateLocker := clistate.NewLocker(m.stateLockTimeout, view)
if d := stateLocker.Lock(sMgr, "backend from plan"); d != nil {
diags = diags.Append(fmt.Errorf("Error locking state: %s", d))
@@ -1165,11 +1171,14 @@ func (m *Meta) backend_C_r_s(ctx context.Context, c *configs.Backend, cHash int,
func (m *Meta) backend_C_r_S_changed(ctx context.Context, c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool, opts *BackendOpts, enc encryption.StateEncryption) (backend.Backend, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
vt := arguments.ViewJSON
var viewOptions arguments.ViewOptions
if opts != nil {
viewOptions = opts.ViewOptions
}
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
if viewOptions.ViewType != arguments.ViewHuman && viewOptions.ViewType != arguments.ViewJSON {
viewOptions.ViewType = arguments.ViewHuman
}
// Get the old state
@@ -1231,7 +1240,7 @@ func (m *Meta) backend_C_r_S_changed(ctx context.Context, c *configs.Backend, cH
DestinationType: c.Type,
Source: oldB,
Destination: b,
ViewType: vt,
ViewOptions: viewOptions,
})
if err != nil {
diags = diags.Append(err)
@@ -1239,7 +1248,7 @@ func (m *Meta) backend_C_r_S_changed(ctx context.Context, c *configs.Backend, cH
}
if m.stateLock {
view := views.NewStateLocker(vt, m.View)
view := views.NewStateLocker(viewOptions, m.View)
stateLocker := clistate.NewLocker(m.stateLockTimeout, view)
if d := stateLocker.Lock(sMgr, "backend from plan"); d != nil {
diags = diags.Append(fmt.Errorf("Error locking state: %s", d))

View File

@@ -31,7 +31,7 @@ import (
type backendMigrateOpts struct {
SourceType, DestinationType string
Source, Destination backend.Backend
ViewType arguments.ViewType
ViewOptions arguments.ViewOptions
// Fields below are set internally when migrate is called
@@ -347,13 +347,16 @@ func (m *Meta) backendMigrateState_s_s(ctx context.Context, opts *backendMigrate
if m.stateLock {
lockCtx := context.Background()
vt := arguments.ViewJSON
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
viewOptions := arguments.ViewOptions{ViewType: arguments.ViewHuman}
if opts != nil {
viewOptions = opts.ViewOptions
if viewOptions.ViewType != arguments.ViewHuman && viewOptions.ViewType != arguments.ViewJSON {
viewOptions.ViewType = arguments.ViewHuman
}
}
view := views.NewStateLocker(vt, m.View)
view := views.NewStateLocker(viewOptions, m.View)
locker := clistate.NewLocker(m.stateLockTimeout, view)
lockerSource := locker.WithContext(lockCtx)

View File

@@ -86,7 +86,7 @@ func (c *PlanCommand) Run(rawArgs []string) int {
}
// Prepare the backend with the backend-specific arguments
be, beDiags := c.PrepareBackend(ctx, args.State, args.ViewOptions.ViewType, enc)
be, beDiags := c.PrepareBackend(ctx, args.State, args.ViewOptions, enc)
diags = diags.Append(beDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
@@ -94,7 +94,7 @@ func (c *PlanCommand) Run(rawArgs []string) int {
}
// Build the operation request
opReq, opDiags := c.OperationRequest(ctx, be, view, args.ViewOptions.ViewType, args.Operation, args.OutPath, args.GenerateConfigPath, enc)
opReq, opDiags := c.OperationRequest(ctx, be, view, args.ViewOptions, args.Operation, args.OutPath, args.GenerateConfigPath, enc)
diags = diags.Append(opDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
@@ -124,7 +124,7 @@ func (c *PlanCommand) Run(rawArgs []string) int {
return op.Result.ExitStatus()
}
func (c *PlanCommand) PrepareBackend(ctx context.Context, args *arguments.State, viewType arguments.ViewType, enc encryption.Encryption) (backend.Enhanced, tfdiags.Diagnostics) {
func (c *PlanCommand) PrepareBackend(ctx context.Context, args *arguments.State, viewOptions arguments.ViewOptions, enc encryption.Encryption) (backend.Enhanced, tfdiags.Diagnostics) {
// FIXME: we need to apply the state arguments to the meta object here
// because they are later used when initializing the backend. Carving a
// path to pass these arguments to the functions that need them is
@@ -138,8 +138,8 @@ func (c *PlanCommand) PrepareBackend(ctx context.Context, args *arguments.State,
// Load the backend
be, beDiags := c.Backend(ctx, &BackendOpts{
Config: backendConfig,
ViewType: viewType,
Config: backendConfig,
ViewOptions: viewOptions,
}, enc.State())
diags = diags.Append(beDiags)
if beDiags.HasErrors() {
@@ -153,7 +153,7 @@ func (c *PlanCommand) OperationRequest(
ctx context.Context,
be backend.Enhanced,
view views.Plan,
viewType arguments.ViewType,
viewOptions arguments.ViewOptions,
args *arguments.Operation,
planOutPath string,
generateConfigOut string,
@@ -162,7 +162,7 @@ func (c *PlanCommand) OperationRequest(
var diags tfdiags.Diagnostics
// Build the operation
opReq := c.Operation(ctx, be, viewType, enc)
opReq := c.Operation(ctx, be, viewOptions, enc)
opReq.ConfigDir = "."
opReq.PlanMode = args.PlanMode
opReq.Hooks = view.Hooks()

View File

@@ -94,7 +94,7 @@ func (c *ProvidersSchemaCommand) Run(args []string) int {
}
// Build the operation
opReq := c.Operation(ctx, b, arguments.ViewJSON, enc)
opReq := c.Operation(ctx, b, arguments.ViewOptions{ViewType: arguments.ViewJSON}, enc)
opReq.ConfigDir = cwd
opReq.ConfigLoader, err = c.initConfigLoader()
var callDiags tfdiags.Diagnostics

View File

@@ -83,7 +83,7 @@ func (c *RefreshCommand) Run(rawArgs []string) int {
}
// Prepare the backend with the backend-specific arguments
be, beDiags := c.PrepareBackend(ctx, args.State, args.ViewOptions.ViewType, enc)
be, beDiags := c.PrepareBackend(ctx, args.State, args.ViewOptions, enc)
diags = diags.Append(beDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
@@ -91,7 +91,7 @@ func (c *RefreshCommand) Run(rawArgs []string) int {
}
// Build the operation request
opReq, opDiags := c.OperationRequest(ctx, be, view, args.ViewOptions.ViewType, args.Operation, enc)
opReq, opDiags := c.OperationRequest(ctx, be, view, args.ViewOptions, args.Operation, enc)
diags = diags.Append(opDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
@@ -118,7 +118,7 @@ func (c *RefreshCommand) Run(rawArgs []string) int {
return op.Result.ExitStatus()
}
func (c *RefreshCommand) PrepareBackend(ctx context.Context, args *arguments.State, viewType arguments.ViewType, enc encryption.Encryption) (backend.Enhanced, tfdiags.Diagnostics) {
func (c *RefreshCommand) PrepareBackend(ctx context.Context, args *arguments.State, viewOptions arguments.ViewOptions, enc encryption.Encryption) (backend.Enhanced, tfdiags.Diagnostics) {
// FIXME: we need to apply the state arguments to the meta object here
// because they are later used when initializing the backend. Carving a
// path to pass these arguments to the functions that need them is
@@ -132,8 +132,8 @@ func (c *RefreshCommand) PrepareBackend(ctx context.Context, args *arguments.Sta
// Load the backend
be, beDiags := c.Backend(ctx, &BackendOpts{
Config: backendConfig,
ViewType: viewType,
Config: backendConfig,
ViewOptions: viewOptions,
}, enc.State())
diags = diags.Append(beDiags)
if beDiags.HasErrors() {
@@ -143,12 +143,12 @@ func (c *RefreshCommand) PrepareBackend(ctx context.Context, args *arguments.Sta
return be, diags
}
func (c *RefreshCommand) OperationRequest(ctx context.Context, be backend.Enhanced, view views.Refresh, viewType arguments.ViewType, args *arguments.Operation, enc encryption.Encryption,
func (c *RefreshCommand) OperationRequest(ctx context.Context, be backend.Enhanced, view views.Refresh, viewOptions arguments.ViewOptions, args *arguments.Operation, enc encryption.Encryption,
) (*backend.Operation, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// Build the operation
opReq := c.Operation(ctx, be, viewType, enc)
opReq := c.Operation(ctx, be, viewOptions, enc)
opReq.ConfigDir = "."
opReq.Hooks = view.Hooks()
opReq.Targets = args.Targets

View File

@@ -109,7 +109,7 @@ func (c *StateMvCommand) Run(args []string) int {
}
if c.stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateFromMgr, "state-mv"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1
@@ -147,7 +147,7 @@ func (c *StateMvCommand) Run(args []string) int {
}
if c.stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateToMgr, "state-mv"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1

View File

@@ -117,7 +117,7 @@ func (c *StatePushCommand) Run(args []string) int {
}
if c.stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateMgr, "state-push"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1

View File

@@ -98,7 +98,7 @@ func (c *StateReplaceProviderCommand) Run(args []string) int {
// Acquire lock if requested
if c.stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateMgr, "state-replace-provider"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1

View File

@@ -66,7 +66,7 @@ func (c *StateRmCommand) Run(args []string) int {
}
if c.stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateMgr, "state-rm"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1

View File

@@ -98,7 +98,7 @@ func (c *StateShowCommand) Run(args []string) int {
}
// Build the operation (required to get the schemas)
opReq := c.Operation(ctx, b, arguments.ViewHuman, enc)
opReq := c.Operation(ctx, b, arguments.ViewOptions{ViewType: arguments.ViewHuman}, enc)
opReq.AllowUnsetVariables = true
opReq.ConfigDir = cwd
var callDiags tfdiags.Diagnostics

View File

@@ -107,7 +107,7 @@ func (c *TaintCommand) Run(args []string) int {
}
if c.stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateMgr, "taint"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1

View File

@@ -98,7 +98,7 @@ func (c *UntaintCommand) Run(args []string) int {
}
if c.stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateMgr, "untaint"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1

View File

@@ -8,6 +8,7 @@ package views
import (
"encoding/json"
"fmt"
"os"
"time"
"github.com/opentofu/opentofu/internal/command/arguments"
@@ -21,14 +22,37 @@ type StateLocker interface {
}
// NewStateLocker returns an initialized StateLocker implementation for the given ViewType.
func NewStateLocker(vt arguments.ViewType, view *View) StateLocker {
switch vt {
func NewStateLocker(args arguments.ViewOptions, view *View) StateLocker {
var state StateLocker
switch args.ViewType {
case arguments.ViewHuman:
return &StateLockerHuman{view: view}
state = &StateLockerHuman{view: view}
case arguments.ViewJSON:
return &StateLockerJSON{view: view}
state = &StateLockerJSON{output: view.streams.Stdout.File}
default:
panic(fmt.Sprintf("unknown view type %v", vt))
panic(fmt.Sprintf("unknown view type %v", args.ViewType))
}
if args.JSONInto != nil {
state = StateLockerMulti{state, &StateLockerJSON{output: args.JSONInto}}
}
return state
}
type StateLockerMulti []StateLocker
var _ StateLocker = (StateLockerMulti)(nil)
func (m StateLockerMulti) Locking() {
for _, s := range m {
s.Locking()
}
}
func (m StateLockerMulti) Unlocking() {
for _, s := range m {
s.Unlocking()
}
}
@@ -39,7 +63,6 @@ type StateLockerHuman struct {
}
var _ StateLocker = (*StateLockerHuman)(nil)
var _ StateLocker = (*StateLockerJSON)(nil)
func (v *StateLockerHuman) Locking() {
v.view.streams.Println("Acquiring state lock. This may take a few moments...")
@@ -52,9 +75,11 @@ func (v *StateLockerHuman) Unlocking() {
// StateLockerJSON is an implementation of StateLocker which prints the state lock status
// to a terminal in machine-readable JSON form.
type StateLockerJSON struct {
view *View
output *os.File
}
var _ StateLocker = (*StateLockerJSON)(nil)
func (v *StateLockerJSON) Locking() {
current_timestamp := time.Now().Format(time.RFC3339)
@@ -66,7 +91,8 @@ func (v *StateLockerJSON) Locking() {
"type": "state_lock_acquire"}
lock_info_message, _ := json.Marshal(json_data)
v.view.streams.Println(string(lock_info_message))
lock_info_message = append(lock_info_message, '\n')
v.output.Write(lock_info_message)
}
func (v *StateLockerJSON) Unlocking() {
@@ -80,5 +106,6 @@ func (v *StateLockerJSON) Unlocking() {
"type": "state_lock_release"}
lock_info_message, _ := json.Marshal(json_data)
v.view.streams.Println(string(lock_info_message))
lock_info_message = append(lock_info_message, '\n')
v.output.Write(lock_info_message)
}

View File

@@ -126,7 +126,7 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
var stateLocker clistate.Locker
if stateLock {
stateLocker = clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker = clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateMgr, "state-replace-provider"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1

View File

@@ -143,7 +143,7 @@ func (c *WorkspaceNewCommand) Run(args []string) int {
}
if stateLock {
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewOptions{ViewType: arguments.ViewHuman}, c.View))
if diags := stateLocker.Lock(stateMgr, "workspace-new"); diags.HasErrors() {
c.showDiagnostics(diags)
return 1