From d78af6a84362d828756d6916b84812c0d9429b83 Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Wed, 8 Aug 2018 00:51:49 +0100 Subject: Check for pipe write permission on start/attach A common pitfall when starting up Erlang nodes is to start them as root and then fail silently when switching to another user, improve this by providing a helpful error message when this happens. --- priv/templates/extended_bin | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 11a0abc..78f25e0 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -492,6 +492,11 @@ case "$1" in test -z "$PIPE_BASE_DIR" || mkdir -m 1777 -p "$PIPE_BASE_DIR" mkdir -p "$PIPE_DIR" + if [ ! -w "$PIPE_DIR" ] + then + echo "failed to start, user '$USER' does not have write privileges on '$PIPE_DIR', either delete it or run node as a different user" + exit 1 + fi relx_run_hooks "$PRE_START_HOOKS" "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ @@ -555,6 +560,12 @@ case "$1" in exit 1 fi + if [ ! -w "$PIPE_DIR" ] + then + echo "failed to attach, user '$USER' does not have sufficient privileges on '$PIPE_DIR', please run node as a different user" + exit 1 + fi + shift exec "$BINDIR/to_erl" "$PIPE_DIR" ;; -- cgit v1.2.3 From d12106901342491ad24252b976dc36ac95fa57c1 Mon Sep 17 00:00:00 2001 From: shamis Date: Wed, 19 Sep 2018 07:50:24 +0000 Subject: using %hostname% in service install --- priv/templates/extended_bin_windows | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index d30d78d..00ecf9b 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -183,10 +183,10 @@ :install set args=%erl_opts% -setcookie %cookie% ++ -rootdir \"%rootdir%\" set start_erl=%erts_dir%\bin\start_erl.exe -set description=Erlang node %node_name% in %rootdir% +set description=Erlang node %node_name%%hostname% in %rootdir% @if "" == "%2" ( :: Install the service - %erlsrv% add %service_name% %node_type% "%node_name%" -c "%description%" -w "%rootdir%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()." + %erlsrv% add %service_name% %node_type% "%node_name%%hostname%" -c "%description%" -w "%rootdir%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()." ) else ( :: relup and reldown goto relup -- cgit v1.2.3 From bb8af6ddec20f44599f7cd0c3e626996a3206dad Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 5 Oct 2018 07:13:56 -0600 Subject: support tuples in overlay_vars so rebar3 can pass variables (#672) --- src/rlx_config.erl | 8 +++++--- src/rlx_prv_overlay.erl | 21 ++++++++------------- test/rlx_release_SUITE.erl | 5 ++++- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/rlx_config.erl b/src/rlx_config.erl index ee58db5..b341ae7 100644 --- a/src/rlx_config.erl +++ b/src/rlx_config.erl @@ -303,8 +303,9 @@ list_of_overlay_vars_files(undefined) -> []; list_of_overlay_vars_files([]) -> []; -list_of_overlay_vars_files([H | _]=FileNames) when erlang:is_list(H) -> - FileNames; +list_of_overlay_vars_files([H | _]=Vars) when erlang:is_list(H) ; + is_tuple(H) -> + Vars; list_of_overlay_vars_files(FileName) when is_list(FileName) -> [FileName]. @@ -328,7 +329,8 @@ merge_configs([{Key, Value} | CliTerms], ConfigTerms) -> end; overlay_vars -> case lists:keyfind(overlay_vars, 1, ConfigTerms) of - {_, [H | _] = Vars} when is_list(H) -> + {_, [H | _] = Vars} when is_list(H) ; + is_tuple(H) -> MergedValue = Vars ++ Value, merge_configs(CliTerms, lists:keyreplace(overlay_vars, 1, ConfigTerms, {Key, MergedValue})); {_, Vars} when is_list(Vars) -> diff --git a/src/rlx_prv_overlay.erl b/src/rlx_prv_overlay.erl index 645f691..516d238 100644 --- a/src/rlx_prv_overlay.erl +++ b/src/rlx_prv_overlay.erl @@ -145,7 +145,8 @@ get_overlay_vars_from_file(State, OverlayVars) -> OverlayVars; [] -> OverlayVars; - [H | _]=FileNames when is_list(H) -> + [H | _]=FileNames when is_list(H) ; + is_tuple(H) -> read_overlay_vars(State, OverlayVars, FileNames); FileName when is_list(FileName) -> read_overlay_vars(State, OverlayVars, [FileName]) @@ -181,30 +182,24 @@ check_overlay_inclusion(_State, _RelativeRoot, [], Terms) -> proplists:proplist(). merge_overlay_vars(State, FileNames) -> RelativeRoot = get_relative_root(State), - lists:foldl(fun(FileName, Acc) -> - RelativePath = filename:join(RelativeRoot, erlang:iolist_to_binary(FileName)), + lists:foldl(fun(FileName, Acc) when is_list(FileName) -> + RelativePath = filename:join(RelativeRoot, iolist_to_binary(FileName)), case file:consult(RelativePath) of - %% {ok, [Terms]} -> - %% lists:ukeymerge(1, lists:ukeysort(1, Terms), Acc); - %% % the location of the included overlay files will be relative - %% %% to the current one being read - %% %% OverlayRelativeRoot = filename:dirname(FileName), - %% %% NewTerms = check_overlay_inclusion(State, OverlayRelativeRoot, Terms), - - %% %% lists:ukeymerge(1, lists:ukeysort(1, NewTerms), Acc); {ok, Terms} -> %% the location of the included overlay files will be relative %% to the current one being read OverlayRelativeRoot = filename:dirname(FileName), NewTerms = check_overlay_inclusion(State, OverlayRelativeRoot, Terms), lists:foldl(fun(NewTerm, A) -> - lists:keystore(element(1, NewTerm), 1, A, NewTerm) + lists:keystore(element(1, NewTerm), 1, A, NewTerm) end, Acc, NewTerms); {error, Reason} -> ec_cmd_log:warn(rlx_state:log(State), format_error({unable_to_read_varsfile, FileName, Reason})), Acc - end + end; + (Var, Acc) -> + lists:keystore(element(1, Var), 1, Acc, Var) end, [], FileNames). -spec render_overlay_vars(proplists:proplist(), proplists:proplist(), diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl index affc0ad..052b5c2 100644 --- a/test/rlx_release_SUITE.erl +++ b/test/rlx_release_SUITE.erl @@ -665,8 +665,10 @@ overlay_release(Config) -> TestFileFull = filename:join(TestDirFull, TestFile), SecondTestDir = "second_test_dir", rlx_test_utils:write_config(ConfigFile, - [{overlay_vars, [OverlayVars1, OverlayVars2, OverlayVars4]}, + [{overlay_vars, [{var_list_dir, "non-file-variable-list"}, + OverlayVars1, OverlayVars2, OverlayVars4]}, {overlay, [{mkdir, "{{target_dir}}/fooo"}, + {mkdir, "{{target_dir}}/{{var_list_dir}}"}, {copy, OverlayVars1, "{{target_dir}}/{{foo_dir}}/vars1.config"}, {copy, OverlayVars1, @@ -727,6 +729,7 @@ overlay_release(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)), + ?assert(ec_file:exists(filename:join([OutputDir, "foo", "non-file-variable-list"]))), ?assert(ec_file:exists(filename:join([OutputDir, "foo", "fooo"]))), ?assert(ec_file:exists(filename:join([OutputDir, "foo", "foodir", "vars1.config"]))), ?assert(ec_file:exists(filename:join([OutputDir, "foo", "yahoo", "vars1.config"]))), -- cgit v1.2.3 From 3d82071245e1c658eef0e70bae297a574c07e6d9 Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Thu, 9 Aug 2018 00:25:59 +0100 Subject: Capture internal start script arguments --- priv/templates/extended_bin | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 78f25e0..57f4cac 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -312,6 +312,16 @@ relx_run_hooks() { done } +relx_disable_hooks() { + PRE_START_HOOKS="" + POST_START_HOOKS="" + PRE_STOP_HOOKS="" + POST_STOP_HOOKS="" + PRE_INSTALL_UPGRADE_HOOKS="" + POST_INSTALL_UPGRADE_HOOKS="" + STATUS_HOOK="" +} + relx_is_extension() { EXTENSION=$1 case "$EXTENSION" in @@ -346,6 +356,26 @@ relx_run_extension() { [ "$SCRIPT_DIR/$EXTENSION_SCRIPT" ] && . "$SCRIPT_DIR/$EXTENSION_SCRIPT" $@ } +# given a list of arguments, identify the internal ones +# --relx-disable-hooks +# and process them accordingly +process_internal_args() { + for arg in $@ + do + shift + case "$arg" in + --relx-disable-hooks) + relx_disable_hooks + ;; + *) + ;; + esac + done +} + +# process internal arguments +process_internal_args $@ + find_erts_dir export ROOTDIR="$RELEASE_ROOT_DIR" export BINDIR="$ERTS_DIR/bin" -- cgit v1.2.3 From e9a8b13668ca3dd1470b8b65320e1491c213c521 Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Thu, 9 Aug 2018 00:26:31 +0100 Subject: Prevent double hook invocation on 'start' command --- priv/templates/extended_bin | 6 +++++- test/rlx_extended_bin_SUITE.erl | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 57f4cac..a06c2c3 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -530,7 +530,7 @@ case "$1" in relx_run_hooks "$PRE_START_HOOKS" "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ - "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" $ARGS" + "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" --relx-disable-hooks $ARGS" relx_run_hooks "$POST_START_HOOKS" ;; @@ -705,6 +705,7 @@ case "$1" in echo "$RELEASE_ROOT_DIR" logger -t "$REL_NAME[$$]" "Starting up" + relx_run_hooks "$PRE_START_HOOKS" # Start the VM exec "$BINDIR/erlexec" $FOREGROUNDOPTIONS \ -boot "$BOOTFILE" -mode "$CODE_LOADING_MODE" \ @@ -712,6 +713,9 @@ case "$1" in -config "$RELX_CONFIG_PATH" \ -args_file "$VMARGS_PATH" \ -pa ${__code_paths} -- "$@" + # exec will replace the current image and nothing else gets + # executed from this point on, this explains the absence + # of the pre start hook ;; rpc) # Make sure a node IS running diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index 86a9d23..3824156 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -49,6 +49,7 @@ replace_os_vars_dev_mode/1, replace_os_vars_twice/1, custom_start_script_hooks/1, + custom_start_script_hooks_console/1, builtin_wait_for_vm_start_script_hook/1, builtin_pid_start_script_hook/1, builtin_wait_for_process_start_script_hook/1, @@ -88,7 +89,8 @@ all() -> ping, shortname_ping, longname_ping, attach, pid, restart, reboot, escript, remote_console, shortname_remote_console, replace_os_vars, replace_os_vars_sys_config_vm_args_src, replace_os_vars_multi_node, replace_os_vars_included_config, - replace_os_vars_custom_location, replace_os_vars_dev_mode, replace_os_vars_twice, custom_start_script_hooks, + replace_os_vars_custom_location, replace_os_vars_dev_mode, replace_os_vars_twice, + custom_start_script_hooks, custom_start_script_hooks_console, builtin_wait_for_vm_start_script_hook, builtin_pid_start_script_hook, builtin_wait_for_process_start_script_hook, mixed_custom_and_builtin_start_script_hooks, builtin_status_script, custom_status_script, @@ -1359,6 +1361,42 @@ builtin_pid_start_script_hook(Config) -> os:cmd(filename:join([OutputDir, "foo", "bin", "foo stop"])), ok. +custom_start_script_hooks_console(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + + rlx_test_utils:create_app(LibDir1, "goal_app", "0.0.1", [stdlib,kernel], []), + + ConfigFile = filename:join([LibDir1, "relx.config"]), + rlx_test_utils:write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + [goal_app]}, + {lib_dirs, [filename:join(LibDir1, "*")]}, + {generate_start_script, true}, + {extended_start_script, true}, + {extended_start_script_hooks, [ + {pre_start, [ + {custom, "hooks/pre_start"} + ]} + ]}, + {mkdir, "scripts"}, + {overlay, [{copy, "./pre_start", "bin/hooks/pre_start"}]} + ]), + + %% write the hook scripts, each of them will write an erlang term to a file + %% that will later be consulted + ok = file:write_file(filename:join([LibDir1, "./pre_start"]), + "#!/bin/bash\n# $*\necho \\{pre_start, $REL_NAME, \\'$NAME\\', $COOKIE\\}. >> test"), + + OutputDir = filename:join([proplists:get_value(priv_dir, Config), + rlx_test_utils:create_random_name("relx-output")]), + {ok, _State} = relx:do(foo, undefined, [], [LibDir1], 3, + OutputDir, ConfigFile), + %% now start/stop the release to make sure the script hooks are really getting + %% executed + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo console &"])), + %% now check that the output file contains the expected format + {ok,[{pre_start, foo, _, foo}]} = file:consult(filename:join([OutputDir, "foo", "test"])). + builtin_wait_for_vm_start_script_hook(Config) -> LibDir1 = proplists:get_value(lib1, Config), -- cgit v1.2.3 From 23a708b7fdfee85635cb9e1650bc400e93d19514 Mon Sep 17 00:00:00 2001 From: slepher Date: Tue, 30 Oct 2018 15:23:16 +0800 Subject: fix --relx-disable-hooks cause start_boot start fail --- priv/templates/extended_bin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index a06c2c3..6c012b2 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -530,7 +530,7 @@ case "$1" in relx_run_hooks "$PRE_START_HOOKS" "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ - "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" --relx-disable-hooks $ARGS" + "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" $ARGS --relx-disable-hooks" relx_run_hooks "$POST_START_HOOKS" ;; -- cgit v1.2.3 From fc2170f006485b5f9705a8ff5e90b92d431c7c2c Mon Sep 17 00:00:00 2001 From: Grigory Starinkin Date: Sun, 4 Nov 2018 13:48:38 +0000 Subject: allow specify additional providers via api and cli calls --- README.md | 1 + src/relx.erl | 3 +- src/rlx_cmd_args.erl | 13 +++++ test/rlx_command_SUITE.erl | 14 ++++- test/rlx_prv_release_alias.erl | 27 ++++++++++ test/rlx_release_SUITE.erl | 117 ++++++++++++++++++++++++++++++++++++----- 6 files changed, 160 insertions(+), 15 deletions(-) create mode 100644 test/rlx_prv_release_alias.erl diff --git a/README.md b/README.md index 728a210..376e676 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ Options | | --sys_config | string | | Path to a file to use for sys.config | | -d | --dev-mode | boolean | false | Symlink all applications and configuration into the release instead of copying| | -i | --include-erts | boolean/string | true | If true include a copy of erts used to build with, if a path include erts at that path. If false, do not include erts | +| | --provider | string | | Specify an additional relx provider | Wiki ---- diff --git a/src/relx.erl b/src/relx.erl index 8027fd4..b5c3ec5 100644 --- a/src/relx.erl +++ b/src/relx.erl @@ -214,7 +214,8 @@ opt_spec_list() -> {sys_config, undefined, "sys_config", string, "Path to a file to use for sys.config"}, {system_libs, undefined, "system_libs", string, "Path to dir of Erlang system libs"}, {version, undefined, "version", undefined, "Print relx version"}, - {root_dir, $r, "root", string, "The project root directory"}]. + {root_dir, $r, "root", string, "The project root directory"}, + {provider, undefined, "provider", atom, "Specify an additional relx provider"}]. -spec format_error(Reason::term()) -> string(). format_error({invalid_return_value, Provider, Value}) -> diff --git a/src/rlx_cmd_args.erl b/src/rlx_cmd_args.erl index b20344c..4f5e9da 100644 --- a/src/rlx_cmd_args.erl +++ b/src/rlx_cmd_args.erl @@ -285,6 +285,19 @@ create(include_erts, Opts) -> create(warnings_as_errors, Opts) -> WarningsAsErrors = proplists:get_value(warnings_as_errors, Opts, false), {warnings_as_errors, WarningsAsErrors}; +create(provider, Opts) -> + case proplists:get_all_values(provider, Opts) of + [] -> + []; + Providers -> + {add_providers, Providers} + end; +create(add_providers, Opts) -> + Providers = proplists:get_value(add_providers, Opts, []), + {add_providers, Providers}; +create(providers, Opts) -> + Providers = proplists:get_value(providers, Opts, []), + {providers, Providers}; create(_, _) -> []. diff --git a/test/rlx_command_SUITE.erl b/test/rlx_command_SUITE.erl index e0beec1..47ffdaf 100644 --- a/test/rlx_command_SUITE.erl +++ b/test/rlx_command_SUITE.erl @@ -27,7 +27,8 @@ lib_expansion_case/1, lib_fail_case/1, spec_parse_fail_case/1, - config_fail_case/1]). + config_fail_case/1, + provider_case/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -42,7 +43,7 @@ end_per_suite(_Config) -> ok. all() -> - [normal_passing_case, lib_expansion_case, lib_fail_case, config_fail_case]. + [normal_passing_case, lib_expansion_case, lib_fail_case, config_fail_case, provider_case]. normal_passing_case(Config) -> DataDir = filename:join(proplists:get_value(priv_dir, Config), ?MODULE), @@ -111,3 +112,12 @@ config_fail_case(_Config) -> {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine), ?assertMatch({error, {_, {invalid_config_file, ConfigFile}}}, rlx_cmd_args:args2state(Opts, Targets)). + +provider_case(_Config) -> + CmdLine = ["--provider", "relx_provider_1", + "--provider", "relx_provider_2"], + {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine), + {ok, State} = rlx_cmd_args:args2state(Opts, Targets), + ?assertEqual( + [relx_provider_1, relx_provider_2], + proplists:get_value(add_providers, rlx_state:cli_args(State))). diff --git a/test/rlx_prv_release_alias.erl b/test/rlx_prv_release_alias.erl new file mode 100644 index 0000000..523940c --- /dev/null +++ b/test/rlx_prv_release_alias.erl @@ -0,0 +1,27 @@ +-module(rlx_prv_release_alias). + +-behaviour(provider). + +-export([init/1, do/1, format_error/1]). + +-define(PROVIDER, test_release_alias). +-define(DEPS, [app_discover]). + +%%============================================================================ +%% API +%%============================================================================ + +-spec init(rlx_state:t()) -> {ok, rlx_state:t()}. +init(State) -> + State1 = rlx_state:add_provider(State, providers:create([{name, ?PROVIDER}, + {module, ?MODULE}, + {deps, ?DEPS}])), + {ok, State1}. + +-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error(). +do(State) -> + rlx_prv_release:do(State). + +-spec format_error(ErrorDetail::term()) -> iolist(). +format_error(ErrorDetail) -> + rlx_prv_release:format_error(ErrorDetail). diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl index 052b5c2..23e9c42 100644 --- a/test/rlx_release_SUITE.erl +++ b/test/rlx_release_SUITE.erl @@ -25,7 +25,9 @@ init_per_testcase/2, all/0, providers/1, + providers_via_api_options/1, add_providers/1, + add_providers_via_api_options/1, make_release/1, make_config_release/1, make_extend_release/1, @@ -82,19 +84,18 @@ init_per_testcase(_, Config) -> {state, State1} | Config]. all() -> - [providers, add_providers, make_release, make_config_release, - make_extend_release, make_extend_config_release, make_scriptless_release, - make_overridden_release, make_auto_skip_empty_app_release, + [providers, providers_via_api_options, add_providers, add_providers_via_api_options, + make_release, make_config_release, make_extend_release, make_extend_config_release, + make_scriptless_release, make_overridden_release, make_auto_skip_empty_app_release, make_skip_app_release, make_exclude_app_release, make_app_type_none_release, - make_implicit_config_release, make_rerun_overridden_release, - overlay_release, make_goalless_release, make_depfree_release, - make_invalid_config_release, make_relup_release, make_relup_release2, - make_one_app_top_level_release, make_dev_mode_release, make_dev_mode_template_release, - make_config_script_release, make_release_twice, make_release_twice_dev_mode, - make_erts_release, make_erts_config_release, - make_included_nodetool_release, make_not_included_nodetool_release, - make_src_release, make_excluded_src_release, make_exclude_modules_release, - make_release_with_sys_config_vm_args_src]. + make_implicit_config_release, make_rerun_overridden_release, overlay_release, + make_goalless_release, make_depfree_release, make_invalid_config_release, + make_relup_release, make_relup_release2, make_one_app_top_level_release, + make_dev_mode_release, make_dev_mode_template_release, make_config_script_release, + make_release_twice, make_release_twice_dev_mode, make_erts_release, + make_erts_config_release, make_included_nodetool_release, + make_not_included_nodetool_release, make_src_release, make_excluded_src_release, + make_exclude_modules_release, make_release_with_sys_config_vm_args_src]. add_providers(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -133,6 +134,52 @@ add_providers(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)). +add_providers_via_api_options(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + + [(fun({Name, Vsn}) -> + rlx_test_utils:create_app(LibDir1, Name, Vsn, [kernel, stdlib], []) + end)(App) + || + App <- + [{rlx_test_utils:create_random_name("lib_app1_"), rlx_test_utils:create_random_vsn()} + || _ <- lists:seq(1, 100)]], + + rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []), + rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []), + rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []), + rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]), + rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []), + + ConfigFile = filename:join([LibDir1, "relx.config"]), + rlx_test_utils:write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + [goal_app_1, + goal_app_2]}]), + OutputDir = filename:join([proplists:get_value(priv_dir, Config), + rlx_test_utils:create_random_name("relx-output")]), + {ok, Cwd} = file:get_cwd(), + Opts = [{relname, undefined}, + {relvsn, undefined}, + {goals, []}, + {overrides, []}, + {output_dir, OutputDir}, + {lib_dirs, [LibDir1]}, + {root_dir, Cwd}, + {log_level, 3}, + {config, ConfigFile}, + {add_providers, [rlx_prv_release_alias]}], + {ok, State} = relx:do(Opts, ["test_release_alias"]), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)), + AppSpecs = rlx_release:applications(Release), + ?assert(lists:keymember(stdlib, 1, AppSpecs)), + ?assert(lists:keymember(kernel, 1, AppSpecs)), + ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)), + ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)), + ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)), + ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), + ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)). + providers(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -170,6 +217,52 @@ providers(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)). +providers_via_api_options(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + + [(fun({Name, Vsn}) -> + rlx_test_utils:create_app(LibDir1, Name, Vsn, [kernel, stdlib], []) + end)(App) + || + App <- + [{rlx_test_utils:create_random_name("lib_app1_"), rlx_test_utils:create_random_vsn()} + || _ <- lists:seq(1, 100)]], + + rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []), + rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []), + rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []), + rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]), + rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []), + + ConfigFile = filename:join([LibDir1, "relx.config"]), + rlx_test_utils:write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + [goal_app_1, + goal_app_2]}]), + OutputDir = filename:join([proplists:get_value(priv_dir, Config), + rlx_test_utils:create_random_name("relx-output")]), + {ok, Cwd} = file:get_cwd(), + Opts = [{relname, undefined}, + {relvsn, undefined}, + {goals, []}, + {overrides, []}, + {output_dir, OutputDir}, + {lib_dirs, [LibDir1]}, + {root_dir, Cwd}, + {log_level, 3}, + {config, ConfigFile}, + {providers, [rlx_prv_release_alias]}], + {ok, State} = relx:do(Opts, ["test_release_alias"]), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)), + AppSpecs = rlx_release:applications(Release), + ?assert(lists:keymember(stdlib, 1, AppSpecs)), + ?assert(lists:keymember(kernel, 1, AppSpecs)), + ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)), + ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)), + ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)), + ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), + ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)). + make_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), -- cgit v1.2.3 From 387033d01f9b3c105829dad284f3d520c2590826 Mon Sep 17 00:00:00 2001 From: eldarko Date: Fri, 16 Nov 2018 15:30:57 +0100 Subject: Don't write to release bin/ directory Let the user provide writable $ROOTDIR/tmp so it can be used for temporary files --- priv/templates/extended_bin | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index a06c2c3..a228413 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -180,9 +180,9 @@ relx_gen_id() { relx_nodetool() { command="$1"; shift - escript_emulator_args $ROOTDIR/bin/nodetool + ESCRIPT_TMP=$(escript_emulator_args_tmp $ROOTDIR/bin/nodetool) - "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ + "$ERTS_DIR/bin/escript" "$ESCRIPT_TMP" "$NAME_TYPE" "$NAME" \ -setcookie "$COOKIE" "$command" $@ } @@ -248,6 +248,24 @@ escript_emulator_args() { fi } +escript_emulator_args_tmp() { + # + # If the user provided $ROOTDIR/tmp directory then don't override + # original files of the package but use temporary files instead + # + local TMP_DIR="$ROOTDIR/tmp"; + + if [ -d "$TMP_DIR" ] && [ -w "$TMP_DIR" ]; then + local TMP_FILE="$TMP_DIR/$(basename $1)" + cp $1 $TMP_FILE + escript_emulator_args $TMP_FILE + echo $TMP_FILE + else + escript_emulator_args $1 + echo $1 + fi +} + add_path() { # Use $CWD/$1 if exists, otherwise releases/VSN/$1 IN_FILE_PATH=$2 @@ -628,9 +646,9 @@ case "$1" in relx_run_hooks "$PRE_INSTALL_UPGRADE_HOOKS" - escript_emulator_args $ROOTDIR/bin/install_upgrade.escript + ESCRIPT_TMP=$(escript_emulator_args_tmp $ROOTDIR/bin/install_upgrade.escript) - exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ + exec "$BINDIR/escript" "$ESCRIPT_TMP" \ "$COMMAND" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@" relx_run_hooks "$POST_INSTALL_UPGRADE_HOOKS" @@ -645,9 +663,9 @@ case "$1" in COMMAND="$1"; shift - escript_emulator_args $ROOTDIR/bin/install_upgrade.escript + ESCRIPT_TMP=$(escript_emulator_args_tmp $ROOTDIR/bin/install_upgrade.escript) - exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ + exec "$BINDIR/escript" "$ESCRIPT_TMP" \ "versions" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@" ;; -- cgit v1.2.3 From 5a5e2c66969f0377328d1d1db9f359c43ec9e903 Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Tue, 27 Nov 2018 18:55:14 +0100 Subject: run named erl nodes to auto-set cookie --- priv/templates/extended_bin | 4 +++- priv/templates/extended_bin_windows | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 78f25e0..854cf6a 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -127,10 +127,12 @@ find_erts_dir() { if [ -d "$__erts_dir" ]; then ERTS_DIR="$__erts_dir"; ROOTDIR="$RELEASE_ROOT_DIR" + # run a dummy distributed erlang node just to ensure that a cookie exists + $ERTS_DIR/bin/erl -sname dummy -boot no_dot_erlang -noshell -eval "halt()" else __erl="$(which erl)" code="io:format(\"~s\", [code:root_dir()]), halt()." - __erl_root="$("$__erl" -boot no_dot_erlang -sasl errlog_type error -noshell -eval "$code")" + __erl_root="$("$__erl" -sname dummy -boot no_dot_erlang -sasl errlog_type error -noshell -eval "$code")" ERTS_DIR="$__erl_root/erts-$ERTS_VSN" ROOTDIR="$__erl_root" fi diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index 00ecf9b..045a80c 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -137,7 +137,7 @@ @for /f "delims=" %%i in ('where erl') do @( set erl=%%i ) -@set dir_cmd="%erl%" -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop +@set dir_cmd="%erl%" -sname dummy -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop @for /f "delims=" %%i in ('%%dir_cmd%%') do @( set erl_root=%%i ) -- cgit v1.2.3 From f2b4f18e51f5ae18136d811f2d69aa1ec4fb31bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andra=CC=81s=20Boroska?= Date: Mon, 31 Dec 2018 14:19:52 +0100 Subject: fix example config --- examples/relx.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/relx.config b/examples/relx.config index b19042b..3622d01 100644 --- a/examples/relx.config +++ b/examples/relx.config @@ -45,7 +45,7 @@ %% When we have multiple releases relx needs to know which one to build. You %% can specify that on the command line with the `-n` and `-v` arguments to %% relx. However, it is often more convenient to do it in the config. -{default_release, sexpr, "0.0.2"}. +{default_release, {sexpr, "0.0.2"}}. {release, {sexpr, "0.0.1"}, [sexpr, -- cgit v1.2.3 From 64871e4cb37b2f52c0956b81bbdf1e500977fd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andra=CC=81s=20Boroska?= Date: Mon, 31 Dec 2018 11:20:55 +0100 Subject: fix handling of default_release in config When no release specified in cli, prevent overwriting default_release in relx config. --- src/rlx_config.erl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rlx_config.erl b/src/rlx_config.erl index b341ae7..4160bba 100644 --- a/src/rlx_config.erl +++ b/src/rlx_config.erl @@ -339,6 +339,9 @@ merge_configs([{Key, Value} | CliTerms], ConfigTerms) -> false -> merge_configs(CliTerms, ConfigTerms++[{Key, Value}]) end; + default_release when Value =:= {undefined, undefined} -> + %% No release specified in cli. Prevent overwriting default_release in ConfigTerms. + merge_configs(CliTerms, lists:keymerge(1, ConfigTerms, [{Key, Value}])); _ -> merge_configs(CliTerms, lists:reverse(lists:keystore(Key, 1, lists:reverse(ConfigTerms), {Key, Value}))) end. -- cgit v1.2.3 From 41284ccc88e89f576309698f1a3691c5e8942b2e Mon Sep 17 00:00:00 2001 From: Luca Favatella Date: Wed, 16 Jan 2019 22:08:27 +0000 Subject: Enable passing arguments with spaces to extensions --- priv/templates/extended_bin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index a228413..6b01b38 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -371,7 +371,7 @@ relx_run_extension() { shift # all extension script locations are expected to be # relative to the start script location - [ "$SCRIPT_DIR/$EXTENSION_SCRIPT" ] && . "$SCRIPT_DIR/$EXTENSION_SCRIPT" $@ + [ "$SCRIPT_DIR/$EXTENSION_SCRIPT" ] && . "$SCRIPT_DIR/$EXTENSION_SCRIPT" "$@" } # given a list of arguments, identify the internal ones @@ -791,7 +791,7 @@ case "$1" in if [ "$IS_EXTENSION" = "1" ]; then EXTENSION_SCRIPT=$(relx_get_extension_script $1) shift - relx_run_extension $EXTENSION_SCRIPT $@ + relx_run_extension $EXTENSION_SCRIPT "$@" # all extension scripts are expected to exit else relx_usage $1 -- cgit v1.2.3 From 7fa443af83c26663ad569dda99a0ce4925e17477 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Fri, 15 Apr 2016 15:54:10 +1000 Subject: Fix renaming of .orig configuration files on Windows Fix .orig rename commands in bin_windows 1. .orig was being prepended second argument rather than appended to the first argument 2. Windows' ren command expects the second argument to be just a file name (not contain drive or path components) 3. Tidy up appending of .orig, place inside double quotes rather than outside of quotes. This matches the usage a few lines later: @if exist "%rel_dir%\%rel_name%.boot" ( Copy rename commands from bin_windows to extended_bin_windows. --- priv/templates/bin_windows | 17 +++++++++++++++++ priv/templates/extended_bin_windows | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/priv/templates/bin_windows b/priv/templates/bin_windows index b3ce796..19c0d2d 100644 --- a/priv/templates/bin_windows +++ b/priv/templates/bin_windows @@ -73,6 +73,23 @@ cd %rootdir% @set "possible_sys=%rel_dir%\sys.config" @if exist "%possible_sys%" ( set sys_config=-config "%possible_sys%" +) else ( + @if exist "%possible_sys%.orig" ( + ren "%possible_sys%.orig" sys.config + set sys_config=-config "%possible_sys%" + ) +) + +:: Find the vm.args file +:find_vm_args +@set "possible_vm_args=%rel_dir%\vm.args" +@if exist "%possible_vm_args%" ( + set vm_args="%possible_vm_args%" +) else ( + @if exist "%possible_vm_args%.orig" ( + ren "%possible_vm_args%.orig" vm.args + set vm_args="%possible_vm_args%" + ) ) @goto :eof diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index 045a80c..694c5c7 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -151,6 +151,13 @@ @if exist %possible_sys% ( set sys_config=-config "%possible_sys%" ) +@if exist "%possible_sys%.orig" ( + ren "%possible_sys%.orig" sys.config + set sys_config=-config "%possible_sys%" +) +@if exist "%rel_dir%\vm.args.orig" ( + ren "%rel_dir%\vm.args.orig" vm.args +) @goto :eof :: set boot_script variable -- cgit v1.2.3 From 50c50a5cc4727ed6a982e27fafff8568b5e83d39 Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Thu, 31 Jan 2019 09:37:07 +0100 Subject: Add sys.config and vm.args check to extended win32 bin --- priv/templates/extended_bin_windows | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index 694c5c7..ec70c47 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -148,15 +148,21 @@ :: Find the sys.config file :find_sys_config @set "possible_sys=%rel_dir%\sys.config" -@if exist %possible_sys% ( - set sys_config=-config "%possible_sys%" -) -@if exist "%possible_sys%.orig" ( - ren "%possible_sys%.orig" sys.config +@if exist "%possible_sys%" ( set sys_config=-config "%possible_sys%" +) else ( + @if exist "%possible_sys%.orig" ( + ren "%possible_sys%.orig" sys.config + set sys_config=-config "%possible_sys%" + ) ) -@if exist "%rel_dir%\vm.args.orig" ( - ren "%rel_dir%\vm.args.orig" vm.args + +:: Find the vm.args file +:find_vm_args +@if not exist "%m_args%" ( + @if exist "%m_args%.orig" ( + ren "%m_args%.orig" vm.args + ) ) @goto :eof -- cgit v1.2.3 From c5068c10dec0ac0126809396a6ec7a6ec2c75081 Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Wed, 6 Feb 2019 15:52:45 +0100 Subject: Add extensions to win32 extended_bin --- priv/templates/extended_bin_windows | 94 ++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index ec70c47..2556c41 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -42,6 +42,7 @@ @set escript="%bindir%\escript.exe" @set werl="%bindir%\werl.exe" @set nodetool="%release_root_dir%\bin\nodetool" +@set extensions={{ extensions }} :: Extract node type and name from vm.args @for /f "usebackq tokens=1-2" %%I in (`findstr /b "\-name \-sname" "%vm_args%"`) do @( @@ -99,6 +100,7 @@ copy "%rel_dir%\%rel_name%.boot" "%rel_dir%\start.boot" >nul ) +@if "%1"=="help" @goto usage @if "%1"=="install" @goto install @if "%1"=="uninstall" @goto uninstall @if "%1"=="start" @goto start @@ -112,6 +114,10 @@ @if "%1"=="attach" @goto attach @if "%1"=="remote_console" @goto attach @if "%1"=="" @goto usage + +@call :is_extension "%1" +@if "%ERRORLEVEL%"=="0" @goto run_extension + @echo Unknown command: "%1" @goto :eof @@ -188,7 +194,63 @@ :: Display usage information :usage -@echo usage: %~n0 ^(install^|uninstall^|start^|stop^|restart^|upgrade^|downgrade^|console^|ping^|list^|attach^|remote_console^) +@if "%2"=="install" ( + @echo "Usage: %rel_name% install [VERSION]" + @echo "Installs a release package VERSION, it assumes that this" + @echo "release package tarball has already been deployed at one" + @echo "of the following locations:" + @echo " releases/-.tar.gz" + @echo " releases//-.tar.gz" + @echo " releases//.tar.gz" + @echo "" + @echo " --no-permanent Install release package VERSION but" + @echo " don't make it permanent" + @goto :eof +) +@if "%2"=="uninstall" ( + @echo "Usage: %rel_name% uninstall [VERSION]" + @echo "Uninstalls a release VERSION, it will only accept" + @echo "versions that are not currently in use" + @goto :eof +) +@if "%2"=="upgrade" ( + @echo "Usage: %rel_name% upgrade [VERSION]" + @echo "Upgrades the currently running release to VERSION, it assumes" + @echo "that a release package tarball has already been deployed at one" + @echo "of the following locations:" + @echo " releases/-.tar.gz" + @echo " releases//-.tar.gz" + @echo " releases//.tar.gz" + @echo "" + @echo " --no-permanent Install release package VERSION but" + @echo " don't make it permanent" + @goto :eof +) +@if "%2"=="downgrade" ( + @echo "Usage: %rel_name% downgrade [VERSION]" + @echo "Downgrades the currently running release to VERSION, it assumes" + @echo "that a release package tarball has already been deployed at one" + @echo "of the following locations:" + @echo " releases/-.tar.gz" + @echo " releases//-.tar.gz" + @echo " releases//.tar.gz" + @echo "" + @echo " --no-permanent Install release package VERSION but" + @echo " don't make it permanent" + @goto :eof +) +@call :is_extension "%2" +@if "%ERRORLEVEL%"=="0" ( + @if exist "%script_dir%\%2.cmd" ( + call "%script_dir%\%2.cmd" help + @goto :eof + ) +) +set commands=install uninstall start stop restart upgrade downgrade console ping list attach remote_console +if not "%extensions%"=="" ( + set "commands=%commands% %extensions%" +) +@echo Usage: %~n0 ^(%commands: =^|%^) @goto :eof :: Install the release as a Windows service @@ -256,3 +318,33 @@ set description=Erlang node %node_name%%hostname% in %rootdir% @start "%node_name% attach" %werl% %boot% ^ -remsh %node_name%%hostname% %node_type% console -setcookie %cookie% @goto :eof + +:: Run extension script +:run_extension +@if exist "%script_dir%\%1.cmd" ( + shift + call "%script_dir%\%1.cmd" %* +) + +@goto :eof + +:: Local Functions + +:is_extension + +@set ext=%~1 + +:: Check for entries in the list, not at the ends +@call set ext_test_1=x%%extensions: %ext% =%% + +:: Check for entry at the start of the list +@call set ext_test_2=x%%extensions:%ext% =%% + +:: Check for entry at the end of the list +@call set ext_test_3=x%%extensions: %ext%=%% + +@if not "%ext_test_1%"=="x%extensions%" exit /b 0 +@if not "%ext_test_2%"=="x%extensions%" exit /b 0 +@if not "%ext_test_3%"=="x%extensions%" exit /b 0 + +@exit /b 1 -- cgit v1.2.3 From 1ad337c4458bc5188a67b8ccf01ba4684fb6383e Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Thu, 7 Feb 2019 09:41:32 +0100 Subject: Fix windows extended bin --- priv/templates/extended_bin_windows | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index 2556c41..2d9e0ff 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -42,7 +42,9 @@ @set escript="%bindir%\escript.exe" @set werl="%bindir%\werl.exe" @set nodetool="%release_root_dir%\bin\nodetool" -@set extensions={{ extensions }} +@set "extensions0={{ extensions }}" +@set "extensions1=%extensions0:|= %" +@set "extensions=%extensions1: undefined=%" :: Extract node type and name from vm.args @for /f "usebackq tokens=1-2" %%I in (`findstr /b "\-name \-sname" "%vm_args%"`) do @( @@ -241,8 +243,8 @@ ) @call :is_extension "%2" @if "%ERRORLEVEL%"=="0" ( - @if exist "%script_dir%\%2.cmd" ( - call "%script_dir%\%2.cmd" help + @if exist "%script_dir%\extensions\%2.cmd" ( + call "%script_dir%\extensions\%2.cmd" help @goto :eof ) ) @@ -321,9 +323,9 @@ set description=Erlang node %node_name%%hostname% in %rootdir% :: Run extension script :run_extension -@if exist "%script_dir%\%1.cmd" ( +@if exist "%script_dir%\extensions\%1.cmd" ( shift - call "%script_dir%\%1.cmd" %* + call "%script_dir%\extensions\%1.cmd" %* ) @goto :eof @@ -332,16 +334,16 @@ set description=Erlang node %node_name%%hostname% in %rootdir% :is_extension -@set ext=%~1 +@set "ext=%~1" :: Check for entries in the list, not at the ends -@call set ext_test_1=x%%extensions: %ext% =%% +@call set "ext_test_1=x%%extensions: %ext% =%%" :: Check for entry at the start of the list -@call set ext_test_2=x%%extensions:%ext% =%% +@call set "ext_test_2=x%%extensions:%ext% =%%" :: Check for entry at the end of the list -@call set ext_test_3=x%%extensions: %ext%=%% +@call set "ext_test_3=x%%extensions: %ext%=%%" @if not "%ext_test_1%"=="x%extensions%" exit /b 0 @if not "%ext_test_2%"=="x%extensions%" exit /b 0 -- cgit v1.2.3 From 3e94923d4a5d683faf84094f60e746e024df4ae3 Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Thu, 7 Feb 2019 16:39:54 +0100 Subject: Fix relx_escript --- priv/templates/extended_bin | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index e5de981..c1b6fff 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -190,7 +190,7 @@ relx_nodetool() { # Run an escript in the node's environment relx_escript() { - shift; scriptpath="$1"; shift + scriptpath="$1"; shift export RELEASE_ROOT_DIR "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@ @@ -598,6 +598,7 @@ case "$1" in escript) ## Run an escript under the node's environment + shift if ! relx_escript $@; then exit 1 fi -- cgit v1.2.3 From 5e7bd9d650d925e9afff13a5bdcea9d6356a2f76 Mon Sep 17 00:00:00 2001 From: Anthony Molinaro Date: Wed, 20 Feb 2019 15:17:10 -0800 Subject: don't create world writable executables (#687) --- src/rlx_prv_assembler.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rlx_prv_assembler.erl b/src/rlx_prv_assembler.erl index cb5bbed..4f9a41e 100644 --- a/src/rlx_prv_assembler.erl +++ b/src/rlx_prv_assembler.erl @@ -433,13 +433,13 @@ write_bin_file(State, Release, OutputDir, RelDir) -> win32 -> rlx_string:concat(VsnRel, ".cmd") end, ok = file:write_file(VsnRelStartFile, StartFile), - ok = file:change_mode(VsnRelStartFile, 8#777), + ok = file:change_mode(VsnRelStartFile, 8#755), BareRelStartFile = case OsFamily of unix -> BareRel; win32 -> rlx_string:concat(BareRel, ".cmd") end, ok = file:write_file(BareRelStartFile, StartFile), - ok = file:change_mode(BareRelStartFile, 8#777) + ok = file:change_mode(BareRelStartFile, 8#755) end, ReleasesDir = filename:join(OutputDir, "releases"), generate_start_erl_data_file(Release, ReleasesDir), -- cgit v1.2.3 From edad2b498ad12ee2860a09f80e7862efadf0eff2 Mon Sep 17 00:00:00 2001 From: Anthony Molinaro Date: Thu, 21 Feb 2019 10:17:07 -0800 Subject: Attempt at a fix for vm.args usage (#688) * Attempt at a fix for vm.args usage * bump sleep time to see if it fixes tests on travis --- priv/templates/extended_bin | 49 +++---------------------- test/rlx_extended_bin_SUITE.erl | 80 +++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 84 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 2cd6d29..7e6dd29 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -170,7 +170,7 @@ relx_rem_sh() { # Setup remote shell command to control node exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \ -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ - -setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME $VM_ARGS + -setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME } # Generate a random id @@ -182,9 +182,7 @@ relx_gen_id() { relx_nodetool() { command="$1"; shift - ESCRIPT_TMP=$(escript_emulator_args_tmp $ROOTDIR/bin/nodetool) - - "$ERTS_DIR/bin/escript" "$ESCRIPT_TMP" "$NAME_TYPE" "$NAME" \ + "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ -setcookie "$COOKIE" "$command" $@ } @@ -233,41 +231,6 @@ replace_os_vars() { }1' < "$1" > "$2" } -escript_emulator_args() { - if [ -n "${VM_ARGS}" ]; then - if grep -q '%%!' $1; then - cmd=$(echo sed -i"'.prev'" "'/%%!.*/ s| ${VM_ARGS}||'" $1) - eval "$cmd" - cmd=$(echo sed -i"'.prev'" "'/%%!.*/ s|$| ${VM_ARGS}|'" $1) - eval "$cmd" - rm ${1}.prev - else - cmd=$(echo sed -i"'.prev'" "'/#!.*/ a \\ -%%! ${VM_ARGS}\n'" $1) - eval "$cmd" - rm ${1}.prev - fi - fi -} - -escript_emulator_args_tmp() { - # - # If the user provided $ROOTDIR/tmp directory then don't override - # original files of the package but use temporary files instead - # - local TMP_DIR="$ROOTDIR/tmp"; - - if [ -d "$TMP_DIR" ] && [ -w "$TMP_DIR" ]; then - local TMP_FILE="$TMP_DIR/$(basename $1)" - cp $1 $TMP_FILE - escript_emulator_args $TMP_FILE - echo $TMP_FILE - else - escript_emulator_args $1 - echo $1 - fi -} - add_path() { # Use $CWD/$1 if exists, otherwise releases/VSN/$1 IN_FILE_PATH=$2 @@ -649,9 +612,7 @@ case "$1" in relx_run_hooks "$PRE_INSTALL_UPGRADE_HOOKS" - ESCRIPT_TMP=$(escript_emulator_args_tmp $ROOTDIR/bin/install_upgrade.escript) - - exec "$BINDIR/escript" "$ESCRIPT_TMP" \ + exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ "$COMMAND" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@" relx_run_hooks "$POST_INSTALL_UPGRADE_HOOKS" @@ -665,10 +626,8 @@ case "$1" in fi COMMAND="$1"; shift - - ESCRIPT_TMP=$(escript_emulator_args_tmp $ROOTDIR/bin/install_upgrade.escript) - exec "$BINDIR/escript" "$ESCRIPT_TMP" \ + exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ "versions" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@" ;; diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index 3824156..21bb131 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -63,6 +63,8 @@ -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/file.hrl"). +-define(SLEEP_TIME, 2500). + suite() -> [{timetrap,{seconds,30}}]. @@ -124,7 +126,7 @@ ping(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), %% a ping should fail after stopping a node @@ -163,7 +165,7 @@ shortname_ping(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), %% a ping should fail after stopping a node @@ -202,7 +204,7 @@ longname_ping(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), %% a ping should fail after stopping a node @@ -235,10 +237,10 @@ attach(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo attach", "&"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])). @@ -269,7 +271,7 @@ pid(Config) -> %% check for a valid pid {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _Pid} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), @@ -303,11 +305,11 @@ restart(Config) -> %% a restart is a gracious operation that does not involve the %% death of the VM, so the pid should be the same {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, Pid1} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo restart"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, Pid2} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), @@ -341,13 +343,13 @@ reboot(Config) -> %% a reboot involves stopping the emulator, it needs to be restarted %% though {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, Pid1} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo reboot"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, Pid2} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), @@ -383,7 +385,7 @@ escript(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), [ExpectedOutput] = io_lib:format("~s", [filename:join([OutputDir, "foo"])]), @@ -417,10 +419,10 @@ remote_console(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo remote_console &"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, NodesStr} = sh(filename:join([OutputDir, "foo", "bin", "foo eval 'nodes(connected).'"])), Nodes = rlx_test_utils:list_to_term(NodesStr), ?assertEqual(1, length(Nodes)), @@ -459,10 +461,10 @@ shortname_remote_console(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo remote_console &"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, NodesStr} = sh(filename:join([OutputDir, "foo", "bin", "foo eval 'nodes(connected).'"])), Nodes = rlx_test_utils:list_to_term(NodesStr), ?assertEqual(1, length(Nodes)), @@ -510,7 +512,7 @@ replace_os_vars(Config) -> {"NODENAME", "node1"}, {"COOKIE", "cookie1"}, {"VAR1", "v1"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node1"}, @@ -549,7 +551,7 @@ replace_os_vars(Config) -> {"NODENAME", "node2"}, {"COOKIE", "cookie2"}, {"VAR1", "v2"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node2"}, @@ -625,7 +627,7 @@ replace_os_vars_sys_config_vm_args_src(Config) -> {"NODENAME", "node1"}, {"COOKIE", "cookie1"}, {"VAR1", "101"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node1"}, @@ -664,7 +666,7 @@ replace_os_vars_sys_config_vm_args_src(Config) -> {"NODENAME", "node2"}, {"COOKIE", "cookie2"}, {"VAR1", "201"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node2"}, @@ -739,7 +741,7 @@ replace_os_vars_multi_node(Config) -> {"NODENAME", "node1"}, {"COOKIE", "cookie1"}, {"VAR1", "v1"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"RELX_MULTI_NODE", "1"}, @@ -787,7 +789,7 @@ replace_os_vars_multi_node(Config) -> {"NODENAME", "node2"}, {"COOKIE", "cookie2"}, {"VAR1", "v2"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"RELX_MULTI_NODE", "1"}, @@ -883,7 +885,7 @@ replace_os_vars_included_config(Config) -> {"NODENAME", "node1"}, {"COOKIE", "cookie1"}, {"VAR1", "v1"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node1"}, @@ -922,7 +924,7 @@ replace_os_vars_included_config(Config) -> {"NODENAME", "node2"}, {"COOKIE", "cookie2"}, {"VAR1", "v2"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node2"}, @@ -997,7 +999,7 @@ replace_os_vars_custom_location(Config) -> {"NODENAME", "node1"}, {"COOKIE", "cookie1"}, {"VAR1", "v1"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"RELX_OUT_FILE_PATH", "/tmp"}, @@ -1043,7 +1045,7 @@ replace_os_vars_custom_location(Config) -> {"NODENAME", "node2"}, {"COOKIE", "cookie2"}, {"VAR1", "v2"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"RELX_OUT_FILE_PATH", "/tmp"}, @@ -1121,7 +1123,7 @@ replace_os_vars_twice(Config) -> {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"VAR1", "v1"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}]), {ok, "\"v1\""} = sh(filename:join([OutputDir, "foo", "bin", @@ -1144,7 +1146,7 @@ replace_os_vars_twice(Config) -> %% start the node again but this time don't replace env variables {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, "\"${VAR1}\""} = sh(filename:join([OutputDir, "foo", "bin", "foo eval '{ok, V} = application:get_env(goal_app, var1), V.'"])), @@ -1196,7 +1198,7 @@ replace_os_vars_dev_mode(Config) -> {"NODENAME", "node1"}, {"COOKIE", "cookie1"}, {"VAR1", "v1"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node1"}, @@ -1235,7 +1237,7 @@ replace_os_vars_dev_mode(Config) -> {"NODENAME", "node2"}, {"COOKIE", "cookie2"}, {"VAR1", "v2"}]), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), [{"RELX_REPLACE_OS_VARS", "1"}, {"NODENAME", "node2"}, @@ -1320,7 +1322,7 @@ custom_start_script_hooks(Config) -> %% now start/stop the release to make sure the script hooks are really getting %% executed os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), os:cmd(filename:join([OutputDir, "foo", "bin", "foo stop"])), %% now check that the output file contains the expected format {ok,[{pre_start, foo, _, foo}, @@ -1423,7 +1425,7 @@ builtin_wait_for_vm_start_script_hook(Config) -> os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])), % this run doesn't need the sleep because the wait_for_vm_start % start script makes it unnecessary - %timer:sleep(2000), + %timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), os:cmd(filename:join([OutputDir, "foo", "bin", "foo stop"])), ok. @@ -1559,7 +1561,7 @@ builtin_status_script(Config) -> {ok, _State} = relx:do(foo, undefined, [], [LibDir1], 3, OutputDir, ConfigFile), os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), %% write the status to a file {ok, ""} = sh(filename:join([OutputDir, "foo", "bin", "foo status"])). @@ -1596,7 +1598,7 @@ custom_status_script(Config) -> {ok, _State} = relx:do(foo, undefined, [], [LibDir1], 3, OutputDir, ConfigFile), os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), %% write the status to a file {ok, StatusStr} = sh(filename:join([OutputDir, "foo", "bin", "foo status"])), @@ -1641,7 +1643,7 @@ start_sname_in_other_argsfile(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), %% a ping should fail after stopping a node @@ -1677,7 +1679,7 @@ start_preserves_arguments(Config) -> %% and preserving the "tricky" argument that contains a string with a space %% in it {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start -goal_app baz '\"bat zing\"'"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), BinFile = filename:join([PrivDir, "goal_app.bin"]), Eval = io_lib:format("{ok,Env}=application:get_env(goal_app,baz),file:write_file(\"~s\",term_to_binary(Env)).", [BinFile]), @@ -1724,7 +1726,7 @@ start_nodetool_with_data_from_argsfile(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), %% a ping should fail after stopping a node @@ -1764,7 +1766,7 @@ start_upgrade_escript_with_argsfile_data(Config) -> %% now start/stop the release to make sure the extended script is working {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, _Ver} = sh(filename:join([OutputDir, "foo", "bin", "foo versions"])), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), %% a ping should fail after stopping a node @@ -1832,7 +1834,7 @@ extension_script(Config) -> proplists:get_value(priv_dir, Config), ExtensionScript), os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])), - timer:sleep(2000), + timer:sleep(?SLEEP_TIME), {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), %% write the extension script output to a file {ok, Str} = sh(filename:join([OutputDir, "foo", "bin", "foo bar"])), -- cgit v1.2.3 From 70a916886156f2f4fe8ee8812fb00a2c648d0ba6 Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Wed, 27 Mar 2019 09:54:19 +0100 Subject: Add helpful debug output of Travis failures --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index ed0f025..0004695 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,9 @@ before_script: - wget https://s3.amazonaws.com/rebar3/rebar3 - chmod +x rebar3 script: "./rebar3 update && ./rebar3 ct" +after_failure: + ## Useful for troubleshooting to view test logs + - find _build/test/logs/ct_run*/lib*logs/run*/log_private/*-output*/*/log -type f -name "erlang*" -exec ls -1rt "{}" \+ | xargs -I % sh -c 'echo "\n\n%"; cat %' branches: only: - master -- cgit v1.2.3 From 00af9bafb2c22f78eb0a02ff89752705e781c20f Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Sun, 31 Mar 2019 23:09:43 +0100 Subject: Add travis.dev host --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0004695..e1a31d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,8 @@ branches: - master addons: hostname: travis.dev + hosts: + - travis.dev notifications: email: - core@erlware.org -- cgit v1.2.3 From 8420f6f43d5049514bfa1636240322fcbe0f440d Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 31 Mar 2019 19:28:07 -0600 Subject: try circleci for CI (#701) --- .circleci/config.yml | 33 +++++++++++++++++++++++++++++++++ .gitignore | 1 + test/rlx_extended_bin_SUITE.erl | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..6cf1061 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,33 @@ +version: 2.1 +orbs: + rebar3: tsloughter/rebar3@0.6.3 + +jobs: + ct: + parameters: + tag: + description: The docker tag to use. + type: string + default: "21.2" + executor: + name: rebar3/erlang + tag: <> + steps: + - checkout + - rebar3/ct + +workflows: + build-test: + jobs: + - ct: + name: "21" + tag: "21.2" + - ct: + name: "20" + tag: "20" + - ct: + name: "19" + tag: "19" + - ct: + name: "18" + tag: "18" diff --git a/.gitignore b/.gitignore index f04f7d2..287aef8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,6 @@ logs test/*_data _rel/* .* +!.circleci erl_crash.dump rebar diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index 21bb131..652e2d6 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -188,7 +188,7 @@ longname_ping(Config) -> {extended_start_script, true} ]), - ec_file:write(VmArgs, "-name foo\n\n" + ec_file:write(VmArgs, "-name foo@127.0.0.1\n\n" "-setcookie cookie\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), -- cgit v1.2.3 From a0706e46bc9b976afe80a0a8c0bbcc595f6b0b63 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 31 Mar 2019 20:09:34 -0600 Subject: RUNNER_LOG_DIR is only used in 'start' so only make it there (#699) --- priv/templates/extended_bin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 7e6dd29..76d2d38 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -457,9 +457,6 @@ esac # Export the variable so that it's available in the 'eval' calls export NAME -# Make sure log directory exists -mkdir -p "$RUNNER_LOG_DIR" - test -z "$PIPE_DIR" && PIPE_BASE_DIR='/tmp/erl_pipes/' PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}" @@ -511,6 +508,9 @@ case "$1" in exit 1 fi + # Make sure log directory exists + mkdir -p "$RUNNER_LOG_DIR" + relx_run_hooks "$PRE_START_HOOKS" "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" $ARGS --relx-disable-hooks" -- cgit v1.2.3 From 46afa565c7b319d1a8b23a7583da9d1d5e1e02e1 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 1 Apr 2019 09:20:02 -0600 Subject: include vm.args.src file in tarball if it exists (#698) * include vm.args.src in tarball if it exists * only check sys.config.src in tar on otp-21+ --- src/rlx_prv_archive.erl | 3 ++- test/rlx_archive_SUITE.erl | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/rlx_prv_archive.erl b/src/rlx_prv_archive.erl index e1735d1..8fd03c1 100644 --- a/src/rlx_prv_archive.erl +++ b/src/rlx_prv_archive.erl @@ -141,9 +141,10 @@ update_tar(State, TempDir, OutputDir, Name, Vsn, ErtsVersion) -> config_files(Vsn, OutputDir) -> VMArgs = {filename:join(["releases", Vsn, "vm.args"]), filename:join([OutputDir, "releases", Vsn, "vm.args"])}, + VMArgsSrc = {filename:join(["releases", Vsn, "vm.args.src"]), filename:join([OutputDir, "releases", Vsn, "vm.args.src"])}, VMArgsOrig = {filename:join(["releases", Vsn, "vm.args.orig"]), filename:join([OutputDir, "releases", Vsn, "vm.args.orig"])}, SysConfigOrig = {filename:join(["releases", Vsn, "sys.config.orig"]), filename:join([OutputDir, "releases", Vsn, "sys.config.orig"])}, - [{NameInArchive, Filename} || {NameInArchive, Filename} <- [VMArgs, VMArgsOrig, SysConfigOrig], filelib:is_file(Filename)]. + [{NameInArchive, Filename} || {NameInArchive, Filename} <- [VMArgsSrc, VMArgs, VMArgsOrig, SysConfigOrig], filelib:is_file(Filename)]. overlay_files(_, undefined, _) -> diff --git a/test/rlx_archive_SUITE.erl b/test/rlx_archive_SUITE.erl index 5122c11..68a5b07 100644 --- a/test/rlx_archive_SUITE.erl +++ b/test/rlx_archive_SUITE.erl @@ -55,11 +55,19 @@ basic_tar(Config) -> rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]), rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []), + SysConfigSrc = filename:join([LibDir1, "config", "sys.config.src"]), + rlx_test_utils:write_config(SysConfigSrc, [{this_is_a_test, "yup it is"}]), + + VmArgsSrc = filename:join([LibDir1, "config", "vm.args.src"]), + ec_file:write(VmArgsSrc, ""), + ConfigFile = filename:join([LibDir1, "relx.config"]), rlx_test_utils:write_config(ConfigFile, [{release, {foo, "0.0.1"}, [goal_app_1, - goal_app_2]}]), + goal_app_2]}, + {sys_config_src, SysConfigSrc}, + {vm_args_src, VmArgsSrc}]), OutputDir = filename:join([proplists:get_value(priv_dir, Config), rlx_test_utils:create_random_name("relx-output")]), {ok, State} = relx:do([{relname, foo}, @@ -84,6 +92,16 @@ basic_tar(Config) -> {ok, Files} = erl_tar:table(TarFile, [compressed]), ?assert(lists:any(fun(X) -> re:run(X, "lib/stdlib-.*/ebin/.*") =/= nomatch end, Files)), ?assert(lists:any(fun(X) -> re:run(X, "lib/kernel-.*/ebin/.*") =/= nomatch end, Files)), + + %% only works in otp-21 and above + case erlang:system_info(otp_release) of + R when R =:= "21" orelse R =:= "22" -> + ?assert(lists:member("releases/0.0.1/vm.args.src", Files)), + ?assert(lists:member("releases/0.0.1/sys.config.src", Files)); + _ -> + ok + end, + ?assert(filelib:is_regular(TarFile)). exclude_erts(Config) -> -- cgit v1.2.3 From efdef34f8f896e450ac9665d529e0b690773df96 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 1 Apr 2019 09:21:19 -0600 Subject: use RELX_OUT_FILE_PATH even when generating from .src files (#700) --- priv/templates/extended_bin | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 76d2d38..059f5bf 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -250,9 +250,9 @@ check_replace_os_vars() { SRC_FILE_PATH="$IN_FILE_PATH.src" ORIG_FILE_PATH="$IN_FILE_PATH.orig" if [ -f "$SRC_FILE_PATH" ]; then + OUT_FILE_PATH=$(make_out_file_path $IN_FILE_PATH) replace_os_vars "$SRC_FILE_PATH" "$OUT_FILE_PATH" elif [ $RELX_REPLACE_OS_VARS ]; then - # Create a new file in the same location as original OUT_FILE_PATH=$(make_out_file_path $IN_FILE_PATH) # If vm.args.orig or sys.config.orig is present then use that if [ -f "$ORIG_FILE_PATH" ]; then @@ -272,7 +272,8 @@ check_replace_os_vars() { else # If vm.arg.orig or sys.config.orig is present then use that if [ -f "$ORIG_FILE_PATH" ]; then - cp "$ORIG_FILE_PATH" "$OUT_FILE_PATH" + OUT_FILE_PATH=$(make_out_file_path $IN_FILE_PATH) + cp "$ORIG_FILE_PATH" "$OUT_FILE_PATH" fi fi echo $OUT_FILE_PATH -- cgit v1.2.3 From cecbe865bcd025e3d8e08d6e6070cb03d47e66e1 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 1 Apr 2019 14:22:09 -0600 Subject: have travis only run 17 and osx. add circleci badge (#703) * have travis only run 17 and osx. add circleci badge * use localhost for shortname nodes in tests --- .travis.yml | 12 ------------ README.md | 1 + test/rlx_extended_bin_SUITE.erl | 24 ++++++++++++------------ 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index e1a31d1..4e4f877 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,18 +4,6 @@ matrix: - os: linux sudo: required otp_release: 17.5 - - os: linux - sudo: required - otp_release: 18.3 - - os: linux - sudo: required - otp_release: 19.3 - - os: linux - sudo: required - otp_release: 20.0 - - os: linux - sudo: required - otp_release: 21.0 - os: osx sudo: required language: generic diff --git a/README.md b/README.md index 728a210..dfc2ef2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Build Status](https://travis-ci.org/erlware/relx.png?branch=master)](https://travis-ci.org/erlware/relx) +[![CircleCI](https://circleci.com/gh/erlware/relx.svg?style=svg)](https://circleci.com/gh/erlware/relx) Relx ======= diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index 652e2d6..041afca 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -149,7 +149,7 @@ shortname_ping(Config) -> {extended_start_script, true} ]), - ec_file:write(VmArgs, "-sname foo\n\n" + ec_file:write(VmArgs, "-sname foo@localhost\n\n" "-setcookie cookie\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -436,7 +436,7 @@ shortname_remote_console(Config) -> ConfigFile = filename:join([LibDir1, "relx.config"]), VmArgs = filename:join([LibDir1, "vm.args"]), - ec_file:write(VmArgs, "-sname foo\n\n" + ec_file:write(VmArgs, "-sname foo@localhost\n\n" "-setcookie cookie\n"), rlx_test_utils:write_config(ConfigFile, @@ -493,7 +493,7 @@ replace_os_vars(Config) -> [[{goal_app, [{var1, "${VAR1}"}, {var2, "${VAR2}"}]}]]), - ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n" "-setcookie ${COOKIE}\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -608,7 +608,7 @@ replace_os_vars_sys_config_vm_args_src(Config) -> %% new with sys.config.src it doesn't have to be valid Erlang %% until after var replacemen at runtime. ec_file:write(SysConfigSrc, "[{goal_app, [{var1, ${VAR1}}]}]."), - ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n" "-setcookie ${COOKIE}\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -721,7 +721,7 @@ replace_os_vars_multi_node(Config) -> rlx_test_utils:write_config(SysConfig, [[{goal_app, [{var1, "${VAR1}"}]}]]), - ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n" "-setcookie ${COOKIE}\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -866,7 +866,7 @@ replace_os_vars_included_config(Config) -> }, "releases/0.0.1/config/included.config"] ]), - ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n" "-setcookie ${COOKIE}\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -979,7 +979,7 @@ replace_os_vars_custom_location(Config) -> rlx_test_utils:write_config(SysConfig, [[{goal_app, [{var1, "${VAR1}"}]}]]), - ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n" "-setcookie ${COOKIE}\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -1106,7 +1106,7 @@ replace_os_vars_twice(Config) -> rlx_test_utils:write_config(SysConfig, [[{goal_app, [{var1, "${VAR1}"}]}]]), - ec_file:write(VmArgs, "-sname node\n\n" + ec_file:write(VmArgs, "-sname node@localhost\n\n" "-setcookie cookie\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -1179,7 +1179,7 @@ replace_os_vars_dev_mode(Config) -> rlx_test_utils:write_config(SysConfig, [[{goal_app, [{var1, "${VAR1}"}]}]]), - ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n" "-setcookie ${COOKIE}\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -1628,7 +1628,7 @@ start_sname_in_other_argsfile(Config) -> ec_file:write(VmArgs, "-args_file " ++ VmArgs2 ++ "\n\n" "-setcookie cookie\n"), - ec_file:write(VmArgs2, "-sname foo\n"), + ec_file:write(VmArgs2, "-sname foo@localhost\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), rlx_test_utils:create_random_name("relx-output")]), @@ -1710,7 +1710,7 @@ start_nodetool_with_data_from_argsfile(Config) -> ]), ec_file:write(VmArgs, "-setcookie cookie\n" - "-sname foo\n\n" + "-sname foo@localhost\n\n" "-proto_dist inet_tcp\n\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), @@ -1750,7 +1750,7 @@ start_upgrade_escript_with_argsfile_data(Config) -> ]), ec_file:write(VmArgs, "-setcookie cookie\n" - "-sname foo\n\n" + "-sname foo@localhost\n\n" "-proto_dist inet_tcp\n\n"), OutputDir = filename:join([proplists:get_value(priv_dir, Config), -- cgit v1.2.3 From 492f7f776648527c22c7148f9a75077cdca1bac7 Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Tue, 2 Apr 2019 16:05:09 +0200 Subject: Store artifacts on Circle CI runs (#704) --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6cf1061..ca75335 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,6 +15,12 @@ jobs: steps: - checkout - rebar3/ct + # Delete OTP files which don't need to be stored + - run: | + find _build/test/logs -type d -and \( -path "*/erts-*" -or -path "*/kernel-*" -or -path "*/stdlib-*" \) -exec rm -rf '{}' \+ || true + find _build/test/logs -type f -name "*.beam" -exec rm -rf '{}' \+ || true + - store_artifacts: + path: _build/test/logs workflows: build-test: -- cgit v1.2.3 From 13c28fd4d5bfd2f91eeb4ff96ace3a2c321664f7 Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Tue, 19 Mar 2019 13:42:36 +0100 Subject: Fix parameter shift on win32 for extension commands --- priv/templates/extended_bin_windows | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index 2d9e0ff..6d8f084 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -324,8 +324,9 @@ set description=Erlang node %node_name%%hostname% in %rootdir% :: Run extension script :run_extension @if exist "%script_dir%\extensions\%1.cmd" ( - shift - call "%script_dir%\extensions\%1.cmd" %* + set _extension_params=%* + call set _extension_params=%%_extension_params:*%1=%% + call "%script_dir%\extensions\%1.cmd" %%_extension_params%% ) @goto :eof -- cgit v1.2.3 From 091e7351d8cac31375ddd5268c235715a1511784 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Wed, 3 Apr 2019 16:39:24 -0600 Subject: try cirrus ci --- .cirrus.yml | 9 +++++++++ .gitignore | 1 + 2 files changed, 10 insertions(+) create mode 100644 .cirrus.yml diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000..bec8f21 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,9 @@ +container: + image: circleci/erlang:21 + +check_task: + # rebar3_cache: + # folder: _build + # fingerprint_script: cat rebar.lock + # populate_script: rebar compile + test_script: rebar3 ct diff --git a/.gitignore b/.gitignore index 287aef8..ce87711 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ test/*_data _rel/* .* !.circleci +!.cirrus.yml erl_crash.dump rebar -- cgit v1.2.3 From fc7df7461507fae28ea2402ebe2840bec35c53af Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Wed, 3 Apr 2019 17:23:56 -0600 Subject: add osx test run --- .cirrus.yml | 26 +++++++++++++++++++------- rebar.config | 3 ++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index bec8f21..2756823 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,9 +1,21 @@ -container: - image: circleci/erlang:21 - check_task: - # rebar3_cache: - # folder: _build - # fingerprint_script: cat rebar.lock - # populate_script: rebar compile + container: + image: circleci/erlang:21 + rebar3_cache: + folder: _build + fingerprint_script: cat rebar.lock + populate_script: rebar3 compile --deps_only + compile_script: rebar3 compile test_script: rebar3 ct + always: + junit_artifacts: + path: "_build/test/logs/ct_run.*/junit_report.xml" + +osx_check_task: + osx_instance: + image: mojave-base + install_script: brew install erlang + test_script: | + wget https://s3.amazonaws.com/rebar3/rebar3 + chmod +x rebar3 + ./rebar3 ct diff --git a/rebar.config b/rebar.config index d7f5312..285b1ce 100644 --- a/rebar.config +++ b/rebar.config @@ -69,7 +69,8 @@ {override, providers, [{erl_opts, [no_debug_info]}]} ]}. -{ct_opts, [{cover_spec, "cover.spec"}]}. +{ct_opts, [{cover_spec, "cover.spec"}, + {ct_hooks, [cth_surefire]}]}. {cover_enabled, true}. {cover_print_enabled, true}. -- cgit v1.2.3 From 4c0df35b8fa1dc9d2e45b92cf0c4f9867ef90f90 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Wed, 3 Apr 2019 18:02:54 -0600 Subject: split out build task --- .cirrus.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 2756823..d7e7e3e 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,11 +1,19 @@ -check_task: +build_task: container: image: circleci/erlang:21 rebar3_cache: folder: _build fingerprint_script: cat rebar.lock populate_script: rebar3 compile --deps_only - compile_script: rebar3 compile + +test_task: + container: + image: circleci/erlang:21 + depends_on: + - build + rebar3_cache: + folder: _build + fingerprint_script: cat rebar.lock test_script: rebar3 ct always: junit_artifacts: -- cgit v1.2.3 From 2a4ff9a61f50adce4c86b5414bf81e29bc013160 Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Fri, 5 Apr 2019 22:30:22 +0200 Subject: Refactor creation of .erlang.cookie for use in start/console procedures (#690) * Randomize dummy node name The static name used so far would result in name clashing when running the script multiple times in short succession. * Fix find_sys_config routine in win32 extended bin * Remove escaping of double quotes * Fix dummy command syntax * Refactor creation of .erlang.cookie at startup * Fix dummy node logic for win32 --- priv/templates/extended_bin | 27 ++++++++++++----- priv/templates/extended_bin_windows | 58 +++++++++++++++++++++++++++---------- 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 059f5bf..fde6729 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -19,7 +19,7 @@ fi # OSX does not support readlink '-f' flag, work # around that -case $OSTYPE in +case $OSTYPE in darwin*) SCRIPT=$(readlink $0 || true) ;; @@ -127,17 +127,26 @@ find_erts_dir() { if [ -d "$__erts_dir" ]; then ERTS_DIR="$__erts_dir"; ROOTDIR="$RELEASE_ROOT_DIR" - # run a dummy distributed erlang node just to ensure that a cookie exists - $ERTS_DIR/bin/erl -sname dummy -boot no_dot_erlang -noshell -eval "halt()" else __erl="$(which erl)" code="io:format(\"~s\", [code:root_dir()]), halt()." - __erl_root="$("$__erl" -sname dummy -boot no_dot_erlang -sasl errlog_type error -noshell -eval "$code")" + __erl_root="$("$__erl" -boot no_dot_erlang -sasl errlog_type error -noshell -eval "$code")" ERTS_DIR="$__erl_root/erts-$ERTS_VSN" ROOTDIR="$__erl_root" fi } +ensure_dot_erlang_cookie() { + # Run a dummy distributed erlang node just to ensure that $HOME/.erlang.cookie exists. + # This action is best-effort and could fail because of the way the system is set up. + # Failures are logged, but ignored. + DUMMY_NAME="dummy-$(relx_gen_id)" + if ! output="$($ERTS_DIR/bin/erl -sname ${DUMMY_NAME} -boot no_dot_erlang -noshell -eval "halt()")" + then + echo "Creating .erlang.cookie failed: ${output}" + fi +} + # Get node pid relx_get_pid() { if output="$(relx_nodetool rpcterms os getpid)" @@ -310,10 +319,10 @@ relx_is_extension() { EXTENSION=$1 case "$EXTENSION" in {{{ extensions }}}) - echo "1" + echo "1" ;; *) - echo "0" + echo "0" ;; esac } @@ -324,7 +333,7 @@ relx_get_extension_script() { # of the form: # foo_extension="path/to/foo_script";bar_extension="path/to/bar_script" {{{extension_declarations}}} - # get the command extension (eg. foo) and + # get the command extension (eg. foo) and # obtain the actual script filename that it # refers to (eg. "path/to/foo_script" eval echo "$"${EXTENSION}_extension"" @@ -512,6 +521,8 @@ case "$1" in # Make sure log directory exists mkdir -p "$RUNNER_LOG_DIR" + ensure_dot_erlang_cookie + relx_run_hooks "$PRE_START_HOOKS" "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" $ARGS --relx-disable-hooks" @@ -682,6 +693,8 @@ case "$1" in -pa ${__code_paths} -- "$@" echo "Root: $ROOTDIR" + ensure_dot_erlang_cookie + # Log the startup echo "$RELEASE_ROOT_DIR" logger -t "$REL_NAME[$$]" "Starting up" diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index 6d8f084..0db46cc 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -37,17 +37,18 @@ @set vm_args=%rel_dir%\vm.args @set progname=erl.exe @set clean_boot_script=%release_root_dir%\bin\start_clean -@set erlsrv="%bindir%\erlsrv.exe" -@set epmd="%bindir%\epmd.exe" -@set escript="%bindir%\escript.exe" -@set werl="%bindir%\werl.exe" -@set nodetool="%release_root_dir%\bin\nodetool" +@set "erlsrv=%bindir%\erlsrv.exe" +@set "epmd=%bindir%\epmd.exe" +@set "escript=%bindir%\escript.exe" +@set "werl=%bindir%\werl.exe" +@set "erl=%bindir%\erl.exe" +@set "nodetool=%release_root_dir%\bin\nodetool" @set "extensions0={{ extensions }}" @set "extensions1=%extensions0:|= %" @set "extensions=%extensions1: undefined=%" :: Extract node type and name from vm.args -@for /f "usebackq tokens=1-2" %%I in (`findstr /b "\-name \-sname" "%vm_args%"`) do @( +@for /f "usebackq tokens=1-2" %%I in ('findstr /b "\-name \-sname" "%vm_args%"') do @( set node_type=%%I set node_name=%%J ) @@ -77,7 +78,7 @@ ) :: Extract cookie from vm.args -@for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do @( +@for /f "usebackq tokens=1-2" %%I in ('findstr /b \-setcookie "%vm_args%"') do @( set cookie=%%J ) @@ -86,7 +87,7 @@ :: Collect any additional VM args into erl_opts @setlocal EnableDelayedExpansion -@for /f "usebackq tokens=1-2" %%I in (`findstr /r "^[^#]" "%vm_args%"`) do @( +@for /f "usebackq tokens=1-2" %%I in ('findstr /r "^[^#]" "%vm_args%"') do @( if not "%%I" == "-name" ( if not "%%I" == "-sname" ( if not "%%I" == "-setcookie" ( @@ -143,11 +144,10 @@ :: Set the ERTS dir from erl :set_erts_dir_from_erl @for /f "delims=" %%i in ('where erl') do @( - set erl=%%i + set "erl=%%i" ) -@set dir_cmd="%erl%" -sname dummy -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop -@for /f "delims=" %%i in ('%%dir_cmd%%') do @( - set erl_root=%%i +@for /f "delims=" %%i in ('"%erl%" -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop') do @( + set "erl_root=%%i" ) @set "erts_dir=%erl_root%\erts-%erts_vsn%" @set "rootdir=%erl_root%" @@ -164,12 +164,13 @@ set sys_config=-config "%possible_sys%" ) ) +@goto :eof :: Find the vm.args file :find_vm_args -@if not exist "%m_args%" ( - @if exist "%m_args%.orig" ( - ren "%m_args%.orig" vm.args +@if not exist "%vm_args%" ( + @if exist "%vm_args%.orig" ( + ren "%vm_args%.orig" vm.args ) ) @goto :eof @@ -278,6 +279,7 @@ set description=Erlang node %node_name%%hostname% in %rootdir% :: Start the Windows service :start +@call :ensure_dot_erlang_cookie @%erlsrv% start %service_name% @goto :eof @@ -299,6 +301,7 @@ set description=Erlang node %node_name%%hostname% in %rootdir% :: Start a console :console +@call :ensure_dot_erlang_cookie @set boot=-boot "%boot_script%" -boot_var RELEASE_DIR "%release_root_dir%" @start "%rel_name% console" %werl% %boot% %sys_config% ^ -args_file "%vm_args%" @@ -351,3 +354,28 @@ set description=Erlang node %node_name%%hostname% in %rootdir% @if not "%ext_test_3%"=="x%extensions%" exit /b 0 @exit /b 1 + +:ensure_dot_erlang_cookie + +:: Run a dummy distributed erlang node just to ensure that %HOMEPATH%\.erlang.cookie exists. +:: This action is best-effort and could fail because of the way the system is set up. +:: Failures are logged, but ignored. + +:: Create random dummy node name +@set /a "_rand_nr=%RANDOM%+100000" +@set "dummy_name=dummy-%_rand_nr%" + +:: Run node and capture output in local var +@for /f "delims=" %%i in ('%erl% -sname %dummy_name% -boot no_dot_erlang -noshell -eval "halt()."') do @( + set "dummy_node_output=%%i" +) + +:: Check for execution error +@if "%dummy_node_output%" neq "" @( + echo Creating .erlang.cookie failed: "%dummy_node_output%" +) + +:: Clear all local variables +@set "dummy_node_output=" + +@exit /b 0 -- cgit v1.2.3 From a6107ec667820de9f6b6d6ae835b0f3b7e613a58 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 12 Apr 2019 08:11:14 -0600 Subject: don't require a cookie in the start script (#708) * don't require a cookie in the start script * remove ensure cookie function from windows script * Add updated cookie handling for win32 --- priv/templates/extended_bin | 62 +++++++++++++++++-------------------- priv/templates/extended_bin_windows | 39 +++++++---------------- 2 files changed, 39 insertions(+), 62 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index fde6729..e224c62 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -136,17 +136,6 @@ find_erts_dir() { fi } -ensure_dot_erlang_cookie() { - # Run a dummy distributed erlang node just to ensure that $HOME/.erlang.cookie exists. - # This action is best-effort and could fail because of the way the system is set up. - # Failures are logged, but ignored. - DUMMY_NAME="dummy-$(relx_gen_id)" - if ! output="$($ERTS_DIR/bin/erl -sname ${DUMMY_NAME} -boot no_dot_erlang -noshell -eval "halt()")" - then - echo "Creating .erlang.cookie failed: ${output}" - fi -} - # Get node pid relx_get_pid() { if output="$(relx_nodetool rpcterms os getpid)" @@ -161,10 +150,19 @@ relx_get_pid() { relx_get_nodename() { id="longname$(relx_gen_id)-${NAME}" - "$BINDIR/erl" -boot start_clean \ - -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ - -eval '[_,H]=re:split(atom_to_list(node()),"@",[unicode,{return,list}]), io:format("~s~n",[H]), halt()' \ - -noshell ${NAME_TYPE} $id + if [ -z "$COOKIE" ]; then + "$BINDIR/erl" -boot start_clean \ + -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ + -eval '[_,H]=re:split(atom_to_list(node()),"@",[unicode,{return,list}]), io:format("~s~n",[H]), halt()' \ + -noshell ${NAME_TYPE} $id + else + # running with setcookie prevents a ~/.erlang.cookie from being created + "$BINDIR/erl" -boot start_clean \ + -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ + -eval '[_,H]=re:split(atom_to_list(node()),"@",[unicode,{return,list}]), io:format("~s~n",[H]), halt()' \ + -setcookie ${COOKIE} \ + -noshell ${NAME_TYPE} $id + fi } # Connect to a remote node @@ -456,6 +454,21 @@ NAME_ARG=$(eval echo "${NAME_ARG}") NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')" NAME="$(echo "$NAME_ARG" | awk '{print $2}')" +# Extract the target cookie +# Do this before relx_get_nodename so we can use it and not create a ~/.erlang.cookie +COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)" +DEFAULT_COOKIE_FILE="$HOME/.erlang.cookie" +if [ -z "$COOKIE_ARG" ]; then + if [ -f "$DEFAULT_COOKIE_FILE" ]; then + COOKIE="$(cat $DEFAULT_COOKIE_FILE)" + else + echo "No cookie is set or found. This limits the scripts functionality, installing, upgrading, rpc and getting a list of versions will not work." + fi +else + # Extract cookie name from COOKIE_ARG + COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')" +fi + # User can specify an sname without @hostname # This will fail when creating remote shell # So here we check for @ and add @hostname if missing @@ -470,21 +483,6 @@ export NAME test -z "$PIPE_DIR" && PIPE_BASE_DIR='/tmp/erl_pipes/' PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}" -# Extract the target cookie -COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)" -DEFAULT_COOKIE_FILE="$HOME/.erlang.cookie" -if [ -z "$COOKIE_ARG" ]; then - if [ -f "$DEFAULT_COOKIE_FILE" ]; then - COOKIE="$(cat $DEFAULT_COOKIE_FILE)" - else - echo "vm.args needs to have a -setcookie, or $DEFAULT_COOKIE_FILE (its permission must be 400) is required." - exit 1 - fi -else - # Extract cookie name from COOKIE_ARG - COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')" -fi - VM_ARGS="$(grep -v -E '^#|^-name|^-sname|^-setcookie|^-heart|^-args_file' "$VMARGS_PATH" | xargs | sed -e 's/ / /g')" cd "$ROOTDIR" @@ -521,8 +519,6 @@ case "$1" in # Make sure log directory exists mkdir -p "$RUNNER_LOG_DIR" - ensure_dot_erlang_cookie - relx_run_hooks "$PRE_START_HOOKS" "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" $ARGS --relx-disable-hooks" @@ -693,8 +689,6 @@ case "$1" in -pa ${__code_paths} -- "$@" echo "Root: $ROOTDIR" - ensure_dot_erlang_cookie - # Log the startup echo "$RELEASE_ROOT_DIR" logger -t "$REL_NAME[$$]" "Starting up" diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows index 0db46cc..16e3d96 100644 --- a/priv/templates/extended_bin_windows +++ b/priv/templates/extended_bin_windows @@ -77,9 +77,18 @@ set "hostname=@%hostname%" ) -:: Extract cookie from vm.args +:: Extract the target cookie +:: Do this before relx_get_nodename so we can use it and not create a ~/.erlang.cookie @for /f "usebackq tokens=1-2" %%I in ('findstr /b \-setcookie "%vm_args%"') do @( - set cookie=%%J + set "cookie=%%J" +) +@set "default_cookie_file=%USERPROFILE%\.erlang.cookie" +@if "%cookie%" == "" @( + if exist "%default_cookie_file%" ( + set /p cookie=<%default_cookie_file% + ) else ( + echo No cookie is set or found. This limits the scripts functionality, installing, upgrading, rpc and getting a list of versions will not work. + ) ) :: Write the erl.ini file to set up paths relative to this script @@ -279,7 +288,6 @@ set description=Erlang node %node_name%%hostname% in %rootdir% :: Start the Windows service :start -@call :ensure_dot_erlang_cookie @%erlsrv% start %service_name% @goto :eof @@ -301,7 +309,6 @@ set description=Erlang node %node_name%%hostname% in %rootdir% :: Start a console :console -@call :ensure_dot_erlang_cookie @set boot=-boot "%boot_script%" -boot_var RELEASE_DIR "%release_root_dir%" @start "%rel_name% console" %werl% %boot% %sys_config% ^ -args_file "%vm_args%" @@ -355,27 +362,3 @@ set description=Erlang node %node_name%%hostname% in %rootdir% @exit /b 1 -:ensure_dot_erlang_cookie - -:: Run a dummy distributed erlang node just to ensure that %HOMEPATH%\.erlang.cookie exists. -:: This action is best-effort and could fail because of the way the system is set up. -:: Failures are logged, but ignored. - -:: Create random dummy node name -@set /a "_rand_nr=%RANDOM%+100000" -@set "dummy_name=dummy-%_rand_nr%" - -:: Run node and capture output in local var -@for /f "delims=" %%i in ('%erl% -sname %dummy_name% -boot no_dot_erlang -noshell -eval "halt()."') do @( - set "dummy_node_output=%%i" -) - -:: Check for execution error -@if "%dummy_node_output%" neq "" @( - echo Creating .erlang.cookie failed: "%dummy_node_output%" -) - -:: Clear all local variables -@set "dummy_node_output=" - -@exit /b 0 -- cgit v1.2.3 From 4825a495febf31f5be172d1a7e9b89a1514f1b5c Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 12 Apr 2019 14:32:04 -0600 Subject: include dist and epmd arguments from vm.args in remote shell and nodetool calls (#710) * remove unused VM_ARGS variable * include dist args in extended start scripts other calls --- priv/templates/extended_bin | 31 ++++++++++++++++++++++++++----- priv/templates/nodetool | 32 ++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index e224c62..cfeb859 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -176,7 +176,7 @@ relx_rem_sh() { # Setup remote shell command to control node exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \ - -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ + -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" $MAYBE_DIST_ARGS \ -setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME } @@ -189,8 +189,16 @@ relx_gen_id() { relx_nodetool() { command="$1"; shift - "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ - -setcookie "$COOKIE" "$command" $@ + if [ -z "${START_EPMD}" ]; then + ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS}" "$ERTS_DIR/bin/escript" \ + "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ + -setcookie "$COOKIE" "$command" $@ + else + ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS}" "$ERTS_DIR/bin/escript" \ + "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ + $START_EPMD -setcookie "$COOKIE" "$command" $@ + fi + } # Run an escript in the node's environment @@ -454,6 +462,21 @@ NAME_ARG=$(eval echo "${NAME_ARG}") NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')" NAME="$(echo "$NAME_ARG" | awk '{print $2}')" +# Extract dist arguments +MAYBE_DIST_ARGS="" +PROTO_DIST="$(grep '^-proto_dist' "$VMARGS_PATH" || true)" +if [ "$PROTO_DIST" ]; then + MAYBE_DIST_ARGS="${PROTO_DIST}" +fi +START_EPMD="$(grep '^-start_epmd' "$VMARGS_PATH" || true)" +if [ "$START_EPMD" ]; then + MAYBE_DIST_ARGS="${MAYBE_DIST_ARGS} ${START_EPMD}" +fi +EPMD_MODULE="$(grep '^-epmd_module' "$VMARGS_PATH" || true)" +if [ "$EPMD_MODULE" ]; then + MAYBE_DIST_ARGS="${MAYBE_DIST_ARGS} ${EPMD_MODULE}" +fi + # Extract the target cookie # Do this before relx_get_nodename so we can use it and not create a ~/.erlang.cookie COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)" @@ -483,8 +506,6 @@ export NAME test -z "$PIPE_DIR" && PIPE_BASE_DIR='/tmp/erl_pipes/' PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}" -VM_ARGS="$(grep -v -E '^#|^-name|^-sname|^-setcookie|^-heart|^-args_file' "$VMARGS_PATH" | xargs | sed -e 's/ / /g')" - cd "$ROOTDIR" # Check the first argument for instructions diff --git a/priv/templates/nodetool b/priv/templates/nodetool index 816be9c..62fa02e 100644 --- a/priv/templates/nodetool +++ b/priv/templates/nodetool @@ -8,9 +8,10 @@ %% ------------------------------------------------------------------- main(Args) -> - ok = start_epmd(), %% Extract the args - {RestArgs, TargetNode} = process_args(Args, [], undefined), + {RestArgs, TargetNode, StartEpmd} = process_args(Args, [], undefined, true), + + ok = start_epmd(StartEpmd), %% See if the node is currently running -- if it's not, we'll bail case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of @@ -87,25 +88,28 @@ main(Args) -> end, net_kernel:stop(). -process_args([], Acc, TargetNode) -> - {lists:reverse(Acc), TargetNode}; -process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) -> +process_args([], Acc, TargetNode, StartEpmd) -> + {lists:reverse(Acc), TargetNode, StartEpmd}; +process_args(["-setcookie", Cookie | Rest], Acc, TargetNode, StartEpmd) -> erlang:set_cookie(node(), list_to_atom(Cookie)), - process_args(Rest, Acc, TargetNode); -process_args(["-name", TargetName | Rest], Acc, _) -> + process_args(Rest, Acc, TargetNode, StartEpmd); +process_args(["-start_epmd", StartEpmd | Rest], Acc, TargetNode, _StartEpmd) -> + process_args(Rest, Acc, TargetNode, list_to_atom(StartEpmd)); +process_args(["-name", TargetName | Rest], Acc, _, StartEpmd) -> ThisNode = append_node_suffix(TargetName, "_maint_"), {ok, _} = net_kernel:start([ThisNode, longnames]), - process_args(Rest, Acc, nodename(TargetName)); -process_args(["-sname", TargetName | Rest], Acc, _) -> + process_args(Rest, Acc, nodename(TargetName), StartEpmd); +process_args(["-sname", TargetName | Rest], Acc, _, StartEpmd) -> ThisNode = append_node_suffix(TargetName, "_maint_"), {ok, _} = net_kernel:start([ThisNode, shortnames]), - process_args(Rest, Acc, nodename(TargetName)); -process_args([Arg | Rest], Acc, Opts) -> - process_args(Rest, [Arg | Acc], Opts). - + process_args(Rest, Acc, nodename(TargetName), StartEpmd); +process_args([Arg | Rest], Acc, Opts, StartEpmd) -> + process_args(Rest, [Arg | Acc], Opts, StartEpmd). -start_epmd() -> +start_epmd(true) -> [] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"), + ok; +start_epmd(_) -> ok. epmd_path() -> -- cgit v1.2.3 From 8ff1e44cebf3aee09969a9324c04074ba87f10b9 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 14 Apr 2019 07:21:04 -0600 Subject: add dist name and cookie to ERL_FLAGS for nodetool (#712) * remove deprecated hex field from .app.src * start nodetool dist node in erl flags --- priv/templates/extended_bin | 20 +++++++++++++------- priv/templates/nodetool | 15 +++++++++++---- src/relx.app.src | 18 ++++++++---------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index cfeb859..a4cba4a 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -189,16 +189,22 @@ relx_gen_id() { relx_nodetool() { command="$1"; shift + # Generate a unique id used to allow multiple nodetool calls to the + # same node transparently + nodetool_id="maint$(relx_gen_id)-${NAME}" + if [ -z "${START_EPMD}" ]; then - ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS}" "$ERTS_DIR/bin/escript" \ - "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ - -setcookie "$COOKIE" "$command" $@ + ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS} ${NAME_TYPE} $nodetool_id -setcookie ${COOKIE}" \ + "$ERTS_DIR/bin/escript" \ + "$ROOTDIR/bin/nodetool" \ + "$NAME_TYPE" "$NAME" \ + "$command" $@ else - ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS}" "$ERTS_DIR/bin/escript" \ - "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ - $START_EPMD -setcookie "$COOKIE" "$command" $@ + ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS} ${NAME_TYPE} $nodetool_id -setcookie ${COOKIE}" \ + "$ERTS_DIR/bin/escript" \ + "$ROOTDIR/bin/nodetool" \ + $START_EPMD "$NAME_TYPE" "$NAME" "$command" $@ fi - } # Run an escript in the node's environment diff --git a/priv/templates/nodetool b/priv/templates/nodetool index 62fa02e..9e24f32 100644 --- a/priv/templates/nodetool +++ b/priv/templates/nodetool @@ -96,16 +96,23 @@ process_args(["-setcookie", Cookie | Rest], Acc, TargetNode, StartEpmd) -> process_args(["-start_epmd", StartEpmd | Rest], Acc, TargetNode, _StartEpmd) -> process_args(Rest, Acc, TargetNode, list_to_atom(StartEpmd)); process_args(["-name", TargetName | Rest], Acc, _, StartEpmd) -> - ThisNode = append_node_suffix(TargetName, "_maint_"), - {ok, _} = net_kernel:start([ThisNode, longnames]), + maybe_start_node(TargetName, longnames), process_args(Rest, Acc, nodename(TargetName), StartEpmd); process_args(["-sname", TargetName | Rest], Acc, _, StartEpmd) -> - ThisNode = append_node_suffix(TargetName, "_maint_"), - {ok, _} = net_kernel:start([ThisNode, shortnames]), + maybe_start_node(TargetName, shortnames), process_args(Rest, Acc, nodename(TargetName), StartEpmd); process_args([Arg | Rest], Acc, Opts, StartEpmd) -> process_args(Rest, [Arg | Acc], Opts, StartEpmd). +maybe_start_node(TargetName, Names) -> + case erlang:node() of + 'nonode@nohost' -> + ThisNode = append_node_suffix(TargetName, "_maint_"), + {ok, _} = net_kernel:start([ThisNode, Names]); + _ -> + ok + end. + start_epmd(true) -> [] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"), ok; diff --git a/src/relx.app.src b/src/relx.app.src index c8915d5..c845982 100644 --- a/src/relx.app.src +++ b/src/relx.app.src @@ -1,11 +1,9 @@ {application,relx, - [{description,"Release assembler for Erlang/OTP Releases"}, - {vsn,"git"}, - {modules,[]}, - {registered,[]}, - {applications,[kernel,stdlib,getopt,erlware_commons,bbmustache, - providers]}, - {maintainers,["Eric Merritt","Tristan Sloughter", - "Jordan Wilberding"]}, - {licenses,["Apache"]}, - {links,[{"Github","https://github.com/erlware/relx"}]}]}. + [{description,"Release assembler for Erlang/OTP Releases"}, + {vsn,"git"}, + {modules,[]}, + {registered,[]}, + {applications,[kernel,stdlib,getopt,erlware_commons,bbmustache, + providers]}, + {licenses,["Apache"]}, + {links,[{"Github","https://github.com/erlware/relx"}]}]}. -- cgit v1.2.3 From 9d47ab01be9819e0f69f7da73c71c34903f5b911 Mon Sep 17 00:00:00 2001 From: emtenet Date: Sun, 24 Apr 2016 13:41:17 +1000 Subject: Remove dead code of cp_r/2, xcopy_win32/2 and cp_r_win32/2. The bulk of the code is hidden behind opposite checks: * os:type() /= {win32, _} in symlink_or_copy/2 * os:type() == {win32, _} in cp_r/2 symlink_or_copy/2 is always using win32_symlink/2 when file:make_symlink/2 fails. --- src/rlx_util.erl | 64 ++------------------------------------------------------ 1 file changed, 2 insertions(+), 62 deletions(-) diff --git a/src/rlx_util.erl b/src/rlx_util.erl index b3fc2b7..f68c291 100644 --- a/src/rlx_util.erl +++ b/src/rlx_util.erl @@ -233,18 +233,14 @@ symlink_or_copy(Source, Target) -> ok; {error, eexist} -> {error, eexist}; - {error, _} -> + {error, _} = Error -> case os:type() of {win32, _} -> S = unicode:characters_to_list(Source), T = unicode:characters_to_list(Target), win32_symlink(filename:nativename(S), filename:nativename(T)); _ -> - case filelib:is_dir(Target) of - true -> ok; - false -> - cp_r([Source], Target) - end + Error end end. @@ -253,62 +249,6 @@ win32_symlink(Source, Target) -> os:cmd("cmd /c mklink /j " ++ Target ++ " " ++ Source), ok. --spec cp_r(list(string()), file:filename()) -> 'ok'. -cp_r(Sources, Dest) -> - case os:type() of - {unix, _} -> - ok; - {win32, _} -> - lists:foreach(fun(Src) -> ok = cp_r_win32(Src,Dest) end, Sources), - ok - end. - -xcopy_win32(Source,Dest)-> - %% "xcopy \"~s\" \"~s\" /q /y /e 2> nul", Chanegd to robocopy to - %% handle long names. May have issues with older windows. - os:cmd("robocopy " ++ Source ++ " " ++ Dest ++ " /e /is"), - ok. - -cp_r_win32({true, SourceDir}, {true, DestDir}) -> - %% from directory to directory - ok = case file:make_dir(DestDir) of - {error, eexist} -> ok; - Other -> Other - end, - ok = xcopy_win32(SourceDir, DestDir); -cp_r_win32({false, Source} = S,{true, DestDir}) -> - %% from file to directory - cp_r_win32(S, {false, filename:join(DestDir, filename:basename(Source))}); -cp_r_win32({false, Source},{false, Dest}) -> - %% from file to file - {ok,_} = file:copy(Source, Dest), - ok; -cp_r_win32({true, SourceDir}, {false, DestDir}) -> - case filelib:is_regular(DestDir) of - true -> - %% From directory to file? This shouldn't happen - {error, lists:flatten( - io_lib:format("Cannot copy dir (~p) to file (~p)\n", - [SourceDir, DestDir]))}; - false -> - %% Specifying a target directory that doesn't currently exist. - %% So let's attempt to create this directory - case filelib:ensure_dir(filename:join(DestDir, "dummy")) of - ok -> - ok = xcopy_win32(SourceDir, DestDir); - {error, Reason} -> - {error, lists:flatten( - io_lib:format("Unable to create dir ~p: ~p\n", - [DestDir, Reason]))} - end - end; -cp_r_win32(Source,Dest) -> - Dst = {filelib:is_dir(Dest), Dest}, - lists:foreach(fun(Src) -> - ok = cp_r_win32({filelib:is_dir(Src), Src}, Dst) - end, filelib:wildcard(Source)), - ok. - %% @doc Returns the color intensity, we first check the application envorinment %% if that is not set we check the environment variable RELX_COLOR. intensity() -> -- cgit v1.2.3 From 07943b1b41e8d1ffdf8b9f770e623212581b12cd Mon Sep 17 00:00:00 2001 From: emtenet Date: Sun, 24 Apr 2016 15:01:09 +1000 Subject: Do not create a junction (soft link) for files When symlink_or_copy/2 cannot use file:make_symlink/2 on Windows due to the user lacking SeCreateSymbolicLinkPrivilege it tries a fall back. Detect the source type and use an appropriate fall back: * junction for directories and, * copy for files. Improve error detection in win32_make_junction/2 and make it repeatable when the target exists --- src/rlx_util.erl | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/src/rlx_util.erl b/src/rlx_util.erl index f68c291..1893353 100644 --- a/src/rlx_util.erl +++ b/src/rlx_util.erl @@ -45,6 +45,8 @@ -define(DFLT_INTENSITY, high). -define(ONE_LEVEL_INDENT, " "). + +-include_lib("kernel/include/file.hrl"). %%============================================================================ %% types %%============================================================================ @@ -233,21 +235,62 @@ symlink_or_copy(Source, Target) -> ok; {error, eexist} -> {error, eexist}; - {error, _} = Error -> + {error, eperm} = Error -> + % We get eperm on Windows if we do not have + % SeCreateSymbolicLinkPrivilege + % Try the next alternative case os:type() of {win32, _} -> - S = unicode:characters_to_list(Source), - T = unicode:characters_to_list(Target), - win32_symlink(filename:nativename(S), filename:nativename(T)); + win32_make_junction_or_copy(Source, Target); _ -> Error - end + end; + {error, _} = Error -> + Error + end. + +win32_make_junction_or_copy(Source, Target) -> + case filelib:is_dir(Source) of + true -> + win32_make_junction(Source, Target); + _ -> + ec_file:copy(Source, Target) end. +win32_make_junction(Source, Target) -> + % The mklink will fail if the target already exists, check for that first + case file:read_link_info(Target) of + {error, enoent} -> + win32_make_junction_cmd(Source, Target); + {ok, #file_info{type = symlink}} -> + case file:read_link(Target) of + {ok, Source} -> + ok; + {ok, _} -> + ok = file:del_dir(Target), + win32_make_junction_cmd(Source, Target); + {error, Reason} -> + {error, {readlink, Reason}} + end; + {ok, #file_info{type = Type}} -> + {error, {mklink_cannot_replace_existing, Type, Target}}; + Error -> + Error + end. -win32_symlink(Source, Target) -> - os:cmd("cmd /c mklink /j " ++ Target ++ " " ++ Source), - ok. +win32_make_junction_cmd(Source, Target) -> + S = unicode:characters_to_list(Source), + T = unicode:characters_to_list(Target), + Cmd = "cmd /c mklink /j " ++ filename:nativename(T) ++ " " ++ filename:nativename(S), + case os:cmd(Cmd) of + "Junction created " ++ _ -> + ok; + [] -> + % When mklink fails it prints the error message to stderr which + % is not picked up by os:cmd() hence this case switch is for + % an empty message + {error, make_junction_failed} + end. %% @doc Returns the color intensity, we first check the application envorinment %% if that is not set we check the environment variable RELX_COLOR. -- cgit v1.2.3 From 476b439de0077b6f7a60622d2498b85e6f52698a Mon Sep 17 00:00:00 2001 From: Tino Breddin Date: Tue, 16 Apr 2019 16:17:10 +0200 Subject: Use recursive copy as last fallback on all platforms --- src/rlx_util.erl | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/rlx_util.erl b/src/rlx_util.erl index 1893353..5d3744d 100644 --- a/src/rlx_util.erl +++ b/src/rlx_util.erl @@ -235,26 +235,28 @@ symlink_or_copy(Source, Target) -> ok; {error, eexist} -> {error, eexist}; - {error, eperm} = Error -> - % We get eperm on Windows if we do not have - % SeCreateSymbolicLinkPrivilege - % Try the next alternative - case os:type() of - {win32, _} -> + {error, Err} -> + case {os:type(), Err} of + {{win32, _}, eperm} -> + % We get eperm on Windows if we do not have + % SeCreateSymbolicLinkPrivilege + % Try the next alternative win32_make_junction_or_copy(Source, Target); _ -> - Error - end; - {error, _} = Error -> - Error + % On other systems we try to copy next + cp_r(Source, Target) + end end. +cp_r(Source, Target) -> + ec_file:copy(Source, Target, [{recursive, true}, {fileinfo, [mode, time, owner, group]}]). + win32_make_junction_or_copy(Source, Target) -> case filelib:is_dir(Source) of true -> win32_make_junction(Source, Target); _ -> - ec_file:copy(Source, Target) + cp_r(Source, Target) end. win32_make_junction(Source, Target) -> @@ -272,8 +274,9 @@ win32_make_junction(Source, Target) -> {error, Reason} -> {error, {readlink, Reason}} end; - {ok, #file_info{type = Type}} -> - {error, {mklink_cannot_replace_existing, Type, Target}}; + {ok, #file_info{type = _Type}} -> + % Directory already exists, so we overwrite the copy + cp_r(Source, Target); Error -> Error end. @@ -289,7 +292,7 @@ win32_make_junction_cmd(Source, Target) -> % When mklink fails it prints the error message to stderr which % is not picked up by os:cmd() hence this case switch is for % an empty message - {error, make_junction_failed} + cp_r(Source, Target) end. %% @doc Returns the color intensity, we first check the application envorinment -- cgit v1.2.3 From f814cd73d7fb97751434fbd1099ec1abb9068769 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 13 May 2019 11:46:43 -0600 Subject: add testing of otp 18 19 and 20 --- .cirrus.yml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index d7e7e3e..38fc107 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,20 +1,12 @@ -build_task: - container: - image: circleci/erlang:21 - rebar3_cache: - folder: _build - fingerprint_script: cat rebar.lock - populate_script: rebar3 compile --deps_only - test_task: container: - image: circleci/erlang:21 - depends_on: - - build - rebar3_cache: - folder: _build - fingerprint_script: cat rebar.lock - test_script: rebar3 ct + matrix: + - image: erlang:21 + - image: erlang:20 + - image: erlang:19 + - image: erlang:18 + test_script: | + rebar3 ct always: junit_artifacts: path: "_build/test/logs/ct_run.*/junit_report.xml" -- cgit v1.2.3 From cb1b86273721a9dcb8999039c09d6629aac310db Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 13 May 2019 13:57:54 -0600 Subject: try to fix failing test --- test/rlx_extended_bin_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index 041afca..807b676 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -1798,7 +1798,7 @@ start_fail_when_nonreadable_argsfile(Config) -> LibDir1 = proplists:get_value(lib1, Config), VmArgs = filename:join([LibDir1, "vm.args"]), VmArgs2 = VmArgs ++ ".nonreadable", - ec_file:write(VmArgs, "-name foo\n\n" + ec_file:write(VmArgs, "-name foo@127.0.0.1\n\n" "-args_file " ++ VmArgs2 ++ "\n\n" "-setcookie cookie\n"), ec_file:write(VmArgs2, ""), -- cgit v1.2.3 From 1984d41553b8294591d40daf65d6e38dafdce9bb Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 13 May 2019 14:20:20 -0600 Subject: see if others pass without this one --- test/rlx_extended_bin_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index 807b676..8788bb2 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -86,7 +86,7 @@ init_per_testcase(_, Config) -> all() -> [start_sname_in_other_argsfile, start_preserves_arguments, start_nodetool_with_data_from_argsfile, start_upgrade_escript_with_argsfile_data, start_fail_when_no_name, start_fail_when_multiple_names, - start_fail_when_missing_argsfile, start_fail_when_nonreadable_argsfile, + start_fail_when_missing_argsfile, %% start_fail_when_nonreadable_argsfile, start_fail_when_relative_argsfile, start_fail_when_circular_argsfiles, ping, shortname_ping, longname_ping, attach, pid, restart, reboot, escript, remote_console, shortname_remote_console, replace_os_vars, replace_os_vars_sys_config_vm_args_src, replace_os_vars_multi_node, -- cgit v1.2.3 From a8c7a33fb485ec0cfa0bb235d51e1fbb5c94f932 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 14 May 2019 13:28:37 -0600 Subject: try with compute credits --- .cirrus.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.cirrus.yml b/.cirrus.yml index 38fc107..b028272 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,4 +1,5 @@ test_task: + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' container: matrix: - image: erlang:21 -- cgit v1.2.3 From f6abbf18842f9f8464e01e7e8c258741ca51adbf Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 14 May 2019 17:01:00 -0600 Subject: increase timetrap --- test/rlx_archive_SUITE.erl | 2 +- test/rlx_command_SUITE.erl | 2 +- test/rlx_discover_SUITE.erl | 2 +- test/rlx_eunit_SUITE.erl | 2 +- test/rlx_extended_bin_SUITE.erl | 2 +- test/rlx_release_SUITE.erl | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/rlx_archive_SUITE.erl b/test/rlx_archive_SUITE.erl index 68a5b07..8d30915 100644 --- a/test/rlx_archive_SUITE.erl +++ b/test/rlx_archive_SUITE.erl @@ -18,7 +18,7 @@ -include_lib("kernel/include/file.hrl"). suite() -> - [{timetrap, {seconds, 30}}]. + [{timetrap, {seconds, 120}}]. init_per_suite(Config) -> Config. diff --git a/test/rlx_command_SUITE.erl b/test/rlx_command_SUITE.erl index e0beec1..46664ab 100644 --- a/test/rlx_command_SUITE.erl +++ b/test/rlx_command_SUITE.erl @@ -33,7 +33,7 @@ -include_lib("eunit/include/eunit.hrl"). suite() -> - [{timetrap,{seconds,30}}]. + [{timetrap,{seconds,120}}]. init_per_suite(Config) -> Config. diff --git a/test/rlx_discover_SUITE.erl b/test/rlx_discover_SUITE.erl index 36d77ae..9385229 100644 --- a/test/rlx_discover_SUITE.erl +++ b/test/rlx_discover_SUITE.erl @@ -34,7 +34,7 @@ -include_lib("eunit/include/eunit.hrl"). suite() -> - [{timetrap,{seconds,30}}]. + [{timetrap,{seconds,120}}]. init_per_suite(Config) -> Config. diff --git a/test/rlx_eunit_SUITE.erl b/test/rlx_eunit_SUITE.erl index 874e5a6..c7c0751 100644 --- a/test/rlx_eunit_SUITE.erl +++ b/test/rlx_eunit_SUITE.erl @@ -30,7 +30,7 @@ -include_lib("eunit/include/eunit.hrl"). suite() -> - [{timetrap,{seconds,30}}]. + [{timetrap,{seconds,120}}]. init_per_suite(Config) -> Config. diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index 8788bb2..a23d571 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -66,7 +66,7 @@ -define(SLEEP_TIME, 2500). suite() -> - [{timetrap,{seconds,30}}]. + [{timetrap,{seconds,120}}]. init_per_suite(Config) -> Config. diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl index 052b5c2..d4a86be 100644 --- a/test/rlx_release_SUITE.erl +++ b/test/rlx_release_SUITE.erl @@ -64,7 +64,7 @@ -include_lib("kernel/include/file.hrl"). suite() -> - [{timetrap,{seconds,30}}]. + [{timetrap,{seconds,120}}]. init_per_suite(Config) -> Config. -- cgit v1.2.3 From 02e3d99d6a93e8c9ee982348366ee607aec45cdb Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 14 May 2019 17:25:21 -0600 Subject: remove travis and circle --- .circleci/config.yml | 39 --------------------------------------- .travis.yml | 35 ----------------------------------- README.md | 3 +-- 3 files changed, 1 insertion(+), 76 deletions(-) delete mode 100644 .circleci/config.yml delete mode 100644 .travis.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index ca75335..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,39 +0,0 @@ -version: 2.1 -orbs: - rebar3: tsloughter/rebar3@0.6.3 - -jobs: - ct: - parameters: - tag: - description: The docker tag to use. - type: string - default: "21.2" - executor: - name: rebar3/erlang - tag: <> - steps: - - checkout - - rebar3/ct - # Delete OTP files which don't need to be stored - - run: | - find _build/test/logs -type d -and \( -path "*/erts-*" -or -path "*/kernel-*" -or -path "*/stdlib-*" \) -exec rm -rf '{}' \+ || true - find _build/test/logs -type f -name "*.beam" -exec rm -rf '{}' \+ || true - - store_artifacts: - path: _build/test/logs - -workflows: - build-test: - jobs: - - ct: - name: "21" - tag: "21.2" - - ct: - name: "20" - tag: "20" - - ct: - name: "19" - tag: "19" - - ct: - name: "18" - tag: "18" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4e4f877..0000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: erlang -matrix: - include: - - os: linux - sudo: required - otp_release: 17.5 - - os: osx - sudo: required - language: generic -before_script: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - ## should eventually use a tap that has previous erlang versions here - ## as this only uses the latest erlang available via brew - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install erlang; fi - - wget https://s3.amazonaws.com/rebar3/rebar3 - - chmod +x rebar3 -script: "./rebar3 update && ./rebar3 ct" -after_failure: - ## Useful for troubleshooting to view test logs - - find _build/test/logs/ct_run*/lib*logs/run*/log_private/*-output*/*/log -type f -name "erlang*" -exec ls -1rt "{}" \+ | xargs -I % sh -c 'echo "\n\n%"; cat %' -branches: - only: - - master -addons: - hostname: travis.dev - hosts: - - travis.dev -notifications: - email: - - core@erlware.org - irc: - channels: - - "irc.freenode.org#erlware" - use_notice: true - skip_join: true diff --git a/README.md b/README.md index dfc2ef2..ce04617 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -[![Build Status](https://travis-ci.org/erlware/relx.png?branch=master)](https://travis-ci.org/erlware/relx) -[![CircleCI](https://circleci.com/gh/erlware/relx.svg?style=svg)](https://circleci.com/gh/erlware/relx) +[![Build Status](https://api.cirrus-ci.com/github/erlware/relx.svg)](https://cirrus-ci.com/github/erlware/relx) Relx ======= -- cgit v1.2.3 From 6b1b0e32e71ac8111f8b60a5aee0cac4ce510e2c Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 17 May 2019 09:24:41 -0600 Subject: add otp 22 to cirrus test matrix --- .cirrus.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.cirrus.yml b/.cirrus.yml index b028272..b49a2b6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,6 +2,7 @@ test_task: use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' container: matrix: + - image: erlang:22 - image: erlang:21 - image: erlang:20 - image: erlang:19 -- cgit v1.2.3 From 5158c869f17878ba6c9e99563a9865ebe8c59d49 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 17 May 2019 09:48:39 -0600 Subject: increase timetrap for otp 22 --- test/rlx_extended_bin_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index a23d571..8444cb4 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -66,7 +66,7 @@ -define(SLEEP_TIME, 2500). suite() -> - [{timetrap,{seconds,120}}]. + [{timetrap,{seconds,300}}]. init_per_suite(Config) -> Config. -- cgit v1.2.3 From 441000c7b0730e96673dfe705a185b82229b30ea Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 12 May 2019 13:32:45 -0600 Subject: add support for git ref and file content as app version --- src/rlx_config.erl | 27 +++++++++++++++++++++++++++ src/rlx_string.erl | 10 +++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/rlx_config.erl b/src/rlx_config.erl index 4160bba..f86f593 100644 --- a/src/rlx_config.erl +++ b/src/rlx_config.erl @@ -346,6 +346,16 @@ merge_configs([{Key, Value} | CliTerms], ConfigTerms) -> merge_configs(CliTerms, lists:reverse(lists:keystore(Key, 1, lists:reverse(ConfigTerms), {Key, Value}))) end. +parse_vsn(Vsn) when Vsn =:= git ; Vsn =:= "git" -> + {ok, V} = ec_git_vsn:vsn(ec_git_vsn:new()), + V; +parse_vsn({git, short}) -> + git_ref("--short"); +parse_vsn({git, long}) -> + git_ref(""); +parse_vsn({file, File}) -> + {ok, Vsn} = file:read_file(File), + binary_to_list(rlx_string:trim(Vsn, both, "\n")); parse_vsn(Vsn) when Vsn =:= semver ; Vsn =:= "semver" -> {ok, V} = ec_git_vsn:vsn(ec_git_vsn:new()), V; @@ -357,3 +367,20 @@ parse_vsn({cmd, Command}) -> V; parse_vsn(Vsn) -> Vsn. + +git_ref(Arg) -> + case os:cmd("git rev-parse " ++ Arg ++ " HEAD") of + String -> + Vsn = rlx_string:trim(String, both, "\n"), + case length(Vsn) =:= 40 orelse length(Vsn) =:= 7 of + true -> + Vsn; + false -> + %% if the result isn't exactly either 40 or 7 characters then + %% it must have failed + {ok, Dir} = file:get_cwd(), + ec_cmd_log:warn("Getting ref of git repo failed in ~ts. " + "Falling back to version 0", [Dir]), + {plain, "0"} + end + end. diff --git a/src/rlx_string.erl b/src/rlx_string.erl index 1f9cc0c..d5f5046 100644 --- a/src/rlx_string.erl +++ b/src/rlx_string.erl @@ -2,14 +2,22 @@ %% OTP-19 and OTP-21, where Unicode support means the deprecation %% of a lot of string functions. -module(rlx_string). --export([concat/2, lexemes/2, join/2]). +-export([concat/2, lexemes/2, join/2, trim/3]). -ifdef(unicode_str). concat(Str1, Str2) -> unicode:characters_to_list([Str1,Str2]). lexemes(Str, Separators) -> string:lexemes(Str, Separators). +trim(Str, Direction, Cluster=[_]) -> string:trim(Str, Direction, Cluster). -else. concat(Str1, Str2) -> string:concat(Str1, Str2). lexemes(Str, Separators) -> string:tokens(Str, Separators). +trim(Str, Direction, [Char]) -> + Dir = case Direction of + both -> both; + leading -> left; + trailing -> right + end, + string:strip(Str, Dir, Char). -endif. %% string:join/2 copy; string:join/2 is getting obsoleted -- cgit v1.2.3 From 5e9de936e28f18bf5ba3e392fcc54502505b01a8 Mon Sep 17 00:00:00 2001 From: Ivan Glushkov Date: Mon, 20 May 2019 11:21:34 +0400 Subject: Revert dependencies order in unit tests The PR https://github.com/erlware/relx/pull/655 changed the behaviour, while the tests were not fixed. This commit fixes the unit tests. --- .cirrus.yml | 4 +- .gitignore | 2 + src/rlx_depsolver.erl | 2 +- src/rlx_depsolver_culprit.erl | 2 +- test/rlx_depsolver_tester.erl | 500 ++++++++++++++++++++++-------------------- test/rlx_depsolver_tests.erl | 2 +- 6 files changed, 268 insertions(+), 244 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index b49a2b6..8e693dd 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -8,7 +8,7 @@ test_task: - image: erlang:19 - image: erlang:18 test_script: | - rebar3 ct + rebar3 eunit && rebar3 ct always: junit_artifacts: path: "_build/test/logs/ct_run.*/junit_report.xml" @@ -20,4 +20,4 @@ osx_check_task: test_script: | wget https://s3.amazonaws.com/rebar3/rebar3 chmod +x rebar3 - ./rebar3 ct + ./rebar3 eunit && ./rebar3 ct diff --git a/.gitignore b/.gitignore index ce87711..64d4e0b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ _rel/* !.cirrus.yml erl_crash.dump rebar +TEST-* +tags diff --git a/src/rlx_depsolver.erl b/src/rlx_depsolver.erl index 8a0f632..08b81a3 100644 --- a/src/rlx_depsolver.erl +++ b/src/rlx_depsolver.erl @@ -1,5 +1,5 @@ %% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*- -%% ex: ts=4 sx=4 et +%% ex: ts=4 sw=4 et %% %% Copyright 2012 Opscode, Inc. All Rights Reserved. %% diff --git a/src/rlx_depsolver_culprit.erl b/src/rlx_depsolver_culprit.erl index cf6dcb2..6368d24 100644 --- a/src/rlx_depsolver_culprit.erl +++ b/src/rlx_depsolver_culprit.erl @@ -1,5 +1,5 @@ %% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*- -%% ex: ts=4 sx=4 et +%% ex: ts=4 sw=4 et %% %% @author Eric Merritt %% diff --git a/test/rlx_depsolver_tester.erl b/test/rlx_depsolver_tester.erl index 9defd91..b3bc146 100644 --- a/test/rlx_depsolver_tester.erl +++ b/test/rlx_depsolver_tester.erl @@ -1,5 +1,5 @@ %% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 92 -*- -%% ex: ts=4 sx=4 et +%% ex: ts=4 sw=4 et %%------------------------------------------------------------------- %% %% Copyright 2012 Opscode, Inc. All Rights Reserved. @@ -49,153 +49,167 @@ run_log(FileName) -> run_log_file(Device). data1_test() -> - ExpectedResult = versionify([{"app6","0.0.1"}, - {"dep_pkg13","0.0.2"}, - {"app13","0.0.1"}, - {"dep_pkg2","0.0.5"}, - {"dep_pkg1","0.0.2"}, + ExpectedResult = versionify([ + {"app9","0.0.1"}, {"dep_pkg7","0.1.2"}, - {"app9","0.0.1"}]), + {"dep_pkg1","0.0.2"}, + {"dep_pkg2","0.0.5"}, + {"app13","0.0.1"}, + {"dep_pkg13","0.0.2"}, + {"app6","0.0.1"} + ]), ?assertMatch({ok, ExpectedResult}, run_data(fix_rebar_brokenness("data1.txt"))). data2_test() -> - ExpectedResult = versionify([{"app18","0.0.1"}, - {"app4","0.0.7"}, - {"app1","0.0.1"}, - {"app6","0.0.1"}, - {"dep_pkg13","0.0.2"}, - {"app13","0.0.1"}, - {"dep_pkg5","0.0.3"}, - {"dep_pkg1","0.0.2"}, - {"dep_pkg2","0.0.5"}, - {"dep_pkg7","0.1.2"}, + ExpectedResult = versionify([ + {"dep_pkg16","1.0.2"}, {"app9","0.0.1"}, - {"dep_pkg16","1.0.2"}]), + {"dep_pkg7","0.1.2"}, + {"dep_pkg2","0.0.5"}, + {"dep_pkg1","0.0.2"}, + {"dep_pkg5","0.0.3"}, + {"app13","0.0.1"}, + {"dep_pkg13","0.0.2"}, + {"app6","0.0.1"}, + {"app1","0.0.1"}, + {"app4","0.0.7"}, + {"app18","0.0.1"} + ]), ?assertMatch({ok, ExpectedResult}, run_data(fix_rebar_brokenness("data2.txt"))). - + data3_test() -> - ExpectedResult = versionify([{"app68","0.0.1"}, - {"app58","0.0.1"}, - {"app48","0.0.7"}, - {"app38","0.0.1"}, - {"app28","0.0.1"}, - {"app18","0.0.1"}, - {"app4","0.0.7"}, - {"app1","0.0.1"}, - {"app6","0.0.1"}, - {"dep_pkg13","0.0.2"}, - {"app13","0.0.1"}, - {"dep_pkg5","0.0.3"}, - {"dep_pkg1","0.0.2"}, - {"dep_pkg2","0.0.5"}, - {"dep_pkg7","0.1.2"}, + ExpectedResult = versionify([ + {"dep_pkg16","1.0.2"}, {"app9","0.0.1"}, - {"dep_pkg16","1.0.2"}]), + {"dep_pkg7","0.1.2"}, + {"dep_pkg2","0.0.5"}, + {"dep_pkg1","0.0.2"}, + {"dep_pkg5","0.0.3"}, + {"app13","0.0.1"}, + {"dep_pkg13","0.0.2"}, + {"app6","0.0.1"}, + {"app1","0.0.1"}, + {"app4","0.0.7"}, + {"app18","0.0.1"}, + {"app28","0.0.1"}, + {"app38","0.0.1"}, + {"app48","0.0.7"}, + {"app58","0.0.1"}, + {"app68","0.0.1"} + ]), ?assertMatch({ok,ExpectedResult}, run_data(fix_rebar_brokenness("data3.txt"))). data4_test() -> - ExpectedResult = versionify([{"dep_pkg20","0.0.2"}, - {"app78","0.0.1"}, - {"app68","0.0.1"}, - {"app58","0.0.1"}, - {"app48","0.0.7"}, - {"app38","0.0.1"}, - {"app28","0.0.1"}, - {"app18","0.0.1"}, - {"app4","0.0.7"}, - {"app1","0.0.1"}, - {"app6","0.0.1"}, - {"dep_pkg13","0.0.2"}, - {"app13","0.0.1"}, - {"dep_pkg5","0.0.3"}, - {"dep_pkg1","0.0.2"}, - {"dep_pkg2","0.0.5"}, - {"dep_pkg7","0.1.2"}, + ExpectedResult = versionify([ + {"dep_pkg16","1.0.2"}, {"app9","0.0.1"}, - {"dep_pkg16","1.0.2"}]), + {"dep_pkg7","0.1.2"}, + {"dep_pkg2","0.0.5"}, + {"dep_pkg1","0.0.2"}, + {"dep_pkg5","0.0.3"}, + {"app13","0.0.1"}, + {"dep_pkg13","0.0.2"}, + {"app6","0.0.1"}, + {"app1","0.0.1"}, + {"app4","0.0.7"}, + {"app18","0.0.1"}, + {"app28","0.0.1"}, + {"app38","0.0.1"}, + {"app48","0.0.7"}, + {"app58","0.0.1"}, + {"app68","0.0.1"}, + {"app78","0.0.1"}, + {"dep_pkg20","0.0.2"} + ]), ?assertMatch({ok, ExpectedResult}, run_data(fix_rebar_brokenness("data4.txt"))). data5_test() -> - ExpectedResult = versionify([{"dep_pkg14","0.0.2"}, - {"dep_pkg22","0.0.2"}, - {"dep_pkg20","0.0.2"}, - {"app78","0.0.1"}, - {"app68","0.0.1"}, - {"app58","0.0.1"}, - {"app48","0.0.7"}, - {"app38","0.0.1"}, - {"app28","0.0.1"}, - {"app18","0.0.1"}, - {"app4","0.0.7"}, - {"app1","0.0.1"}, - {"app6","0.0.1"}, - {"dep_pkg13","0.0.2"}, - {"app13","0.0.1"}, - {"dep_pkg5","0.0.3"}, - {"dep_pkg1","0.0.2"}, - {"dep_pkg2","0.0.5"}, - {"dep_pkg7","0.1.2"}, + ExpectedResult = versionify([ + {"dep_pkg16","1.0.2"}, {"app9","0.0.1"}, - {"dep_pkg16","1.0.2"}]), + {"dep_pkg7","0.1.2"}, + {"dep_pkg2","0.0.5"}, + {"dep_pkg1","0.0.2"}, + {"dep_pkg5","0.0.3"}, + {"app13","0.0.1"}, + {"dep_pkg13","0.0.2"}, + {"app6","0.0.1"}, + {"app1","0.0.1"}, + {"app4","0.0.7"}, + {"app18","0.0.1"}, + {"app28","0.0.1"}, + {"app38","0.0.1"}, + {"app48","0.0.7"}, + {"app58","0.0.1"}, + {"app68","0.0.1"}, + {"app78","0.0.1"}, + {"dep_pkg20","0.0.2"}, + {"dep_pkg22","0.0.2"}, + {"dep_pkg14","0.0.2"} + ]), ?assertMatch({ok, ExpectedResult}, run_data(fix_rebar_brokenness("data5.txt"))). data6_test() -> - ExpectedResult = versionify([{"app108","0.0.1"}, - {"app98","0.0.1"}, - {"app88","0.0.1"}, - {"dep_pkg14","0.0.2"}, - {"dep_pkg22","0.0.2"}, - {"dep_pkg20","0.0.2"}, - {"app78","0.0.1"}, - {"app68","0.0.1"}, - {"app58","0.0.1"}, - {"app48","0.0.7"}, - {"app38","0.0.1"}, - {"app28","0.0.1"}, - {"app18","0.0.1"}, - {"app4","0.0.7"}, - {"app1","0.0.1"}, - {"app6","0.0.1"}, - {"dep_pkg13","0.0.2"}, - {"app13","0.0.1"}, - {"dep_pkg5","0.0.3"}, - {"dep_pkg1","0.0.2"}, - {"dep_pkg2","0.0.5"}, - {"dep_pkg7","0.1.2"}, + ExpectedResult = versionify([ + {"dep_pkg16","1.0.2"}, {"app9","0.0.1"}, - {"dep_pkg16","1.0.2"}]), + {"dep_pkg7","0.1.2"}, + {"dep_pkg2","0.0.5"}, + {"dep_pkg1","0.0.2"}, + {"dep_pkg5","0.0.3"}, + {"app13","0.0.1"}, + {"dep_pkg13","0.0.2"}, + {"app6","0.0.1"}, + {"app1","0.0.1"}, + {"app4","0.0.7"}, + {"app18","0.0.1"}, + {"app28","0.0.1"}, + {"app38","0.0.1"}, + {"app48","0.0.7"}, + {"app58","0.0.1"}, + {"app68","0.0.1"}, + {"app78","0.0.1"}, + {"dep_pkg20","0.0.2"}, + {"dep_pkg22","0.0.2"}, + {"dep_pkg14","0.0.2"}, + {"app88","0.0.1"}, + {"app98","0.0.1"}, + {"app108","0.0.1"} + ]), ?assertMatch({ok, ExpectedResult}, run_data(fix_rebar_brokenness("data6.txt"))). log_07be9e47_test() -> Data = run_log(fix_rebar_brokenness("log-07be9e47-6f42-4a5d-b8b5-1d2eae1ad83b.txt")), - ExpectedResult = versionify([{"0","0"}, - {"1","0"}, - {"3","0"}, - {"4","0"}, - {"5","0"}, - {"6","0"}, - {"7","0"}, - {"8","0"}, - {"9","0"}, - {"10","0"}, - {"11","0"}, - {"12","0"}, - {"13","0"}, - {"14","0"}, - {"15","0"}, - {"16","0"}, - {"18","0"}, - {"19","0"}, - {"21","0"}, - {"22","0"}, - {"23","0"}, + ExpectedResult = versionify([ + {"25","0"}, {"24","0"}, - {"25","0"}]), + {"23","0"}, + {"22","0"}, + {"21","0"}, + {"19","0"}, + {"18","0"}, + {"16","0"}, + {"15","0"}, + {"14","0"}, + {"13","0"}, + {"12","0"}, + {"11","0"}, + {"10","0"}, + {"9","0"}, + {"8","0"}, + {"7","0"}, + {"6","0"}, + {"5","0"}, + {"4","0"}, + {"3","0"}, + {"1","0"}, + {"0","0"} + ]), ?assertMatch({ok, ExpectedResult}, Data). @@ -206,144 +220,152 @@ log_183998c1_test() -> log_311a15e7_test() -> {ok, Data} = run_log(fix_rebar_brokenness("log-311a15e7-3378-4c5b-beb7-86a1b9cf0ea9.txt")), - ExpectedResult = lists:sort(versionify([{"45", "22"}, - {"40","1"}, - {"3","5"}, - {"9","0"}, - {"8","0"}, - {"7","0"}, - {"6","2"}, - {"1","5"}, - {"0","2"}, - {"61","1"}, - {"60","0"}, - {"35","4"}, - {"39","0"}, - {"38","2"}, - {"37","2"}, - {"36","3"}, - {"32","24"}, - {"30","0"}, - {"19","1"}, - {"18","0"}, - {"17","2"}, - {"16","0"}, - {"15","0"}, - {"14","1"}, - {"13","0"}, - {"12","1"}, - {"11","0"}, - {"10","1"}, - {"59","0"}, - {"58","1"}, - {"57","0"}, - {"56","0"}, - {"55","4"}, - {"29","2"}, - {"27","2"}, - {"26","0"}, - {"25","5"}, - {"24","3"}, - {"23","1"}, - {"22","3"}, + ExpectedResult = lists:sort(versionify([ + {"20","0"}, {"21","2"}, - {"20","0"}])), + {"22","3"}, + {"23","1"}, + {"24","3"}, + {"25","5"}, + {"26","0"}, + {"27","2"}, + {"29","2"}, + {"55","4"}, + {"56","0"}, + {"57","0"}, + {"58","1"}, + {"59","0"}, + {"10","1"}, + {"11","0"}, + {"12","1"}, + {"13","0"}, + {"14","1"}, + {"15","0"}, + {"16","0"}, + {"17","2"}, + {"18","0"}, + {"19","1"}, + {"30","0"}, + {"32","24"}, + {"36","3"}, + {"37","2"}, + {"38","2"}, + {"39","0"}, + {"35","4"}, + {"60","0"}, + {"61","1"}, + {"0","2"}, + {"1","5"}, + {"6","2"}, + {"7","0"}, + {"8","0"}, + {"9","0"}, + {"3","5"}, + {"40","1"}, + {"45", "22"} + ])), ?assertMatch(ExpectedResult, lists:sort(Data)). log_382cfe5b_test() -> {ok, Data} = run_log(fix_rebar_brokenness("log-382cfe5b-0ac2-48b8-83d1-717cb4620990.txt")), - ExpectedResult = lists:sort(versionify([{"18","0"}, - {"17","0"}, - {"15","1"}, - {"14","0"}, - {"10","0"}, - {"7","0"}, - {"6","0"}, - {"5","0"}, - {"4","0"}, - {"3","0"}, - {"2","1"}, + ExpectedResult = lists:sort(versionify([ + {"0","0"}, {"1","0"}, - {"0","0"}])), + {"2","1"}, + {"3","0"}, + {"4","0"}, + {"5","0"}, + {"6","0"}, + {"7","0"}, + {"10","0"}, + {"14","0"}, + {"15","1"}, + {"17","0"}, + {"18","0"} + ])), ?assertMatch(ExpectedResult, lists:sort(Data)). log_d3564ef6_test() -> {ok, Data} = run_log(fix_rebar_brokenness("log-d3564ef6-6437-41e7-90b6-dbdb849551a6_mod.txt")), - ExpectedResult = lists:sort(versionify([{"57","5"}, - {"56","3"}, - {"55","4"}, - {"54","0"}, - {"53","1"}, - {"82","0"}, - {"81","0"}, - {"80","1"}, - {"29","0"}, - {"28","5"}, - {"27","3"}, - {"26","1"}, - {"25","3"}, - {"24","2"}, - {"23","0"}, - {"22","1"}, - {"21","0"}, - {"20","2"}, - {"75","32"}, - {"79","2"}, - {"78","4"}, - {"74","7"}, - {"73","11"}, - {"72","0"}, - {"70","1"}, - {"47","4"}, - {"45","1"}, - {"44","1"}, - {"43","7"}, - {"42","1"}, - {"41","2"}, - {"40","2"}, - {"19","0"}, - {"18","0"}, - {"17","1"}, - {"16","0"}, - {"15","1"}, - {"14","0"}, - {"13","1"}, - {"12","0"}, - {"11","0"}, - {"10","0"}, - {"9","2"}, - {"4","5"}, - {"3","2"}, - {"0","3"}, - {"69","0"}, - {"68","1"}, - {"67","7"}, - {"39","3"}, - {"35","24"}, - {"33","0"}, + ExpectedResult = lists:sort(versionify([ + {"30","2"}, {"32","2"}, - {"30","2"}])), + {"33","0"}, + {"35","24"}, + {"39","3"}, + {"67","7"}, + {"68","1"}, + {"69","0"}, + {"0","3"}, + {"3","2"}, + {"4","5"}, + {"9","2"}, + {"10","0"}, + {"11","0"}, + {"12","0"}, + {"13","1"}, + {"14","0"}, + {"15","1"}, + {"16","0"}, + {"17","1"}, + {"18","0"}, + {"19","0"}, + {"40","2"}, + {"41","2"}, + {"42","1"}, + {"43","7"}, + {"44","1"}, + {"45","1"}, + {"47","4"}, + {"70","1"}, + {"72","0"}, + {"73","11"}, + {"74","7"}, + {"78","4"}, + {"79","2"}, + {"75","32"}, + {"20","2"}, + {"21","0"}, + {"22","1"}, + {"23","0"}, + {"24","2"}, + {"25","3"}, + {"26","1"}, + {"27","3"}, + {"28","5"}, + {"29","0"}, + {"80","1"}, + {"81","0"}, + {"82","0"}, + {"53","1"}, + {"54","0"}, + {"55","4"}, + {"56","3"}, + {"57","5"} + ])), ?assertMatch(ExpectedResult, lists:sort(Data)). log_ea2d264b_test() -> {ok, Data} = run_log(fix_rebar_brokenness("log-ea2d264b-003e-4611-94ed-14efc7732083.txt")), - ExpectedResult = lists:sort(versionify([{"18","1"}, - {"17","0"}, - {"16","0"}, - {"15","0"}, - {"14","0"}, - {"13","1"}, - {"10","1"}, - {"9","1"}, - {"8","2"}, - {"6","0"}, - {"5","0"}, - {"4","0"}, - {"3","0"}, - {"2","0"}, + ExpectedResult = lists:sort(versionify([ + {"0","1"}, {"1","0"}, - {"0","1"}])), + {"2","0"}, + {"3","0"}, + {"4","0"}, + {"5","0"}, + {"6","0"}, + {"8","2"}, + {"9","1"}, + {"10","1"}, + {"13","1"}, + {"14","0"}, + {"15","0"}, + {"16","0"}, + {"17","0"}, + {"18","1"} + ])), ?assertMatch(ExpectedResult, lists:sort(Data)). %%============================================================================ diff --git a/test/rlx_depsolver_tests.erl b/test/rlx_depsolver_tests.erl index 206bad4..b1c8228 100644 --- a/test/rlx_depsolver_tests.erl +++ b/test/rlx_depsolver_tests.erl @@ -1,5 +1,5 @@ %% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*- -%% ex: ts=4 sx=4 et +%% ex: ts=4 sw=4 et %% %%------------------------------------------------------------------- %% Copyright 2012 Opscode, Inc. All Rights Reserved. -- cgit v1.2.3