No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

111 líneas
3.5 KiB

  1. %%% Common functions to boot/stop distributed setups for
  2. %%% the rebar3 script.
  3. -module(rebar_dist_utils).
  4. -export([either/3, short/2, long/2, find_options/1]).
  5. -include("rebar.hrl").
  6. %%%%%%%%%%%%%%%%%%
  7. %%% PUBLIC API %%%
  8. %%%%%%%%%%%%%%%%%%
  9. %% @doc allows to pick whether to use a short or long name, and
  10. %% starts the distributed mode for it.
  11. -spec either(Name::atom(), SName::atom(), Opts::[{setcookie,term()}]) -> atom().
  12. either(undefined, undefined, _) ->
  13. 'nonode@nohost';
  14. either(Name, undefined, Opts) ->
  15. long(Name, Opts),
  16. node();
  17. either(undefined, SName, Opts) ->
  18. short(SName, Opts),
  19. node();
  20. either(_, _, _) ->
  21. ?ABORT("Cannot have both short and long node names defined", []).
  22. %% @doc starts a node with a short name.
  23. -spec short(SName::atom(), Opts::[{setcookie,term()}]) -> term().
  24. short(Name, Opts) ->
  25. start(Name, shortnames, Opts).
  26. %% @doc starts a node with a long name.
  27. -spec long(Name::atom(), Opts::[{setcookie,term()}]) -> term().
  28. long(Name, Opts) ->
  29. start(Name, longnames, Opts).
  30. %% @doc utility function to extract all distribution options
  31. %% from a rebar3 state tuple.
  32. -spec find_options(rebar_state:t()) -> {Long, Short, Opts} when
  33. Long :: atom(),
  34. Short :: atom(),
  35. Opts :: [{setcookie,term()}].
  36. find_options(State) ->
  37. {Long, Short} = find_name_options(State),
  38. case find_cookie_option(State) of
  39. nocookie ->
  40. {Long, Short, []};
  41. Cookie ->
  42. {Long, Short, [{setcookie, Cookie}]}
  43. end.
  44. %%%%%%%%%%%%%%%
  45. %%% PRIVATE %%%
  46. %%%%%%%%%%%%%%%
  47. start(Name, Type, Opts) ->
  48. case dist_up(net_kernel:start([Name, Type])) of
  49. false ->
  50. start_epmd(),
  51. dist_up(net_kernel:start([Name, Type])) orelse warn_dist();
  52. true ->
  53. ok
  54. end,
  55. setup_cookie(Opts).
  56. dist_up({error,{{shutdown,{_,net_kernel,{'EXIT',nodistribution}}},_}}) -> false;
  57. dist_up(_) -> true.
  58. start_epmd() ->
  59. %% Indirectly boot EPMD through calling Erlang so that we don't risk
  60. %% attaching it to the current proc
  61. ?CONSOLE("Attempting to start epmd...", []),
  62. os:cmd("erl -sname a -noinput -eval \"halt(0).\"").
  63. warn_dist() ->
  64. ?ERROR("Erlang Distribution failed, falling back to nonode@nohost.", []).
  65. setup_cookie(Opts) ->
  66. case {node(), proplists:get_value(setcookie, Opts, nocookie)} of
  67. {'nonode@nohost', _} -> nocookie;
  68. {_, nocookie} -> nocookie;
  69. {Node, Name} -> erlang:set_cookie(Node, Name)
  70. end.
  71. find_name_options(State) ->
  72. {Opts, _} = rebar_state:command_parsed_args(State),
  73. %% First try the CLI
  74. case {proplists:get_value(name, Opts), proplists:get_value(sname, Opts)} of
  75. {undefined, undefined} ->
  76. %% Else try the config file
  77. DistOpts = rebar_state:get(State, dist_node, []),
  78. %% Pick the first one seen to support profile merges
  79. find_first_name(DistOpts);
  80. Res ->
  81. Res
  82. end.
  83. find_first_name([]) -> {undefined, undefined};
  84. find_first_name([{sname,Val}|_]) -> {undefined, Val};
  85. find_first_name([{name,Val}|_]) -> {Val, undefined};
  86. find_first_name([_|Opts]) -> find_first_name(Opts).
  87. find_cookie_option(State) ->
  88. {Opts, _} = rebar_state:command_parsed_args(State),
  89. %% First try the CLI
  90. case proplists:get_value(setcookie, Opts) of
  91. undefined ->
  92. %% Else try the config file
  93. DistOpts = rebar_state:get(State, dist_node, []),
  94. proplists:get_value(setcookie, DistOpts, nocookie);
  95. Res ->
  96. Res
  97. end.