@@ -741,9 +741,7 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
741
741
if err != nil {
742
742
syncError = err
743
743
logger .WithError (err ).Warn ("csv has invalid installmodes" )
744
- if out .Status .Reason != v1alpha1 .CSVReasonInvalidInstallModes {
745
- out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonInvalidInstallModes , syncError .Error (), now , a .recorder )
746
- }
744
+ out .SetPhaseWithEventIfChanged (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonInvalidInstallModes , syncError .Error (), now , a .recorder )
747
745
return
748
746
}
749
747
@@ -754,16 +752,12 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
754
752
755
753
if err := modeSet .Supports (out .GetNamespace (), namespaces ); err != nil {
756
754
logger .WithField ("reason" , err .Error ()).Info ("installmodeset does not support operatorgroups namespace selection" )
757
- if out .Status .Reason != v1alpha1 .CSVReasonUnsupportedOperatorGroup {
758
- out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonUnsupportedOperatorGroup , err .Error (), now , a .recorder )
759
- }
755
+ out .SetPhaseWithEventIfChanged (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonUnsupportedOperatorGroup , err .Error (), now , a .recorder )
760
756
return
761
757
}
762
758
} else {
763
759
logger .Info ("csv missing olm.targetNamespaces annotation" )
764
- if out .Status .Reason != v1alpha1 .CSVReasonNoTargetNamespaces {
765
- out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonNoTargetNamespaces , "csv missing olm.targetNamespaces annotation" , now , a .recorder )
766
- }
760
+ out .SetPhaseWithEventIfChanged (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonNoTargetNamespaces , "csv missing olm.targetNamespaces annotation" , now , a .recorder )
767
761
return
768
762
}
769
763
@@ -855,6 +849,7 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
855
849
}
856
850
857
851
// Check for CRD ownership conflicts
852
+ // TODO: find CSVs that provide any of those that out does across all namespaces
858
853
csvSet := a .csvSet (out .GetNamespace (), v1alpha1 .CSVPhaseAny )
859
854
if syncError = a .crdOwnerConflicts (out , csvSet ); syncError != nil {
860
855
out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonOwnerConflict , fmt .Sprintf ("crd owner conflict: %s" , syncError ), now , a .recorder )
@@ -893,6 +888,7 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
893
888
a .Log .Warn (err .Error ())
894
889
}
895
890
return
891
+
896
892
case v1alpha1 .CSVPhaseInstalling :
897
893
installer , strategy , _ := a .parseStrategiesAndUpdateStatus (out )
898
894
if strategy == nil {
@@ -902,15 +898,22 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
902
898
if installErr := a .updateInstallStatus (out , installer , strategy , v1alpha1 .CSVPhaseInstalling , v1alpha1 .CSVReasonWaiting ); installErr == nil {
903
899
logger .WithField ("strategy" , out .Spec .InstallStrategy .StrategyName ).Infof ("install strategy successful" )
904
900
}
901
+
905
902
case v1alpha1 .CSVPhaseSucceeded :
906
903
installer , strategy , _ := a .parseStrategiesAndUpdateStatus (out )
907
904
if strategy == nil {
908
905
return
909
906
}
910
907
911
- // Check install status
912
- if installErr := a .updateInstallStatus (out , installer , strategy , v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonComponentUnhealthy ); installErr != nil {
913
- logger .WithField ("strategy" , out .Spec .InstallStrategy .StrategyName ).Warnf ("unhealthy component: %s" , installErr )
908
+ // Check if any generated resources are missing
909
+ if err := a .checkAPIServiceResources (out , certs .PEMSHA256 ); err != nil {
910
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonAPIServiceResourceIssue , err .Error (), now , a .recorder )
911
+ return
912
+ }
913
+
914
+ // Check if it's time to refresh owned APIService certs
915
+ if a .shouldRotateCerts (out ) {
916
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonNeedsCertRotation , "owned APIServices need cert refresh" , now , a .recorder )
914
917
return
915
918
}
916
919
@@ -926,15 +929,9 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
926
929
return
927
930
}
928
931
929
- // Check if any generated resources are missing
930
- if resErr := a .checkAPIServiceResources (out , certs .PEMSHA256 ); len (resErr ) > 0 {
931
- out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonAPIServiceResourceIssue , resErr [0 ].Error (), now , a .recorder )
932
- return
933
- }
934
-
935
- // Check if it's time to refresh owned APIService certs
936
- if a .shouldRotateCerts (out ) {
937
- out .SetPhaseWithEvent (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonNeedsCertRotation , "owned APIServices need cert refresh" , now , a .recorder )
932
+ // Check install status
933
+ if installErr := a .updateInstallStatus (out , installer , strategy , v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonComponentUnhealthy ); installErr != nil {
934
+ logger .WithField ("strategy" , out .Spec .InstallStrategy .StrategyName ).Warnf ("unhealthy component: %s" , installErr )
938
935
return
939
936
}
940
937
@@ -971,15 +968,9 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
971
968
return
972
969
}
973
970
974
- // Check install status
975
- if installErr := a .updateInstallStatus (out , installer , strategy , v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonNeedsReinstall ); installErr != nil {
976
- logger .WithField ("strategy" , out .Spec .InstallStrategy .StrategyName ).Warnf ("needs reinstall: %s" , installErr )
977
- return
978
- }
979
-
980
971
// Check if requirements exist
981
972
met , statuses , err := a .requirementAndPermissionStatus (out )
982
- if err != nil {
973
+ if err != nil && out . Status . Reason != v1alpha1 . CSVReasonInvalidStrategy {
983
974
logger .Warn ("invalid install strategy" )
984
975
out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonInvalidStrategy , fmt .Sprintf ("install strategy invalid: %s" , err .Error ()), now , a .recorder )
985
976
return
@@ -989,20 +980,24 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
989
980
return
990
981
}
991
982
992
- // Check if any generated resources are missing
993
- if resErr := a .checkAPIServiceResources (out , certs .PEMSHA256 ); len ( resErr ) > 0 {
983
+ // Check if any generated resources are missing and that OLM can action on them
984
+ if err := a .checkAPIServiceResources (out , certs .PEMSHA256 ); err != nil && a . apiServiceResourceErrorActionable ( err ) {
994
985
// Check if API services are adoptable. If not, keep CSV as Failed state
995
- if a .apiServiceResourceErrorsActionable (resErr ) {
996
- out .SetPhaseWithEvent (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonAPIServiceResourcesNeedReinstall , resErr [0 ].Error (), now , a .recorder )
997
- return
998
- }
986
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonAPIServiceResourcesNeedReinstall , err .Error (), now , a .recorder )
987
+ return
999
988
}
1000
989
1001
990
// Check if it's time to refresh owned APIService certs
1002
991
if a .shouldRotateCerts (out ) {
1003
992
out .SetPhaseWithEvent (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonNeedsCertRotation , "owned APIServices need cert refresh" , now , a .recorder )
1004
993
return
1005
994
}
995
+
996
+ // Check install status
997
+ if installErr := a .updateInstallStatus (out , installer , strategy , v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonNeedsReinstall ); installErr != nil {
998
+ logger .WithField ("strategy" , out .Spec .InstallStrategy .StrategyName ).Warnf ("needs reinstall: %s" , installErr )
999
+ }
1000
+
1006
1001
case v1alpha1 .CSVPhaseReplacing :
1007
1002
// determine CSVs that are safe to delete by finding a replacement chain to a CSV that's running
1008
1003
// since we don't know what order we'll process replacements, we have to guard against breaking that chain
@@ -1109,41 +1104,38 @@ func (a *Operator) checkReplacementsAndUpdateStatus(csv *v1alpha1.ClusterService
1109
1104
}
1110
1105
1111
1106
func (a * Operator ) updateInstallStatus (csv * v1alpha1.ClusterServiceVersion , installer install.StrategyInstaller , strategy install.Strategy , requeuePhase v1alpha1.ClusterServiceVersionPhase , requeueConditionReason v1alpha1.ConditionReason ) error {
1112
- apiServicesInstalled , apiServiceErr := a .areAPIServicesAvailable (csv . Spec . APIServiceDefinitions . Owned )
1107
+ apiServicesInstalled , apiServiceErr := a .areAPIServicesAvailable (csv )
1113
1108
strategyInstalled , strategyErr := installer .CheckInstalled (strategy )
1114
1109
now := timeNow ()
1115
1110
1116
1111
if strategyInstalled && apiServicesInstalled {
1117
1112
// if there's no error, we're successfully running
1118
- if csv .Status .Phase != v1alpha1 .CSVPhaseSucceeded {
1119
- csv .SetPhaseWithEvent (v1alpha1 .CSVPhaseSucceeded , v1alpha1 .CSVReasonInstallSuccessful , "install strategy completed with no errors" , now , a .recorder )
1120
- }
1113
+ csv .SetPhaseWithEventIfChanged (v1alpha1 .CSVPhaseSucceeded , v1alpha1 .CSVReasonInstallSuccessful , "install strategy completed with no errors" , now , a .recorder )
1121
1114
return nil
1122
1115
}
1123
1116
1124
1117
// installcheck determined we can't progress (e.g. deployment failed to come up in time)
1125
1118
if install .IsErrorUnrecoverable (strategyErr ) {
1126
- csv .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonInstallCheckFailed , fmt .Sprintf ("install failed: %s" , strategyErr ), now , a .recorder )
1119
+ csv .SetPhaseWithEventIfChanged (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonInstallCheckFailed , fmt .Sprintf ("install failed: %s" , strategyErr ), now , a .recorder )
1127
1120
return strategyErr
1128
1121
}
1129
1122
1130
1123
if apiServiceErr != nil {
1131
- csv .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonAPIServiceInstallFailed , fmt .Sprintf ("APIService install failed: %s" , apiServiceErr ), now , a .recorder )
1124
+ csv .SetPhaseWithEventIfChanged (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonAPIServiceInstallFailed , fmt .Sprintf ("APIService install failed: %s" , apiServiceErr ), now , a .recorder )
1132
1125
return apiServiceErr
1133
1126
}
1134
1127
1135
1128
if ! apiServicesInstalled {
1136
- csv .SetPhaseWithEvent (requeuePhase , requeueConditionReason , fmt .Sprintf ("APIServices not installed" ), now , a .recorder )
1137
- err := a .csvQueueSet .Requeue (csv .GetName (), csv .GetNamespace ())
1138
- if err != nil {
1129
+ csv .SetPhaseWithEventIfChanged (requeuePhase , requeueConditionReason , fmt .Sprintf ("APIServices not installed" ), now , a .recorder )
1130
+ if err := a .csvQueueSet .Requeue (csv .GetName (), csv .GetNamespace ()); err != nil {
1139
1131
a .Log .Warn (err .Error ())
1140
1132
}
1141
1133
1142
1134
return fmt .Errorf ("APIServices not installed" )
1143
1135
}
1144
1136
1145
1137
if strategyErr != nil {
1146
- csv .SetPhaseWithEvent (requeuePhase , requeueConditionReason , fmt .Sprintf ("installing: %s" , strategyErr ), now , a .recorder )
1138
+ csv .SetPhaseWithEventIfChanged (requeuePhase , requeueConditionReason , fmt .Sprintf ("installing: %s" , strategyErr ), now , a .recorder )
1147
1139
return strategyErr
1148
1140
}
1149
1141
@@ -1178,23 +1170,20 @@ func (a *Operator) parseStrategiesAndUpdateStatus(csv *v1alpha1.ClusterServiceVe
1178
1170
}
1179
1171
1180
1172
func (a * Operator ) crdOwnerConflicts (in * v1alpha1.ClusterServiceVersion , csvsInNamespace map [string ]* v1alpha1.ClusterServiceVersion ) error {
1181
- owned := false
1182
1173
for _ , crd := range in .Spec .CustomResourceDefinitions .Owned {
1183
1174
for csvName , csv := range csvsInNamespace {
1184
1175
if csvName == in .GetName () {
1185
1176
continue
1186
1177
}
1187
1178
if csv .OwnsCRD (crd .Name ) {
1188
- owned = true
1189
- }
1190
- if owned && in . Spec . Replaces == csvName {
1191
- return nil
1179
+ if in . Spec . Replaces == csvName {
1180
+ return nil
1181
+ }
1182
+ return ErrCRDOwnerConflict
1192
1183
}
1193
1184
}
1194
1185
}
1195
- if owned {
1196
- return ErrCRDOwnerConflict
1197
- }
1186
+
1198
1187
return nil
1199
1188
}
1200
1189
0 commit comments