Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 51 additions & 5 deletions cmd/cli/commands/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,28 @@ package commands

import (
"bytes"
"context"
"fmt"
"net/url"
"os"
"path/filepath"
"sort"
"strconv"
"time"

"github.com/docker/cli/cli/command"
"github.com/docker/model-runner/cmd/cli/commands/formatter"
"github.com/docker/model-runner/cmd/cli/desktop"
"github.com/docker/model-runner/cmd/cli/pkg/modelctx"
"github.com/docker/model-runner/cmd/cli/pkg/standalone"
"github.com/docker/model-runner/cmd/cli/pkg/types"
"github.com/spf13/cobra"
)

// defaultContextDetectTimeout is the maximum time allowed for detecting the
// engine kind when building the synthetic "default" context row.
const defaultContextDetectTimeout = 2 * time.Second

// newContextCmd returns the "docker model context" parent command. Its
// subcommands manage named Model Runner contexts stored on disk, so they do
// not require a running backend and override PersistentPreRunE accordingly.
Expand Down Expand Up @@ -66,6 +75,37 @@ func dockerConfigDir() (string, error) {
return filepath.Join(home, ".docker"), nil
}

// resolveDefaultContext attempts to detect the Docker engine kind for the
// synthetic "default" context row. When the CLI is available it probes the
// Docker daemon (with a short timeout) and returns a descriptive host and
// description derived from the detected engine kind. If detection fails or
// the CLI is unavailable it falls back to generic strings.
func resolveDefaultContext(ctx context.Context) (host, description string) {
const fallbackHost = "(auto-detect)"
const fallbackDescription = "Auto-detected Docker context"

if dockerCLI == nil {
return fallbackHost, fallbackDescription
}

detectCtx, cancel := context.WithTimeout(ctx, defaultContextDetectTimeout)
defer cancel()

kind := desktop.DetectEngineKind(detectCtx, dockerCLI)
description = "Model Runner on " + kind.String()

switch kind {
case types.ModelRunnerEngineKindDesktop:
host = kind.String()
case types.ModelRunnerEngineKindCloud:
host = "http://localhost:" + strconv.Itoa(standalone.DefaultControllerPortCloud)
case types.ModelRunnerEngineKindMoby, types.ModelRunnerEngineKindMobyManual:
host = "http://localhost:" + strconv.Itoa(standalone.DefaultControllerPortMoby)
}

return host, description
}

// newContextCreateCmd returns the "context create" command.
func newContextCreateCmd() *cobra.Command {
var (
Expand Down Expand Up @@ -223,12 +263,16 @@ func newContextLsCmd() *cobra.Command {
)
}

// Resolve the host and description for the synthetic "default"
// row by detecting the engine kind (Desktop, Moby, Cloud).
defaultHost, defaultDescription := resolveDefaultContext(cmd.Context())

// Build rows: synthetic "default" first, then named contexts sorted.
rows := []contextListRow{
{
name: modelctx.DefaultContextName,
host: "(auto-detect)",
description: "Auto-detected Docker context",
host: defaultHost,
description: defaultDescription,
active: activeName == modelctx.DefaultContextName,
},
}
Expand Down Expand Up @@ -328,12 +372,14 @@ func newContextInspectCmd() *cobra.Command {
results := make([]namedContextInspect, 0, len(args))
for _, name := range args {
if name == modelctx.DefaultContextName {
// Return a synthetic entry for "default".
// Return a synthetic entry for "default",
// resolved from the detected engine kind.
defaultHost, defaultDescription := resolveDefaultContext(cmd.Context())
results = append(results, namedContextInspect{
Name: modelctx.DefaultContextName,
ContextConfig: modelctx.ContextConfig{
Host: "(auto-detect)",
Description: "Auto-detected Docker context",
Host: defaultHost,
Description: defaultDescription,
},
})
continue
Expand Down
15 changes: 15 additions & 0 deletions cmd/cli/desktop/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,21 @@ func namedContextStore(cli *command.DockerCli) (*modelctx.Store, error) {
return modelctx.New(configDir)
}

// DetectEngineKind determines the Docker engine kind associated with the
// current CLI context without performing any side effects (such as waking
// up Docker Cloud). It is intended for informational commands like
// "context ls" that need to display the resolved engine kind without
// triggering backend initialisation.
func DetectEngineKind(ctx context.Context, cli *command.DockerCli) types.ModelRunnerEngineKind {
if isDesktopContext(ctx, cli) {
return types.ModelRunnerEngineKindDesktop
}
if isCloudContext(cli) {
return types.ModelRunnerEngineKindCloud
}
return types.ModelRunnerEngineKindMoby
}

// DetectContext determines the current Docker Model Runner context.
func DetectContext(ctx context.Context, cli *command.DockerCli, printer standalone.StatusPrinter) (*ModelRunnerContext, error) {
// Check for an explicit endpoint setting.
Expand Down
Loading