@@ -880,7 +880,17 @@ sync_cluster_task(Nodes) ->
880880 [] ->
881881 FeatureNames = list_feature_flags_enabled_somewhere (
882882 Inventory , false ),
883- enable_many (Inventory , FeatureNames );
883+
884+ % % In addition to feature flags enabled somewhere, we also
885+ % % ensure required feature flags are enabled accross the
886+ % % board.
887+ RequiredFeatureNames = list_required_feature_flags (
888+ Inventory ),
889+
890+ FeatureNamesToEnable = lists :usort (
891+ FeatureNames ++
892+ RequiredFeatureNames ),
893+ enable_many (Inventory , FeatureNamesToEnable );
884894 _ ->
885895 ? LOG_ERROR (
886896 " Feature flags: the following deprecated features "
@@ -998,7 +1008,7 @@ enable_with_registry_locked(
9981008 [FeatureName ],
9991009 #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
10001010
1001- case check_required_and_enable (Inventory , FeatureName ) of
1011+ case update_feature_state_and_enable (Inventory , FeatureName ) of
10021012 {ok , _Inventory } = Ok ->
10031013 ? LOG_NOTICE (
10041014 " Feature flags: `~ts ` enabled" ,
@@ -1014,91 +1024,6 @@ enable_with_registry_locked(
10141024 end
10151025 end .
10161026
1017- - spec check_required_and_enable (Inventory , FeatureName ) -> Ret when
1018- Inventory :: rabbit_feature_flags :cluster_inventory (),
1019- FeatureName :: rabbit_feature_flags :feature_name (),
1020- Ret :: {ok , Inventory } | {error , Reason },
1021- Reason :: term ().
1022-
1023- check_required_and_enable (
1024- #{feature_flags := FeatureFlags ,
1025- states_per_node := _ } = Inventory ,
1026- FeatureName ) ->
1027- % % Required feature flags vs. virgin nodes.
1028- FeatureProps = maps :get (FeatureName , FeatureFlags ),
1029- Stability = rabbit_feature_flags :get_stability (FeatureProps ),
1030- ProvidedBy = maps :get (provided_by , FeatureProps ),
1031- NodesWhereDisabled = list_nodes_where_feature_flag_is_disabled (
1032- Inventory , FeatureName ),
1033-
1034- MarkDirectly = case Stability of
1035- required when ProvidedBy =:= rabbit ->
1036- ? LOG_DEBUG (
1037- " Feature flags: `~s `: the feature flag is "
1038- " required on some nodes; list virgin nodes "
1039- " to determine if the feature flag can simply "
1040- " be marked as enabled" ,
1041- [FeatureName ],
1042- #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
1043- VirginNodesWhereDisabled =
1044- lists :filter (
1045- fun (Node ) ->
1046- case rabbit_db :is_virgin_node (Node ) of
1047- IsVirgin when is_boolean (IsVirgin ) ->
1048- IsVirgin ;
1049- undefined ->
1050- false
1051- end
1052- end , NodesWhereDisabled ),
1053- VirginNodesWhereDisabled =:= NodesWhereDisabled ;
1054- required when ProvidedBy =/= rabbit ->
1055- % % A plugin can be enabled/disabled at runtime and
1056- % % between restarts. Thus we have no way to
1057- % % distinguish a newly enabled plugin from a plugin
1058- % % which was enabled in the past.
1059- % %
1060- % % Therefore, we always mark required feature flags
1061- % % from plugins directly as enabled. However, the
1062- % % plugin is responsible for checking that its
1063- % % possibly existing data is as it expects it or
1064- % % perform any cleanup/conversion!
1065- ? LOG_DEBUG (
1066- " Feature flags: `~s `: the feature flag is "
1067- " required on some nodes; it comes from a "
1068- " plugin which can be enabled at runtime, "
1069- " so it can be marked as enabled" ,
1070- [FeatureName ],
1071- #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
1072- true ;
1073- _ ->
1074- false
1075- end ,
1076-
1077- case MarkDirectly of
1078- false ->
1079- case Stability of
1080- required ->
1081- ? LOG_DEBUG (
1082- " Feature flags: `~s `: some nodes where the feature "
1083- " flag is disabled are not virgin, we need to perform "
1084- " a regular sync" ,
1085- [FeatureName ],
1086- #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS });
1087- _ ->
1088- ok
1089- end ,
1090- update_feature_state_and_enable (Inventory , FeatureName );
1091- true ->
1092- ? LOG_DEBUG (
1093- " Feature flags: `~s `: all nodes where the feature flag is "
1094- " disabled are virgin, we can directly mark it as enabled "
1095- " there" ,
1096- [FeatureName ],
1097- #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
1098- mark_as_enabled_on_nodes (
1099- NodesWhereDisabled , Inventory , FeatureName , true )
1100- end .
1101-
11021027- spec update_feature_state_and_enable (Inventory , FeatureName ) -> Ret when
11031028 Inventory :: rabbit_feature_flags :cluster_inventory (),
11041029 FeatureName :: rabbit_feature_flags :feature_name (),
@@ -1445,6 +1370,19 @@ list_feature_flags_enabled_somewhere(
14451370 end , #{}, StatesPerNode ),
14461371 lists :sort (maps :keys (MergedStates )).
14471372
1373+ list_required_feature_flags (#{feature_flags := FeatureFlags }) ->
1374+ RequiredFeatureNames = maps :fold (
1375+ fun (FeatureName , FeatureProps , Acc ) ->
1376+ Stability = (
1377+ rabbit_feature_flags :get_stability (
1378+ FeatureProps )),
1379+ case Stability of
1380+ required -> [FeatureName | Acc ];
1381+ _ -> Acc
1382+ end
1383+ end , [], FeatureFlags ),
1384+ lists :sort (RequiredFeatureNames ).
1385+
14481386- spec list_deprecated_features_that_cant_be_denied (Inventory ) ->
14491387 Ret when
14501388 Inventory :: rabbit_feature_flags :cluster_inventory (),
0 commit comments