Просмотр исходного кода

feat(bin/emqx): add cold_eval nodetool command

Zaiming Shi 4 лет назад
Родитель
Сommit
6f99f14540
2 измененных файлов с 49 добавлено и 33 удалено
  1. 10 9
      bin/emqx
  2. 39 24
      bin/nodetool

+ 10 - 9
bin/emqx

@@ -14,6 +14,11 @@ ROOT_DIR="$(cd "$(dirname "$(readlink "$0" || echo "$0")")"/..; pwd -P)"
 # shellcheck disable=SC1090
 . "$ROOT_DIR"/releases/emqx_vars
 
+# defined in emqx_vars
+export RUNNER_ROOT_DIR
+export RUNNER_ETC_DIR
+export REL_VSN
+
 RUNNER_SCRIPT="$RUNNER_BIN_DIR/$REL_NAME"
 CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
 REL_DIR="$RUNNER_ROOT_DIR/releases/$REL_VSN"
@@ -109,7 +114,7 @@ relx_usage() {
             echo "                      don't make it permanent"
             ;;
         *)
-            echo "Usage: $REL_NAME {start|start_boot <file>|ertspath|foreground|stop|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|uninstall|versions|escript|ctl|rpc|rpcterms|eval|root_dir}"
+            echo "Usage: $REL_NAME {start|start_boot <file>|ertspath|foreground|stop|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|uninstall|versions|escript|ctl|rpc|rpcterms|eval|cold_eval|root_dir}"
             ;;
     esac
 }
@@ -198,18 +203,12 @@ relx_gen_id() {
 # Control a node
 relx_nodetool() {
     command="$1"; shift
-    export RUNNER_ROOT_DIR
-    export REL_VSN
-
     ERL_FLAGS="$ERL_FLAGS $EPMD_ARG" \
     "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
                                 -setcookie "$COOKIE" "$command" "$@"
 }
 
 call_hocon() {
-    export RUNNER_ROOT_DIR
-    export RUNNER_ETC_DIR
-    export REL_VSN
     "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" hocon "$@" \
         || die "call_hocon_failed: $*" $?
 }
@@ -217,8 +216,6 @@ call_hocon() {
 # Run an escript in the node's environment
 relx_escript() {
     shift; scriptpath="$1"; shift
-    export RUNNER_ROOT_DIR
-
     "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" "$@"
 }
 
@@ -709,6 +706,10 @@ case "$1" in
         shift
         relx_nodetool "eval" "$@"
         ;;
+    cold_eval)
+        shift;
+        "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" cold_eval "$@"
+        ;;
     *)
         relx_usage "$1"
         exit 1

+ 39 - 24
bin/nodetool

@@ -24,6 +24,8 @@ main(Args) ->
         ["hocon" | Rest] ->
             %% forward the call to hocon_cli
             hocon_cli:main(Rest);
+        ["cold_eval" | Rest] ->
+            code_eval(Rest);
         _ ->
             do(Args)
     end.
@@ -117,40 +119,53 @@ do(Args) ->
                     io:format("~p\n", [Other])
             end;
         ["eval" | ListOfArgs] ->
-            % shells may process args into more than one, and end up stripping
-            % spaces, so this converts all of that to a single string to parse
-            String = binary_to_list(
-                      list_to_binary(
-                        join(ListOfArgs," ")
-                      )
-                    ),
-
-            % then just as a convenience to users, if they forgot a trailing
-            % '.' add it for them.
-            Normalized =
-              case lists:reverse(String) of
-                [$. | _] -> String;
-                R -> lists:reverse([$. | R])
-              end,
-
-            % then scan and parse the string
-            {ok, Scanned, _} = erl_scan:string(Normalized),
-            {ok, Parsed } = erl_parse:parse_exprs(Scanned),
-
+            Parsed = parse_eval_args(ListOfArgs),
             % and evaluate it on the remote node
             case rpc:call(TargetNode, erl_eval, exprs, [Parsed, [] ]) of
                 {value, Value, _} ->
-                    io:format ("~p\n",[Value]);
+                    io:format ("~p~n",[Value]);
                 {badrpc, Reason} ->
-                    io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]),
+                    io:format("RPC to ~p failed: ~p~n", [TargetNode, Reason]),
                     halt(1)
             end;
         Other ->
-            io:format("Other: ~p\n", [Other]),
-            io:format("Usage: nodetool {genconfig, chkconfig|getpid|ping|stop|rpc|rpc_infinity|rpcterms|eval [Terms]} [RPC]\n")
+            io:format("Other: ~p~n", [Other]),
+            io:format("Usage: nodetool chkconfig|getpid|ping|stop|rpc|rpc_infinity|rpcterms|eval|cold_eval [Terms] [RPC]\n")
     end,
     net_kernel:stop().
 
+code_eval(Args) ->
+    Parsed = parse_eval_args(Args),
+    case erl_eval:exprs(Parsed, []) of
+        {value, Value, _} ->
+            io:format ("~p~n", [Value]);
+        Other ->
+            io:format("cold_eval_failed_with: ~p~n", [Other]),
+            halt(1)
+    end.
+
+parse_eval_args(Args) ->
+    % shells may process args into more than one, and end up stripping
+    % spaces, so this converts all of that to a single string to parse
+    String = binary_to_list(
+                list_to_binary(
+                join(Args," ")
+                )
+            ),
+
+    % then just as a convenience to users, if they forgot a trailing
+    % '.' add it for them.
+    Normalized =
+        case lists:reverse(String) of
+        [$. | _] -> String;
+        R -> lists:reverse([$. | R])
+        end,
+
+    % then scan and parse the string
+    {ok, Scanned, _} = erl_scan:string(Normalized),
+    {ok, Parsed } = erl_parse:parse_exprs(Scanned),
+    Parsed.
+
 do_with_ret(Args, Name, Handler) ->
     {arity, Arity} = erlang:fun_info(Handler, arity),
     case take_args(Args, Name, Arity) of