From 5946ce347cd280f7905a43e35d15016c2fe76d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 9 Dec 2025 12:09:58 +0100 Subject: [PATCH 1/8] WIP --- deps/rabbit/docs/rabbitmqctl.8 | 51 +----- deps/rabbit/src/rabbit_mnesia.erl | 2 +- .../test/clustering_management_SUITE.erl | 147 ++---------------- .../change_cluster_node_type_command.ex | 103 ------------ .../cli/ctl/commands/join_cluster_command.ex | 8 +- .../test/ctl/join_cluster_command_test.exs | 4 +- 6 files changed, 19 insertions(+), 296 deletions(-) delete mode 100644 deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_cluster_node_type_command.ex diff --git a/deps/rabbit/docs/rabbitmqctl.8 b/deps/rabbit/docs/rabbitmqctl.8 index ecbc5132b17b..d09775b47042 100644 --- a/deps/rabbit/docs/rabbitmqctl.8 +++ b/deps/rabbit/docs/rabbitmqctl.8 @@ -286,28 +286,6 @@ For example, to wait for two RabbitMQ nodes to start: .sp .Dl rabbitmqctl await_online_nodes 2 .\" ------------------------------------------------------------------ -.It Cm change_cluster_node_type Ar type -.Pp -Changes the type of the cluster node. -.Pp -The -.Ar type -must be one of the following: -.Bl -bullet -compact -.It -.Cm disc -.It -.Cm ram -.El -.Pp -The node must be stopped for this operation to succeed, and when turning -a node into a RAM node the node must not be the only disc node in the -cluster. -.Pp -For example, this command will turn a RAM node into a disc node: -.sp -.Dl rabbitmqctl change_cluster_node_type disc -.\" ------------------------------------------------------------------ .It Cm cluster_status .Pp Displays all the nodes in the cluster grouped by node type, together @@ -413,14 +391,10 @@ from the node .sp .Dl rabbitmqctl -n hare@mcnulty forget_cluster_node rabbit@stringer .\" ------------------------------------------------------------------ -.It Cm join_cluster Ar seed-node Op Fl -ram +.It Cm join_cluster Ar seed-node .Bl -tag -width Ds .It Ar seed-node Existing cluster member (seed node) to cluster with. -.It Fl -ram -If provided, the node will join the cluster as a RAM node. -RAM node use is discouraged. Use only if you understand why -exactly you need to use them. .El .Pp Instructs the node to become a member of the cluster that the specified @@ -431,23 +405,6 @@ For this command to succeed the RabbitMQ application must have been stopped, e.g. with .Cm stop_app . .Pp -Cluster nodes can be of two types: disc or RAM. -Disc nodes replicate data in RAM and on disk, thus providing redundancy -in the event of node failure and recovery from global events such as -power failure across all nodes. -RAM nodes replicate data in RAM only (except for queue contents, which -can reside on disk if the queue is persistent or too big to fit in -memory) and are mainly used for scalability. -RAM nodes are more performant only when managing resources (e.g.\& -adding/removing queues, exchanges, or bindings). -A cluster must always have at least one disc node and usually should -have more than one. -.Pp -The node will be a disc node by default. -If you wish to create a RAM node, provide the -.Fl -ram -flag. -.Pp After executing the .Cm join_cluster command, whenever the RabbitMQ application is started on the current @@ -461,12 +418,6 @@ You can also remove nodes remotely with the .Cm forget_cluster_node command. .Pp -For example, this command instructs the RabbitMQ node to join the cluster that -.Qq hare@elena -is part of, as a ram node: -.sp -.Dl rabbitmqctl join_cluster hare@elena --ram -.Pp To learn more, see the .Lk https://www.rabbitmq.com/docs/clustering "RabbitMQ Clustering guide". .\" ------------------------------------------------------------------ diff --git a/deps/rabbit/src/rabbit_mnesia.erl b/deps/rabbit/src/rabbit_mnesia.erl index 541f98b23465..64496d1ab252 100644 --- a/deps/rabbit/src/rabbit_mnesia.erl +++ b/deps/rabbit/src/rabbit_mnesia.erl @@ -104,7 +104,7 @@ -rabbit_deprecated_feature( {ram_node_type, - #{deprecation_phase => permitted_by_default, + #{deprecation_phase => removed, doc_url => "https://blog.rabbitmq.com/posts/2021/08/4.0-deprecation-announcements/#removal-of-ram-nodes" }}). diff --git a/deps/rabbit/test/clustering_management_SUITE.erl b/deps/rabbit/test/clustering_management_SUITE.erl index 2b585f1df8fa..807f48556835 100644 --- a/deps/rabbit/test/clustering_management_SUITE.erl +++ b/deps/rabbit/test/clustering_management_SUITE.erl @@ -41,7 +41,6 @@ groups() -> join_cluster_bad_operations, join_to_start_interval, forget_cluster_node, - change_cluster_node_type, change_cluster_when_node_offline ]} ]}, @@ -57,8 +56,7 @@ groups() -> pid_file_and_await_node_startup, await_running_count, start_with_invalid_schema_in_path, - persistent_cluster_id, - reset_last_disc_node + persistent_cluster_id ]} ]} ]}, @@ -66,7 +64,6 @@ groups() -> {clustered_2_nodes, [], [ {cluster_size_2, [], [ - change_cluster_node_type_in_khepri, forget_node_in_khepri, forget_removes_things_in_khepri, reset_in_khepri, @@ -277,20 +274,19 @@ join_and_part_cluster(Config) -> stop_join_start(Config, Rabbit, Bunny), assert_clustered([Rabbit, Bunny]), - stop_join_start(Config, Hare, Bunny, true), - assert_cluster_status( - {[Bunny, Hare, Rabbit], [Bunny, Rabbit], [Bunny, Hare, Rabbit]}, - [Rabbit, Hare, Bunny]), + stop_join_start(Config, Hare, Bunny), + assert_clustered([Rabbit, Bunny, Hare]), %% Allow clustering with already clustered node ok = stop_app(Config, Rabbit), ok = join_cluster(Config, Rabbit, Hare), ok = start_app(Config, Rabbit), + assert_clustered([Rabbit, Bunny, Hare]), + stop_reset_start(Config, Rabbit), assert_not_clustered(Rabbit), - assert_cluster_status({[Bunny, Hare], [Bunny], [Bunny, Hare]}, - [Hare, Bunny]), + assert_clustered([Hare, Rabbit]), stop_reset_start(Config, Hare), assert_not_clustered(Hare), @@ -385,12 +381,7 @@ join_and_part_cluster_in_khepri(Config) -> assert_clustered([Rabbit, Bunny, Hare]). join_cluster_bad_operations(Config) -> - [Rabbit, Hare, Bunny] = cluster_members(Config), - - UsePrelaunch = rabbit_ct_broker_helpers:rpc( - Config, Hare, - erlang, function_exported, - [rabbit_prelaunch, get_context, 0]), + [Rabbit, _Hare, _Bunny] = cluster_members(Config), %% Nonexistent node ok = stop_app(Config, Rabbit), @@ -404,30 +395,6 @@ join_cluster_bad_operations(Config) -> ok = start_app(Config, Rabbit), assert_not_clustered(Rabbit), - %% Do not let the node leave the cluster or reset if it's the only - %% ram node - stop_join_start(Config, Hare, Rabbit, true), - assert_cluster_status({[Rabbit, Hare], [Rabbit], [Rabbit, Hare]}, - [Rabbit, Hare]), - ok = stop_app(Config, Hare), - assert_failure(fun () -> join_cluster(Config, Rabbit, Bunny) end), - assert_failure(fun () -> reset(Config, Rabbit) end), - ok = start_app(Config, Hare), - assert_cluster_status({[Rabbit, Hare], [Rabbit], [Rabbit, Hare]}, - [Rabbit, Hare]), - - %% Cannot start RAM-only node first - ok = stop_app(Config, Rabbit), - ok = stop_app(Config, Hare), - assert_failure(fun () -> start_app(Config, Hare) end), - ok = start_app(Config, Rabbit), - case UsePrelaunch of - true -> - ok = start_app(Config, Hare); - false -> - %% The Erlang VM has stopped after previous rabbit app failure - ok = rabbit_ct_broker_helpers:start_node(Config, Hare) - end, ok. join_cluster_bad_operations_in_khepri(Config) -> @@ -470,10 +437,10 @@ join_cluster_in_minority(Config) -> ok = rabbit_ct_broker_helpers:stop_node(Config, Rabbit), ok = stop_app(Config, Hare), - ?assertEqual(ok, join_cluster(Config, Hare, Bunny, false)), + ?assertEqual(ok, join_cluster(Config, Hare, Bunny)), ok = rabbit_ct_broker_helpers:start_node(Config, Rabbit), - ?assertEqual(ok, join_cluster(Config, Hare, Rabbit, false)), + ?assertEqual(ok, join_cluster(Config, Hare, Rabbit)), ?assertEqual(ok, start_app(Config, Hare)), assert_clustered([Rabbit, Bunny, Hare]). @@ -489,10 +456,10 @@ join_cluster_with_rabbit_stopped(Config) -> ok = stop_app(Config, Rabbit), ok = stop_app(Config, Hare), - ?assertEqual(ok, join_cluster(Config, Hare, Bunny, false)), + ?assertEqual(ok, join_cluster(Config, Hare, Bunny)), ok = start_app(Config, Rabbit), - ?assertEqual(ok, join_cluster(Config, Hare, Rabbit, false)), + ?assertEqual(ok, join_cluster(Config, Hare, Rabbit)), ?assertEqual(ok, start_app(Config, Hare)), assert_clustered([Rabbit, Bunny, Hare]). @@ -758,27 +725,6 @@ is_in_minority(Ret) -> {error, _, Msg} = Ret, ?assertMatch(match, re:run(Msg, ".*timed out.*minority.*", [{capture, none}])). -reset_last_disc_node(Config) -> - [Rabbit, Hare | _] = cluster_members(Config), - - stop_app(Config, Hare), - ?assertEqual(ok, change_cluster_node_type(Config, Hare, ram)), - start_app(Config, Hare), - - case rabbit_ct_broker_helpers:enable_feature_flag(Config, [Rabbit], khepri_db) of - ok -> - %% The reset works after the switch to Khepri because the RAM node was - %% implicitly converted to a disc one as Khepri always writes data on disc. - stop_app(Config, Rabbit), - ?assertEqual(ok, reset(Config, Rabbit)), - start_app(Config, Rabbit), - assert_not_clustered(Rabbit), - assert_not_clustered(Hare), - ok; - {skip, _} = Skip -> - Skip - end. - forget_offline_removes_things(Config) -> [Rabbit, Hare] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), @@ -833,54 +779,6 @@ force_boot_in_khepri(Config) -> ?assertMatch({ok, []}, rabbit_ct_broker_helpers:rabbitmqctl(Config, Rabbit, ["force_boot"])), ok. -change_cluster_node_type(Config) -> - [Rabbit, Hare, _Bunny] = cluster_members(Config), - - %% Trying to change the node to the ram type when not clustered should always fail - ok = stop_app(Config, Rabbit), - assert_failure(fun () -> change_cluster_node_type(Config, Rabbit, ram) end), - ok = start_app(Config, Rabbit), - - ok = stop_app(Config, Rabbit), - join_cluster(Config, Rabbit, Hare), - assert_cluster_status({[Rabbit, Hare], [Rabbit, Hare], [Hare]}, - [Rabbit, Hare]), - change_cluster_node_type(Config, Rabbit, ram), - assert_cluster_status({[Rabbit, Hare], [Hare], [Rabbit, Hare], [Hare], [Hare]}, - [Rabbit, Hare]), - change_cluster_node_type(Config, Rabbit, disc), - - assert_cluster_status({[Rabbit, Hare], [Rabbit, Hare], [Hare]}, - [Rabbit, Hare]), - change_cluster_node_type(Config, Rabbit, ram), - ok = start_app(Config, Rabbit), - assert_cluster_status({[Rabbit, Hare], [Hare], [Hare, Rabbit]}, - [Rabbit, Hare]), - - %% Changing to ram when you're the only ram node should fail - ok = stop_app(Config, Hare), - assert_failure(fun () -> change_cluster_node_type(Config, Hare, ram) end), - ok = start_app(Config, Hare). - -change_cluster_node_type_in_khepri(Config) -> - [Rabbit, Hare] = cluster_members(Config), - - assert_cluster_status({[Rabbit, Hare], [Rabbit, Hare], [Rabbit, Hare]}, - [Rabbit, Hare]), - - ok = stop_app(Config, Rabbit), - {error, 69, Msg} = change_cluster_node_type(Config, Rabbit, ram), - ?assertEqual( - match, - re:run( - Msg, "Feature `ram_node_type` is deprecated", - [{capture, none}])), - - ok = change_cluster_node_type(Config, Rabbit, disc), - ok = start_app(Config, Rabbit), - assert_cluster_status({[Rabbit, Hare], [Rabbit, Hare], [Rabbit, Hare]}, - [Rabbit, Hare]). - change_cluster_when_node_offline(Config) -> [Rabbit, Hare, Bunny] = cluster_members(Config), @@ -1281,15 +1179,7 @@ start_app(Config, Node) -> end. join_cluster(Config, Node, To) -> - join_cluster(Config, Node, To, false). - -join_cluster(Config, Node, To, Ram) -> - Cmd = case Ram of - true -> - ["join_cluster", "--ram", atom_to_list(To)]; - false -> - ["join_cluster", atom_to_list(To)] - end, + Cmd = ["join_cluster", atom_to_list(To)], case rabbit_ct_broker_helpers:rabbitmqctl(Config, Node, Cmd) of {ok, _} -> ok; Error -> Error @@ -1326,22 +1216,11 @@ forget_cluster_node(Config, Node, Removee, RemoveWhenOffline) -> forget_cluster_node(Config, Node, Removee) -> forget_cluster_node(Config, Node, Removee, false). -change_cluster_node_type(Config, Node, Type) -> - Ret = rabbit_ct_broker_helpers:rabbitmqctl( - Config, Node, ["change_cluster_node_type", atom_to_list(Type)]), - case Ret of - {ok, _} -> ok; - Error -> Error - end. - -stop_join_start(Config, Node, ClusterTo, Ram) -> +stop_join_start(Config, Node, ClusterTo) -> ok = stop_app(Config, Node), ok = join_cluster(Config, Node, ClusterTo, Ram), ok = start_app(Config, Node). -stop_join_start(Config, Node, ClusterTo) -> - stop_join_start(Config, Node, ClusterTo, false). - stop_reset_start(Config, Node) -> ok = stop_app(Config, Node), ok = reset(Config, Node), diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_cluster_node_type_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_cluster_node_type_command.ex deleted file mode 100644 index d583a1be5508..000000000000 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_cluster_node_type_command.ex +++ /dev/null @@ -1,103 +0,0 @@ -## This Source Code Form is subject to the terms of the Mozilla Public -## License, v. 2.0. If a copy of the MPL was not distributed with this -## file, You can obtain one at https://mozilla.org/MPL/2.0/. -## -## Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved. - -defmodule RabbitMQ.CLI.Ctl.Commands.ChangeClusterNodeTypeCommand do - alias RabbitMQ.CLI.Core.DocGuide - - @behaviour RabbitMQ.CLI.CommandBehaviour - - def merge_defaults(args, opts) do - {args, opts} - end - - def validate([], _), do: {:validation_failure, :not_enough_args} - - # node type - def validate(["disc"], _), do: :ok - def validate(["disk"], _), do: :ok - def validate(["ram"], _), do: :ok - - def validate([_], _), - do: {:validation_failure, {:bad_argument, "The node type must be either disc or ram."}} - - def validate(_, _), do: {:validation_failure, :too_many_args} - - use RabbitMQ.CLI.Core.RequiresRabbitAppStopped - - def run([node_type_arg], %{node: node_name}) do - normalized_type = normalize_type(String.to_atom(node_type_arg)) - - current_type = - case :rabbit_misc.rpc_call(node_name, :rabbit_db_cluster, :node_type, []) do - {:badrpc, {:EXIT, {:undef, _}}} -> - :rabbit_misc.rpc_call(node_name, :rabbit_mnesia, :node_type, []) - - ret -> - ret - end - - case current_type do - ^normalized_type -> - {:ok, "Node type is already #{normalized_type}"} - - _ -> - case :rabbit_misc.rpc_call(node_name, :rabbit_db_cluster, :change_node_type, [ - normalized_type - ]) do - {:badrpc, {:EXIT, {:undef, _}}} -> - :rabbit_misc.rpc_call(node_name, :rabbit_mnesia, :change_cluster_node_type, [ - normalized_type - ]) - - ret -> - ret - end - end - end - - def usage() do - "change_cluster_node_type " - end - - def usage_additional() do - [ - ["", "New node type"] - ] - end - - def usage_doc_guides() do - [ - DocGuide.clustering() - ] - end - - def help_section(), do: :cluster_management - - def description(), do: "Changes the type of the cluster node" - - def banner([node_type], %{node: node_name}) do - "Turning #{node_name} into a #{node_type} node" - end - - def output({:error, :mnesia_unexpectedly_running}, %{node: node_name}) do - {:error, RabbitMQ.CLI.Core.ExitCodes.exit_software(), - RabbitMQ.CLI.DefaultOutput.mnesia_running_error(node_name)} - end - - use RabbitMQ.CLI.DefaultOutput - - defp normalize_type(:ram) do - :ram - end - - defp normalize_type(:disc) do - :disc - end - - defp normalize_type(:disk) do - :disc - end -end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex index a4810217ed8d..f4ee5eaad728 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex @@ -98,7 +98,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do end def usage() do - "join_cluster [--disc|--ram] " + "join_cluster [--disc] " end def usage_additional() do @@ -106,11 +106,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do ["", "Existing cluster member (node) to join"], [ "--disc", - "new node should be a disk one (stores its schema on disk). Highly recommended, used by default." - ], - [ - "--ram", - "new node should be a RAM one (stores schema in RAM). Not recommended. Consult clustering doc guides first." + "new node will be a disk one (stores its schema on disk). This is the default." ] ] end diff --git a/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs b/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs index 36be4a58bd81..a79e14375c8f 100644 --- a/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs @@ -31,10 +31,10 @@ defmodule JoinClusterCommandTest do }} end - test "validate: specifying both --disc and --ram is reported as invalid", context do + test "validate: specifying --ram is reported as invalid", context do assert match?( {:validation_failure, {:bad_argument, _}}, - @command.validate(["a"], Map.merge(context[:opts], %{disc: true, ram: true})) + @command.validate(["a"], Map.merge(context[:opts], %{ram: true})) ) end From dd1c251b6b69a5513823be4168d4b47f0241b5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 9 Dec 2025 12:16:04 +0100 Subject: [PATCH 2/8] fixup! WIP --- deps/rabbit/test/clustering_management_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rabbit/test/clustering_management_SUITE.erl b/deps/rabbit/test/clustering_management_SUITE.erl index 807f48556835..84ecf7d72387 100644 --- a/deps/rabbit/test/clustering_management_SUITE.erl +++ b/deps/rabbit/test/clustering_management_SUITE.erl @@ -1218,7 +1218,7 @@ forget_cluster_node(Config, Node, Removee) -> stop_join_start(Config, Node, ClusterTo) -> ok = stop_app(Config, Node), - ok = join_cluster(Config, Node, ClusterTo, Ram), + ok = join_cluster(Config, Node, ClusterTo), ok = start_app(Config, Node). stop_reset_start(Config, Node) -> From 3442d9b041cacdac91217b16cfc3bcda0d09e1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 9 Dec 2025 14:18:45 +0100 Subject: [PATCH 3/8] fixup! WIP --- deps/rabbit/test/clustering_management_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rabbit/test/clustering_management_SUITE.erl b/deps/rabbit/test/clustering_management_SUITE.erl index 84ecf7d72387..4c6478cb9ea8 100644 --- a/deps/rabbit/test/clustering_management_SUITE.erl +++ b/deps/rabbit/test/clustering_management_SUITE.erl @@ -286,7 +286,7 @@ join_and_part_cluster(Config) -> stop_reset_start(Config, Rabbit), assert_not_clustered(Rabbit), - assert_clustered([Hare, Rabbit]), + assert_clustered([Bunny, Hare]), stop_reset_start(Config, Hare), assert_not_clustered(Hare), From 461dd4ea6220e120f48be1dfd087dcb3b099b474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 11 Dec 2025 15:18:09 +0100 Subject: [PATCH 4/8] fixup! WIP --- .../change_cluster_node_type_command_test.exs | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs diff --git a/deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs b/deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs deleted file mode 100644 index 12f82ea1ce41..000000000000 --- a/deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs +++ /dev/null @@ -1,101 +0,0 @@ -## This Source Code Form is subject to the terms of the Mozilla Public -## License, v. 2.0. If a copy of the MPL was not distributed with this -## file, You can obtain one at https://mozilla.org/MPL/2.0/. -## -## Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved. - -defmodule ChangeClusterNodeTypeCommandTest do - use ExUnit.Case, async: false - import TestHelper - - @command RabbitMQ.CLI.Ctl.Commands.ChangeClusterNodeTypeCommand - - setup_all do - RabbitMQ.CLI.Core.Distribution.start() - - start_rabbitmq_app() - - on_exit([], fn -> - start_rabbitmq_app() - end) - - :ok - end - - setup do - {:ok, - opts: %{ - node: get_rabbit_hostname() - }} - end - - test "validate: node type of disc, disk, and ram pass validation", context do - assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["foo"], context[:opts]) - ) - - assert :ok == @command.validate(["ram"], context[:opts]) - assert :ok == @command.validate(["disc"], context[:opts]) - assert :ok == @command.validate(["disk"], context[:opts]) - end - - test "validate: providing no arguments fails validation", context do - assert @command.validate([], context[:opts]) == - {:validation_failure, :not_enough_args} - end - - test "validate: providing too many arguments fails validation", context do - assert @command.validate(["a", "b", "c"], context[:opts]) == - {:validation_failure, :too_many_args} - end - - # TODO - # test "run: change ram node to disc node", context do - # end - - # TODO - # test "run: change disk node to ram node", context do - # end - - test "run: request to a node with running RabbitMQ app fails", context do - node = RabbitMQ.CLI.Core.Helpers.normalise_node(context[:node], :shortnames) - - case :rabbit_misc.rpc_call(node, :rabbit_khepri, :is_enabled, []) do - true -> - assert match?( - {:error, _}, - @command.run(["ram"], context[:opts]) - ) - - false -> - assert match?( - {:error, :mnesia_unexpectedly_running}, - @command.run(["ram"], context[:opts]) - ) - end - end - - test "run: request to an unreachable node returns a badrpc", _context do - opts = %{node: :jake@thedog, timeout: 200} - - assert match?( - {:badrpc, :nodedown}, - @command.run(["ram"], opts) - ) - end - - test "banner", context do - assert @command.banner(["ram"], context[:opts]) =~ - ~r/Turning #{get_rabbit_hostname()} into a ram node/ - end - - test "output mnesia is running error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() - - assert match?( - {:error, ^exit_code, "Mnesia is still running on node " <> _}, - @command.output({:error, :mnesia_unexpectedly_running}, context[:opts]) - ) - end -end From c3aae0c21f58f0a51029f6f6277d6812ff2b4b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 11 Dec 2025 15:45:04 +0100 Subject: [PATCH 5/8] fixup! WIP --- deps/rabbit/test/clustering_management_SUITE.erl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/deps/rabbit/test/clustering_management_SUITE.erl b/deps/rabbit/test/clustering_management_SUITE.erl index 4c6478cb9ea8..4a3ba64226b6 100644 --- a/deps/rabbit/test/clustering_management_SUITE.erl +++ b/deps/rabbit/test/clustering_management_SUITE.erl @@ -840,8 +840,14 @@ classic_config_discovery_node_list(Config) -> ok = rpc:call(Hare, application, set_env, [rabbit, cluster_nodes, {[Rabbit], ram}]), ok = start_app(Config, Hare), - assert_cluster_status({[Rabbit, Hare], [Rabbit], [Rabbit, Hare]}, - [Rabbit, Hare]), + %% 4.2 nodes can still be RAM. 4.3+ nodes can't. + case rabbit_ct_helpers:is_mixed_versions() of + true -> + assert_cluster_status({[Rabbit, Hare], [Rabbit], [Rabbit, Hare]}, + [Rabbit, Hare]); + false -> + assert_clustered([Rabbit, Hare]) + end, %% List of nodes [node()] is equivalent to {[node()], disk} ok = stop_app(Config, Hare), From 8602a034732f540e2a6cfe02c96f7d8082dc9eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 12 Dec 2025 12:45:33 +0100 Subject: [PATCH 6/8] fixup! WIP --- deps/rabbit/src/rabbit_db_cluster.erl | 6 ++++-- .../cli/ctl/commands/join_cluster_command.ex | 19 ++++--------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/deps/rabbit/src/rabbit_db_cluster.erl b/deps/rabbit/src/rabbit_db_cluster.erl index 1fd720e527fe..902a05505370 100644 --- a/deps/rabbit/src/rabbit_db_cluster.erl +++ b/deps/rabbit/src/rabbit_db_cluster.erl @@ -240,8 +240,10 @@ join(RemoteNode, NodeType) Error end. -join_using_mnesia(ClusterNodes, NodeType) when is_list(ClusterNodes) -> - rabbit_mnesia:join_cluster(ClusterNodes, NodeType). +join_using_mnesia(ClusterNodes, disc) when is_list(ClusterNodes) -> + rabbit_mnesia:join_cluster(ClusterNodes, disc); +join_using_khepri(_ClusterNodes, ram = NodeType) -> + {error, {node_type_unsupported, mnesia, NodeType}}. join_using_khepri(ClusterNodes, disc) -> rabbit_khepri:add_member(node(), ClusterNodes); diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex index f4ee5eaad728..21f533ca1d74 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex @@ -11,31 +11,20 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do def switches() do [ - disc: :boolean, - ram: :boolean + disc: :boolean ] end def merge_defaults(args, opts) do - {args, Map.merge(%{disc: false, ram: false}, opts)} - end - - def validate(_, %{disc: true, ram: true}) do - {:validation_failure, {:bad_argument, "The node type must be either disc or ram."}} + {args, Map.merge(%{disc: false}, opts)} end def validate([], _), do: {:validation_failure, :not_enough_args} def validate([_], _), do: :ok def validate(_, _), do: {:validation_failure, :too_many_args} - def run([target_node], %{node: node_name, ram: ram, disc: disc} = opts) do - node_type = - case {ram, disc} do - {true, false} -> :ram - {false, true} -> :disc - ## disc is default - {false, false} -> :disc - end + def run([target_node], %{node: node_name} = opts) do + node_type = :disc long_or_short_names = Config.get_option(:longnames, opts) target_node_normalised = Helpers.normalise_node(target_node, long_or_short_names) From 6b0bc02f94062041e99c3ab3995d8cec0bf9a734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 12 Dec 2025 13:02:26 +0100 Subject: [PATCH 7/8] fixup! WIP --- deps/rabbit/src/rabbit_db_cluster.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rabbit/src/rabbit_db_cluster.erl b/deps/rabbit/src/rabbit_db_cluster.erl index 902a05505370..772e35aa3f68 100644 --- a/deps/rabbit/src/rabbit_db_cluster.erl +++ b/deps/rabbit/src/rabbit_db_cluster.erl @@ -242,7 +242,7 @@ join(RemoteNode, NodeType) join_using_mnesia(ClusterNodes, disc) when is_list(ClusterNodes) -> rabbit_mnesia:join_cluster(ClusterNodes, disc); -join_using_khepri(_ClusterNodes, ram = NodeType) -> +join_using_mnesia(_ClusterNodes, ram = NodeType) -> {error, {node_type_unsupported, mnesia, NodeType}}. join_using_khepri(ClusterNodes, disc) -> From 9751824e571b35249199cfe36a505e1333650000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 12 Dec 2025 14:30:06 +0100 Subject: [PATCH 8/8] fixup! WIP --- .../lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex index 21f533ca1d74..b354579cc45b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex @@ -19,6 +19,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do {args, Map.merge(%{disc: false}, opts)} end + def validate(_, %{disc: true}) do + {:validation_failure, {:bad_argument, "The node type must be disc."}} + end + def validate([], _), do: {:validation_failure, :not_enough_args} def validate([_], _), do: :ok def validate(_, _), do: {:validation_failure, :too_many_args}