From 5bf6fce628c35d777df004e83f2394f3cc732d26 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Wed, 25 Jun 2025 12:07:03 +0200 Subject: [PATCH 1/3] introduce status --json and document endpoint URL Signed-off-by: Nicolas De Loof --- commands/status.go | 79 ++++++++++++++++++++----- docs/reference/docker_model_status.yaml | 10 ++++ docs/reference/model_status.md | 6 ++ 3 files changed, 79 insertions(+), 16 deletions(-) diff --git a/commands/status.go b/commands/status.go index 2f295521..9ef7158a 100644 --- a/commands/status.go +++ b/commands/status.go @@ -7,44 +7,91 @@ import ( "github.com/docker/cli/cli-plugins/hooks" "github.com/docker/model-cli/commands/completion" + "github.com/docker/model-cli/desktop" "github.com/spf13/cobra" ) func newStatusCmd() *cobra.Command { + var formatJson bool c := &cobra.Command{ Use: "status", Short: "Check if the Docker Model Runner is running", RunE: func(cmd *cobra.Command, args []string) error { - if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), cmd); err != nil { + standalone, err := ensureStandaloneRunnerAvailable(cmd.Context(), cmd) + if err != nil { return fmt.Errorf("unable to initialize standalone model runner: %w", err) } status := desktopClient.Status() if status.Error != nil { return handleClientError(status.Error, "Failed to get Docker Model Runner status") } - if status.Running { - cmd.Println("Docker Model Runner is running") - cmd.Println("\nStatus:") - var backendStatus map[string]string - if err := json.Unmarshal(status.Status, &backendStatus); err != nil { - cmd.PrintErrln(string(status.Status)) - } - for b, s := range backendStatus { - if s != "not running" { - cmd.Println(b+":", s) - } - } + + var backendStatus map[string]string + if err := json.Unmarshal(status.Status, &backendStatus); err != nil { + cmd.PrintErrln(string(status.Status)) + } + + if formatJson { + return jsonStatus(standalone, status, backendStatus) } else { - cmd.Println("Docker Model Runner is not running") - hooks.PrintNextSteps(cmd.OutOrStdout(), []string{enableViaCLI, enableViaGUI}) - osExit(1) + textStatus(cmd, status, backendStatus) } return nil }, ValidArgsFunction: completion.NoComplete, } + c.Flags().BoolVar(&formatJson, "json", false, "Format output in JSON") return c } +func textStatus(cmd *cobra.Command, status desktop.Status, backendStatus map[string]string) { + if status.Running { + cmd.Println("Docker Model Runner is running") + cmd.Println("\nStatus:") + for b, s := range backendStatus { + if s != "not running" { + cmd.Println(b+":", s) + } + } + } else { + cmd.Println("Docker Model Runner is not running") + hooks.PrintNextSteps(cmd.OutOrStdout(), []string{enableViaCLI, enableViaGUI}) + osExit(1) + } +} + +func jsonStatus(standalone *standaloneRunner, status desktop.Status, backendStatus map[string]string) error { + type Status struct { + Running bool `json:"running"` + Backends map[string]string `json:"backends"` + Endpoint string `json:"endpoint"` + } + var endpoint string + kind := modelRunner.EngineKind() + switch kind { + case desktop.ModelRunnerEngineKindDesktop: + endpoint = "http://model-runner.docker.internal/engines/v1/" + case desktop.ModelRunnerEngineKindMobyManual: + endpoint = modelRunner.URL("/engines/v1/") + case desktop.ModelRunnerEngineKindCloud: + fallthrough + case desktop.ModelRunnerEngineKindMoby: + endpoint = fmt.Sprintf("http://%s:%d/engines/v1", standalone.gatewayIP, standalone.gatewayPort) + default: + return fmt.Errorf("unhandled engine kind: %v", kind) + } + s := Status{ + Running: status.Running, + Backends: backendStatus, + Endpoint: endpoint, + } + marshal, err := json.Marshal(s) + if err != nil { + return err + } + fmt.Println(string(marshal)) + return nil +} + var osExit = os.Exit diff --git a/docs/reference/docker_model_status.yaml b/docs/reference/docker_model_status.yaml index 07da71d0..6c1e89d8 100644 --- a/docs/reference/docker_model_status.yaml +++ b/docs/reference/docker_model_status.yaml @@ -5,6 +5,16 @@ long: | usage: docker model status pname: docker model plink: docker_model.yaml +options: + - option: format + value_type: string + description: Output format [text|json] + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false diff --git a/docs/reference/model_status.md b/docs/reference/model_status.md index 72a0bf79..33fe7600 100644 --- a/docs/reference/model_status.md +++ b/docs/reference/model_status.md @@ -3,6 +3,12 @@ Check if the Docker Model Runner is running +### Options + +| Name | Type | Default | Description | +|:-----------|:---------|:--------|:---------------------------| +| `--format` | `string` | | Output format [text\|json] | + From 99fe714d56f93d636ca045835abca23ee7fcaa7b Mon Sep 17 00:00:00 2001 From: Jacob Howard Date: Wed, 25 Jun 2025 16:43:45 -0600 Subject: [PATCH 2/3] Update docs for new status flag. Signed-off-by: Jacob Howard --- docs/reference/docker_model_status.yaml | 7 ++++--- docs/reference/model_status.md | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/reference/docker_model_status.yaml b/docs/reference/docker_model_status.yaml index 6c1e89d8..5b0c33b4 100644 --- a/docs/reference/docker_model_status.yaml +++ b/docs/reference/docker_model_status.yaml @@ -6,9 +6,10 @@ usage: docker model status pname: docker model plink: docker_model.yaml options: - - option: format - value_type: string - description: Output format [text|json] + - option: json + value_type: bool + default_value: "false" + description: Format output in JSON deprecated: false hidden: false experimental: false diff --git a/docs/reference/model_status.md b/docs/reference/model_status.md index 33fe7600..baa63007 100644 --- a/docs/reference/model_status.md +++ b/docs/reference/model_status.md @@ -5,9 +5,9 @@ Check if the Docker Model Runner is running ### Options -| Name | Type | Default | Description | -|:-----------|:---------|:--------|:---------------------------| -| `--format` | `string` | | Output format [text\|json] | +| Name | Type | Default | Description | +|:---------|:-------|:--------|:----------------------| +| `--json` | `bool` | | Format output in JSON | From a64a773393feee2ec0cfbed981709cd736dfe141 Mon Sep 17 00:00:00 2001 From: Dorin Geman Date: Thu, 26 Jun 2025 14:45:27 +0300 Subject: [PATCH 3/3] status: prevent JSON unmarshal errors on empty status Signed-off-by: Dorin Geman --- commands/status.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/commands/status.go b/commands/status.go index 9ef7158a..2b90120c 100644 --- a/commands/status.go +++ b/commands/status.go @@ -26,9 +26,13 @@ func newStatusCmd() *cobra.Command { return handleClientError(status.Error, "Failed to get Docker Model Runner status") } + if len(status.Status) == 0 { + status.Status = []byte("{}") + } + var backendStatus map[string]string if err := json.Unmarshal(status.Status, &backendStatus); err != nil { - cmd.PrintErrln(string(status.Status)) + cmd.PrintErrln(fmt.Errorf("failed to parse status response: %w", err)) } if formatJson {