<commit_before>%% @author Northscale <<EMAIL>>
%% @copyright 2009 NorthScale, Inc.
%%
%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% Distributed erlang configuration and management
%%
-module(dist_manager).

-behaviour(gen_server).

-include("ns_common.hrl").

-export([start_link/0]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-export([adjust_my_address/1, read_address_config/0, save_address_config/1, ip_config_path/0]).

-record(state, {self_started, my_ip}).

-define(WAIT_FOR_ADDRESS_ATTEMPTS, 10).
-define(WAIT_FOR_ADDRESS_SLEEP, 1000).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

ip_config_path() ->
    path_config:component_path(data, "ip").

strip_full(String) ->
    String2 = string:strip(String),
    String3 = string:strip(String2, both, $\n),
    String4 = string:strip(String3, both, $\r),
    case String4 =:= String of
        true ->
            String4;
        _ ->
            strip_full(String4)
    end.

read_address_config() ->
    Path = ip_config_path(),
    ?log_info("Reading ip config from ~p", [Path]),
    case file:read_file(Path) of
        {ok, BinaryContents} ->
            strip_full(binary_to_list(BinaryContents));
        {error, enoent} ->
            ?log_info("ip config not found. Looks like we're brand new node"),
            undefined;
        {error, Error} ->
            ?log_error("Failed to read ip config from `~s`: ~p",
                       [Path, Error]),
            read_error
    end.

is_good_address(AddrString) ->
    case inet:getaddr(AddrString, inet) of
        {error, Errno1} ->
            ?log_warning("Could not resolve address `~s`: ~p",
                         [AddrString, Errno1]),
            false;
        {ok, IpAddr} ->
            case gen_udp:open(0, [inet, {ip, IpAddr}]) of
                {error, Errno2} ->
                    ?log_warning("Cannot listen on address `~s`: ~p",
                                 [AddrString, Errno2]),
                    false;
                {ok, Socket} ->
                    gen_udp:close(Socket),
                    true
            end
    end.

wait_for_address(Address) ->
    wait_for_address(Address, ?WAIT_FOR_ADDRESS_ATTEMPTS).

wait_for_address(_Address, 0) ->
    bad_address;
wait_for_address(Address, N) ->
    case is_good_address(Address) of
        true ->
            ok;
        false ->
            ?log_info("Configured address `~s` seems to be invalid. "
                      "Giving OS a chance to bring it up.", [Address]),
            timer:sleep(?WAIT_FOR_ADDRESS_SLEEP),
            wait_for_address(Address, N - 1)
    end.

save_address_config(State) ->
    Path = ip_config_path(),
    ?log_info("saving ip config to ~p", [Path]),
    misc:atomic_write_file(Path, State#state.my_ip).

save_node(NodeName, Path) ->
    ?log_info("saving node to ~p", [Path]),
    misc:atomic_write_file(Path, NodeName ++ "\n").

save_node(NodeName) ->
    case application:get_env(nodefile) of
        {ok, NodeFile} -> save_node(NodeName, NodeFile);
        X -> X
    end.

init([]) ->
    Address =
        case read_address_config() of
            undefined ->
                "127.0.0.1";
            read_error ->
                ?log_error("Could not read ip config. "
                           "Will refuse to start for safety reasons."),
                ale:sync(?NS_SERVER_LOGGER),
                erlang:halt(1);<commit_msg>MB-5627 Handle empty ip configuration file.<commit_after>%% @author Northscale <<EMAIL>>
%% @copyright 2009 NorthScale, Inc.
%%
%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% Distributed erlang configuration and management
%%
-module(dist_manager).

-behaviour(gen_server).

-include("ns_common.hrl").

-export([start_link/0]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-export([adjust_my_address/1, read_address_config/0, save_address_config/1, ip_config_path/0]).

-record(state, {self_started, my_ip}).

-define(WAIT_FOR_ADDRESS_ATTEMPTS, 10).
-define(WAIT_FOR_ADDRESS_SLEEP, 1000).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

ip_config_path() ->
    path_config:component_path(data, "ip").

strip_full(String) ->
    String2 = string:strip(String),
    String3 = string:strip(String2, both, $\n),
    String4 = string:strip(String3, both, $\r),
    case String4 =:= String of
        true ->
            String4;
        _ ->
            strip_full(String4)
    end.

read_address_config() ->
    Path = ip_config_path(),
    ?log_info("Reading ip config from ~p", [Path]),
    case file:read_file(Path) of
        {ok, BinaryContents} ->
            case strip_full(binary_to_list(BinaryContents)) of
                "" ->
                    undefined;
                V ->
                    V
            end;
        {error, enoent} ->
            undefined;
        {error, Error} ->
            ?log_error("Failed to read ip config from `~s`: ~p",
                       [Path, Error]),
            read_error
    end.

is_good_address(AddrString) ->
    case inet:getaddr(AddrString, inet) of
        {error, Errno1} ->
            ?log_warning("Could not resolve address `~s`: ~p",
                         [AddrString, Errno1]),
            false;
        {ok, IpAddr} ->
            case gen_udp:open(0, [inet, {ip, IpAddr}]) of
                {error, Errno2} ->
                    ?log_warning("Cannot listen on address `~s`: ~p",
                                 [AddrString, Errno2]),
                    false;
                {ok, Socket} ->
                    gen_udp:close(Socket),
                    true
            end
    end.

wait_for_address(Address) ->
    wait_for_address(Address, ?WAIT_FOR_ADDRESS_ATTEMPTS).

wait_for_address(_Address, 0) ->
    bad_address;
wait_for_address(Address, N) ->
    case is_good_address(Address) of
        true ->
            ok;
        false ->
            ?log_info("Configured address `~s` seems to be invalid. "
                      "Giving OS a chance to bring it up.", [Address]),
            timer:sleep(?WAIT_FOR_ADDRESS_SLEEP),
            wait_for_address(Address, N - 1)
    end.

save_address_config(State) ->
    Path = ip_config_path(),
    ?log_info("saving ip config to ~p", [Path]),
    misc:atomic_write_file(Path, State#state.my_ip).

save_node(NodeName, Path) ->
    ?log_info("saving node to ~p", [Path]),
    misc:atomic_write_file(Path, NodeName ++ "\n").

save_node(NodeName) ->
    case application:get_env(nodefile) of
        {ok, NodeFile} -> save_node(NodeName, NodeFile);
        X -> X
    end.

init([]) ->
    Address =
        case read_address_config() of
            undefined ->
                ?log_info("ip config not found. Looks like we're brand new node"),
                "127.0.0.1";
            read_error ->
                ?log_error("Could not read ip config. "
                           "Will refuse to start for safety reasons."),
                ale:sync(?NS_SERVER_LOGGER),
                erlang:halt(1);
{'fraction_non_alphanumeric': 0.1263533464566929, 'fraction_numerical': 0.012057086614173228, 'mean_word_length': 2.2502998800479808, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7420907', 'n_tokens_mistral': 2539, 'n_tokens_neox': 2447, 'n_words': 630}