Skip to content

Commit 36c78a5

Browse files
committed
fix(controller): agent image name parsing
Support image name with registry prefix containing port number or without tag (default to latest)
1 parent ce9c319 commit 36c78a5

File tree

2 files changed

+105
-10
lines changed

2 files changed

+105
-10
lines changed

cmd/controller/root.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,10 @@ var rootCmd = &cobra.Command{
4747
}
4848
},
4949
Run: func(cmd *cobra.Command, args []string) {
50-
var image *config.Image
51-
imageTokens := strings.Split(agentImage, ":")
52-
if len(imageTokens) == 2 {
53-
image = config.NewImage(imageTokens[0], imageTokens[1])
54-
} else {
55-
fmt.Fprintf(os.Stderr, "Error parse agent image name\n")
56-
if err := cmd.Help(); err != nil {
57-
os.Exit(1)
58-
}
59-
os.Exit(0)
50+
image, err := parseImageNameAndTag(agentImage)
51+
if err != nil {
52+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
53+
os.Exit(1)
6054
}
6155

6256
options := &config.ControllerOptions{
@@ -96,3 +90,26 @@ func init() {
9690
func execute() {
9791
cobra.CheckErr(rootCmd.Execute())
9892
}
93+
94+
func parseImageNameAndTag(image string) (*config.Image, error) {
95+
idx := strings.LastIndex(image, ":")
96+
97+
if idx == -1 {
98+
return config.NewImage(image, "latest"), nil
99+
}
100+
101+
// If the last colon is immediately followed by the end of the string, it's invalid (no tag).
102+
if idx == len(image)-1 {
103+
return nil, fmt.Errorf("invalid image name: colon without tag")
104+
}
105+
106+
if strings.Count(image, ":") > 2 {
107+
return nil, fmt.Errorf("invalid image name: multiple colons found")
108+
}
109+
110+
if idx <= strings.LastIndex(image, "/") {
111+
return config.NewImage(image, "latest"), nil
112+
}
113+
114+
return config.NewImage(image[:idx], image[idx+1:]), nil
115+
}

cmd/controller/root_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/harvester/vm-dhcp-controller/pkg/config"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestParseImageNameAndTag(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
image string
14+
expected *config.Image
15+
err bool
16+
}{
17+
{
18+
name: "valid image with registry and tag",
19+
image: "myregistry.local:5000/rancher/harvester-vm-dhcp-controller:v0.3.3",
20+
expected: &config.Image{
21+
Repository: "myregistry.local:5000/rancher/harvester-vm-dhcp-controller",
22+
Tag: "v0.3.3",
23+
},
24+
err: false,
25+
},
26+
{
27+
name: "valid image with only image and tag",
28+
image: "rancher/harvester-vm-dhcp-controller:v0.3.3",
29+
expected: &config.Image{
30+
Repository: "rancher/harvester-vm-dhcp-controller",
31+
Tag: "v0.3.3",
32+
},
33+
err: false,
34+
},
35+
{
36+
name: "valid image without tag",
37+
image: "rancher/harvester-vm-dhcp-controller",
38+
expected: &config.Image{
39+
Repository: "rancher/harvester-vm-dhcp-controller",
40+
Tag: "latest",
41+
},
42+
err: false,
43+
},
44+
{
45+
name: "valid image with port but no tag",
46+
image: "myregistry.local:5000/rancher/harvester-vm-dhcp-controller",
47+
expected: &config.Image{
48+
Repository: "myregistry.local:5000/rancher/harvester-vm-dhcp-controller",
49+
Tag: "latest",
50+
},
51+
err: false,
52+
},
53+
{
54+
name: "invalid image with colon but no tag",
55+
image: "myregistry.local:5000/rancher/harvester-vm-dhcp-controller:",
56+
expected: nil,
57+
err: true,
58+
},
59+
{
60+
name: "invalid image with multiple colons",
61+
image: "myregistry.local:5000/rancher/harvester-vm-dhcp-controller:v0.3.3:latest",
62+
expected: nil,
63+
err: true,
64+
},
65+
}
66+
67+
for _, tt := range tests {
68+
t.Run(tt.name, func(t *testing.T) {
69+
result, err := parseImageNameAndTag(tt.image)
70+
if tt.err {
71+
assert.Error(t, err)
72+
} else {
73+
assert.NoError(t, err)
74+
assert.Equal(t, tt.expected, result)
75+
}
76+
})
77+
}
78+
}

0 commit comments

Comments
 (0)