Skip to content

Commit 536b0b4

Browse files
authored
Merge pull request #528 from doringeman/cmd-ensure-dmr-container
refactor(cli): centralize standalone runner initialization
2 parents 73f3b89 + 1b6f2ce commit 536b0b4

File tree

12 files changed

+77
-51
lines changed

12 files changed

+77
-51
lines changed

cmd/cli/commands/bench.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,6 @@ measuring the tokens per second (TPS) that the model can generate.`,
8383
return handleClientError(err, "Failed to inspect model")
8484
}
8585

86-
// Ensure model runner is available
87-
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), false); err != nil {
88-
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
89-
}
90-
9186
if !jsonOutput {
9287
fmt.Printf("Prompt: %s\n", prompt)
9388
fmt.Printf("Duration: %v per concurrency level\n", duration)

cmd/cli/commands/compose.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ func newUpCommand() *cobra.Command {
5252

5353
sendInfo("Initializing model runner...")
5454
kind := modelRunner.EngineKind()
55-
standalone, err := ensureStandaloneRunnerAvailable(cmd.Context(), nil, false)
55+
runner, err := getStandaloneRunner(cmd.Context())
5656
if err != nil {
57-
_ = sendErrorf("Failed to initialize standalone model runner: %v", err)
58-
return fmt.Errorf("Failed to initialize standalone model runner: %w", err)
57+
_ = sendErrorf("Failed to get standalone model runner info: %v", err)
58+
return fmt.Errorf("Failed to get standalone model runner info: %w", err)
5959
} else if ((kind == types.ModelRunnerEngineKindMoby || kind == types.ModelRunnerEngineKindCloud) &&
60-
standalone == nil) ||
61-
(standalone != nil && (standalone.gatewayIP == "" || standalone.gatewayPort == 0)) {
60+
runner == nil) ||
61+
(runner != nil && (runner.gatewayIP == "" || runner.gatewayPort == 0)) {
6262
return errors.New("unable to determine standalone runner endpoint")
6363
}
6464

@@ -109,7 +109,7 @@ func newUpCommand() *cobra.Command {
109109
case types.ModelRunnerEngineKindCloud:
110110
fallthrough
111111
case types.ModelRunnerEngineKindMoby:
112-
_ = setenv("URL", "http://"+net.JoinHostPort(standalone.gatewayIP, strconv.Itoa(int(standalone.gatewayPort)))+"/engines/v1/")
112+
_ = setenv("URL", "http://"+net.JoinHostPort(runner.gatewayIP, strconv.Itoa(int(runner.gatewayPort)))+"/engines/v1/")
113113
default:
114114
return fmt.Errorf("unhandled engine kind: %v", kind)
115115
}

cmd/cli/commands/inspect.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ func newInspectCmd() *cobra.Command {
1717
Short: "Display detailed information on one model",
1818
Args: requireExactArgs(1, "inspect", "MODEL"),
1919
RunE: func(cmd *cobra.Command, args []string) error {
20-
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), false); err != nil {
21-
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
22-
}
2320
if openai && remote {
2421
return fmt.Errorf("--remote flag cannot be used with --openai flag")
2522
}

cmd/cli/commands/install-runner.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,53 @@ func ensureStandaloneRunnerAvailable(ctx context.Context, printer standalone.Sta
163163
return inspectStandaloneRunner(container), nil
164164
}
165165

166+
// withStandaloneRunner wraps a command's RunE to ensure the standalone runner
167+
// is available before executing the command. This is a no-op in unsupported
168+
// contexts (e.g., Docker Desktop) or if automatic installations have been disabled.
169+
func withStandaloneRunner(cmd *cobra.Command) *cobra.Command {
170+
if cmd.RunE == nil {
171+
return cmd
172+
}
173+
originalRunE := cmd.RunE
174+
cmd.RunE = func(cmd *cobra.Command, args []string) error {
175+
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), false); err != nil {
176+
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
177+
}
178+
return originalRunE(cmd, args)
179+
}
180+
return cmd
181+
}
182+
183+
// getStandaloneRunner returns the standalone runner info by finding the controller container.
184+
// This is useful for commands that need runner details after withStandaloneRunner has run.
185+
// Returns nil for non-standalone contexts (e.g., Docker Desktop).
186+
func getStandaloneRunner(ctx context.Context) (*standaloneRunner, error) {
187+
// Only standalone contexts have a runner container to inspect.
188+
engineKind := modelRunner.EngineKind()
189+
standaloneSupported := engineKind == types.ModelRunnerEngineKindMoby ||
190+
engineKind == types.ModelRunnerEngineKindCloud
191+
if !standaloneSupported {
192+
return nil, nil
193+
}
194+
195+
if dockerCLI == nil {
196+
return nil, nil
197+
}
198+
199+
dockerClient, err := desktop.DockerClientForContext(dockerCLI, dockerCLI.CurrentContext())
200+
if err != nil {
201+
return nil, fmt.Errorf("failed to create Docker client: %w", err)
202+
}
203+
containerID, _, ctr, err := standalone.FindControllerContainer(ctx, dockerClient)
204+
if err != nil {
205+
return nil, fmt.Errorf("unable to find standalone model runner: %w", err)
206+
}
207+
if containerID == "" {
208+
return nil, nil
209+
}
210+
return inspectStandaloneRunner(ctr), nil
211+
}
212+
166213
// runnerOptions holds common configuration for install/start/reinstall commands
167214
type runnerOptions struct {
168215
port uint16

cmd/cli/commands/pull.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package commands
22

33
import (
4-
"fmt"
5-
64
"github.com/docker/model-runner/cmd/cli/commands/completion"
75
"github.com/docker/model-runner/cmd/cli/desktop"
86
"github.com/spf13/cobra"
@@ -14,9 +12,6 @@ func newPullCmd() *cobra.Command {
1412
Short: "Pull a model from Docker Hub or HuggingFace to your local environment",
1513
Args: requireExactArgs(1, "pull", "MODEL"),
1614
RunE: func(cmd *cobra.Command, args []string) error {
17-
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), false); err != nil {
18-
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
19-
}
2015
return pullModel(cmd, desktopClient, args[0])
2116
},
2217
ValidArgsFunction: completion.NoComplete,

cmd/cli/commands/push.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package commands
22

33
import (
4-
"fmt"
5-
64
"github.com/docker/model-runner/cmd/cli/commands/completion"
75
"github.com/docker/model-runner/cmd/cli/desktop"
86
"github.com/spf13/cobra"
@@ -14,9 +12,6 @@ func newPushCmd() *cobra.Command {
1412
Short: "Push a model to Docker Hub",
1513
Args: requireExactArgs(1, "push", "MODEL"),
1614
RunE: func(cmd *cobra.Command, args []string) error {
17-
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), false); err != nil {
18-
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
19-
}
2015
return pushModel(cmd, desktopClient, args[0])
2116
},
2217
ValidArgsFunction: completion.NoComplete,

cmd/cli/commands/requests.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ func newRequestsCmd() *cobra.Command {
2525
return nil
2626
},
2727
RunE: func(cmd *cobra.Command, args []string) error {
28-
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), false); err != nil {
29-
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
30-
}
31-
3228
responseBody, cancel, err := desktopClient.Requests(model, follow, includeExisting)
3329
if err != nil {
3430
errMsg := "Failed to get requests"

cmd/cli/commands/rm.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package commands
22

33
import (
4-
"fmt"
5-
64
"github.com/docker/model-runner/cmd/cli/commands/completion"
75
"github.com/spf13/cobra"
86
)
@@ -15,9 +13,6 @@ func newRemoveCmd() *cobra.Command {
1513
Short: "Remove local models downloaded from Docker Hub",
1614
Args: requireMinArgs(1, "rm", "[MODEL...]"),
1715
RunE: func(cmd *cobra.Command, args []string) error {
18-
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), false); err != nil {
19-
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
20-
}
2116
response, err := desktopClient.Remove(args, force)
2217
if response != "" {
2318
cmd.Print(response)

cmd/cli/commands/root.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,33 +84,42 @@ func NewRootCmd(cli *command.DockerCli) *cobra.Command {
8484
globalOptions.InstallFlags(rootCmd.Flags())
8585
}
8686

87-
// Add subcommands.
87+
// Runner management commands - these manage the runner itself and don't need automatic runner initialization.
8888
rootCmd.AddCommand(
8989
newVersionCmd(),
90+
newInstallRunner(),
91+
newUninstallRunner(),
92+
newStartRunner(),
93+
newStopRunner(),
94+
newRestartRunner(),
95+
newReinstallRunner(),
96+
)
97+
98+
// Commands that require a running model runner. These are wrapped to ensure the standalone runner is available.
99+
for _, cmd := range []*cobra.Command{
90100
newStatusCmd(),
91101
newPullCmd(),
92102
newPushCmd(),
93103
newPackagedCmd(),
94104
newListCmd(),
95105
newLogsCmd(),
96-
newRunCmd(),
97106
newRemoveCmd(),
98107
newInspectCmd(),
99108
newComposeCmd(),
100109
newTagCmd(),
101-
newInstallRunner(),
102-
newUninstallRunner(),
103-
newStartRunner(),
104-
newStopRunner(),
105-
newRestartRunner(),
106-
newReinstallRunner(),
107110
newConfigureCmd(),
108111
newPSCmd(),
109112
newDFCmd(),
110113
newUnloadCmd(),
111114
newRequestsCmd(),
112115
newPurgeCmd(),
113116
newBenchCmd(),
114-
)
117+
} {
118+
rootCmd.AddCommand(withStandaloneRunner(cmd))
119+
}
120+
121+
// run command handles standalone runner initialization itself (needs debug flag)
122+
rootCmd.AddCommand(newRunCmd())
123+
115124
return rootCmd
116125
}

cmd/cli/commands/run.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,10 @@ func newRunCmd() *cobra.Command {
585585
}
586586
},
587587
RunE: func(cmd *cobra.Command, args []string) error {
588+
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), debug); err != nil {
589+
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
590+
}
591+
588592
model := args[0]
589593
prompt := ""
590594
argsLen := len(args)
@@ -674,10 +678,6 @@ func newRunCmd() *cobra.Command {
674678
return nil
675679
}
676680

677-
if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), asPrinter(cmd), debug); err != nil {
678-
return fmt.Errorf("unable to initialize standalone model runner: %w", err)
679-
}
680-
681681
_, err := desktopClient.Inspect(model, false)
682682
if err != nil {
683683
if !errors.Is(err, desktop.ErrNotFound) {

0 commit comments

Comments
 (0)