Skip to content

Commit 7d592cc

Browse files
authored
Merge branch 'pss/pss-with-state-commands' into pss/pss-with-output-show-commands
2 parents df08ca6 + 8248ba0 commit 7d592cc

26 files changed

+566
-194
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: BUG FIXES
2+
body: 'actions: make after_create & after_update actions run after the resource has applied'
3+
time: 2025-11-24T15:00:00.316597+01:00
4+
custom:
5+
Issue: "37936"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: BUG FIXES
2+
body: 'cli: Fixed `terraform init -json` to properly format all backend configuration messages as JSON instead of plain text'
3+
time: 2025-11-19T10:30:00.000000Z
4+
custom:
5+
Issue: "37911"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: BUG FIXES
2+
body: '`state show`: The `state show` command will now explicitly fail and return code 1 when it fails to render the named resources state'
3+
time: 2025-11-21T18:30:45.571448Z
4+
custom:
5+
Issue: "37933"

internal/backend/pluggable/chunks.go renamed to internal/backend/pluggable/chunks/chunks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) HashiCorp, Inc.
22
// SPDX-License-Identifier: BUSL-1.1
33

4-
package pluggable
4+
package chunks
55

66
const (
77
// DefaultStateStoreChunkSize is the default chunk size proposed

internal/backend/pluggable/pluggable.go

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ package pluggable
55

66
import (
77
"errors"
8+
"fmt"
9+
"log"
810

911
"github.com/hashicorp/terraform/internal/backend"
12+
"github.com/hashicorp/terraform/internal/backend/pluggable/chunks"
1013
"github.com/hashicorp/terraform/internal/configs/configschema"
1114
"github.com/hashicorp/terraform/internal/providers"
1215
"github.com/hashicorp/terraform/internal/states/remote"
@@ -15,19 +18,22 @@ import (
1518
"github.com/zclconf/go-cty/cty"
1619
)
1720

18-
// NewPluggable returns an instance of the backend.Backend interface that
19-
// contains a provider interface. These are the assumptions about that
20-
// provider:
21+
// NewPluggable returns a Pluggable. A Pluggable fulfils the
22+
// backend.Backend interface and allows management of state via
23+
// a state store implemented in the provider that's within the Pluggable.
2124
//
25+
// These are the assumptions about that
26+
// provider:
2227
// * The provider implements at least one state store.
23-
// * The provider has already been configured before using NewPluggable.
28+
// * The provider has already been fully configured before using NewPluggable.
2429
//
2530
// The state store could also be configured prior to using NewPluggable,
26-
// or it could be configured using the relevant backend.Backend methods.
31+
// but preferably it will be configured via the Pluggable,
32+
// using the relevant backend.Backend methods.
2733
//
2834
// By wrapping a configured provider in a Pluggable we allow calling code
2935
// to use the provider's gRPC methods when interacting with state.
30-
func NewPluggable(p providers.Interface, typeName string) (backend.Backend, error) {
36+
func NewPluggable(p providers.Interface, typeName string) (*Pluggable, error) {
3137
if p == nil {
3238
return nil, errors.New("Attempted to initialize pluggable state with a nil provider interface. This is a bug in Terraform and should be reported")
3339
}
@@ -102,14 +108,47 @@ func (p *Pluggable) PrepareConfig(config cty.Value) (cty.Value, tfdiags.Diagnost
102108
//
103109
// Configure implements backend.Backend
104110
func (p *Pluggable) Configure(config cty.Value) tfdiags.Diagnostics {
111+
var diags tfdiags.Diagnostics
105112
req := providers.ConfigureStateStoreRequest{
106113
TypeName: p.typeName,
107114
Config: config,
108115
Capabilities: providers.StateStoreClientCapabilities{
109-
ChunkSize: DefaultStateStoreChunkSize,
116+
// The core binary will always request the default chunk size from the provider to start
117+
ChunkSize: chunks.DefaultStateStoreChunkSize,
110118
},
111119
}
112120
resp := p.provider.ConfigureStateStore(req)
121+
diags = diags.Append(resp.Diagnostics)
122+
if diags.HasErrors() {
123+
return diags
124+
}
125+
126+
// Validate the returned value from chunk size negotiation
127+
chunkSize := resp.Capabilities.ChunkSize
128+
if chunkSize == 0 || chunkSize > chunks.MaxStateStoreChunkSize {
129+
diags = diags.Append(fmt.Errorf("Failed to negotiate acceptable chunk size. "+
130+
"Expected size > 0 and <= %d bytes, provider wants %d bytes",
131+
chunks.MaxStateStoreChunkSize, chunkSize,
132+
))
133+
return diags
134+
}
135+
136+
// Negotiated chunk size is valid, so set it in the provider server
137+
// that will use the value for future RPCs to read/write state.
138+
if cs, ok := p.provider.(providers.StateStoreChunkSizeSetter); ok {
139+
cs.SetStateStoreChunkSize(p.typeName, int(chunkSize))
140+
} else {
141+
// TODO: Remove
142+
// I've put this here to try and fish for types of test setup that
143+
// use other things that should implement SetStateStoreChunkSize but
144+
// don't yet.
145+
panic("provider does not implement providers.StateStoreChunkSizeSetter interface. This is a bug in Terraform and should be reported.")
146+
}
147+
log.Printf("[TRACE] Pluggable.Configure: negotiated a chunk size of %v when configuring state store %s",
148+
chunkSize,
149+
p.typeName,
150+
)
151+
113152
return resp.Diagnostics
114153
}
115154

internal/backend/pluggable/pluggable_test.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,7 @@ func TestPluggable_ProviderSchema(t *testing.T) {
417417
t.Fatalf("unexpected error: %s", err)
418418
}
419419

420-
// Calling code will need to case to Pluggable after using NewPluggable,
421-
// so we do something similar in this test
422-
var providerSchema *configschema.Block
423-
if pluggable, ok := p.(*Pluggable); ok {
424-
providerSchema = pluggable.ProviderSchema()
425-
}
420+
providerSchema := p.ProviderSchema()
426421

427422
if !mock.GetProviderSchemaCalled {
428423
t.Fatal("expected ProviderSchema to call the GetProviderSchema RPC")
@@ -450,12 +445,7 @@ func TestPluggable_ProviderSchema(t *testing.T) {
450445
t.Fatalf("unexpected error: %s", err)
451446
}
452447

453-
// Calling code will need to case to Pluggable after using NewPluggable,
454-
// so we do something similar in this test
455-
var providerSchema *configschema.Block
456-
if pluggable, ok := p.(*Pluggable); ok {
457-
providerSchema = pluggable.ProviderSchema()
458-
}
448+
providerSchema := p.ProviderSchema()
459449

460450
if !mock.GetProviderSchemaCalled {
461451
t.Fatal("expected ProviderSchema to call the GetProviderSchema RPC")

0 commit comments

Comments
 (0)