Skip to content

Commit 446685f

Browse files
committed
Refine persistent config command
1 parent ab77cd1 commit 446685f

10 files changed

Lines changed: 118 additions & 59 deletions

File tree

cmd/cli/commands/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package commands
2+
3+
import "github.com/spf13/cobra"
4+
5+
func newConfigCmd() *cobra.Command {
6+
c := &cobra.Command{
7+
Use: "config",
8+
Short: "Manage persistent model runner configuration",
9+
}
10+
11+
c.AddCommand(newSandboxConfigCmd())
12+
13+
return c
14+
}

cmd/cli/commands/launch.go

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,12 @@ Examples:
147147
// resolving runner endpoints. This keeps sandbox launch independent of
148148
// whether the host app binary itself is installed.
149149
if _, ok := hostApps[app]; ok {
150-
sandboxTool, err := readSandboxToolConfig()
150+
sandboxTool, err := configuredSandboxTool()
151151
if err != nil {
152152
return err
153153
}
154154

155155
if sandboxTool != "" {
156-
if err := validateSandboxTool(sandboxTool); err != nil {
157-
return err
158-
}
159156
return launchSandboxedHostApp(cmd, sandboxTool, app, appArgs, dryRun)
160157
}
161158
}
@@ -178,7 +175,6 @@ Examples:
178175
if ca, ok := containerApps[app]; ok {
179176
return launchContainerApp(cmd, ca, ep.container, image, port, detach, appArgs, dryRun)
180177
}
181-
182178
if cli, ok := hostApps[app]; ok {
183179
return launchHostApp(cmd, app, ep.host, cli, model, runner, appArgs, dryRun)
184180
}
@@ -196,28 +192,9 @@ Examples:
196192
}
197193

198194
func launchSandboxedHostApp(cmd *cobra.Command, sandboxTool, app string, appArgs []string, dryRun bool) error {
199-
if err := validateSandboxTool(sandboxTool); err != nil {
200-
return err
201-
}
202-
203195
args := append([]string{app}, appArgs...)
204196

205-
switch sandboxTool {
206-
case "sbx":
207-
if dryRun {
208-
cmd.Printf("sbx %s\n", strings.Join(args, " "))
209-
return nil
210-
}
211-
212-
launchCmd := exec.Command("sbx", args...)
213-
launchCmd.Stdin = os.Stdin
214-
launchCmd.Stdout = os.Stdout
215-
launchCmd.Stderr = os.Stderr
216-
217-
return launchCmd.Run()
218-
default:
219-
return fmt.Errorf("unsupported sandbox tool %q", sandboxTool)
220-
}
197+
return runSandboxTool(cmd, sandboxTool, args, dryRun)
221198
}
222199

223200
// listSupportedApps prints all supported apps with their descriptions and install status.

cmd/cli/commands/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func NewRootCmd(cli *command.DockerCli) *cobra.Command {
120120
newShowCmd(),
121121
newComposeCmd(),
122122
newLaunchCmd(),
123-
newSandboxConfigCmd(),
123+
newConfigCmd(),
124124
newTagCmd(),
125125
newConfigureCmd(),
126126
newPSCmd(),

cmd/cli/commands/sandbox.go

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bufio"
55
"fmt"
66
"os"
7+
"os/exec"
78
"path/filepath"
89
"strings"
910

@@ -16,32 +17,26 @@ var allowedSandboxTools = map[string]struct{}{
1617

1718
func newSandboxConfigCmd() *cobra.Command {
1819
return &cobra.Command{
19-
Use: "config <key> <value>",
20-
Short: "Set model runner configuration values",
21-
Args: cobra.ExactArgs(2),
20+
Use: "sandbox.tool <tool>",
21+
Short: "Set the sandbox tool",
22+
Args: cobra.ExactArgs(1),
2223
RunE: func(_ *cobra.Command, args []string) error {
23-
key := args[0]
24-
value := args[1]
25-
26-
if key != "sandbox.tool" {
27-
return fmt.Errorf("unsupported config key %q", key)
28-
}
29-
30-
if err := validateSandboxTool(value); err != nil {
24+
tool, err := validateSandboxTool(args[0])
25+
if err != nil {
3126
return err
3227
}
3328

34-
return writeSandboxToolConfig(value)
29+
return writeSandboxToolConfig(tool)
3530
},
3631
}
3732
}
3833

39-
func validateSandboxTool(tool string) error {
34+
func validateSandboxTool(tool string) (string, error) {
4035
if _, ok := allowedSandboxTools[tool]; !ok {
41-
return fmt.Errorf("unsupported sandbox tool %q", tool)
36+
return "", fmt.Errorf("unsupported sandbox tool %q", tool)
4237
}
4338

44-
return nil
39+
return tool, nil
4540
}
4641

4742
func dmrConfigPath() (string, error) {
@@ -124,3 +119,38 @@ func readSandboxToolConfig() (string, error) {
124119

125120
return "", nil
126121
}
122+
func runSandboxTool(cmd *cobra.Command, sandboxTool string, args []string, dryRun bool) error {
123+
validatedSandboxTool, err := validateSandboxTool(sandboxTool)
124+
if err != nil {
125+
return err
126+
}
127+
128+
if dryRun {
129+
cmd.Printf("%s %s\n", validatedSandboxTool, strings.Join(args, " "))
130+
return nil
131+
}
132+
133+
switch validatedSandboxTool {
134+
case "sbx":
135+
launchCmd := exec.Command("sbx", args...)
136+
launchCmd.Stdin = os.Stdin
137+
launchCmd.Stdout = os.Stdout
138+
launchCmd.Stderr = os.Stderr
139+
140+
return launchCmd.Run()
141+
default:
142+
return fmt.Errorf("unsupported sandbox tool %q", validatedSandboxTool)
143+
}
144+
}
145+
func configuredSandboxTool() (string, error) {
146+
sandboxTool, err := readSandboxToolConfig()
147+
if err != nil {
148+
return "", err
149+
}
150+
151+
if sandboxTool == "" {
152+
return "", nil
153+
}
154+
155+
return validateSandboxTool(sandboxTool)
156+
}

cmd/cli/commands/sandbox_test.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,42 +52,47 @@ func TestReadSandboxToolConfigMissingFile(t *testing.T) {
5252
}
5353

5454
func TestValidateSandboxToolAllowsSbx(t *testing.T) {
55-
if err := validateSandboxTool("sbx"); err != nil {
55+
tool, err := validateSandboxTool("sbx")
56+
if err != nil {
5657
t.Fatalf("validateSandboxTool() error = %v", err)
5758
}
59+
60+
if tool != "sbx" {
61+
t.Fatalf("validateSandboxTool() = %q, want %q", tool, "sbx")
62+
}
5863
}
5964

6065
func TestValidateSandboxToolRejectsUnsupportedTool(t *testing.T) {
61-
err := validateSandboxTool("firejail")
66+
_, err := validateSandboxTool("firejail")
6267
if err == nil {
6368
t.Fatal("validateSandboxTool() error = nil, want error")
6469
}
6570
}
6671

67-
func TestSandboxConfigCommandRejectsUnsupportedKey(t *testing.T) {
68-
cmd := newSandboxConfigCmd()
72+
func TestConfigCommandRejectsUnsupportedKey(t *testing.T) {
73+
cmd := newConfigCmd()
6974
cmd.SetArgs([]string{"unsupported.key", "sbx"})
7075

7176
if err := cmd.Execute(); err == nil {
7277
t.Fatal("config command error = nil, want error")
7378
}
7479
}
7580

76-
func TestSandboxConfigCommandRejectsUnsupportedTool(t *testing.T) {
81+
func TestConfigCommandRejectsUnsupportedTool(t *testing.T) {
7782
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
7883

79-
cmd := newSandboxConfigCmd()
84+
cmd := newConfigCmd()
8085
cmd.SetArgs([]string{"sandbox.tool", "firejail"})
8186

8287
if err := cmd.Execute(); err == nil {
8388
t.Fatal("config command error = nil, want error")
8489
}
8590
}
8691

87-
func TestSandboxConfigCommandWritesConfig(t *testing.T) {
92+
func TestConfigCommandWritesSandboxToolConfig(t *testing.T) {
8893
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
8994

90-
cmd := newSandboxConfigCmd()
95+
cmd := newConfigCmd()
9196
cmd.SetArgs([]string{"sandbox.tool", "sbx"})
9297

9398
if err := cmd.Execute(); err != nil {
@@ -104,14 +109,16 @@ func TestSandboxConfigCommandWritesConfig(t *testing.T) {
104109
}
105110
}
106111

107-
func TestLaunchCommandRequiresConfiguredSandboxTool(t *testing.T) {
112+
func TestConfiguredSandboxToolMissingConfig(t *testing.T) {
108113
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
109114

110-
cmd := newLaunchCmd()
111-
cmd.SetArgs([]string{"opencode"})
115+
got, err := configuredSandboxTool()
116+
if err != nil {
117+
t.Fatalf("configuredSandboxTool() error = %v", err)
118+
}
112119

113-
if err := cmd.Execute(); err == nil {
114-
t.Fatal("launch command error = nil, want error")
120+
if got != "" {
121+
t.Fatalf("configuredSandboxTool() = %q, want empty string", got)
115122
}
116123
}
117124

cmd/cli/docs/reference/docker_model_config.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
command: docker model config
2-
short: Set model runner configuration values
3-
long: Set model runner configuration values
4-
usage: docker model config <key> <value>
2+
short: Manage persistent model runner configuration
3+
long: Manage persistent model runner configuration
54
pname: docker model
65
plink: docker_model.yaml
6+
cname:
7+
- docker model config sandbox.tool
8+
clink:
9+
- docker_model_config_sandbox.tool.yaml
710
deprecated: false
811
hidden: false
912
experimental: false
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
command: docker model config sandbox.tool
2+
short: Set the sandbox tool
3+
long: Set the sandbox tool
4+
usage: docker model config sandbox.tool <tool>
5+
pname: docker model config
6+
plink: docker_model_config.yaml
7+
deprecated: false
8+
hidden: false
9+
experimental: false
10+
experimentalcli: false
11+
kubernetes: false
12+
swarm: false
13+

cmd/cli/docs/reference/model.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Docker Model Runner
88
| Name | Description |
99
|:------------------------------------------------|:-----------------------------------------------------------------------|
1010
| [`bench`](model_bench.md) | Benchmark a model's performance at different concurrency levels |
11-
| [`config`](model_config.md) | Set model runner configuration values |
11+
| [`config`](model_config.md) | Manage persistent model runner configuration |
1212
| [`context`](model_context.md) | Manage Docker Model Runner contexts |
1313
| [`df`](model_df.md) | Show Docker Model Runner disk usage |
1414
| [`gateway`](model_gateway.md) | Run an OpenAI-compatible LLM gateway |

cmd/cli/docs/reference/model_config.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
# docker model config
22

33
<!---MARKER_GEN_START-->
4-
Set model runner configuration values
4+
Manage persistent model runner configuration
5+
6+
### Subcommands
7+
8+
| Name | Description |
9+
|:-----------------------------------------------|:---------------------|
10+
| [`sandbox.tool`](model_config_sandbox.tool.md) | Set the sandbox tool |
11+
512

613

714
<!---MARKER_GEN_END-->
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# docker model config sandbox.tool
2+
3+
<!---MARKER_GEN_START-->
4+
Set the sandbox tool
5+
6+
7+
<!---MARKER_GEN_END-->
8+

0 commit comments

Comments
 (0)