Skip to content

Commit 3e4005a

Browse files
committed
fix: Add ExitTimeout to terraform.ServeOptions
1 parent 5cbb712 commit 3e4005a

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

provisioner/terraform/provision.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ import (
1414
"github.com/coder/coder/provisionersdk/proto"
1515
)
1616

17-
const (
18-
// Define how long we will wait for Terraform to exit cleanly
19-
// after receiving an interrupt (if the provision was stopped).
20-
terraformCancelTimeout = 5 * time.Minute
21-
)
22-
2317
// Provision executes `terraform apply` or `terraform plan` for dry runs.
2418
func (s *server) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
2519
request, err := stream.Recv()
@@ -54,7 +48,7 @@ func (s *server) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
5448
// part of graceful server shutdown procedure. Waiting on a
5549
// process here should delay provisioner/coder shutdown.
5650
select {
57-
case <-time.After(terraformCancelTimeout):
51+
case <-time.After(s.exitTimeout):
5852
kill()
5953
case <-killCtx.Done():
6054
}

provisioner/terraform/serve.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"path/filepath"
66
"sync"
7+
"time"
78

89
"github.com/cli/safeexec"
910
"github.com/hashicorp/go-version"
@@ -26,6 +27,10 @@ var (
2627
terraformMinorVersionMismatch = xerrors.New("Terraform binary minor version mismatch.")
2728
)
2829

30+
const (
31+
defaultExitTimeout = 5 * time.Minute
32+
)
33+
2934
type ServeOptions struct {
3035
*provisionersdk.ServeOptions
3136

@@ -34,6 +39,17 @@ type ServeOptions struct {
3439
BinaryPath string
3540
CachePath string
3641
Logger slog.Logger
42+
43+
// ExitTimeout defines how long we will wait for a running Terraform
44+
// command to exit (cleanly) if the provision was stopped. This only
45+
// happens when the command is still running after the provision
46+
// stream is closed. If the provision is canceled via RPC, this
47+
// timeout will not be used.
48+
//
49+
// This is a no-op on Windows where the process can't be interrupted.
50+
//
51+
// Default value: 5 minutes.
52+
ExitTimeout time.Duration
3753
}
3854

3955
func absoluteBinaryPath(ctx context.Context) (string, error) {
@@ -92,10 +108,14 @@ func Serve(ctx context.Context, options *ServeOptions) error {
92108
options.BinaryPath = absoluteBinary
93109
}
94110
}
111+
if options.ExitTimeout == 0 {
112+
options.ExitTimeout = defaultExitTimeout
113+
}
95114
return provisionersdk.Serve(ctx, &server{
96-
binaryPath: options.BinaryPath,
97-
cachePath: options.CachePath,
98-
logger: options.Logger,
115+
binaryPath: options.BinaryPath,
116+
cachePath: options.CachePath,
117+
logger: options.Logger,
118+
exitTimeout: options.ExitTimeout,
99119
}, options.ServeOptions)
100120
}
101121

@@ -107,6 +127,8 @@ type server struct {
107127
binaryPath string
108128
cachePath string
109129
logger slog.Logger
130+
131+
exitTimeout time.Duration
110132
}
111133

112134
func (s *server) executor(workdir string) executor {

0 commit comments

Comments
 (0)