Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd10a605

Browse files
committed
feat: workspace bash background parameter
1 parentf641d85 commitd10a605

File tree

3 files changed

+62
-9
lines changed

3 files changed

+62
-9
lines changed

‎codersdk/toolsdk/bash.go‎

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package toolsdk
33
import (
44
"bytes"
55
"context"
6+
_"embed"
7+
"encoding/base64"
68
"errors"
79
"fmt"
810
"io"
@@ -18,19 +20,24 @@ import (
1820
"github.com/coder/coder/v2/cli/cliui"
1921
"github.com/coder/coder/v2/codersdk"
2022
"github.com/coder/coder/v2/codersdk/workspacesdk"
23+
"github.com/coder/coder/v2/cryptorand"
2124
)
2225

2326
typeWorkspaceBashArgsstruct {
24-
Workspacestring`json:"workspace"`
25-
Commandstring`json:"command"`
26-
TimeoutMsint`json:"timeout_ms,omitempty"`
27+
Workspacestring`json:"workspace"`
28+
Commandstring`json:"command"`
29+
TimeoutMsint`json:"timeout_ms,omitempty"`
30+
Backgroundbool`json:"background,omitempty"`
2731
}
2832

2933
typeWorkspaceBashResultstruct {
3034
Outputstring`json:"output"`
3135
ExitCodeint`json:"exit_code"`
3236
}
3337

38+
//go:embed resources/background.sh
39+
varbackgroundScriptstring
40+
3441
varWorkspaceBash=Tool[WorkspaceBashArgs,WorkspaceBashResult]{
3542
Tool: aisdk.Tool{
3643
Name:ToolNameWorkspaceBash,
@@ -53,6 +60,7 @@ If the command times out, all output captured up to that point is returned with
5360
Examples:
5461
- workspace: "my-workspace", command: "ls -la"
5562
- workspace: "john/dev-env", command: "git status", timeout_ms: 30000
63+
- workspace: "my-workspace", command: "npm run dev", background: true
5664
- workspace: "my-workspace.main", command: "docker ps"`,
5765
Schema: aisdk.Schema{
5866
Properties:map[string]any{
@@ -70,6 +78,10 @@ Examples:
7078
"default":60000,
7179
"minimum":1,
7280
},
81+
"background":map[string]any{
82+
"type":"boolean",
83+
"description":"Whether to run the command in the background. The command will not be affected by the timeout.",
84+
},
7385
},
7486
Required: []string{"workspace","command"},
7587
},
@@ -82,7 +94,7 @@ Examples:
8294
returnWorkspaceBashResult{},xerrors.New("command cannot be empty")
8395
}
8496

85-
ctx,cancel:=context.WithTimeoutCause(ctx,5*time.Minute,errors.New("MCP handler timeout after 5 min"))
97+
ctx,cancel:=context.WithTimeoutCause(ctx,5*time.Minute,xerrors.New("MCP handler timeout after 5 min"))
8698
defercancel()
8799

88100
// Normalize workspace input to handle various formats
@@ -137,23 +149,41 @@ Examples:
137149

138150
// Set default timeout if not specified (60 seconds)
139151
timeoutMs:=args.TimeoutMs
152+
defaultTimeoutMs:=60000
140153
iftimeoutMs<=0 {
141-
timeoutMs=60000
154+
timeoutMs=defaultTimeoutMs
155+
}
156+
command:=args.Command
157+
ifargs.Background {
158+
// Background commands are not affected by the timeout
159+
timeoutMs=defaultTimeoutMs
160+
encodedCommand:=base64.StdEncoding.EncodeToString([]byte(args.Command))
161+
encodedScript:=base64.StdEncoding.EncodeToString([]byte(backgroundScript))
162+
commandID,err:=cryptorand.StringCharset(cryptorand.Human,8)
163+
iferr!=nil {
164+
returnWorkspaceBashResult{},xerrors.Errorf("failed to generate command ID: %w",err)
165+
}
166+
command=fmt.Sprintf(
167+
"ARG_COMMAND=\"$(echo -n %s | base64 -d)\" ARG_COMMAND_ID=%s bash -c\"$(echo -n %s | base64 -d)\"",
168+
encodedCommand,
169+
commandID,
170+
encodedScript,
171+
)
142172
}
143173

144174
// Create context with timeout
145175
ctx,cancel=context.WithTimeout(ctx,time.Duration(timeoutMs)*time.Millisecond)
146176
defercancel()
147177

148178
// Execute command with timeout handling
149-
output,err:=executeCommandWithTimeout(ctx,session,args.Command)
179+
output,err:=executeCommandWithTimeout(ctx,session,command)
150180
outputStr:=strings.TrimSpace(string(output))
151181

152182
// Handle command execution results
153183
iferr!=nil {
154184
// Check if the command timed out
155185
iferrors.Is(context.Cause(ctx),context.DeadlineExceeded) {
156-
outputStr+="\nCommandcancelled due to timeout"
186+
outputStr+="\nCommandcanceled due to timeout"
157187
returnWorkspaceBashResult{
158188
Output:outputStr,
159189
ExitCode:124,
@@ -386,7 +416,7 @@ func executeCommandWithTimeout(ctx context.Context, session *gossh.Session, comm
386416
// Command completed normally
387417
returnsafeWriter.Bytes(),err
388418
case<-ctx.Done():
389-
// Context wascancelled (timeout or other cancellation)
419+
// Context wascanceled (timeout or other cancellation)
390420
// Close the session to stop the command
391421
_=session.Close()
392422

‎codersdk/toolsdk/bash_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,6 @@ func TestWorkspaceBashTimeoutIntegration(t *testing.T) {
335335
require.Equal(t,"normal command",result.Output)
336336

337337
// Should NOT contain timeout message
338-
require.NotContains(t,result.Output,"Commandcancelled due to timeout")
338+
require.NotContains(t,result.Output,"Commandcanceled due to timeout")
339339
})
340340
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
3+
# This script is used to run a command in the background.
4+
5+
set -o errexit
6+
set -o pipefail
7+
8+
set -o nounset
9+
10+
COMMAND="$ARG_COMMAND"
11+
COMMAND_ID="$ARG_COMMAND_ID"
12+
13+
set +o nounset
14+
15+
LOG_DIR="/tmp/mcp-bg"
16+
LOG_PATH="$LOG_DIR/$COMMAND_ID.log"
17+
mkdir -p"$LOG_DIR"
18+
19+
nohup bash -c"$COMMAND">"$LOG_PATH"2>&1&
20+
COMMAND_PID="$!"
21+
22+
echo"Command started with PID:$COMMAND_PID"
23+
echo"Log path:$LOG_PATH"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp