1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (the "License"); you may not use this file except in
%% compliance with the License. You may obtain a copy of the License
%% at http://www.mozilla.org/MPL/
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and
%% limitations under the License.
%%
%% The Original Code is RabbitMQ.
%%
%% The Initial Developer of the Original Code is VMware, Inc.
%% Copyright (c) 2007-2012 VMware, Inc. All rights reserved.
%%
-module(rabbit_nodes).
-export([names/1, diagnostics/1, make/1, parts/1, cookie_hash/0]).
-define(EPMD_TIMEOUT, 30000).
%%----------------------------------------------------------------------------
%% Specs
%%----------------------------------------------------------------------------
-ifdef(use_specs).
-spec(names/1 :: (string()) -> rabbit_types:ok_or_error2(
[{string(), integer()}], term())).
-spec(diagnostics/1 :: ([node()]) -> string()).
-spec(make/1 :: ({string(), string()} | string()) -> node()).
-spec(parts/1 :: (node() | string()) -> {string(), string()}).
-spec(cookie_hash/0 :: () -> string()).
-endif.
%%----------------------------------------------------------------------------
names(Hostname) ->
Self = self(),
process_flag(trap_exit, true),
Pid = spawn_link(fun () -> Self ! {names, net_adm:names(Hostname)} end),
timer:exit_after(?EPMD_TIMEOUT, Pid, timeout),
Res = receive
{names, Names} -> Names;
{'EXIT', Pid, Reason} -> {error, Reason}
end,
process_flag(trap_exit, false),
Res.
diagnostics(Nodes) ->
Hosts = lists:usort([element(2, parts(Node)) || Node <- Nodes]),
NodeDiags = [{"~nDIAGNOSTICS~n===========~n~n"
"nodes in question: ~p~n~n"
"hosts, their running nodes and ports:", [Nodes]}] ++
[diagnostics_host(Host) || Host <- Hosts] ++
diagnostics0(),
lists:flatten([io_lib:format(F ++ "~n", A) || NodeDiag <- NodeDiags,
{F, A} <- [NodeDiag]]).
diagnostics0() ->
[{"~ncurrent node details:~n- node name: ~w", [node()]},
case init:get_argument(home) of
{ok, [[Home]]} -> {"- home dir: ~s", [Home]};
Other -> {"- no home dir: ~p", [Other]}
end,
{"- cookie hash: ~s", [cookie_hash()]}].
diagnostics_host(Host) ->
case names(Host) of
{error, EpmdReason} ->
{"- unable to connect to epmd on ~s: ~w",
[Host, EpmdReason]};
{ok, NamePorts} ->
{"- ~s: ~p",
[Host, [{list_to_atom(Name), Port} ||
{Name, Port} <- NamePorts]]}
end.
make({Prefix, Suffix}) -> list_to_atom(lists:append([Prefix, "@", Suffix]));
make(NodeStr) -> make(parts(NodeStr)).
parts(Node) when is_atom(Node) ->
parts(atom_to_list(Node));
parts(NodeStr) ->
case lists:splitwith(fun (E) -> E =/= $@ end, NodeStr) of
{Prefix, []} -> {_, Suffix} = parts(node()),
{Prefix, Suffix};
{Prefix, Suffix} -> {Prefix, tl(Suffix)}
end.
cookie_hash() ->
base64:encode_to_string(erlang:md5(atom_to_list(erlang:get_cookie()))).
|