@@ -184,6 +184,91 @@ var _ = Describe("InstanceHa Controller", func() {
184184 })
185185 })
186186
187+ When ("container image resolution" , func () {
188+ BeforeEach (func () {
189+ DeferCleanup (k8sClient .Delete , ctx , th .CreateConfigMap (types.NamespacedName {
190+ Name : "openstack-config" ,
191+ Namespace : namespace ,
192+ }, map [string ]any {
193+ "clouds.yaml" : "test-data" ,
194+ }))
195+
196+ DeferCleanup (k8sClient .Delete , ctx , th .CreateSecret (types.NamespacedName {
197+ Name : "openstack-config-secret" ,
198+ Namespace : namespace ,
199+ }, map [string ][]byte {
200+ "secure.yaml" : []byte ("test-data" ),
201+ }))
202+
203+ DeferCleanup (k8sClient .Delete , ctx , th .CreateSecret (types.NamespacedName {
204+ Name : "fencing-secret" ,
205+ Namespace : namespace ,
206+ }, map [string ][]byte {
207+ "fencing.yaml" : []byte ("test-data" ),
208+ }))
209+ })
210+
211+ It ("should use explicit containerImage from the CR when set" , func () {
212+ spec := GetDefaultInstanceHaSpec ()
213+ spec ["containerImage" ] = "my-custom-image:v1"
214+ ih := CreateInstanceHaConfig (namespace , spec )
215+ instanceHaName .Name = ih .GetName ()
216+ instanceHaName .Namespace = ih .GetNamespace ()
217+ DeferCleanup (th .DeleteInstance , ih )
218+
219+ // Also create the ConfigMap to ensure CR takes precedence
220+ DeferCleanup (k8sClient .Delete , ctx , th .CreateConfigMap (types.NamespacedName {
221+ Name : "infra-instanceha-config" ,
222+ Namespace : namespace ,
223+ }, map [string ]any {
224+ "instanceha-image" : "configmap-image:latest" ,
225+ }))
226+
227+ Eventually (func (g Gomega ) {
228+ dep := & appsv1.Deployment {}
229+ g .Expect (k8sClient .Get (ctx , instanceHaName , dep )).Should (Succeed ())
230+ g .Expect (dep .Spec .Template .Spec .Containers [0 ].Image ).To (Equal ("my-custom-image:v1" ))
231+ }, timeout , interval ).Should (Succeed ())
232+ })
233+
234+ It ("should use ConfigMap image when containerImage is not set on the CR" , func () {
235+ spec := GetDefaultInstanceHaSpec ()
236+ delete (spec , "containerImage" )
237+ ih := CreateInstanceHaConfig (namespace , spec )
238+ instanceHaName .Name = ih .GetName ()
239+ instanceHaName .Namespace = ih .GetNamespace ()
240+ DeferCleanup (th .DeleteInstance , ih )
241+
242+ DeferCleanup (k8sClient .Delete , ctx , th .CreateConfigMap (types.NamespacedName {
243+ Name : "infra-instanceha-config" ,
244+ Namespace : namespace ,
245+ }, map [string ]any {
246+ "instanceha-image" : "configmap-image:latest" ,
247+ }))
248+
249+ Eventually (func (g Gomega ) {
250+ dep := & appsv1.Deployment {}
251+ g .Expect (k8sClient .Get (ctx , instanceHaName , dep )).Should (Succeed ())
252+ g .Expect (dep .Spec .Template .Spec .Containers [0 ].Image ).To (Equal ("configmap-image:latest" ))
253+ }, timeout , interval ).Should (Succeed ())
254+ })
255+
256+ It ("should fall back to the default image when neither CR nor ConfigMap provide one" , func () {
257+ spec := GetDefaultInstanceHaSpec ()
258+ delete (spec , "containerImage" )
259+ ih := CreateInstanceHaConfig (namespace , spec )
260+ instanceHaName .Name = ih .GetName ()
261+ instanceHaName .Namespace = ih .GetNamespace ()
262+ DeferCleanup (th .DeleteInstance , ih )
263+
264+ Eventually (func (g Gomega ) {
265+ dep := & appsv1.Deployment {}
266+ g .Expect (k8sClient .Get (ctx , instanceHaName , dep )).Should (Succeed ())
267+ g .Expect (dep .Spec .Template .Spec .Containers [0 ].Image ).To (Equal (instancehav1 .InstanceHaContainerImage ))
268+ }, timeout , interval ).Should (Succeed ())
269+ })
270+ })
271+
187272 When ("MetricsTLS is configured without the TLS secret" , func () {
188273 BeforeEach (func () {
189274 spec := GetDefaultInstanceHaSpec ()
0 commit comments