From f00a952bd5e133cad30689d9edcc98f5d33a71a9 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Thu, 16 Jun 2016 16:44:48 +0200 Subject: [PATCH] Enable dump/restore users from RabbitMQ ver. 3.6.x RabbitMQ changed internal_users scheme since ver. 3.6.0. See the following links for further details: * rabbitmq/rabbitmq-server#270 * rabbitmq/rabbitmq-server#310 * rabbitmq/rabbitmq-common@9c86a7401cf464dc20527890192c5dc0fe43b6c8 * rabbitmq/rabbitmq-server@93b5a3a8092f52063cbca3ab661c7c6bae43c512 CC @oalbrigt Signed-off-by: Peter Lemenkov --- heartbeat/rabbitmq-cluster | 64 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/heartbeat/rabbitmq-cluster b/heartbeat/rabbitmq-cluster index 0724901..facca35 100755 --- a/heartbeat/rabbitmq-cluster +++ b/heartbeat/rabbitmq-cluster @@ -342,14 +342,40 @@ rmq_start() { rmq_join_existing "$join_list" rc=$? - # Restore users (if any) - BaseDataDir=`dirname $RMQ_DATA_DIR` - if [ -f $BaseDataDir/users.erl ] ; then - rabbitmqctl eval " - {ok, [Users]} = file:consult(\"$BaseDataDir/users.erl\"), - lists:foreach(fun(X) -> mnesia:dirty_write(rabbit_user, X) end, Users). - " - rm -f $BaseDataDir/users.erl + # Restore users (if any) + BaseDataDir=`dirname $RMQ_DATA_DIR` + if [ -f $BaseDataDir/users.erl ] ; then + rabbitmqctl eval " + + [WildPattern] = ets:select(mnesia_gvar, [ { {{rabbit_user, wild_pattern}, '\\\$1'}, [], ['\\\$1'] } ]), + + %% Read users first + {ok, [Users]} = file:consult(\"$BaseDataDir/users.erl\"), + + Upgrade = fun + ({internal_user, A, B, C}) -> {internal_user, A, B, C, rabbit_password_hashing_md5}; + ({internal_user, A, B, C, D}) -> {internal_user, A, B, C, D} + end, + + Downgrade = fun + ({internal_user, A, B, C}) -> {internal_user, A, B, C}; + ({internal_user, A, B, C, rabbit_password_hashing_md5}) -> {internal_user, A, B, C}; + %% Incompatible scheme, so we will loose user's password ('B' value) during conversion. + %% Unfortunately, this case will require manual intervention - user have to run: + %% rabbitmqctl change_password + ({internal_user, A, B, C, _}) -> {internal_user, A, B, C} + end, + + case WildPattern of + %% Version < 3.6.0 + {internal_user,'_','_','_'} -> + lists:foreach(fun(X) -> mnesia:dirty_write(rabbit_user, Downgrade(X)) end, Users); + %% Version >= 3.6.0 + {internal_user,'_','_','_','_'} -> + lists:foreach(fun(X) -> mnesia:dirty_write(rabbit_user, Upgrade(X)) end, Users) + end. + " + rm -f $BaseDataDir/users.erl fi if [ $rc -ne 0 ]; then @@ -362,12 +388,22 @@ rmq_start() { } rmq_stop() { - # Backup users - BaseDataDir=`dirname $RMQ_DATA_DIR` - rabbitmqctl eval " - Users = mnesia:dirty_select(rabbit_user, [{ {internal_user, '\\\$1', '_', '_'}, [{'/=', '\\\$1', <<\"guest\">>}], ['\\\$_'] } ]), - file:write_file(\"$BaseDataDir/users.erl\", io_lib:fwrite(\"~p.~n\", [Users])). - " + # Backup users + BaseDataDir=`dirname $RMQ_DATA_DIR` + rabbitmqctl eval " + [WildPattern] = ets:select(mnesia_gvar, [ { {{rabbit_user, wild_pattern}, '\\\$1'}, [], ['\\\$1'] } ]), + + Users = case WildPattern of + %% Version < 3.6.0 + {internal_user,'_','_','_'} -> + mnesia:dirty_select(rabbit_user, [{ {internal_user, '\\\$1', '_', '_'}, [{'/=', '\\\$1', <<\"guest\">>}], ['\\\$_'] } ]); + %% Version >= 3.6.0 + {internal_user,'_','_','_','_'} -> + mnesia:dirty_select(rabbit_user, [{ {internal_user, '\\\$1', '_', '_', '_'}, [{'/=', '\\\$1', <<\"guest\">>}], ['\\\$_'] } ]) + end, + + file:write_file(\"$BaseDataDir/users.erl\", io_lib:fwrite(\"~p.~n\", [Users])). + " rmq_monitor if [ $? -eq $OCF_NOT_RUNNING ]; then