@@ -686,345 +686,6 @@ var _ = Describe("OpenStackOperator controller", func() {
686686
687687 })
688688
689- // Test that minor updates don't hang when OVN is disabled
690- When ("Minor update with OVN disabled" , func () {
691- var (
692- initialVersion = "old"
693- updatedVersion = "0.0.1"
694- targetRabbitMQVersion = ""
695- targetMariaDBVersion = ""
696- targetMemcachedVersion = ""
697- targetKeystoneAPIVersion = ""
698- testRabbitMQImage = "foo/rabbit:0.0.2"
699- testMariaDBImage = "foo/maria:0.0.2"
700- testMemcachedImage = "foo/memcached:0.0.2"
701- testKeystoneAPIImage = "foo/keystone:0.0.2"
702- )
703-
704- BeforeEach (func () {
705- // Lightweight controlplane spec with OVN DISABLED
706- spec := GetDefaultOpenStackControlPlaneSpec ()
707-
708- // a single galera database
709- galeraTemplate := map [string ]interface {}{
710- names .DBName .Name : map [string ]interface {}{
711- "storageRequest" : "500M" ,
712- },
713- }
714- spec ["galera" ] = map [string ]interface {}{
715- "enabled" : true ,
716- "templates" : galeraTemplate ,
717- }
718-
719- // Disable non-essential services
720- spec ["horizon" ] = map [string ]interface {}{"enabled" : false }
721- spec ["glance" ] = map [string ]interface {}{"enabled" : false }
722- spec ["cinder" ] = map [string ]interface {}{"enabled" : false }
723- spec ["neutron" ] = map [string ]interface {}{"enabled" : false }
724- spec ["manila" ] = map [string ]interface {}{"enabled" : false }
725- spec ["heat" ] = map [string ]interface {}{"enabled" : false }
726- spec ["telemetry" ] = map [string ]interface {}{"enabled" : false }
727- spec ["tls" ] = GetTLSPublicSpec ()
728-
729- // CRITICAL: Disable OVN
730- spec ["ovn" ] = map [string ]interface {}{
731- "enabled" : false ,
732- }
733-
734- DeferCleanup (
735- th .DeleteInstance ,
736- CreateOpenStackVersion (names .OpenStackVersionName , GetDefaultOpenStackVersionSpec ()),
737- )
738-
739- // create cert secrets for rabbitmq instances
740- DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .RabbitMQCertName ))
741- DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .RabbitMQCell1CertName ))
742-
743- // create root CA secrets
744- DeferCleanup (k8sClient .Delete , ctx , CreateCertSecret (names .RootCAPublicName ))
745- DeferCleanup (k8sClient .Delete , ctx , CreateCertSecret (names .RootCAInternalName ))
746- DeferCleanup (k8sClient .Delete , ctx , CreateCertSecret (names .RootCAOvnName ))
747- DeferCleanup (k8sClient .Delete , ctx , CreateCertSecret (names .RootCALibvirtName ))
748-
749- // create cert secrets for galera instances
750- DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .DBCertName ))
751- DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .DBCell1CertName ))
752-
753- // create cert secrets for memcached instance
754- DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .MemcachedCertName ))
755-
756- // wait for initial version to be created (this gives us version 0.0.1)
757- Eventually (func (g Gomega ) {
758- th .ExpectCondition (
759- names .OpenStackVersionName ,
760- ConditionGetterFunc (OpenStackVersionConditionGetter ),
761- corev1 .OpenStackVersionInitialized ,
762- k8s_corev1 .ConditionTrue ,
763- )
764-
765- version := GetOpenStackVersion (names .OpenStackVersionName )
766- // capture target versions
767- targetRabbitMQVersion = * version .Status .ContainerImages .RabbitmqImage
768- targetMariaDBVersion = * version .Status .ContainerImages .MariadbImage
769- targetMemcachedVersion = * version .Status .ContainerImages .InfraMemcachedImage
770- targetKeystoneAPIVersion = * version .Status .ContainerImages .KeystoneAPIImage
771- g .Expect (version ).Should (Not (BeNil ()))
772-
773- g .Expect (* version .Status .AvailableVersion ).Should (ContainSubstring ("0.0.1" ))
774- g .Expect (version .Spec .TargetVersion ).Should (ContainSubstring ("0.0.1" ))
775- updatedVersion = * version .Status .AvailableVersion
776- }, timeout , interval ).Should (Succeed ())
777-
778- // inject an "old" version
779- Eventually (func (g Gomega ) {
780- version := GetOpenStackVersion (names .OpenStackVersionName )
781- version .Status .ContainerImageVersionDefaults [initialVersion ] = version .Status .ContainerImageVersionDefaults [updatedVersion ]
782- version .Status .ContainerImageVersionDefaults [initialVersion ].RabbitmqImage = & testRabbitMQImage
783- version .Status .ContainerImageVersionDefaults [initialVersion ].MariadbImage = & testMariaDBImage
784- version .Status .ContainerImageVersionDefaults [initialVersion ].InfraMemcachedImage = & testMemcachedImage
785- version .Status .ContainerImageVersionDefaults [initialVersion ].KeystoneAPIImage = & testKeystoneAPIImage
786- g .Expect (th .K8sClient .Status ().Update (th .Ctx , version )).To (Succeed ())
787- }, timeout , interval ).Should (Succeed ())
788-
789- Eventually (func (g Gomega ) {
790- version := GetOpenStackVersion (names .OpenStackVersionName )
791- version .Spec .TargetVersion = initialVersion
792- g .Expect (th .K8sClient .Update (th .Ctx , version )).To (Succeed ())
793- }, timeout , interval ).Should (Succeed ())
794-
795- Eventually (func (g Gomega ) {
796- osversion := GetOpenStackVersion (names .OpenStackVersionName )
797- g .Expect (osversion ).Should (Not (BeNil ()))
798- g .Expect (osversion .Generation ).Should (Equal (osversion .Status .ObservedGeneration ))
799-
800- th .ExpectCondition (
801- names .OpenStackVersionName ,
802- ConditionGetterFunc (OpenStackVersionConditionGetter ),
803- corev1 .OpenStackVersionInitialized ,
804- k8s_corev1 .ConditionTrue ,
805- )
806-
807- g .Expect (* osversion .Status .AvailableVersion ).Should (Equal (updatedVersion ))
808- g .Expect (osversion .Spec .TargetVersion ).Should (Equal (initialVersion ))
809- g .Expect (osversion .Status .DeployedVersion ).Should (BeNil ())
810- }, timeout , interval ).Should (Succeed ())
811-
812- DeferCleanup (
813- th .DeleteInstance ,
814- CreateOpenStackControlPlane (names .OpenStackControlplaneName , spec ),
815- )
816-
817- DeferCleanup (
818- th .DeleteInstance ,
819- CreateDataplaneNodeSet (names .OpenStackVersionName , DefaultDataPlaneNoNodeSetSpec (false )),
820- )
821-
822- dataplanenodeset := GetDataplaneNodeset (names .OpenStackVersionName )
823- dataplanenodeset .Status .DeployedVersion = initialVersion
824- Expect (th .K8sClient .Status ().Update (th .Ctx , dataplanenodeset )).To (Succeed ())
825-
826- th .CreateSecret (types.NamespacedName {Name : "openstack-config-secret" , Namespace : namespace }, map [string ][]byte {"secure.yaml" : []byte ("foo" )})
827- th .CreateConfigMap (types.NamespacedName {Name : "openstack-config" , Namespace : namespace }, map [string ]interface {}{"clouds.yaml" : string ("foo" ), "OS_CLOUD" : "default" })
828-
829- // Verify OVN is disabled
830- OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
831- Expect (OSCtlplane .Spec .Ovn .Enabled ).Should (BeFalse ())
832-
833- SimulateControlplaneReady ()
834-
835- // verify that DeployedVersion is set
836- Eventually (func (g Gomega ) {
837- th .ExpectCondition (
838- names .OpenStackControlplaneName ,
839- ConditionGetterFunc (OpenStackControlPlaneConditionGetter ),
840- condition .ReadyCondition ,
841- k8s_corev1 .ConditionTrue ,
842- )
843- OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
844- g .Expect (OSCtlplane .Status .DeployedVersion ).Should (Equal (& initialVersion ))
845- }, timeout , interval ).Should (Succeed ())
846-
847- // verify DeployedVersion also gets set on the OpenStackVersion resource
848- Eventually (func (g Gomega ) {
849- osversion := GetOpenStackVersion (names .OpenStackVersionName )
850- g .Expect (osversion ).Should (Not (BeNil ()))
851- g .Expect (osversion .Generation ).Should (Equal (osversion .Status .ObservedGeneration ))
852- g .Expect (osversion .Status .DeployedVersion ).Should (Equal (& initialVersion ))
853- }, timeout , interval ).Should (Succeed ())
854- })
855-
856- It ("updating targetVersion should not hang on OVN checks" , Serial , func () {
857- // Trigger minor update by switching to updated version
858- osversion := GetOpenStackVersion (names .OpenStackVersionName )
859-
860- // should have a condition which reflects an update is available
861- th .ExpectCondition (
862- names .OpenStackVersionName ,
863- ConditionGetterFunc (OpenStackVersionConditionGetter ),
864- corev1 .OpenStackVersionMinorUpdateAvailable ,
865- k8s_corev1 .ConditionTrue ,
866- )
867-
868- osversion .Spec .TargetVersion = updatedVersion
869- Expect (k8sClient .Update (ctx , osversion )).Should (Succeed ())
870-
871- // Verify the OpenStackVersion gets re-initialized with new version
872- Eventually (func (g Gomega ) {
873- osversion := GetOpenStackVersion (names .OpenStackVersionName )
874- g .Expect (osversion ).Should (Not (BeNil ()))
875- g .Expect (osversion .Generation ).Should (Equal (osversion .Status .ObservedGeneration ))
876-
877- th .ExpectCondition (
878- names .OpenStackVersionName ,
879- ConditionGetterFunc (OpenStackVersionConditionGetter ),
880- corev1 .OpenStackVersionInitialized ,
881- k8s_corev1 .ConditionTrue ,
882- )
883-
884- g .Expect (* osversion .Status .AvailableVersion ).Should (Equal (updatedVersion ))
885- g .Expect (osversion .Spec .TargetVersion ).Should (Equal (updatedVersion ))
886- // target images should be set
887- g .Expect (* osversion .Status .ContainerImages .RabbitmqImage ).Should (Equal (targetRabbitMQVersion ))
888- g .Expect (* osversion .Status .ContainerImages .MariadbImage ).Should (Equal (targetMariaDBVersion ))
889- g .Expect (* osversion .Status .ContainerImages .InfraMemcachedImage ).Should (Equal (targetMemcachedVersion ))
890- g .Expect (* osversion .Status .ContainerImages .KeystoneAPIImage ).Should (Equal (targetKeystoneAPIVersion ))
891- }, timeout , interval ).Should (Succeed ())
892-
893- // CRITICAL: Verify that OVN controlplane update condition is immediately set to true (not hanging)
894- // This is the key assertion that proves the bug is fixed
895- Eventually (func (g Gomega ) {
896- osversion := GetOpenStackVersion (names .OpenStackVersionName )
897- g .Expect (osversion ).Should (Not (BeNil ()))
898-
899- // The OVN update condition should be true because OVN is disabled
900- th .ExpectCondition (
901- names .OpenStackVersionName ,
902- ConditionGetterFunc (OpenStackVersionConditionGetter ),
903- corev1 .OpenStackVersionMinorUpdateOVNControlplane ,
904- k8s_corev1 .ConditionTrue ,
905- )
906- }, timeout , interval ).Should (Succeed ())
907-
908- // Verify OVN dataplane update also proceeds
909- Eventually (func (_ Gomega ) {
910- th .ExpectCondition (
911- names .OpenStackVersionName ,
912- ConditionGetterFunc (OpenStackVersionConditionGetter ),
913- corev1 .OpenStackVersionMinorUpdateOVNDataplane ,
914- k8s_corev1 .ConditionTrue ,
915- )
916- }, timeout , interval ).Should (Succeed ())
917-
918- // Continue with infrastructure services
919- th .ExpectCondition (
920- names .OpenStackVersionName ,
921- ConditionGetterFunc (OpenStackVersionConditionGetter ),
922- corev1 .OpenStackVersionMinorUpdateRabbitMQ ,
923- k8s_corev1 .ConditionFalse ,
924- )
925-
926- SimulateRabbitmqReady ()
927- Eventually (func (g Gomega ) {
928- th .ExpectCondition (
929- names .OpenStackVersionName ,
930- ConditionGetterFunc (OpenStackVersionConditionGetter ),
931- corev1 .OpenStackVersionMinorUpdateRabbitMQ ,
932- k8s_corev1 .ConditionTrue ,
933- )
934-
935- OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
936- g .Expect (* OSCtlplane .Status .ContainerImages .RabbitmqImage ).Should (Equal (targetRabbitMQVersion ))
937- }, timeout * 4 , interval ).Should (Succeed ())
938-
939- SimulateGalaraReady ()
940- Eventually (func (g Gomega ) {
941- th .ExpectCondition (
942- names .OpenStackVersionName ,
943- ConditionGetterFunc (OpenStackVersionConditionGetter ),
944- corev1 .OpenStackVersionMinorUpdateMariaDB ,
945- k8s_corev1 .ConditionTrue ,
946- )
947- OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
948- g .Expect (* OSCtlplane .Status .ContainerImages .MariadbImage ).Should (Equal (targetMariaDBVersion ))
949- }, timeout , interval ).Should (Succeed ())
950-
951- SimulateMemcachedReady ()
952- Eventually (func (g Gomega ) {
953- th .ExpectCondition (
954- names .OpenStackVersionName ,
955- ConditionGetterFunc (OpenStackVersionConditionGetter ),
956- corev1 .OpenStackVersionMinorUpdateMemcached ,
957- k8s_corev1 .ConditionTrue ,
958- )
959- OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
960- g .Expect (* OSCtlplane .Status .ContainerImages .InfraMemcachedImage ).Should (Equal (targetMemcachedVersion ))
961- }, timeout , interval ).Should (Succeed ())
962-
963- keystone .SimulateKeystoneAPIReady (names .KeystoneAPIName )
964- Eventually (func (g Gomega ) {
965- th .ExpectCondition (
966- names .OpenStackVersionName ,
967- ConditionGetterFunc (OpenStackVersionConditionGetter ),
968- corev1 .OpenStackVersionMinorUpdateKeystone ,
969- k8s_corev1 .ConditionTrue ,
970- )
971-
972- osversion := GetOpenStackVersion (names .OpenStackVersionName )
973- OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
974- g .Expect (OSCtlplane .Status .ContainerImages .KeystoneAPIImage ).Should (Equal (osversion .Status .ContainerImages .KeystoneAPIImage ))
975- }, timeout , interval ).Should (Succeed ())
976-
977- // Simulate controlplane ready
978- SimulateControlplaneReady ()
979- Eventually (func (g Gomega ) {
980- th .ExpectCondition (
981- names .OpenStackVersionName ,
982- ConditionGetterFunc (OpenStackVersionConditionGetter ),
983- corev1 .OpenStackVersionMinorUpdateControlplane ,
984- k8s_corev1 .ConditionTrue ,
985- )
986- th .ExpectCondition (
987- names .OpenStackControlplaneName ,
988- ConditionGetterFunc (OpenStackControlPlaneConditionGetter ),
989- condition .ReadyCondition ,
990- k8s_corev1 .ConditionTrue ,
991- )
992-
993- osversion := GetOpenStackVersion (names .OpenStackVersionName )
994- OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
995- // verify images match
996- g .Expect (OSCtlplane .Status .ContainerImages .RabbitmqImage ).Should (Equal (osversion .Status .ContainerImages .RabbitmqImage ))
997- g .Expect (OSCtlplane .Status .ContainerImages .MariadbImage ).Should (Equal (osversion .Status .ContainerImages .MariadbImage ))
998- g .Expect (OSCtlplane .Status .ContainerImages .KeystoneAPIImage ).Should (Equal (osversion .Status .ContainerImages .KeystoneAPIImage ))
999- g .Expect (OSCtlplane .Status .ContainerImages .InfraMemcachedImage ).Should (Equal (osversion .Status .ContainerImages .InfraMemcachedImage ))
1000- }, timeout , interval ).Should (Succeed ())
1001-
1002- // Simulate dataplane deployment complete
1003- dataplanenodeset := GetDataplaneNodeset (names .OpenStackVersionName )
1004- dataplanenodeset .Status .ObservedGeneration = dataplanenodeset .Generation
1005- dataplanenodeset .Status .DeployedVersion = osversion .Spec .TargetVersion
1006- dataplanenodeset .Status .Conditions .MarkTrue (condition .ReadyCondition , dataplanev1 .NodeSetReadyMessage )
1007- Expect (th .K8sClient .Status ().Update (th .Ctx , dataplanenodeset )).To (Succeed ())
1008-
1009- // Verify minor update completes successfully
1010- Eventually (func (g Gomega ) {
1011- osversion := GetOpenStackVersion (names .OpenStackVersionName )
1012- g .Expect (osversion ).Should (Not (BeNil ()))
1013- g .Expect (osversion .OwnerReferences ).Should (HaveLen (1 ))
1014- th .ExpectCondition (
1015- names .OpenStackVersionName ,
1016- ConditionGetterFunc (OpenStackVersionConditionGetter ),
1017- condition .ReadyCondition ,
1018- k8s_corev1 .ConditionTrue ,
1019- )
1020- g .Expect (osversion .Status .DeployedVersion ).Should (Equal (& updatedVersion ))
1021- // no condition which reflects an update is available
1022- g .Expect (osversion .Status .Conditions .Has (corev1 .OpenStackVersionMinorUpdateAvailable )).To (BeFalse ())
1023- }, timeout , interval ).Should (Succeed ())
1024- })
1025-
1026- })
1027-
1028689 When ("CustomContainerImages are set" , func () {
1029690 var (
1030691 initialVersion = "0.0.1"
0 commit comments