Skip to content

Commit dd5abdf

Browse files
committed
Fix agent leaking script process
1 parent 35c1c11 commit dd5abdf

File tree

5 files changed

+33
-27
lines changed

5 files changed

+33
-27
lines changed

agent/agent_test.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,9 +1214,9 @@ func TestAgent_Lifecycle(t *testing.T) {
12141214

12151215
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
12161216
Scripts: []codersdk.WorkspaceAgentScript{{
1217-
Script: "sleep 3",
1218-
TimeoutSeconds: time.Nanosecond,
1219-
RunOnStart: true,
1217+
Script: "sleep 3",
1218+
Timeout: time.Nanosecond,
1219+
RunOnStart: true,
12201220
}},
12211221
}, 0)
12221222

@@ -1239,9 +1239,9 @@ func TestAgent_Lifecycle(t *testing.T) {
12391239

12401240
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
12411241
Scripts: []codersdk.WorkspaceAgentScript{{
1242-
Script: "false",
1243-
TimeoutSeconds: 30 * time.Second,
1244-
RunOnStart: true,
1242+
Script: "false",
1243+
Timeout: 30 * time.Second,
1244+
RunOnStart: true,
12451245
}},
12461246
}, 0)
12471247

@@ -1264,9 +1264,9 @@ func TestAgent_Lifecycle(t *testing.T) {
12641264

12651265
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
12661266
Scripts: []codersdk.WorkspaceAgentScript{{
1267-
Script: "true",
1268-
TimeoutSeconds: 30 * time.Second,
1269-
RunOnStart: true,
1267+
Script: "true",
1268+
Timeout: 30 * time.Second,
1269+
RunOnStart: true,
12701270
}},
12711271
}, 0)
12721272

@@ -1289,9 +1289,9 @@ func TestAgent_Lifecycle(t *testing.T) {
12891289

12901290
_, client, _, _, closer := setupAgent(t, agentsdk.Manifest{
12911291
Scripts: []codersdk.WorkspaceAgentScript{{
1292-
Script: "sleep 3",
1293-
TimeoutSeconds: 30 * time.Second,
1294-
RunOnStop: true,
1292+
Script: "sleep 3",
1293+
Timeout: 30 * time.Second,
1294+
RunOnStop: true,
12951295
}},
12961296
}, 0)
12971297

@@ -1330,9 +1330,9 @@ func TestAgent_Lifecycle(t *testing.T) {
13301330

13311331
_, client, _, _, closer := setupAgent(t, agentsdk.Manifest{
13321332
Scripts: []codersdk.WorkspaceAgentScript{{
1333-
Script: "sleep 3",
1334-
TimeoutSeconds: time.Nanosecond,
1335-
RunOnStop: true,
1333+
Script: "sleep 3",
1334+
Timeout: time.Nanosecond,
1335+
RunOnStop: true,
13361336
}},
13371337
}, 0)
13381338

@@ -1372,9 +1372,9 @@ func TestAgent_Lifecycle(t *testing.T) {
13721372

13731373
_, client, _, _, closer := setupAgent(t, agentsdk.Manifest{
13741374
Scripts: []codersdk.WorkspaceAgentScript{{
1375-
Script: "false",
1376-
TimeoutSeconds: 30 * time.Second,
1377-
RunOnStop: true,
1375+
Script: "false",
1376+
Timeout: 30 * time.Second,
1377+
RunOnStop: true,
13781378
}},
13791379
}, 0)
13801380

agent/agentscripts/agentscripts.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func (r *Runner) Execute(ctx context.Context, filter func(script codersdk.Worksp
130130
func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) error {
131131
logPath := script.LogPath
132132
if logPath == "" {
133-
logPath = fmt.Sprintf("coder-%s-script.log", script.LogSourceID)
133+
logPath = fmt.Sprintf("coder-script-%s.log", script.LogSourceID)
134134
}
135135
if !filepath.IsAbs(logPath) {
136136
logPath = filepath.Join(r.LogDir, logPath)
@@ -149,13 +149,19 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript)
149149
}
150150
}()
151151

152+
var cmd *exec.Cmd
153+
if script.Timeout > 0 {
154+
var ctxCancel context.CancelFunc
155+
ctx, ctxCancel = context.WithTimeout(ctx, script.Timeout)
156+
defer ctxCancel()
157+
}
152158
cmdPty, err := r.SSHServer.CreateCommand(ctx, script.Script, nil)
153159
if err != nil {
154160
return xerrors.Errorf("%s script: create command: %w", logPath, err)
155161
}
156-
cmd := cmdPty.AsExec()
162+
cmd = cmdPty.AsExec()
157163
cmd.SysProcAttr = cmdSysProcAttr()
158-
cmd.WaitDelay = script.TimeoutSeconds + (10 * time.Second)
164+
cmd.WaitDelay = 10 * time.Second
159165
cmd.Cancel = cmdCancel(cmd)
160166

161167
send, flushAndClose := agentsdk.LogsSender(script.LogSourceID, r.PatchLogs, logger)
@@ -200,9 +206,9 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript)
200206

201207
// timeout stores whether the process timed out then was gracefully killed.
202208
var timeout chan struct{}
203-
if script.TimeoutSeconds > 0 {
209+
if script.Timeout > 0 {
204210
timeout = make(chan struct{})
205-
timer := time.AfterFunc(script.TimeoutSeconds, func() {
211+
timer := time.AfterFunc(script.Timeout, func() {
206212
close(timeout)
207213
err := cmd.Process.Signal(os.Interrupt)
208214
if err != nil {

agent/agentscripts/agentscripts_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ func TestTimeout(t *testing.T) {
4646
runner := setup(t, nil)
4747
defer runner.Close()
4848
err := runner.Init([]codersdk.WorkspaceAgentScript{{
49-
Script: "sleep 3",
50-
TimeoutSeconds: time.Nanosecond,
49+
Script: "sleep 3",
50+
Timeout: time.Nanosecond,
5151
}})
5252
require.NoError(t, err)
5353
require.ErrorIs(t, runner.Execute(context.Background(), nil), agentscripts.ErrTimeout)

coderd/workspaceagents.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,7 @@ func convertScripts(dbScripts []database.WorkspaceAgentScript) []codersdk.Worksp
14591459
RunOnStart: dbScript.RunOnStart,
14601460
RunOnStop: dbScript.RunOnStop,
14611461
StartBlocksLogin: dbScript.StartBlocksLogin,
1462-
TimeoutSeconds: time.Duration(dbScript.TimeoutSeconds) * time.Second,
1462+
Timeout: time.Duration(dbScript.TimeoutSeconds) * time.Second,
14631463
})
14641464
}
14651465
return scripts

codersdk/workspaceagents.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ type WorkspaceAgentScript struct {
199199
RunOnStart bool `json:"run_on_start"`
200200
RunOnStop bool `json:"run_on_stop"`
201201
StartBlocksLogin bool `json:"start_blocks_login"`
202-
TimeoutSeconds time.Duration `json:"timeout_seconds"`
202+
Timeout time.Duration `json:"timeout"`
203203
}
204204

205205
type WorkspaceAgentHealth struct {

0 commit comments

Comments
 (0)