Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 0 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ WORKDIR /app
# Copy go mod/sum first for better caching
COPY --link go.mod go.sum ./

# Copy pkg/go-containerregistry for the replace directive in go.mod
COPY --link pkg/go-containerregistry ./pkg/go-containerregistry

# Download dependencies (with cache mounts)
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
Expand Down
40 changes: 30 additions & 10 deletions cmd/cli/commands/configure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ func TestConfigureCmdHfOverridesFlag(t *testing.T) {
hfOverridesFlag := cmd.Flags().Lookup("hf_overrides")
if hfOverridesFlag == nil {
t.Fatal("--hf_overrides flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Get values to avoid potential nil dereference flagged by linter
defValue := hfOverridesFlag.DefValue

// Verify the default value is empty
if hfOverridesFlag.DefValue != "" {
t.Errorf("Expected default hf_overrides value to be empty, got '%s'", hfOverridesFlag.DefValue)
if defValue != "" {
t.Errorf("Expected default hf_overrides value to be empty, got '%s'", defValue)
}

// Verify the flag type
Expand All @@ -33,11 +37,15 @@ func TestConfigureCmdContextSizeFlag(t *testing.T) {
contextSizeFlag := cmd.Flags().Lookup("context-size")
if contextSizeFlag == nil {
t.Fatal("--context-size flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Get values to avoid potential nil dereference flagged by linter
defValue := contextSizeFlag.DefValue

// Verify the default value is empty (nil pointer)
if contextSizeFlag.DefValue != "" {
t.Errorf("Expected default context-size value to be '' (nil), got '%s'", contextSizeFlag.DefValue)
if defValue != "" {
t.Errorf("Expected default context-size value to be '' (nil), got '%s'", defValue)
}

// Test setting the flag value
Expand Down Expand Up @@ -83,11 +91,15 @@ func TestConfigureCmdModeFlag(t *testing.T) {
modeFlag := cmd.Flags().Lookup("mode")
if modeFlag == nil {
t.Fatal("--mode flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Get values to avoid potential nil dereference flagged by linter
defValue := modeFlag.DefValue

// Verify the default value is empty
if modeFlag.DefValue != "" {
t.Errorf("Expected default mode value to be empty, got '%s'", modeFlag.DefValue)
if defValue != "" {
t.Errorf("Expected default mode value to be empty, got '%s'", defValue)
}

// Verify the flag type
Expand All @@ -104,11 +116,15 @@ func TestConfigureCmdThinkFlag(t *testing.T) {
thinkFlag := cmd.Flags().Lookup("think")
if thinkFlag == nil {
t.Fatal("--think flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Get values to avoid potential nil dereference flagged by linter
defValue := thinkFlag.DefValue

// Verify the default value is empty
if thinkFlag.DefValue != "" {
t.Errorf("Expected default think value to be empty (nil), got '%s'", thinkFlag.DefValue)
if defValue != "" {
t.Errorf("Expected default think value to be empty (nil), got '%s'", defValue)
}

// Verify the flag type
Expand Down Expand Up @@ -136,11 +152,15 @@ func TestConfigureCmdGPUMemoryUtilizationFlag(t *testing.T) {
gpuMemFlag := cmd.Flags().Lookup("gpu-memory-utilization")
if gpuMemFlag == nil {
t.Fatal("--gpu-memory-utilization flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Get values to avoid potential nil dereference flagged by linter
defValue := gpuMemFlag.DefValue

// Verify the default value is empty (nil pointer)
if gpuMemFlag.DefValue != "" {
t.Errorf("Expected default gpu-memory-utilization value to be '' (nil), got '%s'", gpuMemFlag.DefValue)
if defValue != "" {
t.Errorf("Expected default gpu-memory-utilization value to be '' (nil), got '%s'", defValue)
}

// Verify the flag type
Expand Down
16 changes: 12 additions & 4 deletions cmd/cli/commands/install-runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ func TestInstallRunnerHostFlag(t *testing.T) {
hostFlag := cmd.Flags().Lookup("host")
if hostFlag == nil {
t.Fatal("--host flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Get values to avoid potential nil dereference flagged by linter
defValue := hostFlag.DefValue

// Verify the default value
if hostFlag.DefValue != "127.0.0.1" {
t.Errorf("Expected default host value to be '127.0.0.1', got '%s'", hostFlag.DefValue)
if defValue != "127.0.0.1" {
t.Errorf("Expected default host value to be '127.0.0.1', got '%s'", defValue)
}

// Verify the flag type
Expand Down Expand Up @@ -77,11 +81,15 @@ func TestInstallRunnerBackendFlag(t *testing.T) {
backendFlag := cmd.Flags().Lookup("backend")
if backendFlag == nil {
t.Fatal("--backend flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Get values to avoid potential nil dereference flagged by linter
defValue := backendFlag.DefValue

// Verify the default value
if backendFlag.DefValue != "" {
t.Errorf("Expected default backend value to be empty, got '%s'", backendFlag.DefValue)
if defValue != "" {
t.Errorf("Expected default backend value to be empty, got '%s'", defValue)
}

// Verify the flag type
Expand Down
21 changes: 18 additions & 3 deletions cmd/cli/commands/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/docker/model-runner/cmd/cli/desktop"
"github.com/docker/model-runner/cmd/cli/pkg/types"
"github.com/docker/model-runner/pkg/distribution/builder"
"github.com/docker/model-runner/pkg/distribution/oci/reference"
"github.com/docker/model-runner/pkg/distribution/registry"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
Expand Down Expand Up @@ -110,6 +111,11 @@ func generateReferenceTestCases(info modelInfo) []referenceTestCase {
func setupTestEnv(t *testing.T) *testEnv {
ctx := context.Background()

// Set environment variables for the test process to match the DMR container.
// This ensures CLI functions use the same default registry when parsing references.
t.Setenv("DEFAULT_REGISTRY", "registry.local:5000")
t.Setenv("INSECURE_REGISTRY", "true")

// Create a custom network for container communication
net, err := network.New(ctx)
require.NoError(t, err)
Expand Down Expand Up @@ -1037,7 +1043,7 @@ func TestIntegration_PackageModel(t *testing.T) {
model, err := env.client.Inspect(targetTag, false)
require.NoError(t, err, "Failed to inspect packaged model by tag: %s", targetTag)
require.NotEmpty(t, model.ID, "Model ID should not be empty")
require.Contains(t, model.Tags, targetTag, "Model should have the expected tag")
require.Contains(t, model.Tags, normalizeRef(t, targetTag), "Model should have the expected tag")

t.Logf("✓ Successfully packaged and tagged model: %s (ID: %s)", targetTag, model.ID[7:19])

Expand Down Expand Up @@ -1070,7 +1076,7 @@ func TestIntegration_PackageModel(t *testing.T) {
// Verify the model was loaded and tagged
model, err := env.client.Inspect(targetTag, false)
require.NoError(t, err, "Failed to inspect packaged model")
require.Contains(t, model.Tags, targetTag, "Model should have the expected tag")
require.Contains(t, model.Tags, normalizeRef(t, targetTag), "Model should have the expected tag")

t.Logf("✓ Successfully packaged model with context size: %s", targetTag)

Expand Down Expand Up @@ -1100,7 +1106,7 @@ func TestIntegration_PackageModel(t *testing.T) {
// Verify the model was loaded and tagged
model, err := env.client.Inspect(targetTag, false)
require.NoError(t, err, "Failed to inspect packaged model")
require.Contains(t, model.Tags, targetTag, "Model should have the expected tag")
require.Contains(t, model.Tags, normalizeRef(t, targetTag), "Model should have the expected tag")

t.Logf("✓ Successfully packaged model with custom org: %s", targetTag)

Expand All @@ -1118,3 +1124,12 @@ func TestIntegration_PackageModel(t *testing.T) {
func int32ptr(n int32) *int32 {
return &n
}

// normalizeRef normalizes a reference to its fully qualified form.
// This is used in tests to compare against the stored tags which are always normalized.
func normalizeRef(t *testing.T, ref string) string {
t.Helper()
parsed, err := reference.ParseReference(ref, registry.GetDefaultRegistryOptions()...)
require.NoError(t, err, "Failed to parse reference: %s", ref)
return parsed.String()
}
8 changes: 4 additions & 4 deletions cmd/cli/commands/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import (
"github.com/docker/model-runner/cmd/cli/desktop"
"github.com/docker/model-runner/pkg/distribution/builder"
"github.com/docker/model-runner/pkg/distribution/distribution"
"github.com/docker/model-runner/pkg/distribution/oci/reference"
"github.com/docker/model-runner/pkg/distribution/packaging"
"github.com/docker/model-runner/pkg/distribution/registry"
"github.com/docker/model-runner/pkg/distribution/tarball"
"github.com/docker/model-runner/pkg/distribution/types"
"github.com/docker/model-runner/pkg/go-containerregistry/pkg/name"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -434,7 +434,7 @@ func packageModel(ctx context.Context, cmd *cobra.Command, client *desktop.Clien
// modelRunnerTarget loads model to Docker Model Runner via models/load endpoint
type modelRunnerTarget struct {
client *desktop.Client
tag name.Tag
tag *reference.Tag
}

func newModelRunnerTarget(client *desktop.Client, tag string) (*modelRunnerTarget, error) {
Expand All @@ -443,7 +443,7 @@ func newModelRunnerTarget(client *desktop.Client, tag string) (*modelRunnerTarge
}
if tag != "" {
var err error
target.tag, err = name.NewTag(tag)
target.tag, err = reference.NewTag(tag, registry.GetDefaultRegistryOptions()...)
if err != nil {
return nil, fmt.Errorf("invalid tag: %w", err)
}
Expand Down Expand Up @@ -477,7 +477,7 @@ func (t *modelRunnerTarget) Write(ctx context.Context, mdl types.ModelArtifact,
if err != nil {
return fmt.Errorf("get model ID: %w", err)
}
if t.tag.String() != "" {
if t.tag != nil {
if err := t.client.Tag(id, parseRepo(t.tag), t.tag.TagStr()); err != nil {
return fmt.Errorf("tag model: %w", err)
}
Expand Down
8 changes: 6 additions & 2 deletions cmd/cli/commands/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func TestRunCmdDetachFlag(t *testing.T) {
detachFlag := cmd.Flags().Lookup("detach")
if detachFlag == nil {
t.Fatal("--detach flag not found")
return // unreachable but satisfies staticcheck SA5011
}

// Verify the shorthand flag exists
Expand All @@ -130,9 +131,12 @@ func TestRunCmdDetachFlag(t *testing.T) {
t.Fatal("-d shorthand flag not found")
}

// Get values to avoid potential nil dereference flagged by linter
defValue := detachFlag.DefValue

// Verify the default value is false
if detachFlag.DefValue != "false" {
t.Errorf("Expected default detach value to be 'false', got '%s'", detachFlag.DefValue)
if defValue != "false" {
t.Errorf("Expected default detach value to be 'false', got '%s'", defValue)
}

// Verify the flag type
Expand Down
6 changes: 3 additions & 3 deletions cmd/cli/commands/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (

"github.com/docker/model-runner/cmd/cli/commands/completion"
"github.com/docker/model-runner/cmd/cli/desktop"
"github.com/docker/model-runner/pkg/distribution/oci/reference"
"github.com/docker/model-runner/pkg/distribution/registry"
"github.com/docker/model-runner/pkg/go-containerregistry/pkg/name"
"github.com/spf13/cobra"
)

Expand All @@ -26,7 +26,7 @@ func newTagCmd() *cobra.Command {

func tagModel(cmd *cobra.Command, desktopClient *desktop.Client, source, target string) error {
// Ensure tag is valid
tag, err := name.NewTag(target, registry.GetDefaultRegistryOptions()...)
tag, err := reference.NewTag(target, registry.GetDefaultRegistryOptions()...)
if err != nil {
return fmt.Errorf("invalid tag: %w", err)
}
Expand All @@ -40,6 +40,6 @@ func tagModel(cmd *cobra.Command, desktopClient *desktop.Client, source, target

// parseRepo returns the repo portion of the original target string. It does not include implicit
// index.docker.io when the registry is omitted.
func parseRepo(tag name.Tag) string {
func parseRepo(tag *reference.Tag) string {
return strings.TrimSuffix(tag.String(), ":"+tag.TagStr())
}
6 changes: 3 additions & 3 deletions cmd/cli/commands/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/docker/cli/cli-plugins/hooks"
"github.com/docker/model-runner/cmd/cli/desktop"
"github.com/docker/model-runner/cmd/cli/pkg/standalone"
"github.com/docker/model-runner/pkg/go-containerregistry/pkg/name"
"github.com/docker/model-runner/pkg/distribution/oci/reference"
"github.com/docker/model-runner/pkg/inference/backends/vllm"
"github.com/moby/term"
"github.com/olekukonko/tablewriter"
Expand All @@ -33,12 +33,12 @@ const (

// getDefaultRegistry returns the default registry, checking for environment override
// If DEFAULT_REGISTRY environment variable is set, it returns that value
// Otherwise, it returns name.DefaultRegistry ("index.docker.io")
// Otherwise, it returns reference.DefaultRegistry ("index.docker.io")
func getDefaultRegistry() string {
if defaultReg := os.Getenv("DEFAULT_REGISTRY"); defaultReg != "" {
return defaultReg
}
return name.DefaultRegistry
return reference.DefaultRegistry
}

var errNotRunning = fmt.Errorf("Docker Model Runner is not running. Please start it and try again.\n")
Expand Down
6 changes: 1 addition & 5 deletions cmd/cli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ require (
github.com/docker/go-connections v0.6.0
github.com/docker/go-units v0.5.0
github.com/docker/model-runner v1.0.10
github.com/docker/model-runner/pkg/go-containerregistry v0.0.0-20251121150728-6951a2a36575
github.com/emirpasic/gods/v2 v2.0.0-alpha
github.com/fatih/color v1.18.0
github.com/mattn/go-runewidth v0.0.19
Expand Down Expand Up @@ -55,7 +54,6 @@ require (
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v1.0.0-rc.2 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/cpuguy83/dockercfg v0.3.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
Expand Down Expand Up @@ -91,7 +89,6 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.1.0 // indirect
github.com/moby/locker v1.0.1 // indirect
Expand Down Expand Up @@ -122,7 +119,6 @@ require (
github.com/smallnest/ringbuffer v0.0.0-20241116012123-461381446e3d // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yuin/goldmark v1.7.8 // indirect
github.com/yuin/goldmark-emoji v1.0.5 // indirect
Expand Down Expand Up @@ -157,4 +153,4 @@ require (

replace github.com/kolesnikovae/go-winjob => github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5

replace github.com/docker/model-runner/pkg/go-containerregistry => ../../pkg/go-containerregistry
replace github.com/docker/model-runner => ../..
8 changes: 0 additions & 8 deletions cmd/cli/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6acgLGv/QzE4=
github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
Expand Down Expand Up @@ -101,8 +99,6 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5 h1:dxSFEb0EEmvceIawSFNDMrvKakRz2t+2WYpY3dFAT04=
github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5/go.mod h1:ICOGmIXdwhfid7rQP+tLvDJqVg0lHdEk3pI5nsapTtg=
github.com/docker/model-runner v1.0.10 h1:meSXhmMqf1wZioYf3Nydr7iXq01qSkUndFsXd/QAjrs=
github.com/docker/model-runner v1.0.10/go.mod h1:PF+WLIG96pKnhQ/AhQOo2Ulr1gaKqXG1quQu88ZmoDg=
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/emirpasic/gods/v2 v2.0.0-alpha h1:dwFlh8pBg1VMOXWGipNMRt8v96dKAIvBehtCt6OtunU=
Expand Down Expand Up @@ -183,8 +179,6 @@ github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebG
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
Expand Down Expand Up @@ -286,8 +280,6 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
Loading
Loading