Browse Source

Merge pull request #13526 from ieQu1/replicant-ee

fix(mria): Reserve replicant role for EE only
ieQu1 1 năm trước cách đây
mục cha
commit
18721d05bc

+ 5 - 4
.github/workflows/run_docker_tests.yaml

@@ -69,7 +69,6 @@ jobs:
         shell: bash
     env:
       EMQX_NAME: ${{ matrix.profile }}
-      _EMQX_TEST_DB_BACKEND: ${{ matrix.cluster_db_backend }}
 
     strategy:
       fail-fast: false
@@ -78,15 +77,17 @@ jobs:
           - emqx
           - emqx-enterprise
           - emqx-elixir
-        cluster_db_backend:
-          - mnesia
-          - rlog
     steps:
       - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
       - name: Set up environment
         id: env
         run: |
           source env.sh
+          if [ "$EMQX_NAME" = "emqx-enterprise" ]; then
+            _EMQX_TEST_DB_BACKEND='rlog'
+          else
+            _EMQX_TEST_DB_BACKEND='mnesia'
+          fi
           PKG_VSN=$(docker run --rm -v $(pwd):$(pwd) -w $(pwd) -u $(id -u) "$EMQX_BUILDER" ./pkg-vsn.sh "$EMQX_NAME")
           echo "PKG_VSN=$PKG_VSN" >> "$GITHUB_ENV"
       - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7

+ 13 - 0
apps/emqx/test/emqx_cth_suite.erl

@@ -79,6 +79,8 @@
 %% "Unofficial" `emqx_config_handler' and `emqx_conf' APIs
 -export([schema_module/0, upgrade_raw_conf/1]).
 
+-export([skip_if_oss/0]).
+
 -export_type([appspec/0]).
 -export_type([appspec_opts/0]).
 
@@ -519,3 +521,14 @@ upgrade_raw_conf(Conf) ->
         ce ->
             emqx_conf_schema:upgrade_raw_conf(Conf)
     end.
+
+skip_if_oss() ->
+    try emqx_release:edition() of
+        ee ->
+            false;
+        _ ->
+            {skip, not_supported_in_oss}
+    catch
+        error:undef ->
+            {skip, standalone_not_supported}
+    end.

+ 1 - 1
apps/emqx/test/emqx_persistent_messages_SUITE.erl

@@ -573,7 +573,7 @@ app_specs(Opts) ->
 
 cluster() ->
     ExtraConf = "\n durable_storage.messages.n_sites = 2",
-    Spec = #{role => core, apps => app_specs(#{extra_emqx_conf => ExtraConf})},
+    Spec = #{apps => app_specs(#{extra_emqx_conf => ExtraConf})},
     [
         {persistent_messages_SUITE1, Spec},
         {persistent_messages_SUITE2, Spec}

+ 19 - 9
apps/emqx/test/emqx_routing_SUITE.erl

@@ -64,18 +64,28 @@ init_per_group(routing_schema_v2, Config) ->
 init_per_group(batch_sync_on, Config) ->
     [{emqx_config, "broker.routing.batch_sync.enable_on = all"} | Config];
 init_per_group(batch_sync_replicants, Config) ->
-    [{emqx_config, "broker.routing.batch_sync.enable_on = replicant"} | Config];
+    case emqx_cth_suite:skip_if_oss() of
+        false ->
+            [{emqx_config, "broker.routing.batch_sync.enable_on = replicant"} | Config];
+        True ->
+            True
+    end;
 init_per_group(batch_sync_off, Config) ->
     [{emqx_config, "broker.routing.batch_sync.enable_on = none"} | Config];
 init_per_group(cluster, Config) ->
-    WorkDir = emqx_cth_suite:work_dir(Config),
-    NodeSpecs = [
-        {emqx_routing_SUITE1, #{apps => [mk_emqx_appspec(1, Config)], role => core}},
-        {emqx_routing_SUITE2, #{apps => [mk_emqx_appspec(2, Config)], role => core}},
-        {emqx_routing_SUITE3, #{apps => [mk_emqx_appspec(3, Config)], role => replicant}}
-    ],
-    Nodes = emqx_cth_cluster:start(NodeSpecs, #{work_dir => WorkDir}),
-    [{cluster, Nodes} | Config];
+    case emqx_cth_suite:skip_if_oss() of
+        false ->
+            WorkDir = emqx_cth_suite:work_dir(Config),
+            NodeSpecs = [
+                {emqx_routing_SUITE1, #{apps => [mk_emqx_appspec(1, Config)], role => core}},
+                {emqx_routing_SUITE2, #{apps => [mk_emqx_appspec(2, Config)], role => core}},
+                {emqx_routing_SUITE3, #{apps => [mk_emqx_appspec(3, Config)], role => replicant}}
+            ],
+            Nodes = emqx_cth_cluster:start(NodeSpecs, #{work_dir => WorkDir}),
+            [{cluster, Nodes} | Config];
+        True ->
+            True
+    end;
 init_per_group(GroupName, Config) when
     GroupName =:= single_batch_on;
     GroupName =:= single

+ 2 - 2
apps/emqx_auth/test/emqx_authz/emqx_authz_api_cluster_SUITE.erl

@@ -118,8 +118,8 @@ mk_cluster_spec(Opts) ->
     Node1Apps = Apps ++ [{emqx_dashboard, "dashboard.listeners.http {enable=true,bind=18083}"}],
     Node2Apps = Apps,
     [
-        {emqx_authz_api_cluster_SUITE1, Opts#{role => core, apps => Node1Apps}},
-        {emqx_authz_api_cluster_SUITE2, Opts#{role => core, apps => Node2Apps}}
+        {emqx_authz_api_cluster_SUITE1, Opts#{apps => Node1Apps}},
+        {emqx_authz_api_cluster_SUITE2, Opts#{apps => Node2Apps}}
     ].
 
 request(Method, URL, Body, Config) ->

+ 1 - 13
apps/emqx_conf/src/emqx_conf_schema.erl

@@ -194,18 +194,6 @@ fields("cluster") ->
                     'readOnly' => true
                 }
             )},
-        {"core_nodes",
-            sc(
-                node_array(),
-                #{
-                    %% This config is nerver needed (since 5.0.0)
-                    importance => ?IMPORTANCE_HIDDEN,
-                    mapping => "mria.core_nodes",
-                    default => [],
-                    'readOnly' => true,
-                    desc => ?DESC(db_core_nodes)
-                }
-            )},
         {"autoclean",
             sc(
                 emqx_schema:duration(),
@@ -600,7 +588,7 @@ fields("node") ->
             )},
         {"role",
             sc(
-                hoconsc:enum([core, replicant]),
+                hoconsc:enum([core] ++ emqx_schema_hooks:injection_point('node.role')),
                 #{
                     mapping => "mria.node_role",
                     default => core,

+ 7 - 1
apps/emqx_conf/src/emqx_conf_schema_inject.erl

@@ -22,12 +22,18 @@ schemas() ->
     schemas(emqx_release:edition()).
 
 schemas(Edition) ->
-    auth_ext(Edition) ++
+    mria(Edition) ++
+        auth_ext(Edition) ++
         cluster_linking(Edition) ++
         authn(Edition) ++
         authz() ++
         customized(Edition).
 
+mria(ce) ->
+    [];
+mria(ee) ->
+    [emqx_enterprise_schema].
+
 auth_ext(ce) ->
     [];
 auth_ext(ee) ->

+ 7 - 7
apps/emqx_conf/test/emqx_conf_app_SUITE.erl

@@ -30,7 +30,7 @@ t_copy_conf_override_on_restarts(Config) ->
     ct:timetrap({seconds, 120}),
     Cluster = cluster(
         ?FUNCTION_NAME,
-        [cluster_spec({core, 1}), cluster_spec({core, 2}), cluster_spec({core, 3})],
+        [cluster_spec(1), cluster_spec(2), cluster_spec(3)],
         Config
     ),
 
@@ -59,7 +59,7 @@ t_copy_new_data_dir(Config) ->
     ct:timetrap({seconds, 120}),
     Cluster = cluster(
         ?FUNCTION_NAME,
-        [cluster_spec({core, 4}), cluster_spec({core, 5}), cluster_spec({core, 6})],
+        [cluster_spec(4), cluster_spec(5), cluster_spec(6)],
         Config
     ),
 
@@ -84,7 +84,7 @@ t_copy_deprecated_data_dir(Config) ->
     ct:timetrap({seconds, 120}),
     Cluster = cluster(
         ?FUNCTION_NAME,
-        [cluster_spec({core, 7}), cluster_spec({core, 8}), cluster_spec({core, 9})],
+        [cluster_spec(7), cluster_spec(8), cluster_spec(9)],
         Config
     ),
 
@@ -109,7 +109,7 @@ t_no_copy_from_newer_version_node(Config) ->
     ct:timetrap({seconds, 120}),
     Cluster = cluster(
         ?FUNCTION_NAME,
-        [cluster_spec({core, 10}), cluster_spec({core, 11}), cluster_spec({core, 12})],
+        [cluster_spec(10), cluster_spec(11), cluster_spec(12)],
         Config
     ),
     OKs = [ok, ok, ok],
@@ -242,12 +242,12 @@ cluster(TC, Specs, Config) ->
         {emqx_conf, #{}}
     ],
     emqx_cth_cluster:mk_nodespecs(
-        [{Name, #{role => Role, apps => Apps}} || {Role, Name} <- Specs],
+        [{Name, #{apps => Apps}} || Name <- Specs],
         #{work_dir => emqx_cth_suite:work_dir(TC, Config)}
     ).
 
-cluster_spec({Type, Num}) ->
-    {Type, list_to_atom(atom_to_list(?MODULE) ++ integer_to_list(Num))}.
+cluster_spec(Num) ->
+    list_to_atom(atom_to_list(?MODULE) ++ integer_to_list(Num)).
 
 sort_highest_uptime(Nodes) ->
     Ranking = lists:sort([{-get_node_uptime(N), N} || N <- Nodes]),

+ 6 - 12
apps/emqx_conf/test/emqx_conf_schema_tests.erl

@@ -32,7 +32,6 @@
                 name = emqxcl
                 discovery_strategy = static
                 static.seeds = ~p
-                core_nodes = ~p
              }
     ").
 
@@ -41,7 +40,7 @@ array_nodes_test() ->
     ExpectNodes = ['emqx1@127.0.0.1', 'emqx2@127.0.0.1'],
     lists:foreach(
         fun(Nodes) ->
-            ConfFile = to_bin(?BASE_CONF, [Nodes, Nodes]),
+            ConfFile = to_bin(?BASE_CONF, [Nodes]),
             {ok, Conf} = hocon:binary(ConfFile, #{format => richmap}),
             ConfList = hocon_tconf:generate(emqx_conf_schema, Conf),
             VMArgs = proplists:get_value(vm_args, ConfList),
@@ -57,11 +56,6 @@ array_nodes_test() ->
                 {static, [{seeds, ExpectNodes}]},
                 ClusterDiscovery,
                 Nodes
-            ),
-            ?assertEqual(
-                ExpectNodes,
-                proplists:get_value(core_nodes, proplists:get_value(mria, ConfList)),
-                Nodes
             )
         end,
         [["emqx1@127.0.0.1", "emqx2@127.0.0.1"], "emqx1@127.0.0.1, emqx2@127.0.0.1"]
@@ -158,7 +152,7 @@ outdated_log_test() ->
 
 validate_log(Conf) ->
     ensure_acl_conf(),
-    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1", "emqx1@127.0.0.1"]),
+    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1"]),
     Conf0 = <<BaseConf/binary, (list_to_binary(Conf))/binary>>,
     {ok, ConfMap0} = hocon:binary(Conf0, #{format => richmap}),
     ConfList = hocon_tconf:generate(emqx_conf_schema, ConfMap0),
@@ -214,7 +208,7 @@ validate_log(Conf) ->
 
 file_log_infinity_rotation_size_test_() ->
     ensure_acl_conf(),
-    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1", "emqx1@127.0.0.1"]),
+    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1"]),
     Gen = fun(#{count := Count, size := Size}) ->
         Conf0 = to_bin(?FILE_LOG_BASE_CONF, [Count, Size]),
         Conf1 = [BaseConf, Conf0],
@@ -292,7 +286,7 @@ log_rotation_count_limit_test() ->
     rotation_size = \"1024MB\"
     }
     ",
-    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1", "emqx1@127.0.0.1"]),
+    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1"]),
     lists:foreach(fun({Conf, Count}) ->
         Conf0 = <<BaseConf/binary, Conf/binary>>,
         {ok, ConfMap0} = hocon:binary(Conf0, #{format => richmap}),
@@ -352,7 +346,7 @@ log_rotation_count_limit_test() ->
 
 authn_validations_test() ->
     ensure_acl_conf(),
-    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1", "emqx1@127.0.0.1"]),
+    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1"]),
 
     OKHttps = to_bin(?BASE_AUTHN_ARRAY, [post, true, <<"https://127.0.0.1:8080">>]),
     Conf0 = <<BaseConf/binary, OKHttps/binary>>,
@@ -410,7 +404,7 @@ authn_validations_test() ->
 
 listeners_test() ->
     ensure_acl_conf(),
-    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1", "emqx1@127.0.0.1"]),
+    BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1"]),
 
     Conf = <<BaseConf/binary, ?LISTENERS>>,
     {ok, ConfMap0} = hocon:binary(Conf, #{format => richmap}),

+ 1 - 1
apps/emqx_enterprise/src/emqx_enterprise.app.src

@@ -1,6 +1,6 @@
 {application, emqx_enterprise, [
     {description, "EMQX Enterprise Edition"},
-    {vsn, "0.2.2"},
+    {vsn, "0.2.3"},
     {registered, []},
     {applications, [
         kernel,

+ 6 - 0
apps/emqx_enterprise/src/emqx_enterprise_schema.erl

@@ -11,6 +11,7 @@
 
 -export([namespace/0, roots/0, fields/1, translations/0, translation/1, desc/1, validations/0]).
 -export([upgrade_raw_conf/1]).
+-export([injected_fields/0]).
 
 -define(EE_SCHEMA_MODULES, [
     emqx_license_schema,
@@ -126,6 +127,11 @@ desc(Name) ->
 validations() ->
     emqx_conf_schema:validations() ++ emqx_license_schema:validations().
 
+injected_fields() ->
+    #{
+        'node.role' => [replicant]
+    }.
+
 %%------------------------------------------------------------------------------
 %% helpers
 %%------------------------------------------------------------------------------

+ 4 - 4
apps/emqx_management/test/emqx_mgmt_api_clients_SUITE.erl

@@ -107,8 +107,8 @@ init_per_group(persistent_sessions, Config) ->
     ],
     Dashboard = emqx_mgmt_api_test_util:emqx_dashboard(),
     Cluster = [
-        {emqx_mgmt_api_clients_SUITE1, #{role => core, apps => AppSpecs ++ [Dashboard]}},
-        {emqx_mgmt_api_clients_SUITE2, #{role => core, apps => AppSpecs}}
+        {emqx_mgmt_api_clients_SUITE1, #{apps => AppSpecs ++ [Dashboard]}},
+        {emqx_mgmt_api_clients_SUITE2, #{apps => AppSpecs}}
     ],
     Nodes =
         [N1 | _] = emqx_cth_cluster:start(
@@ -128,8 +128,8 @@ init_per_group(non_persistent_cluster, Config) ->
     ],
     Dashboard = emqx_mgmt_api_test_util:emqx_dashboard(),
     Cluster = [
-        {mgmt_api_clients_SUITE1, #{role => core, apps => AppSpecs ++ [Dashboard]}},
-        {mgmt_api_clients_SUITE2, #{role => core, apps => AppSpecs}}
+        {mgmt_api_clients_SUITE1, #{apps => AppSpecs ++ [Dashboard]}},
+        {mgmt_api_clients_SUITE2, #{apps => AppSpecs}}
     ],
     Nodes =
         [N1 | _] = emqx_cth_cluster:start(

+ 6 - 1
apps/emqx_management/test/emqx_mgmt_api_cluster_SUITE.erl

@@ -24,7 +24,12 @@
 -define(APPS, [emqx_conf, emqx_management]).
 
 all() ->
-    emqx_common_test_helpers:all(?MODULE).
+    case emqx_cth_suite:skip_if_oss() of
+        false ->
+            emqx_common_test_helpers:all(?MODULE);
+        True ->
+            True
+    end.
 
 init_per_suite(Config) ->
     Config.

+ 6 - 1
apps/emqx_management/test/emqx_mgmt_api_data_backup_SUITE.erl

@@ -36,7 +36,12 @@
 ).
 
 all() ->
-    emqx_common_test_helpers:all(?MODULE).
+    case emqx_cth_suite:skip_if_oss() of
+        false ->
+            emqx_common_test_helpers:all(?MODULE);
+        True ->
+            True
+    end.
 
 init_per_suite(Config) ->
     Config.

+ 7 - 1
apps/emqx_management/test/emqx_mgmt_cli_SUITE.erl

@@ -22,7 +22,13 @@
 -include_lib("common_test/include/ct.hrl").
 
 all() ->
-    emqx_common_test_helpers:all(?MODULE).
+    All = emqx_common_test_helpers:all(?MODULE),
+    case emqx_cth_suite:skip_if_oss() of
+        false ->
+            All;
+        _ ->
+            All -- [t_autocluster_leave]
+    end.
 
 init_per_suite(Config) ->
     Apps = emqx_cth_suite:start(

+ 6 - 1
apps/emqx_management/test/emqx_mgmt_data_backup_SUITE.erl

@@ -52,7 +52,12 @@
 >>).
 
 all() ->
-    emqx_common_test_helpers:all(?MODULE).
+    case emqx_cth_suite:skip_if_oss() of
+        false ->
+            emqx_common_test_helpers:all(?MODULE);
+        True ->
+            True
+    end.
 
 init_per_suite(Config) ->
     Config.

+ 3 - 3
apps/emqx_opentelemetry/test/emqx_otel_trace_SUITE.erl

@@ -414,9 +414,9 @@ mqtt_host_port(Node) ->
 cluster(TC, Config) ->
     Nodes = emqx_cth_cluster:start(
         [
-            {otel_trace_core1, #{role => core, apps => apps_spec()}},
-            {otel_trace_core2, #{role => core, apps => apps_spec()}},
-            {otel_trace_replicant, #{role => replicant, apps => apps_spec()}}
+            {otel_trace_node1, #{apps => apps_spec()}},
+            {otel_trace_node2, #{apps => apps_spec()}},
+            {otel_trace_node3, #{apps => apps_spec()}}
         ],
         #{work_dir => emqx_cth_suite:work_dir(TC, Config)}
     ),

+ 5 - 0
changes/ce/breaking-13526.en.md

@@ -0,0 +1,5 @@
+- Core-replicant feature has been removed from the Open-Source Edition.
+  Starting from release 5.8, all nodes running Open-Source Edition will assume Core role.
+  This change doesn't affect Enterprise Edition users.
+
+- Obsolete and unused `cluster.core_nodes` configuration parameter has been removed.

+ 2 - 2
rel/config/examples/node.conf.example

@@ -11,11 +11,11 @@ node {
     ## Secret cookie is a random string that should be the same on all nodes in the cluster, but unique per EMQX cluster
     cookie = "Yzc0NGExM2Rj"
 
-    ## Select a node role
+    ## Select a node role (Enterprise Edition feature)
     ## Possible values:
     ##   - core: This is a core node which provides durability of the client states, and takes care of writes
     ##   - replicant: This is a stateless worker node
-    role = core
+    ## role = core
 
     ## Maximum number of simultaneously existing processes for this Erlang system
     process_limit = 2097152