Merge pull request #35778 from hashicorp/jbardin/ephemeral-cancel

core: get a cancelation context to the ephemeral resources
pull/35783/head
James Bardin 2 years ago committed by GitHub
commit bb476a311e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -140,8 +140,11 @@ func (r *Resources) Close(ctx context.Context) tfdiags.Diagnostics {
r.mu.Lock()
defer r.mu.Unlock()
// We might be closing due to a context cancellation, but we still need
// to be able to make non-canceled Close requests.
// We might be closing due to a context cancellation, but we still need to
// be able to make non-canceled Close requests.
//
// TODO: if we're going to ignore the cancellation to ensure that Close is
// always called, should we add some sort of timeout?
ctx = context.WithoutCancel(ctx)
var diags tfdiags.Diagnostics

@ -4,6 +4,8 @@
package terraform
import (
"context"
"github.com/hashicorp/hcl/v2"
"github.com/zclconf/go-cty/cty"
@ -28,9 +30,9 @@ import (
// EvalContext is the interface that is given to eval nodes to execute.
type EvalContext interface {
// Stopped returns a channel that is closed when evaluation is stopped
// via Terraform.Context.Stop()
Stopped() <-chan struct{}
// Stopped returns a context that is canceled when evaluation is stopped via
// Terraform.Context.Stop()
StopCtx() context.Context
// Path is the current module path.
Path() addrs.ModuleInstance

@ -102,13 +102,13 @@ func (ctx *BuiltinEvalContext) withScope(scope evalContextScope) EvalContext {
return &newCtx
}
func (ctx *BuiltinEvalContext) Stopped() <-chan struct{} {
func (ctx *BuiltinEvalContext) StopCtx() context.Context {
// This can happen during tests. During tests, we just block forever.
if ctx.StopContext == nil {
return nil
return context.TODO()
}
return ctx.StopContext.Done()
return ctx.StopContext
}
func (ctx *BuiltinEvalContext) Hook(fn func(Hook) (HookAction, error)) error {

@ -4,6 +4,8 @@
package terraform
import (
"context"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
@ -31,8 +33,8 @@ import (
// MockEvalContext is a mock version of EvalContext that can be used
// for tests.
type MockEvalContext struct {
StoppedCalled bool
StoppedValue <-chan struct{}
StopCtxCalled bool
StopCtxValue context.Context
HookCalled bool
HookHook Hook
@ -164,9 +166,12 @@ type MockEvalContext struct {
// MockEvalContext implements EvalContext
var _ EvalContext = (*MockEvalContext)(nil)
func (c *MockEvalContext) Stopped() <-chan struct{} {
c.StoppedCalled = true
return c.StoppedValue
func (c *MockEvalContext) StopCtx() context.Context {
c.StopCtxCalled = true
if c.StopCtxValue != nil {
return c.StopCtxValue
}
return context.TODO()
}
func (c *MockEvalContext) Hook(fn func(Hook) (HookAction, error)) error {

@ -4,7 +4,6 @@
package terraform
import (
"context"
"log"
"github.com/hashicorp/terraform/internal/addrs"
@ -215,7 +214,7 @@ func (n *nodeCloseModule) Execute(ctx EvalContext, op walkOperation) (diags tfdi
diags = diags.Append(ctx.ClosePlugins())
// We also close up the ephemeral resource manager
diags = diags.Append(ctx.EphemeralResources().Close(context.TODO()))
diags = diags.Append(ctx.EphemeralResources().Close(ctx.StopCtx()))
switch op {
case walkApply, walkDestroy:

@ -124,12 +124,8 @@ func ephemeralResourceOpen(ctx EvalContext, inp ephemeralResourceInput) tfdiags.
provider: provider,
internal: resp.InternalContext,
}
// TODO: What can we use as a signal to cancel the context we're passing in
// here, so that the object will stop renewing things when we start shutting
// down?
// TODO: The context Stopped channel should probably be updated
// finally to a Context
ephemerals.RegisterInstance(context.TODO(), inp.addr, ephemeral.ResourceInstanceRegistration{
ephemerals.RegisterInstance(ctx.StopCtx(), inp.addr, ephemeral.ResourceInstanceRegistration{
Value: resultVal,
ConfigBody: config.Config,
Impl: impl,
@ -172,7 +168,7 @@ func (n *nodeEphemeralResourceClose) ModulePath() addrs.Module {
func (n *nodeEphemeralResourceClose) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
log.Printf("[TRACE] nodeEphemeralResourceClose: closing all instances of %s", n.addr)
resources := ctx.EphemeralResources()
return resources.CloseInstances(context.TODO(), n.addr)
return resources.CloseInstances(ctx.StopCtx(), n.addr)
}
// ephemeralResourceInstImpl implements ephemeral.ResourceInstance as an

Loading…
Cancel
Save