Skip to content

Commit dcecb82

Browse files
committed
WIP - attempt to fix the bug
1 parent b3bdad6 commit dcecb82

File tree

4 files changed

+47
-22
lines changed

4 files changed

+47
-22
lines changed

internal/command/init.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func (c *InitCommand) initCloud(ctx context.Context, root *configs.Module, extra
158158
return back, true, diags
159159
}
160160

161-
func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, initArgs *arguments.Init, configLocks *depsfile.Locks, view views.Init) (be backend.Backend, output bool, diags tfdiags.Diagnostics) {
161+
func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, initArgs *arguments.Init, previousLocks *depsfile.Locks, configLocks *depsfile.Locks, view views.Init) (be backend.Backend, output bool, diags tfdiags.Diagnostics) {
162162
ctx, span := tracer.Start(ctx, "initialize backend")
163163
_ = ctx // prevent staticcheck from complaining to avoid a maintenance hazard of having the wrong ctx in scope here
164164
defer span.End()
@@ -234,6 +234,7 @@ func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, ini
234234
opts = &BackendOpts{
235235
StateStoreConfig: root.StateStore,
236236
Locks: configLocks,
237+
PreviousLocks: previousLocks,
237238
CreateDefaultWorkspace: initArgs.CreateDefaultWorkspace,
238239
ConfigOverride: configOverride,
239240
Init: true,

internal/command/init_run.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,10 @@ func (c *InitCommand) run(initArgs *arguments.Init, view views.Init) int {
234234
case initArgs.Cloud && rootModEarly.CloudConfig != nil:
235235
back, backendOutput, backDiags = c.initCloud(ctx, rootModEarly, initArgs.BackendConfig, initArgs.ViewType, view)
236236
case initArgs.Backend:
237-
back, backendOutput, backDiags = c.initBackend(ctx, rootModEarly, initArgs, configLocks, view)
237+
back, backendOutput, backDiags = c.initBackend(ctx, rootModEarly, initArgs, previousLocks, configLocks, view)
238238
default:
239239
// load the previously-stored backend config
240-
back, backDiags = c.Meta.backendFromState(ctx)
240+
back, backDiags = c.Meta.backendFromState(ctx, previousLocks)
241241
}
242242
if backendOutput {
243243
header = true

internal/command/meta_backend.go

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ type BackendOpts struct {
6666
// version in use currently.
6767
Locks *depsfile.Locks
6868

69+
// PreviousLocks allows state-migration logic to use the older version of the provider
70+
// during upgrade-triggered migrations.
71+
PreviousLocks *depsfile.Locks
72+
6973
// ConfigOverride is an hcl.Body that, if non-nil, will be used with
7074
// configs.MergeBodies to override the type-specific backend configuration
7175
// arguments in Config.
@@ -1049,7 +1053,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
10491053
v := views.NewInit(opts.ViewType, m.View)
10501054
v.Output(views.InitMessageCode("state_store_unset"), s.StateStore.Type)
10511055

1052-
return m.stateStore_to_backend(sMgr, "local", localB, nil, opts.ViewType)
1056+
return m.stateStore_to_backend(sMgr, "local", localB, nil, opts)
10531057

10541058
// Configuring a backend for the first time or -reconfigure flag was used
10551059
case backendConfig != nil && s.Backend.Empty() &&
@@ -1123,7 +1127,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
11231127
newBackendCfgState.SetConfig(configVal, b.ConfigSchema())
11241128
newBackendCfgState.Hash = uint64(cHash)
11251129

1126-
return m.stateStore_to_backend(sMgr, backendConfig.Type, b, newBackendCfgState, opts.ViewType)
1130+
return m.stateStore_to_backend(sMgr, backendConfig.Type, b, newBackendCfgState, opts)
11271131

11281132
// Migration from backend to state store
11291133
case backendConfig == nil && !s.Backend.Empty() &&
@@ -1225,7 +1229,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
12251229
// AND we're not providing any overrides. An override can mean a change overriding an unchanged backend block (indicated by the hash value).
12261230
if (uint64(cHash) == s.StateStore.Hash) && (!opts.Init || opts.ConfigOverride == nil) {
12271231
log.Printf("[TRACE] Meta.Backend: using already-initialized, unchanged %q state_store configuration", stateStoreConfig.Type)
1228-
savedStateStore, sssDiags := m.savedStateStore(sMgr)
1232+
savedStateStore, sssDiags := m.savedStateStore(sMgr, opts.Locks)
12291233
diags = diags.Append(sssDiags)
12301234
// Verify that selected workspace exist. Otherwise prompt user to create one
12311235
if opts.Init && savedStateStore != nil {
@@ -1243,7 +1247,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
12431247
// don't need to migrate, we update the state store cache hash value.
12441248
if !m.stateStoreConfigNeedsMigration(stateStoreConfig, s.StateStore, opts) {
12451249
log.Printf("[TRACE] Meta.Backend: using already-initialized %q state store configuration", stateStoreConfig.Type)
1246-
savedStateStore, moreDiags := m.savedStateStore(sMgr)
1250+
savedStateStore, moreDiags := m.savedStateStore(sMgr, opts.Locks)
12471251
diags = diags.Append(moreDiags)
12481252
if moreDiags.HasErrors() {
12491253
return nil, diags
@@ -1448,7 +1452,7 @@ func (m *Meta) determineStateStoreInitReason(cfgState *workdir.StateStoreConfigS
14481452
// from the backend state. This should be used only when a user runs
14491453
// `terraform init -backend=false`. This function returns a local backend if
14501454
// there is no backend state or no backend configured.
1451-
func (m *Meta) backendFromState(_ context.Context) (backend.Backend, tfdiags.Diagnostics) {
1455+
func (m *Meta) backendFromState(_ context.Context, locks *depsfile.Locks) (backend.Backend, tfdiags.Diagnostics) {
14521456
var diags tfdiags.Diagnostics
14531457
// Get the path to where we store a local cache of backend configuration
14541458
// if we're using a remote backend. This may not yet exist which means
@@ -1474,7 +1478,7 @@ func (m *Meta) backendFromState(_ context.Context) (backend.Backend, tfdiags.Dia
14741478
// state_store
14751479
log.Printf("[TRACE] Meta.Backend: working directory was previously initialized for %q state store", s.StateStore.Type)
14761480
var ssDiags tfdiags.Diagnostics
1477-
b, ssDiags = m.savedStateStore(sMgr) // Relies on the state manager's internal state being refreshed above.
1481+
b, ssDiags = m.savedStateStore(sMgr, locks) // Relies on the state manager's internal state being refreshed above.
14781482
diags = diags.Append(ssDiags)
14791483
if ssDiags.HasErrors() {
14801484
return nil, diags
@@ -2523,17 +2527,17 @@ func (m *Meta) stateStore_C_s(c *configs.StateStore, stateStoreHash int, backend
25232527
}
25242528

25252529
// Migrating a state store to backend (including local).
2526-
func (m *Meta) stateStore_to_backend(ssSMgr *clistate.LocalState, dstBackendType string, dstBackend backend.Backend, newBackendState *workdir.BackendConfigState, viewType arguments.ViewType) (backend.Backend, tfdiags.Diagnostics) {
2530+
func (m *Meta) stateStore_to_backend(ssSMgr *clistate.LocalState, dstBackendType string, dstBackend backend.Backend, newBackendState *workdir.BackendConfigState, opts *BackendOpts) (backend.Backend, tfdiags.Diagnostics) {
25272531
var diags tfdiags.Diagnostics
25282532

25292533
s := ssSMgr.State()
25302534
stateStoreType := s.StateStore.Type
25312535

2532-
view := views.NewInit(viewType, m.View)
2536+
view := views.NewInit(opts.ViewType, m.View)
25332537
view.Output(views.StateMigrateLocalMessage, stateStoreType)
25342538

25352539
// Initialize the configured state store
2536-
ss, moreDiags := m.savedStateStore(ssSMgr)
2540+
ss, moreDiags := m.savedStateStore(ssSMgr, opts.Locks)
25372541
diags = diags.Append(moreDiags)
25382542
if moreDiags.HasErrors() {
25392543
return nil, diags
@@ -2545,7 +2549,7 @@ func (m *Meta) stateStore_to_backend(ssSMgr *clistate.LocalState, dstBackendType
25452549
DestinationType: dstBackendType,
25462550
Source: ss,
25472551
Destination: dstBackend,
2548-
ViewType: viewType,
2552+
ViewType: opts.ViewType,
25492553
})
25502554
if err != nil {
25512555
diags = diags.Append(err)
@@ -2660,7 +2664,7 @@ func (m *Meta) stateStore_changed(cfg *configs.StateStore, cfgHash int, sMgr *cl
26602664
}
26612665

26622666
// Grab the source state store
2663-
srcB, srcBDiags := m.savedStateStore(sMgr)
2667+
srcB, srcBDiags := m.savedStateStore(sMgr, opts.PreviousLocks)
26642668
diags = diags.Append(srcBDiags)
26652669
if srcBDiags.HasErrors() {
26662670
return nil, diags
@@ -2843,7 +2847,7 @@ func (m *Meta) createDefaultWorkspace(c *configs.StateStore, b backend.Backend)
28432847
}
28442848

28452849
// Initializing a saved state store from the backend state file (aka 'cache file', aka 'legacy state file')
2846-
func (m *Meta) savedStateStore(sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) {
2850+
func (m *Meta) savedStateStore(sMgr *clistate.LocalState, locks *depsfile.Locks) (backend.Backend, tfdiags.Diagnostics) {
28472851
// We're preparing a state_store version of backend.Backend.
28482852
//
28492853
// The provider and state store will be configured using the backend state file.
@@ -2852,7 +2856,7 @@ func (m *Meta) savedStateStore(sMgr *clistate.LocalState) (backend.Backend, tfdi
28522856

28532857
s := sMgr.State()
28542858

2855-
factory, pDiags := m.StateStoreProviderFactoryFromConfigState(s.StateStore)
2859+
factory, pDiags := m.StateStoreProviderFactoryFromConfigState(s.StateStore, locks)
28562860
diags = diags.Append(pDiags)
28572861
if pDiags.HasErrors() {
28582862
return nil, diags
@@ -3366,7 +3370,7 @@ func (m *Meta) StateStoreProviderFactoryFromConfig(config *configs.StateStore, l
33663370
return factory, diags
33673371
}
33683372

3369-
func (m *Meta) StateStoreProviderFactoryFromConfigState(cfgState *workdir.StateStoreConfigState) (providers.Factory, tfdiags.Diagnostics) {
3373+
func (m *Meta) StateStoreProviderFactoryFromConfigState(cfgState *workdir.StateStoreConfigState, locks *depsfile.Locks) (providers.Factory, tfdiags.Diagnostics) {
33703374
var diags tfdiags.Diagnostics
33713375

33723376
if cfgState == nil {
@@ -3382,7 +3386,7 @@ func (m *Meta) StateStoreProviderFactoryFromConfigState(cfgState *workdir.StateS
33823386
})
33833387
}
33843388

3385-
factories, err := m.ProviderFactories()
3389+
factories, err := m.providerFactoriesFromLocks(locks)
33863390
if err != nil {
33873391
// This may happen if the provider isn't present in the provider cache.
33883392
// This should be caught earlier by logic that diffs the config against the backend state file.

internal/command/meta_backend_test.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,7 +2159,12 @@ func TestBackendFromState(t *testing.T) {
21592159
// them to match just for this test.
21602160
wd.OverrideDataDir(".")
21612161

2162-
stateBackend, diags := m.backendFromState(context.Background())
2162+
locks, diags := m.lockedDependencies()
2163+
if diags.HasErrors() {
2164+
t.Fatal(diags.Err())
2165+
}
2166+
2167+
stateBackend, diags := m.backendFromState(context.Background(), locks)
21632168
if diags.HasErrors() {
21642169
t.Fatal(diags.Err())
21652170
}
@@ -2419,8 +2424,13 @@ func TestSavedStateStore(t *testing.T) {
24192424
t.Fatalf("unexpected error: %s", err)
24202425
}
24212426

2427+
locks, diags := m.lockedDependencies()
2428+
if diags.HasErrors() {
2429+
t.Fatal(diags.Err())
2430+
}
2431+
24222432
// Code under test
2423-
b, diags := m.savedStateStore(sMgr)
2433+
b, diags := m.savedStateStore(sMgr, locks)
24242434
if diags.HasErrors() {
24252435
t.Fatalf("unexpected errors: %s", diags.Err())
24262436
}
@@ -2459,7 +2469,12 @@ func TestSavedStateStore(t *testing.T) {
24592469
t.Fatalf("unexpected error: %s", err)
24602470
}
24612471

2462-
_, diags := m.savedStateStore(sMgr)
2472+
locks, dDiags := m.lockedDependencies()
2473+
if dDiags.HasErrors() {
2474+
t.Fatal(dDiags.Err())
2475+
}
2476+
2477+
_, diags := m.savedStateStore(sMgr, locks)
24632478
if !diags.HasErrors() {
24642479
t.Fatal("expected errors but got none")
24652480
}
@@ -2496,7 +2511,12 @@ func TestSavedStateStore(t *testing.T) {
24962511
t.Fatalf("unexpected error: %s", err)
24972512
}
24982513

2499-
_, diags := m.savedStateStore(sMgr)
2514+
locks, dDiags := m.lockedDependencies()
2515+
if dDiags.HasErrors() {
2516+
t.Fatal(dDiags.Err())
2517+
}
2518+
2519+
_, diags := m.savedStateStore(sMgr, locks)
25002520
if !diags.HasErrors() {
25012521
t.Fatal("expected errors but got none")
25022522
}

0 commit comments

Comments
 (0)