Skip to content

Commit 9629145

Browse files
committed
feat: workspace bash background parameter
1 parent 00dd127 commit 9629145

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

codersdk/toolsdk/bash.go

Lines changed: 35 additions & 5 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
type WorkspaceBashArgs struct {
24-
Workspace string `json:"workspace"`
25-
Command string `json:"command"`
26-
TimeoutMs int `json:"timeout_ms,omitempty"`
27+
Workspace string `json:"workspace"`
28+
Command string `json:"command"`
29+
TimeoutMs int `json:"timeout_ms,omitempty"`
30+
Background bool `json:"background,omitempty"`
2731
}
2832

2933
type WorkspaceBashResult struct {
3034
Output string `json:"output"`
3135
ExitCode int `json:"exit_code"`
3236
}
3337

38+
//go:embed resources/background.sh
39+
var backgroundScript string
40+
3441
var WorkspaceBash = 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
},
@@ -137,16 +149,34 @@ Examples:
137149

138150
// Set default timeout if not specified (60 seconds)
139151
timeoutMs := args.TimeoutMs
152+
defaultTimeoutMs := 60000
140153
if timeoutMs <= 0 {
141-
timeoutMs = 60000
154+
timeoutMs = defaultTimeoutMs
155+
}
156+
command := args.Command
157+
if args.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+
if err != nil {
164+
return WorkspaceBashResult{}, 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
defer cancel()
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
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy