fix(container): recognize localhost without port as explicit registry
hasExplicitRegistry failed to treat "localhost/image" (no port) as an explicit registry, causing buildImageRef to incorrectly re-prefix it. Added check for registryPart == "localhost" before port/dot checks.
- commit
- 855fc0449b31d452063f41ed5037b9aab5f6fffc
- author
- bnema · · 2026-02-03 20:30 UTC
- parent
- 160b399
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +13 -1
M internal/usecase/container/service.go +6 -1
| @@ -655,7 +655,7 @@ func (s *Service) buildImageRef(image string) string { | |||
| 655 | 655 | } | |
| 656 | 656 | ||
| 657 | 657 | // hasExplicitRegistry checks if an image reference already includes an explicit registry. | |
| 658 | - | // Returns true for patterns like "docker.io/image", "localhost:5000/image", "registry:8080/image". | |
| 658 | + | // Returns true for patterns like "docker.io/image", "localhost:5000/image", "localhost/image", "registry:8080/image". | |
| 659 | 659 | func hasExplicitRegistry(image string) bool { | |
| 660 | 660 | // Find the first slash which separates registry from image name | |
| 661 | 661 | slashIdx := strings.Index(image, "/") | |
| @@ -666,6 +666,11 @@ func hasExplicitRegistry(image string) bool { | |||
| 666 | 666 | // Extract the part before the first slash (potential registry) | |
| 667 | 667 | registryPart := image[:slashIdx] | |
| 668 | 668 | ||
| 669 | + | // Check for localhost (with or without port) | |
| 670 | + | if registryPart == "localhost" { | |
| 671 | + | return true | |
| 672 | + | } | |
| 673 | + | ||
| 669 | 674 | // Check for host:port pattern (e.g., "localhost:5000", "registry:8080") | |
| 670 | 675 | if colonIdx := strings.LastIndex(registryPart, ":"); colonIdx != -1 { | |
| 671 | 676 | port := registryPart[colonIdx+1:] | |
| @@ -655,7 +655,7 @@ func (s *Service) buildImageRef(image string) string { | |||||
| 655 | } | 655 | } | ||
| 656 | 656 | ||||
| 657 | // hasExplicitRegistry checks if an image reference already includes an explicit registry. | 657 | // hasExplicitRegistry checks if an image reference already includes an explicit registry. | ||
| 658 | - | // Returns true for patterns like "docker.io/image", "localhost:5000/image", "registry:8080/image". | 658 | + | // Returns true for patterns like "docker.io/image", "localhost:5000/image", "localhost/image", "registry:8080/image". |
| 659 | func hasExplicitRegistry(image string) bool { | 659 | func hasExplicitRegistry(image string) bool { | ||
| 660 | // Find the first slash which separates registry from image name | 660 | // Find the first slash which separates registry from image name | ||
| 661 | slashIdx := strings.Index(image, "/") | 661 | slashIdx := strings.Index(image, "/") | ||
| @@ -666,6 +666,11 @@ func hasExplicitRegistry(image string) bool { | |||||
| 666 | // Extract the part before the first slash (potential registry) | 666 | // Extract the part before the first slash (potential registry) | ||
| 667 | registryPart := image[:slashIdx] | 667 | registryPart := image[:slashIdx] | ||
| 668 | 668 | ||||
| 669 | + | // Check for localhost (with or without port) | |||
| 670 | + | if registryPart == "localhost" { | |||
| 671 | + | return true | |||
| 672 | + | } | |||
| 673 | + | ||||
| 669 | // Check for host:port pattern (e.g., "localhost:5000", "registry:8080") | 674 | // Check for host:port pattern (e.g., "localhost:5000", "registry:8080") | ||
| 670 | if colonIdx := strings.LastIndex(registryPart, ":"); colonIdx != -1 { | 675 | if colonIdx := strings.LastIndex(registryPart, ":"); colonIdx != -1 { | ||
| 671 | port := registryPart[colonIdx+1:] | 676 | port := registryPart[colonIdx+1:] | ||
M internal/usecase/container/service_test.go +7 -0
| @@ -821,6 +821,13 @@ func TestBuildImageRef(t *testing.T) { | |||
| 821 | 821 | registryDomain: "localhost:5000", | |
| 822 | 822 | wantRef: "quay.io/org/app:tag", | |
| 823 | 823 | }, | |
| 824 | + | { | |
| 825 | + | name: "localhost without port keeps existing prefix", | |
| 826 | + | image: "localhost/myapp:latest", | |
| 827 | + | registryAuthEnabled: true, | |
| 828 | + | registryDomain: "localhost:5000", | |
| 829 | + | wantRef: "localhost/myapp:latest", | |
| 830 | + | }, | |
| 824 | 831 | } | |
| 825 | 832 | ||
| 826 | 833 | for _, tt := range tests { | |
| @@ -821,6 +821,13 @@ func TestBuildImageRef(t *testing.T) { | |||||
| 821 | registryDomain: "localhost:5000", | 821 | registryDomain: "localhost:5000", | ||
| 822 | wantRef: "quay.io/org/app:tag", | 822 | wantRef: "quay.io/org/app:tag", | ||
| 823 | }, | 823 | }, | ||
| 824 | + | { | |||
| 825 | + | name: "localhost without port keeps existing prefix", | |||
| 826 | + | image: "localhost/myapp:latest", | |||
| 827 | + | registryAuthEnabled: true, | |||
| 828 | + | registryDomain: "localhost:5000", | |||
| 829 | + | wantRef: "localhost/myapp:latest", | |||
| 830 | + | }, | |||
| 824 | } | 831 | } | ||
| 825 | 832 | ||||
| 826 | for _, tt := range tests { | 833 | for _, tt := range tests { | ||