diff --git a/clustermesh/clustermesh.go b/clustermesh/clustermesh.go index b656863dad..19b2dae54a 100644 --- a/clustermesh/clustermesh.go +++ b/clustermesh/clustermesh.go @@ -153,8 +153,7 @@ etcdctl auth enable; exit`} func (k *K8sClusterMesh) apiserverImage(imagePathMode utils.ImagePathMode) string { - defaultImage := defaults.ClusterMeshApiserverImage + ":" + k.imageVersion - return utils.BuildImagePath(k.params.ApiserverImage, k.params.ApiserverVersion, defaultImage, imagePathMode) + return utils.BuildImagePath(k.params.ApiserverImage, k.params.ApiserverVersion, defaults.ClusterMeshApiserverImage, k.imageVersion, imagePathMode) } func (k *K8sClusterMesh) etcdImage() string { diff --git a/hubble/relay.go b/hubble/relay.go index 22912eac80..2acf5fde27 100644 --- a/hubble/relay.go +++ b/hubble/relay.go @@ -237,8 +237,7 @@ disable-server-tls: true } func (k *K8sHubble) relayImage(imagePathMode utils.ImagePathMode) string { - defaultImage := defaults.RelayImage + ":" + k.ciliumVersion - return utils.BuildImagePath(k.params.RelayImage, k.params.RelayVersion, defaultImage, imagePathMode) + return utils.BuildImagePath(k.params.RelayImage, k.params.RelayVersion, defaults.RelayImage, k.ciliumVersion, imagePathMode) } func (k *K8sHubble) disableRelay(ctx context.Context) error { diff --git a/hubble/relay_test.go b/hubble/relay_test.go new file mode 100644 index 0000000000..2844ef8061 --- /dev/null +++ b/hubble/relay_test.go @@ -0,0 +1,47 @@ +package hubble + +import ( + "strconv" + "testing" + + "github.com/cilium/cilium-cli/internal/utils" +) + +func TestK8sHubbleRelayImage(t *testing.T) { + tests := []struct { + ciliumVersion string + relayImage string + relayVersion string + imagePathMode utils.ImagePathMode + want string + }{ + { + ciliumVersion: "-cluster-mesh:v1.11.0-beta.1", + relayImage: "", + relayVersion: "", + imagePathMode: utils.ImagePathExcludeDigest, + want: "quay.io/cilium/hubble-relay-cluster-mesh:v1.11.0-beta.1", + }, + { + ciliumVersion: "v1.11.1", + relayImage: "", + relayVersion: "-cluster-mesh:v1.11.0-beta.1", + imagePathMode: utils.ImagePathExcludeDigest, + want: "quay.io/cilium/hubble-relay-cluster-mesh:v1.11.0-beta.1", + }, + } + for i, tt := range tests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + k := &K8sHubble{ + ciliumVersion: tt.ciliumVersion, + params: Parameters{ + RelayImage: tt.relayImage, + RelayVersion: tt.relayVersion, + }, + } + if got := k.relayImage(tt.imagePathMode); got != tt.want { + t.Errorf("k.relayImage(%d) == %q, want %q", tt.imagePathMode, got, tt.want) + } + }) + } +} diff --git a/hubble/ui.go b/hubble/ui.go index f613bc1c9d..ad99e540ad 100644 --- a/hubble/ui.go +++ b/hubble/ui.go @@ -257,13 +257,11 @@ func (k *K8sHubble) generateHubbleUIDeployment() *appsv1.Deployment { } func (k *K8sHubble) uiImage(imagePathMode utils.ImagePathMode) string { - defaultImage := defaults.HubbleUIImage + ":" + defaults.HubbleUIVersion - return utils.BuildImagePath(k.params.UIImage, k.params.UIVersion, defaultImage, imagePathMode) + return utils.BuildImagePath(k.params.UIImage, k.params.UIVersion, defaults.HubbleUIImage, defaults.HubbleUIVersion, imagePathMode) } func (k *K8sHubble) uiBackendImage(imagePathMode utils.ImagePathMode) string { - defaultImage := defaults.HubbleUIBackendImage + ":" + defaults.HubbleUIVersion - return utils.BuildImagePath(k.params.UIBackendImage, k.params.UIVersion, defaultImage, imagePathMode) + return utils.BuildImagePath(k.params.UIBackendImage, k.params.UIVersion, defaults.HubbleUIBackendImage, defaults.HubbleUIVersion, imagePathMode) } func (k *K8sHubble) disableUI(ctx context.Context) error { diff --git a/install/install.go b/install/install.go index d874a30711..d198c5a338 100644 --- a/install/install.go +++ b/install/install.go @@ -1142,20 +1142,19 @@ func (k *K8sInstaller) daemonRunPathOnHost() string { } func (k *K8sInstaller) fqAgentImage(imagePathMode utils.ImagePathMode) string { - defaultImage := defaults.AgentImage + ":" + defaults.Version - return utils.BuildImagePath(k.params.AgentImage, k.params.Version, defaultImage, imagePathMode) + return utils.BuildImagePath(k.params.AgentImage, k.params.Version, defaults.AgentImage, defaults.Version, imagePathMode) } func (k *K8sInstaller) fqOperatorImage(imagePathMode utils.ImagePathMode) string { - defaultImage := defaults.OperatorImage + ":" + defaults.Version + defaultImage := defaults.OperatorImage switch k.params.DatapathMode { case DatapathAwsENI: - defaultImage = defaults.OperatorImageAWS + ":" + defaults.Version + defaultImage = defaults.OperatorImageAWS case DatapathAzure: - defaultImage = defaults.OperatorImageAzure + ":" + defaults.Version + defaultImage = defaults.OperatorImageAzure } - return utils.BuildImagePath(k.params.OperatorImage, k.params.Version, defaultImage, imagePathMode) + return utils.BuildImagePath(k.params.OperatorImage, k.params.Version, defaultImage, defaults.Version, imagePathMode) } func (k *K8sInstaller) operatorCommand() []string { diff --git a/internal/utils/utils.go b/internal/utils/utils.go index de59f1fb4d..cbda56a11d 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -44,25 +44,23 @@ var imageRegexp = regexp.MustCompile(`\A(.*?)(?:(:.*?)(@sha256:[0-9a-f]{64})?)?\ // If imagePathMode is ImagePathIncludeDigest and the resulting image is well // known (i.e. is in defaults.WellKnownImageDigests) then its digest is appended // to the path. -func BuildImagePath(userImage, userVersion, defaultImage string, imagePathMode ImagePathMode) string { - m := imageRegexp.FindStringSubmatch(defaultImage) - if m == nil { - panic(fmt.Sprintf("invalid syntax %q for image", defaultImage)) - } - defaultPath := m[1] - +func BuildImagePath(userImage, userVersion, defaultImage, defaultVersion string, imagePathMode ImagePathMode) string { var image string switch { case userImage == "" && userVersion == "": - image = defaultImage + if strings.Contains(defaultVersion, ":") { + image = defaultImage + defaultVersion + } else { + image = defaultImage + ":" + defaultVersion + } case userImage == "" && strings.Contains(userVersion, ":"): // userVersion already contains the colon. Useful for ":latest", // or for "-ci:" - image = defaultPath + userVersion + image = defaultImage + userVersion case userImage == "" && !strings.HasPrefix(userVersion, "v"): - image = defaultPath + ":v" + userVersion + image = defaultImage + ":v" + userVersion case userImage == "": - image = defaultPath + ":" + userVersion + image = defaultImage + ":" + userVersion case strings.Contains(userImage, ":"): // Fully-qualified userImage? image = userImage diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index d54ebf57a1..7c35a2c9b5 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -48,67 +48,97 @@ func TestCheckVersion(t *testing.T) { } func TestBuildImagePath(t *testing.T) { - defaultImage := "quay.io/cilium/cilium:v1.10.4@sha256:7d354052ccf2a7445101d78cebd14444c7c40129ce7889f2f04b89374dbf8a1d" tests := []struct { - userImage string - userVersion string - imagePathMode ImagePathMode - want string + userImage string + userVersion string + defaultImage string + defaultVersion string + imagePathMode ImagePathMode + want string }{ { - userVersion: "", - imagePathMode: ImagePathIncludeDigest, - want: "quay.io/cilium/cilium:v1.10.4@sha256:7d354052ccf2a7445101d78cebd14444c7c40129ce7889f2f04b89374dbf8a1d", + userVersion: "", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + imagePathMode: ImagePathIncludeDigest, + want: "quay.io/cilium/cilium:v1.10.4@sha256:7d354052ccf2a7445101d78cebd14444c7c40129ce7889f2f04b89374dbf8a1d", }, { - userVersion: "", - want: "quay.io/cilium/cilium:v1.10.4", + userVersion: "", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium:v1.10.4", }, { - userVersion: "v1.9.10", - want: "quay.io/cilium/cilium:v1.9.10", + userVersion: "v1.9.10", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium:v1.9.10", }, { - userVersion: "1.9.10", - want: "quay.io/cilium/cilium:v1.9.10", + userVersion: "1.9.10", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium:v1.9.10", }, { - userVersion: "-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", - want: "quay.io/cilium/cilium-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", + userVersion: "-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", }, { - userVersion: ":latest", - want: "quay.io/cilium/cilium:latest", + userVersion: ":latest", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium:latest", }, { - userImage: "quay.io/cilium/cilium-ci", - userVersion: "v1.9.10", - want: "quay.io/cilium/cilium-ci:v1.9.10", + userImage: "quay.io/cilium/cilium-ci", + userVersion: "v1.9.10", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium-ci:v1.9.10", }, { - userImage: "quay.io/cilium/cilium-ci", - userVersion: "latest", - want: "quay.io/cilium/cilium-ci:latest", + userImage: "quay.io/cilium/cilium-ci", + userVersion: "latest", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium-ci:latest", }, { - userImage: "quay.io/cilium/cilium-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", - want: "quay.io/cilium/cilium-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", + userImage: "quay.io/cilium/cilium-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium-ci:92ff7ffa762f6f8bc397a28e6f3147906e20e8fa", }, { - userVersion: "v1.11.0", - imagePathMode: ImagePathIncludeDigest, - want: "quay.io/cilium/cilium:v1.11.0@sha256:ea677508010800214b0b5497055f38ed3bff57963fa2399bcb1c69cf9476453a", + userVersion: "v1.11.0", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + imagePathMode: ImagePathIncludeDigest, + want: "quay.io/cilium/cilium:v1.11.0@sha256:ea677508010800214b0b5497055f38ed3bff57963fa2399bcb1c69cf9476453a", }, { - userVersion: "v1.11.0", - want: "quay.io/cilium/cilium:v1.11.0", + userVersion: "v1.11.0", + defaultImage: "quay.io/cilium/cilium", + defaultVersion: "v1.10.4", + want: "quay.io/cilium/cilium:v1.11.0", + }, + { + userVersion: "-service-mesh:v1.11.0-beta.1", + defaultImage: "quay.io/cilium/hubble-relay", + defaultVersion: "v1.11.0", + imagePathMode: ImagePathIncludeDigest, + want: "quay.io/cilium/hubble-relay-service-mesh:v1.11.0-beta.1@sha256:db4e82f2905073b99dc9da656a23efb6856833a8a1353f8317a3c52ff5ee53aa", }, } for _, tt := range tests { - ui, uv, di, ipm := tt.userImage, tt.userVersion, defaultImage, tt.imagePathMode - fn := fmt.Sprintf("BuildImagePath(%q, %q, %q, %v)", ui, uv, di, ipm) + ui, uv, di, dv, ipm := tt.userImage, tt.userVersion, tt.defaultImage, tt.defaultVersion, tt.imagePathMode + fn := fmt.Sprintf("BuildImagePath(%q, %q, %q, %q, %v)", ui, uv, di, dv, ipm) t.Run(fn, func(t *testing.T) { - if got := BuildImagePath(ui, uv, di, ipm); got != tt.want { + if got := BuildImagePath(ui, uv, di, dv, ipm); got != tt.want { t.Errorf("%s == %q, want %q", fn, got, tt.want) } })