@@ -675,48 +675,64 @@ enable_task(FeatureNames) ->
675675 end .
676676
677677enable_default_task () ->
678- FeatureNames = get_forced_feature_flag_names (),
679- case FeatureNames of
678+ Ret = get_forced_feature_flag_names (),
679+ case Ret of
680680 undefined ->
681681 ? LOG_DEBUG (
682682 " Feature flags: starting an unclustered node for the first "
683683 " time: all stable feature flags will be enabled by default" ,
684684 #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
685685 {ok , Inventory } = collect_inventory_on_nodes ([node ()]),
686- #{feature_flags := FeatureFlags } = Inventory ,
687- StableFeatureNames =
688- maps :fold (
689- fun (FeatureName , FeatureProps , Acc ) ->
690- Stability = rabbit_feature_flags :get_stability (
691- FeatureProps ),
692- case Stability of
693- stable -> [FeatureName | Acc ];
694- _ -> Acc
695- end
696- end , [], FeatureFlags ),
686+ StableFeatureNames = get_stable_feature_flags (Inventory ),
697687 enable_many (Inventory , StableFeatureNames );
698- [] ->
688+ { abs , []} ->
699689 ? LOG_DEBUG (
700690 " Feature flags: starting an unclustered node for the first "
701691 " time: all feature flags are forcibly left disabled from "
702692 " the $RABBITMQ_FEATURE_FLAGS environment variable" ,
703693 #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
704694 ok ;
705- _ ->
695+ { abs , FeatureNames } ->
706696 ? LOG_DEBUG (
707697 " Feature flags: starting an unclustered node for the first "
708698 " time: only the following feature flags specified in the "
709699 " $RABBITMQ_FEATURE_FLAGS environment variable will be enabled: "
710- " ~tp " ,
700+ " ~0tp " ,
711701 [FeatureNames ],
712702 #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
713703 {ok , Inventory } = collect_inventory_on_nodes ([node ()]),
704+ enable_many (Inventory , FeatureNames );
705+ {rel , Plus , Minus } ->
706+ ? LOG_DEBUG (
707+ " Feature flags: starting an unclustered node for the first "
708+ " time: all stable feature flags will be enabled, after "
709+ " applying changes from $RABBITMQ_FEATURE_FLAGS: adding ~0tp , "
710+ " skipping ~0tp " ,
711+ [Plus , Minus ],
712+ #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS }),
713+ {ok , Inventory } = collect_inventory_on_nodes ([node ()]),
714+ StableFeatureNames = get_stable_feature_flags (Inventory ),
715+ FeatureNames = (StableFeatureNames -- Minus ) ++ Plus ,
714716 enable_many (Inventory , FeatureNames )
715717 end .
716718
719+ get_stable_feature_flags (#{feature_flags := FeatureFlags }) ->
720+ maps :fold (
721+ fun (FeatureName , FeatureProps , Acc ) ->
722+ Stability = rabbit_feature_flags :get_stability (FeatureProps ),
723+ case Stability of
724+ stable -> [FeatureName | Acc ];
725+ _ -> Acc
726+ end
727+ end , [], FeatureFlags ).
728+
717729-spec get_forced_feature_flag_names () -> Ret when
718- Ret :: FeatureNames | undefined ,
719- FeatureNames :: [rabbit_feature_flags :feature_name ()].
730+ Ret :: Abs | Rel | undefined ,
731+ Abs :: {abs , AbsNames },
732+ AbsNames :: [rabbit_feature_flags :feature_name ()],
733+ Rel :: {rel , PlusNames , MinusNames },
734+ PlusNames :: [rabbit_feature_flags :feature_name ()],
735+ MinusNames :: [rabbit_feature_flags :feature_name ()].
720736% % @doc Returns the (possibly empty) list of feature flags the user wants to
721737% % enable out-of-the-box when starting a node for the first time.
722738% %
@@ -737,59 +753,70 @@ enable_default_task() ->
737753% % @private
738754
739755get_forced_feature_flag_names () ->
740- Ret = case get_forced_feature_flag_names_from_env () of
741- undefined -> get_forced_feature_flag_names_from_config ();
742- List -> List
743- end ,
744- case Ret of
756+ Value = case get_forced_feature_flag_names_from_env () of
757+ undefined -> get_forced_feature_flag_names_from_config ();
758+ List -> List
759+ end ,
760+ case Value of
745761 undefined ->
746- ok ;
762+ Value ;
747763 [] ->
748- ? LOG_INFO (
749- " Feature flags: automatic enablement of feature flags "
750- " disabled (i.e. none will be enabled automatically)" ,
751- #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS });
752- _ ->
753- ? LOG_INFO (
754- " Feature flags: automatic enablement of feature flags "
755- " limited to the following list: ~tp " ,
756- [Ret ],
757- #{domain => ? RMQLOG_DOMAIN_FEAT_FLAGS })
758- end ,
759- Ret .
764+ {abs , Value };
765+ [[Op | _ ] | _ ] when Op =:= $+ orelse Op =:= $- ->
766+ lists :foldr (
767+ fun
768+ ([$+ | NameS ], {rel , Plus , Minus }) ->
769+ Name = list_to_atom (NameS ),
770+ Plus1 = [Name | Plus ],
771+ {rel , Plus1 , Minus };
772+ ([$- | NameS ], {rel , Plus , Minus }) ->
773+ Name = list_to_atom (NameS ),
774+ Minus1 = [Name | Minus ],
775+ {rel , Plus , Minus1 }
776+ end , {rel , [], []}, Value );
777+ _ when is_list (Value ) ->
778+ lists :foldr (
779+ fun
780+ (Name , {abs , Abs })
781+ when is_atom (Name ) ->
782+ Abs1 = [Name | Abs ],
783+ {abs , Abs1 };
784+ ([C | _ ] = NameS , {abs , Abs })
785+ when C =/= $+ andalso C =/= $- ->
786+ Name = list_to_atom (NameS ),
787+ Abs1 = [Name | Abs ],
788+ {abs , Abs1 }
789+ end , {abs , []}, Value )
790+ end .
760791
761792- spec get_forced_feature_flag_names_from_env () -> Ret when
762793 Ret :: FeatureNames | undefined ,
763- FeatureNames :: [rabbit_feature_flags :feature_name ()].
794+ FeatureNames :: [rabbit_feature_flags :feature_name () | string () ].
764795% % @private
765796
766797get_forced_feature_flag_names_from_env () ->
767798 case rabbit_prelaunch :get_context () of
768799 #{forced_feature_flags_on_init := ForcedFFs }
769800 when is_list (ForcedFFs ) ->
770801 ForcedFFs ;
802+ #{forced_feature_flags_on_init := {'+' , List } = ForcedFFs }
803+ when is_list (List ) ->
804+ ForcedFFs ;
771805 _ ->
772806 undefined
773807 end .
774808
775809- spec get_forced_feature_flag_names_from_config () -> Ret when
776810 Ret :: FeatureNames | undefined ,
777- FeatureNames :: [rabbit_feature_flags :feature_name ()].
811+ FeatureNames :: [rabbit_feature_flags :feature_name () | string () ].
778812% % @private
779813
780814get_forced_feature_flag_names_from_config () ->
781815 Value = application :get_env (
782816 rabbit , forced_feature_flags_on_init , undefined ),
783817 case Value of
784- undefined ->
785- Value ;
786- _ when is_list (Value ) ->
787- case lists :all (fun is_atom /1 , Value ) of
788- true -> Value ;
789- false -> undefined
790- end ;
791- _ ->
792- undefined
818+ undefined -> Value ;
819+ _ when is_list (Value ) -> Value
793820 end .
794821
795822- spec sync_cluster_task () -> Ret when
0 commit comments