Skip to content

Commit ddd598e

Browse files
committed
command/meta: Ensure PreviousLocks are passed through
1 parent 24db15c commit ddd598e

5 files changed

Lines changed: 50 additions & 22 deletions

File tree

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
ConfigOverride: configOverride,
238239
Init: true,
239240
ViewType: initArgs.ViewType,

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
@@ -65,6 +65,10 @@ type BackendOpts struct {
6565
// version in use currently.
6666
Locks *depsfile.Locks
6767

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

1047-
return m.stateStore_to_backend(sMgr, "local", localB, nil, opts.ViewType)
1051+
return m.stateStore_to_backend(sMgr, "local", localB, nil, opts)
10481052

10491053
// Configuring a backend for the first time or -reconfigure flag was used
10501054
case backendConfig != nil && s.Backend.Empty() &&
@@ -1118,7 +1122,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
11181122
newBackendCfgState.SetConfig(configVal, b.ConfigSchema())
11191123
newBackendCfgState.Hash = uint64(cHash)
11201124

1121-
return m.stateStore_to_backend(sMgr, backendConfig.Type, b, newBackendCfgState, opts.ViewType)
1125+
return m.stateStore_to_backend(sMgr, backendConfig.Type, b, newBackendCfgState, opts)
11221126

11231127
// Migration from backend to state store
11241128
case backendConfig == nil && !s.Backend.Empty() &&
@@ -1220,7 +1224,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
12201224
// AND we're not providing any overrides. An override can mean a change overriding an unchanged backend block (indicated by the hash value).
12211225
if (uint64(cHash) == s.StateStore.Hash) && (!opts.Init || opts.ConfigOverride == nil) {
12221226
log.Printf("[TRACE] Meta.Backend: using already-initialized, unchanged %q state_store configuration", stateStoreConfig.Type)
1223-
savedStateStore, sssDiags := m.savedStateStore(sMgr)
1227+
savedStateStore, sssDiags := m.savedStateStore(sMgr, opts.Locks)
12241228
diags = diags.Append(sssDiags)
12251229
// Verify that selected workspace exist. Otherwise prompt user to create one
12261230
if opts.Init && savedStateStore != nil {
@@ -1238,7 +1242,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
12381242
// don't need to migrate, we update the state store cache hash value.
12391243
if !m.stateStoreConfigNeedsMigration(stateStoreConfig, s.StateStore, opts) {
12401244
log.Printf("[TRACE] Meta.Backend: using already-initialized %q state store configuration", stateStoreConfig.Type)
1241-
savedStateStore, moreDiags := m.savedStateStore(sMgr)
1245+
savedStateStore, moreDiags := m.savedStateStore(sMgr, opts.Locks)
12421246
diags = diags.Append(moreDiags)
12431247
if moreDiags.HasErrors() {
12441248
return nil, diags
@@ -1467,7 +1471,7 @@ func (m *Meta) determineStateStoreInitReason(cfgState *workdir.StateStoreConfigS
14671471
// from the backend state. This should be used only when a user runs
14681472
// `terraform init -backend=false`. This function returns a local backend if
14691473
// there is no backend state or no backend configured.
1470-
func (m *Meta) backendFromState(_ context.Context) (backend.Backend, tfdiags.Diagnostics) {
1474+
func (m *Meta) backendFromState(_ context.Context, locks *depsfile.Locks) (backend.Backend, tfdiags.Diagnostics) {
14711475
var diags tfdiags.Diagnostics
14721476
// Get the path to where we store a local cache of backend configuration
14731477
// if we're using a remote backend. This may not yet exist which means
@@ -1493,7 +1497,7 @@ func (m *Meta) backendFromState(_ context.Context) (backend.Backend, tfdiags.Dia
14931497
// state_store
14941498
log.Printf("[TRACE] Meta.Backend: working directory was previously initialized for %q state store", s.StateStore.Type)
14951499
var ssDiags tfdiags.Diagnostics
1496-
b, ssDiags = m.savedStateStore(sMgr) // Relies on the state manager's internal state being refreshed above.
1500+
b, ssDiags = m.savedStateStore(sMgr, locks) // Relies on the state manager's internal state being refreshed above.
14971501
diags = diags.Append(ssDiags)
14981502
if ssDiags.HasErrors() {
14991503
return nil, diags
@@ -2531,17 +2535,17 @@ func (m *Meta) stateStore_C_s(c *configs.StateStore, stateStoreHash int, backend
25312535
}
25322536

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

25372541
s := ssSMgr.State()
25382542
stateStoreType := s.StateStore.Type
25392543

2540-
view := views.NewInit(viewType, m.View)
2544+
view := views.NewInit(opts.ViewType, m.View)
25412545
view.Output(views.StateMigrateLocalMessage, stateStoreType)
25422546

25432547
// Initialize the configured state store
2544-
ss, moreDiags := m.savedStateStore(ssSMgr)
2548+
ss, moreDiags := m.savedStateStore(ssSMgr, opts.Locks)
25452549
diags = diags.Append(moreDiags)
25462550
if moreDiags.HasErrors() {
25472551
return nil, diags
@@ -2553,7 +2557,7 @@ func (m *Meta) stateStore_to_backend(ssSMgr *clistate.LocalState, dstBackendType
25532557
DestinationType: dstBackendType,
25542558
Source: ss,
25552559
Destination: dstBackend,
2556-
ViewType: viewType,
2560+
ViewType: opts.ViewType,
25572561
})
25582562
if err != nil {
25592563
diags = diags.Append(err)
@@ -2668,7 +2672,7 @@ func (m *Meta) stateStore_changed(cfg *configs.StateStore, cfgHash int, sMgr *cl
26682672
}
26692673

26702674
// Grab the source state store
2671-
srcB, srcBDiags := m.savedStateStore(sMgr)
2675+
srcB, srcBDiags := m.savedStateStore(sMgr, opts.PreviousLocks)
26722676
diags = diags.Append(srcBDiags)
26732677
if srcBDiags.HasErrors() {
26742678
return nil, diags
@@ -2822,7 +2826,7 @@ To make the initial dependency selections that will initialize the dependency lo
28222826
}
28232827

28242828
// Initializing a saved state store from the backend state file (aka 'cache file', aka 'legacy state file')
2825-
func (m *Meta) savedStateStore(sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) {
2829+
func (m *Meta) savedStateStore(sMgr *clistate.LocalState, locks *depsfile.Locks) (backend.Backend, tfdiags.Diagnostics) {
28262830
// We're preparing a state_store version of backend.Backend.
28272831
//
28282832
// The provider and state store will be configured using the backend state file.
@@ -2831,7 +2835,7 @@ func (m *Meta) savedStateStore(sMgr *clistate.LocalState) (backend.Backend, tfdi
28312835

28322836
s := sMgr.State()
28332837

2834-
factory, pDiags := m.StateStoreProviderFactoryFromConfigState(s.StateStore)
2838+
factory, pDiags := m.StateStoreProviderFactoryFromConfigState(s.StateStore, locks)
28352839
diags = diags.Append(pDiags)
28362840
if pDiags.HasErrors() {
28372841
return nil, diags
@@ -3346,7 +3350,7 @@ func (m *Meta) StateStoreProviderFactoryFromConfig(config *configs.StateStore, l
33463350
return factory, diags
33473351
}
33483352

3349-
func (m *Meta) StateStoreProviderFactoryFromConfigState(cfgState *workdir.StateStoreConfigState) (providers.Factory, tfdiags.Diagnostics) {
3353+
func (m *Meta) StateStoreProviderFactoryFromConfigState(cfgState *workdir.StateStoreConfigState, locks *depsfile.Locks) (providers.Factory, tfdiags.Diagnostics) {
33503354
var diags tfdiags.Diagnostics
33513355

33523356
if cfgState == nil {
@@ -3362,7 +3366,7 @@ func (m *Meta) StateStoreProviderFactoryFromConfigState(cfgState *workdir.StateS
33623366
})
33633367
}
33643368

3365-
factories, err := m.ProviderFactories()
3369+
factories, err := m.providerFactoriesFromLocks(locks)
33663370
if err != nil {
33673371
// This may happen if the provider isn't present in the provider cache.
33683372
// 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
}

internal/provider-simple-v6/state_store_fs.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ func (f *FsStore) ReadStateBytes(req providers.ReadStateBytesRequest) providers.
178178

179179
// E.g. terraform.tfstate.d/foobar/terraform.tfstate
180180
path := f.getStatePath(req.StateId)
181+
log.Printf("[DEBUG] ReadStateBytes: reading data from path %q", path)
181182
file, err := os.Open(path)
182183

183184
fileExists := true
@@ -231,6 +232,8 @@ func (f *FsStore) WriteStateBytes(req providers.WriteStateBytesRequest) provider
231232
// E.g. terraform.tfstate.d/foobar/terraform.tfstate
232233
path := f.getStatePath(req.StateId)
233234

235+
log.Printf("[DEBUG] WriteStateBytes: writing data to path %q", path)
236+
234237
// Create or open state file
235238
dir := f.getStateDir(req.StateId)
236239
err := os.MkdirAll(dir, 0755)

0 commit comments

Comments
 (0)