/rel/files/nodetool
#! | 116 lines | 106 code | 10 blank | 0 comment | 0 complexity | 9082f7a09ec9fb94800c6572c31409f2 MD5 | raw file
1%% -*- mode:erlang;tab-width:4;erlang-indent-level:4;indent-tabs-mode:nil -*- 2%% ex: ft=erlang ts=4 sw=4 et 3%% ------------------------------------------------------------------- 4%% 5%% nodetool: Helper Script for interacting with live nodes 6%% 7%% ------------------------------------------------------------------- 8 9main(Args) -> 10 %% Extract the args 11 {RestArgs, TargetNode} = process_args(Args, [], undefined), 12 13 %% See if the node is currently running -- if it's not, we'll bail 14 case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of 15 {true, pong} -> 16 ok; 17 {_, pang} -> 18 io:format("Node ~p not responding to pings.\n", [TargetNode]), 19 halt(1) 20 end, 21 22 case RestArgs of 23 ["ping"] -> 24 %% If we got this far, the node already responsed to a ping, so just dump 25 %% a "pong" 26 io:format("pong\n"); 27 ["stop"] -> 28 io:format("~p\n", [rpc:call(TargetNode, init, stop, [], 60000)]); 29 ["restart"] -> 30 io:format("~p\n", [rpc:call(TargetNode, init, restart, [], 60000)]); 31 ["reboot"] -> 32 io:format("~p\n", [rpc:call(TargetNode, init, reboot, [], 60000)]); 33 ["rpc", Module, Function | RpcArgs] -> 34 case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), 35 [RpcArgs], 60000) of 36 ok -> 37 ok; 38 {badrpc, Reason} -> 39 io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), 40 halt(1); 41 _ -> 42 halt(1) 43 end; 44 ["rpcterms", Module, Function, ArgsAsString] -> 45 case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), 46 consult(ArgsAsString), 60000) of 47 {badrpc, Reason} -> 48 io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), 49 halt(1); 50 Other -> 51 io:format("~p\n", [Other]) 52 end; 53 Other -> 54 io:format("Other: ~p\n", [Other]), 55 io:format("Usage: nodetool {ping|stop|restart|reboot}\n") 56 end, 57 net_kernel:stop(). 58 59process_args([], Acc, TargetNode) -> 60 {lists:reverse(Acc), TargetNode}; 61process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) -> 62 erlang:set_cookie(node(), list_to_atom(Cookie)), 63 process_args(Rest, Acc, TargetNode); 64process_args(["-name", TargetName | Rest], Acc, _) -> 65 ThisNode = append_node_suffix(TargetName, "_maint_"), 66 {ok, _} = net_kernel:start([ThisNode, longnames]), 67 process_args(Rest, Acc, nodename(TargetName)); 68process_args(["-sname", TargetName | Rest], Acc, _) -> 69 ThisNode = append_node_suffix(TargetName, "_maint_"), 70 {ok, _} = net_kernel:start([ThisNode, shortnames]), 71 process_args(Rest, Acc, nodename(TargetName)); 72process_args([Arg | Rest], Acc, Opts) -> 73 process_args(Rest, [Arg | Acc], Opts). 74 75 76nodename(Name) -> 77 case string:tokens(Name, "@") of 78 [_Node, _Host] -> 79 list_to_atom(Name); 80 [Node] -> 81 [_, Host] = string:tokens(atom_to_list(node()), "@"), 82 list_to_atom(lists:concat([Node, "@", Host])) 83 end. 84 85append_node_suffix(Name, Suffix) -> 86 case string:tokens(Name, "@") of 87 [Node, Host] -> 88 list_to_atom(lists:concat([Node, Suffix, os:getpid(), "@", Host])); 89 [Node] -> 90 list_to_atom(lists:concat([Node, Suffix, os:getpid()])) 91 end. 92 93 94%% 95%% Given a string or binary, parse it into a list of terms, ala file:consult/0 96%% 97consult(Str) when is_list(Str) -> 98 consult([], Str, []); 99consult(Bin) when is_binary(Bin)-> 100 consult([], binary_to_list(Bin), []). 101 102consult(Cont, Str, Acc) -> 103 case erl_scan:tokens(Cont, Str, 0) of 104 {done, Result, Remaining} -> 105 case Result of 106 {ok, Tokens, _} -> 107 {ok, Term} = erl_parse:parse_term(Tokens), 108 consult([], Remaining, [Term | Acc]); 109 {eof, _Other} -> 110 lists:reverse(Acc); 111 {error, Info, _} -> 112 {error, Info} 113 end; 114 {more, Cont1} -> 115 consult(Cont1, eof, Acc) 116 end.