diff --git a/apps/els_core/src/els_config_runtime.erl b/apps/els_core/src/els_config_runtime.erl index 34dcbf5a5..bb3abfb8d 100644 --- a/apps/els_core/src/els_config_runtime.erl +++ b/apps/els_core/src/els_config_runtime.erl @@ -8,6 +8,8 @@ %% Getters -export([ get_node_name/0, + get_hostname/0, + get_domain/0, get_otp_path/0, get_start_cmd/0, get_start_args/0, @@ -20,6 +22,8 @@ -spec default_config() -> config(). default_config() -> #{ + "hostname" => default_hostname(), + "domain" => default_domain(), "node_name" => default_node_name(), "otp_path" => default_otp_path(), "start_cmd" => default_start_cmd(), @@ -31,6 +35,17 @@ get_node_name() -> Value = maps:get("node_name", els_config:get(runtime), default_node_name()), els_utils:compose_node_name(Value, get_name_type()). +-spec get_hostname() -> string(). +get_hostname() -> + case els_config:get(runtime) of + undefined -> default_hostname(); + Runtime -> maps:get("hostname", Runtime, default_hostname()) + end. + +-spec get_domain() -> string(). +get_domain() -> + maps:get("domain", els_config:get(runtime), default_domain()). + -spec get_otp_path() -> string(). get_otp_path() -> maps:get("otp_path", els_config:get(runtime), default_otp_path()). @@ -65,12 +80,21 @@ get_cookie() -> -spec default_node_name() -> string(). default_node_name() -> RootUri = els_config:get(root_uri), - {ok, Hostname} = inet:gethostname(), + Hostname = get_hostname(), NodeName = els_distribution_server:normalize_node_name( filename:basename(els_uri:path(RootUri)) ), NodeName ++ "@" ++ Hostname. +-spec default_hostname() -> string(). +default_hostname() -> + {ok, Hostname} = inet:gethostname(), + Hostname. + +-spec default_domain() -> string(). +default_domain() -> + proplists:get_value(domain, inet:get_rc(), ""). + -spec default_otp_path() -> string(). default_otp_path() -> filename:dirname(filename:dirname(code:root_dir())). diff --git a/apps/els_core/src/els_distribution_server.erl b/apps/els_core/src/els_distribution_server.erl index 6b30da914..97efca4ba 100644 --- a/apps/els_core/src/els_distribution_server.erl +++ b/apps/els_core/src/els_distribution_server.erl @@ -18,7 +18,6 @@ rpc_call/3, rpc_call/4, node_name/2, - node_name/3, normalize_node_name/1 ]). @@ -223,15 +222,7 @@ node_name(Prefix, Name0) -> Name = normalize_node_name(Name0), Int = erlang:phash2(erlang:timestamp()), Id = lists:flatten(io_lib:format("~s_~s_~p", [Prefix, Name, Int])), - {ok, HostName} = inet:gethostname(), - node_name(Id, HostName, els_config_runtime:get_name_type()). - --spec node_name(string(), string(), 'longnames' | 'shortnames') -> atom(). -node_name(Id, HostName, shortnames) -> - list_to_atom(Id ++ "@" ++ HostName); -node_name(Id, HostName, longnames) -> - Domain = proplists:get_value(domain, inet:get_rc(), ""), - list_to_atom(Id ++ "@" ++ HostName ++ "." ++ Domain). + els_utils:compose_node_name(Id, els_config_runtime:get_name_type()). -spec normalize_node_name(string() | binary()) -> string(). normalize_node_name(Name) -> diff --git a/apps/els_core/src/els_utils.erl b/apps/els_core/src/els_utils.erl index edb562436..242ee2589 100644 --- a/apps/els_core/src/els_utils.erl +++ b/apps/els_core/src/els_utils.erl @@ -453,15 +453,18 @@ compose_node_name(Name, Type) -> true -> Name; _ -> - {ok, HostName} = inet:gethostname(), + HostName = els_config_runtime:get_hostname(), Name ++ [$@ | HostName] end, case Type of shortnames -> list_to_atom(NodeName); longnames -> - Domain = proplists:get_value(domain, inet:get_rc(), ""), - list_to_atom(NodeName ++ "." ++ Domain) + Domain = els_config_runtime:get_domain(), + case Domain of + "" -> list_to_atom(NodeName); + _ -> list_to_atom(NodeName ++ "." ++ Domain) + end end. %% @doc Given an MFA or a FA, return a printable version of the diff --git a/apps/els_dap/src/els_dap_general_provider.erl b/apps/els_dap/src/els_dap_general_provider.erl index da3ee1888..46a9b0878 100644 --- a/apps/els_dap/src/els_dap_general_provider.erl +++ b/apps/els_dap/src/els_dap_general_provider.erl @@ -1023,22 +1023,6 @@ safe_eval(ProjectNode, Debugged, Expression, Update) -> end, Return. --spec check_project_node_name(binary(), boolean()) -> atom(). -check_project_node_name(ProjectNode, false) -> - binary_to_atom(ProjectNode, utf8); -check_project_node_name(ProjectNode, true) -> - case binary:match(ProjectNode, <<"@">>) of - nomatch -> - {ok, HostName} = inet:gethostname(), - BinHostName = list_to_binary(HostName), - DomainStr = proplists:get_value(domain, inet:get_rc(), ""), - Domain = list_to_binary(DomainStr), - BinName = <>, - binary_to_atom(BinName, utf8); - _ -> - binary_to_atom(ProjectNode, utf8) - end. - -spec start_distribution(map()) -> {ok, map()} | {error, any()}. start_distribution(Params) -> #{<<"cwd">> := Cwd} = Params, @@ -1062,10 +1046,6 @@ start_distribution(Params) -> <<"cookie">> := ConfCookie, <<"use_long_names">> := UseLongNames } = Config, - ConfProjectNode = check_project_node_name(RawProjectNode, UseLongNames), - ?LOG_INFO("Configured Project Node Name: ~p", [ConfProjectNode]), - Cookie = binary_to_atom(ConfCookie, utf8), - NameType = case UseLongNames of true -> @@ -1073,12 +1053,14 @@ start_distribution(Params) -> false -> shortnames end, + + ConfProjectNode0 = binary_to_list(RawProjectNode), + ConfProjectNode = els_utils:compose_node_name(ConfProjectNode0, NameType), + ?LOG_INFO("Configured Project Node Name: ~p", [ConfProjectNode]), + Cookie = binary_to_atom(ConfCookie, utf8), + %% start distribution - Prefix = <<"erlang_ls_dap">>, - Int = erlang:phash2(erlang:timestamp()), - Id = lists:flatten(io_lib:format("~s_~s_~p", [Prefix, Name, Int])), - {ok, HostName} = inet:gethostname(), - LocalNode = els_distribution_server:node_name(Id, HostName, NameType), + LocalNode = els_distribution_server:node_name(<<"erlang_ls_dap">>, Name), case els_distribution_server:start_distribution( LocalNode, diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 5e048ac9a..618e769cd 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -28,6 +28,8 @@ compiler_telemetry/1, code_path_extra_dirs/1, use_long_names/1, + use_long_names_no_domain/1, + use_long_names_custom_hostname/1, epp_with_nonexistent_macro/1, code_reload/1, code_reload_sticky_mod/1, @@ -120,15 +122,20 @@ init_per_testcase(code_path_extra_dirs, Config) -> els_mock_diagnostics:setup(), els_test_utils:init_per_testcase(code_path_extra_dirs, Config); init_per_testcase(use_long_names, Config) -> - meck:new(yamerl, [passthrough, no_link]), + Content = + <<"runtime:\n", " use_long_names: true\n", " cookie: mycookie\n", + " node_name: my_node\n", " domain: test.local">>, + init_long_names_config(Content, Config); +init_per_testcase(use_long_names_no_domain, Config) -> Content = <<"runtime:\n", " use_long_names: true\n", " cookie: mycookie\n", " node_name: my_node\n">>, - meck:expect(yamerl, decode_file, 2, fun(_, Opts) -> - yamerl:decode(Content, Opts) - end), - els_mock_diagnostics:setup(), - els_test_utils:init_per_testcase(code_path_extra_dirs, Config); + init_long_names_config(Content, Config); +init_per_testcase(use_long_names_custom_hostname, Config) -> + Content = + <<"runtime:\n", " use_long_names: true\n", " cookie: mycookie\n", + " node_name: my_node\n", " hostname: 127.0.0.1">>, + init_long_names_config(Content, Config); init_per_testcase(exclude_unused_includes = TestCase, Config) -> els_mock_diagnostics:setup(), NewConfig = els_test_utils:init_per_testcase(TestCase, Config), @@ -224,7 +231,9 @@ end_per_testcase(TestCase, Config) when ok; end_per_testcase(TestCase, Config) when TestCase =:= code_path_extra_dirs orelse - TestCase =:= use_long_names + TestCase =:= use_long_names orelse + TestCase =:= use_long_names_no_domain orelse + TestCase =:= use_long_names_custom_hostname -> meck:unload(yamerl), els_test_utils:end_per_testcase(code_path_extra_dirs, Config), @@ -271,6 +280,15 @@ end_per_testcase(TestCase, Config) -> els_mock_diagnostics:teardown(), ok. +-spec init_long_names_config(binary(), config()) -> config(). +init_long_names_config(Content, Config) -> + meck:new(yamerl, [passthrough, no_link]), + meck:expect(yamerl, decode_file, 2, fun(_, Opts) -> + yamerl:decode(Content, Opts) + end), + els_mock_diagnostics:setup(), + els_test_utils:init_per_testcase(code_path_extra_dirs, Config). + % RefactorErl %%============================================================================== @@ -626,12 +644,30 @@ code_path_extra_dirs(_Config) -> -spec use_long_names(config()) -> ok. use_long_names(_Config) -> - {ok, HostName} = inet:gethostname(), + HostName = els_config_runtime:get_hostname(), NodeName = "my_node@" ++ HostName ++ "." ++ - proplists:get_value(domain, inet:get_rc(), ""), + els_config_runtime:get_domain(), + Node = list_to_atom(NodeName), + ?assertMatch(Node, els_config_runtime:get_node_name()), + ok. + +-spec use_long_names_no_domain(config()) -> ok. +use_long_names_no_domain(_Config) -> + HostName = els_config_runtime:get_hostname(), + NodeName = + "my_node@" ++ HostName, + Node = list_to_atom(NodeName), + ?assertMatch(Node, els_config_runtime:get_node_name()), + ok. + +-spec use_long_names_custom_hostname(config()) -> ok. +use_long_names_custom_hostname(_Config) -> + HostName = els_config_runtime:get_hostname(), + NodeName = "my_node@127.0.0.1", Node = list_to_atom(NodeName), + ?assertMatch(HostName, "127.0.0.1"), ?assertMatch(Node, els_config_runtime:get_node_name()), ok.