Skip to content

Commit ae96ffd

Browse files
authored
Merge pull request #232 from docker/implement-docker-model-reinstall-runner
Add reinstall-runner command implementation
2 parents fb5e172 + 6073d73 commit ae96ffd

8 files changed

Lines changed: 219 additions & 20 deletions

File tree

cmd/cli/commands/install-runner.go

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,14 @@ func ensureStandaloneRunnerAvailable(ctx context.Context, printer standalone.Sta
160160
return inspectStandaloneRunner(container), nil
161161
}
162162

163-
// runnerOptions holds common configuration for install/start commands
163+
// runnerOptions holds common configuration for install/start/reinstall commands
164164
type runnerOptions struct {
165-
port uint16
166-
host string
167-
gpuMode string
168-
doNotTrack bool
169-
pullImage bool
165+
port uint16
166+
host string
167+
gpuMode string
168+
doNotTrack bool
169+
pullImage bool
170+
pruneContainers bool
170171
}
171172

172173
// runInstallOrStart is shared logic for install-runner and start-runner commands
@@ -216,16 +217,23 @@ func runInstallOrStart(cmd *cobra.Command, opts runnerOptions) error {
216217
return fmt.Errorf("failed to create Docker client: %w", err)
217218
}
218219

219-
// Check if an active model runner container already exists.
220-
if ctrID, ctrName, _, err := standalone.FindControllerContainer(cmd.Context(), dockerClient); err != nil {
221-
return err
222-
} else if ctrID != "" {
223-
if ctrName != "" {
224-
cmd.Printf("Model Runner container %s (%s) is already running\n", ctrName, ctrID[:12])
225-
} else {
226-
cmd.Printf("Model Runner container %s is already running\n", ctrID[:12])
220+
// If pruning containers (reinstall), remove any existing model runner containers.
221+
if opts.pruneContainers {
222+
if err := standalone.PruneControllerContainers(cmd.Context(), dockerClient, false, cmd); err != nil {
223+
return fmt.Errorf("unable to remove model runner container(s): %w", err)
224+
}
225+
} else {
226+
// Check if an active model runner container already exists (install only).
227+
if ctrID, ctrName, _, err := standalone.FindControllerContainer(cmd.Context(), dockerClient); err != nil {
228+
return err
229+
} else if ctrID != "" {
230+
if ctrName != "" {
231+
cmd.Printf("Model Runner container %s (%s) is already running\n", ctrName, ctrID[:12])
232+
} else {
233+
cmd.Printf("Model Runner container %s is already running\n", ctrID[:12])
234+
}
235+
return nil
227236
}
228-
return nil
229237
}
230238

231239
// Determine GPU support.
@@ -272,11 +280,12 @@ func newInstallRunner() *cobra.Command {
272280
Short: "Install Docker Model Runner (Docker Engine only)",
273281
RunE: func(cmd *cobra.Command, args []string) error {
274282
return runInstallOrStart(cmd, runnerOptions{
275-
port: port,
276-
host: host,
277-
gpuMode: gpuMode,
278-
doNotTrack: doNotTrack,
279-
pullImage: true,
283+
port: port,
284+
host: host,
285+
gpuMode: gpuMode,
286+
doNotTrack: doNotTrack,
287+
pullImage: true,
288+
pruneContainers: false,
280289
})
281290
},
282291
ValidArgsFunction: completion.NoComplete,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package commands
2+
3+
import (
4+
"github.com/docker/model-runner/cmd/cli/commands/completion"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
func newReinstallRunner() *cobra.Command {
9+
var port uint16
10+
var host string
11+
var gpuMode string
12+
var doNotTrack bool
13+
c := &cobra.Command{
14+
Use: "reinstall-runner",
15+
Short: "Reinstall Docker Model Runner (Docker Engine only)",
16+
RunE: func(cmd *cobra.Command, args []string) error {
17+
return runInstallOrStart(cmd, runnerOptions{
18+
port: port,
19+
host: host,
20+
gpuMode: gpuMode,
21+
doNotTrack: doNotTrack,
22+
pullImage: true,
23+
pruneContainers: true,
24+
})
25+
},
26+
ValidArgsFunction: completion.NoComplete,
27+
}
28+
c.Flags().Uint16Var(&port, "port", 0,
29+
"Docker container port for Docker Model Runner (default: 12434 for Docker Engine, 12435 for Cloud mode)")
30+
c.Flags().StringVar(&host, "host", "127.0.0.1", "Host address to bind Docker Model Runner")
31+
c.Flags().StringVar(&gpuMode, "gpu", "auto", "Specify GPU support (none|auto|cuda)")
32+
c.Flags().BoolVar(&doNotTrack, "do-not-track", false, "Do not track models usage in Docker Model Runner")
33+
return c
34+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package commands
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestReinstallRunnerHostFlag(t *testing.T) {
8+
testCases := []struct {
9+
name string
10+
value string
11+
}{
12+
{"localhost", "127.0.0.1"},
13+
{"all_interfaces", "0.0.0.0"},
14+
{"specific_IP", "192.168.1.100"},
15+
}
16+
17+
for _, tc := range testCases {
18+
t.Run(tc.name, func(t *testing.T) {
19+
// Reset the command for each test
20+
cmd := newReinstallRunner()
21+
err := cmd.Flags().Set("host", tc.value)
22+
if err != nil {
23+
t.Errorf("Failed to set host flag to '%s': %v", tc.value, err)
24+
}
25+
26+
// Verify the value was set
27+
hostValue, err := cmd.Flags().GetString("host")
28+
if err != nil {
29+
t.Errorf("Failed to get host flag value: %v", err)
30+
}
31+
if hostValue != tc.value {
32+
t.Errorf("Expected host value to be '%s', got '%s'", tc.value, hostValue)
33+
}
34+
})
35+
}
36+
}
37+
38+
func TestReinstallRunnerCommandFlags(t *testing.T) {
39+
cmd := newReinstallRunner()
40+
41+
// Verify all expected flags exist
42+
expectedFlags := []string{"port", "host", "gpu", "do-not-track"}
43+
for _, flagName := range expectedFlags {
44+
if cmd.Flags().Lookup(flagName) == nil {
45+
t.Errorf("Expected flag '--%s' not found", flagName)
46+
}
47+
}
48+
}
49+
50+
func TestReinstallRunnerCommandType(t *testing.T) {
51+
cmd := newReinstallRunner()
52+
53+
// Verify command properties
54+
if cmd.Use != "reinstall-runner" {
55+
t.Errorf("Expected command Use to be 'reinstall-runner', got '%s'", cmd.Use)
56+
}
57+
58+
if cmd.Short != "Reinstall Docker Model Runner (Docker Engine only)" {
59+
t.Errorf("Unexpected command Short description: %s", cmd.Short)
60+
}
61+
62+
// Verify RunE is set
63+
if cmd.RunE == nil {
64+
t.Error("Expected RunE to be set")
65+
}
66+
}
67+
68+
func TestReinstallRunnerValidArgsFunction(t *testing.T) {
69+
cmd := newReinstallRunner()
70+
71+
// The reinstall-runner command should not accept any arguments
72+
// So ValidArgsFunction should be set to handle no arguments
73+
if cmd.ValidArgsFunction == nil {
74+
t.Error("Expected ValidArgsFunction to be set")
75+
}
76+
}

cmd/cli/commands/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ func NewRootCmd(cli *command.DockerCli) *cobra.Command {
109109
newStartRunner(),
110110
newStopRunner(),
111111
newRestartRunner(),
112+
newReinstallRunner(),
112113
newConfigureCmd(),
113114
newPSCmd(),
114115
newDFCmd(),

cmd/cli/docs/reference/docker_model.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ cname:
1616
- docker model ps
1717
- docker model pull
1818
- docker model push
19+
- docker model reinstall-runner
1920
- docker model requests
2021
- docker model restart-runner
2122
- docker model rm
@@ -38,6 +39,7 @@ clink:
3839
- docker_model_ps.yaml
3940
- docker_model_pull.yaml
4041
- docker_model_push.yaml
42+
- docker_model_reinstall-runner.yaml
4143
- docker_model_requests.yaml
4244
- docker_model_restart-runner.yaml
4345
- docker_model_rm.yaml
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
command: docker model reinstall-runner
2+
short: Reinstall Docker Model Runner (Docker Engine only)
3+
long: |
4+
This command removes the existing Docker Model Runner container and reinstalls it with the specified configuration. Models and images are preserved during reinstallation.
5+
usage: docker model reinstall-runner
6+
pname: docker model
7+
plink: docker_model.yaml
8+
options:
9+
- option: do-not-track
10+
value_type: bool
11+
default_value: "false"
12+
description: Do not track models usage in Docker Model Runner
13+
deprecated: false
14+
hidden: false
15+
experimental: false
16+
experimentalcli: false
17+
kubernetes: false
18+
swarm: false
19+
- option: gpu
20+
value_type: string
21+
default_value: auto
22+
description: Specify GPU support (none|auto|cuda)
23+
deprecated: false
24+
hidden: false
25+
experimental: false
26+
experimentalcli: false
27+
kubernetes: false
28+
swarm: false
29+
- option: host
30+
value_type: string
31+
default_value: 127.0.0.1
32+
description: Host address to bind Docker Model Runner
33+
deprecated: false
34+
hidden: false
35+
experimental: false
36+
experimentalcli: false
37+
kubernetes: false
38+
swarm: false
39+
- option: port
40+
value_type: uint16
41+
default_value: "0"
42+
description: |
43+
Docker container port for Docker Model Runner (default: 12434 for Docker Engine, 12435 for Cloud mode)
44+
deprecated: false
45+
hidden: false
46+
experimental: false
47+
experimentalcli: false
48+
kubernetes: false
49+
swarm: false
50+
deprecated: false
51+
hidden: false
52+
experimental: false
53+
experimentalcli: false
54+
kubernetes: false
55+
swarm: false
56+

cmd/cli/docs/reference/model.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Docker Model Runner
1717
| [`ps`](model_ps.md) | List running models |
1818
| [`pull`](model_pull.md) | Pull a model from Docker Hub or HuggingFace to your local environment |
1919
| [`push`](model_push.md) | Push a model to Docker Hub |
20+
| [`reinstall-runner`](model_reinstall-runner.md) | Reinstall Docker Model Runner (Docker Engine only) |
2021
| [`requests`](model_requests.md) | Fetch requests+responses from Docker Model Runner |
2122
| [`restart-runner`](model_restart-runner.md) | Restart Docker Model Runner (Docker Engine only) |
2223
| [`rm`](model_rm.md) | Remove local models downloaded from Docker Hub |
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# docker model reinstall-runner
2+
3+
<!---MARKER_GEN_START-->
4+
Reinstall Docker Model Runner (Docker Engine only)
5+
6+
### Options
7+
8+
| Name | Type | Default | Description |
9+
|:-----------------|:---------|:------------|:-------------------------------------------------------------------------------------------------------|
10+
| `--do-not-track` | `bool` | | Do not track models usage in Docker Model Runner |
11+
| `--gpu` | `string` | `auto` | Specify GPU support (none\|auto\|cuda) |
12+
| `--host` | `string` | `127.0.0.1` | Host address to bind Docker Model Runner |
13+
| `--port` | `uint16` | `0` | Docker container port for Docker Model Runner (default: 12434 for Docker Engine, 12435 for Cloud mode) |
14+
15+
16+
<!---MARKER_GEN_END-->
17+
18+
## Description
19+
20+
This command removes the existing Docker Model Runner container and reinstalls it with the specified configuration. Models and images are preserved during reinstallation.

0 commit comments

Comments
 (0)