From f0e0d1acc7e4b645e9dac38e8323bbc1cb8fb03c Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Sun, 23 Oct 2016 23:47:39 +0100 Subject: Fix replace os vars functionality The first run would correctly replace the environment variables, however it would also overwrite the original vm.args and sys.config thus preventing any further substitution in subsequent runs. Dev mode runs were also broken, all runs after the first were required to also define the RELX_REPLACE_OS_VARS variable in order not to overwrite the current vm.args with the original one, this prevented simply attaching to an already running node that was started this way. Add tests to exercise this functionality. --- priv/templates/bin_windows | 7 - priv/templates/extended_bin | 66 +++++----- src/rlx_prv_assembler.erl | 2 +- src/rlx_prv_overlay.erl | 8 ++ test/rlx_extended_bin_SUITE.erl | 284 ++++++++++++++++++++++++++++++++++++++-- test/rlx_release_SUITE.erl | 67 +++++++++- 6 files changed, 381 insertions(+), 53 deletions(-) diff --git a/priv/templates/bin_windows b/priv/templates/bin_windows index 06303f5..b9eb9e2 100644 --- a/priv/templates/bin_windows +++ b/priv/templates/bin_windows @@ -74,13 +74,6 @@ cd %rootdir% @if exist "%possible_sys%" ( set sys_config=-config "%possible_sys%" ) -@if exist "%possible_sys%".orig ( - ren "%possible_sys%".orig "%possible_sys%" - set sys_config=-config "%possible_sys%" -) -@if exist "%rel_dir%\vm.args".orig ( - ren "%rel_dir%\vm.args" ".orig %rel_dir%\vm.args" -) @goto :eof :: set boot_script variable diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index 7a9f0c7..e844e46 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -98,28 +98,6 @@ if [ -z "$VMARGS_PATH" ]; then fi fi -orig_vmargs_path="$VMARGS_PATH.orig" -if [ $RELX_REPLACE_OS_VARS ]; then - #Make sure we don't break dev mode by keeping the symbolic link to - #the user's vm.args - if [ ! -L "$orig_vmargs_path" ]; then - #we're in copy mode, rename the vm.args file to vm.args.orig - mv "$VMARGS_PATH" "$orig_vmargs_path" - fi - - awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_vmargs_path" > "$VMARGS_PATH" - else - #We don't need to replace env. vars, just rename the - #symlink vm.args.orig to vm.args, and keep it as a - #symlink. - if [ -L "$orig_vmargs_path" ]; then - mv "$orig_vmargs_path" "$VMARGS_PATH" - fi -fi - -# Make sure log directory exists -mkdir -p "$RUNNER_LOG_DIR" - # Use $CWD/sys.config if exists, otherwise releases/VSN/sys.config if [ -z "$RELX_CONFIG_PATH" ]; then if [ -f "$RELEASE_ROOT_DIR/sys.config" ]; then @@ -129,25 +107,49 @@ if [ -z "$RELX_CONFIG_PATH" ]; then fi fi +orig_vmargs_path="$VMARGS_PATH.orig" +if [ $RELX_REPLACE_OS_VARS ]; then + # if there is no vm.args.orig then make a copy of the + # the original vm.args + if [ ! -f "$orig_vmargs_path" ]; then + mv "$VMARGS_PATH" "$orig_vmargs_path" + fi + + # apply the environment variable substitution to vm.args.orig + # the result is saved to vm.args + awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_vmargs_path" > "$VMARGS_PATH" +else + # if a vm.args.orig is present this means that + # env variable substitution has occurred before + # so use the original + if [ -f "$orig_vmargs_path" ]; then + mv "$orig_vmargs_path" "$VMARGS_PATH" + fi +fi + orig_relx_config_path="$RELX_CONFIG_PATH.orig" if [ $RELX_REPLACE_OS_VARS ]; then - #Make sure we don't break dev mode by keeping the symbolic link to - #the user's sys.config - if [ ! -L "$orig_relx_config_path" ]; then - #We're in copy mode, rename sys.config to sys.config.orig + # if there is no sys.config.orig then make a copy of the + # the original sys.config + if [ ! -f "$orig_relx_config_path" ]; then mv "$RELX_CONFIG_PATH" "$orig_relx_config_path" fi + # apply the environment variable substitution to sys.config.orig + # the result is saved to sys.config awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_relx_config_path" > "$RELX_CONFIG_PATH" - else - #We don't need to replace env. vars, just rename the - #symlink sys.config.orig to sys.config. Keep it as - #a symlink. - if [ -L "$orig_relx_config_path" ]; then - mv "$orig_relx_config_path" "$RELX_CONFIG_PATH" +else + # if a sys.config.orig is present this means that + # env variable substitution has occurred before + # so use the original + if [ -f "$orig_relx_config_path" ]; then + mv "$orig_relx_config_path" "$RELX_CONFIG_PATH" fi fi +# Make sure log directory exists +mkdir -p "$RUNNER_LOG_DIR" + # Extract the target node name from node.args NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true) if [ -z "$NAME_ARG" ]; then diff --git a/src/rlx_prv_assembler.erl b/src/rlx_prv_assembler.erl index 0eac379..7ff1d61 100644 --- a/src/rlx_prv_assembler.erl +++ b/src/rlx_prv_assembler.erl @@ -453,7 +453,7 @@ copy_or_symlink_config_file(State, ConfigPath, RelConfPath) -> ensure_not_exist(RelConfPath), case rlx_state:dev_mode(State) of true -> - ok = rlx_util:symlink_or_copy(ConfigPath, RelConfPath ++ ".orig"); + ok = rlx_util:symlink_or_copy(ConfigPath, RelConfPath); _ -> ok = ec_file:copy(ConfigPath, RelConfPath) end. diff --git a/src/rlx_prv_overlay.erl b/src/rlx_prv_overlay.erl index 71aca97..a4c0fa4 100644 --- a/src/rlx_prv_overlay.erl +++ b/src/rlx_prv_overlay.erl @@ -461,6 +461,14 @@ write_template(OverlayVars, FromFile, ToFile) -> {ok, IoData} -> case filelib:ensure_dir(ToFile) of ok -> + %% we were asked to render a template + %% onto a symlink, this would cause an overwrite + %% of the original file, so we delete the symlink + %% and go ahead with the template render + case ec_file:is_symlink(ToFile) of + true -> ec_file:remove(ToFile); + false -> ok + end, case file:write_file(ToFile, IoData) of ok -> {ok, FileInfo} = file:read_file_info(FromFile), diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl index ce72437..9a15bf8 100644 --- a/test/rlx_extended_bin_SUITE.erl +++ b/test/rlx_extended_bin_SUITE.erl @@ -28,7 +28,10 @@ restart/1, reboot/1, escript/1, - remote_console/1]). + remote_console/1, + replace_os_vars/1, + replace_os_vars_dev_mode/1, + replace_os_vars_twice/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -54,7 +57,7 @@ init_per_testcase(_, Config) -> all() -> [ping, attach, pid, restart, reboot, escript, - remote_console]. + remote_console, replace_os_vars, replace_os_vars_dev_mode]. ping(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -87,7 +90,7 @@ ping(Config) -> {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 - {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])). + {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])). attach(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -121,7 +124,7 @@ attach(Config) -> {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo attach", "&"])), timer:sleep(2000), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), - {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])). + {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])). pid(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -154,7 +157,7 @@ pid(Config) -> {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"])), - {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])). + {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])). restart(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -191,7 +194,7 @@ restart(Config) -> timer:sleep(2000), {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"])), + {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), ?assertEqual(Pid1, Pid2). reboot(Config) -> @@ -231,7 +234,7 @@ reboot(Config) -> timer:sleep(2000), {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"])), + {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])), ?assertNotEqual(Pid1, Pid2). escript(Config) -> @@ -307,6 +310,267 @@ remote_console(Config) -> ?assertEqual(1, length(Nodes)), {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])). +replace_os_vars(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"]), + SysConfig = filename:join([LibDir1, "sys.config"]), + VmArgs = filename:join([LibDir1, "vm.args"]), + + rlx_test_utils:write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + [goal_app]}, + {lib_dirs, [filename:join(LibDir1, "*")]}, + {sys_config, SysConfig}, + {vm_args, VmArgs}, + {generate_start_script, true}, + {extended_start_script, true} + ]), + + rlx_test_utils:write_config(SysConfig, + [[{goal_app, [{var1, "${VAR1}"}]}]]), + ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + "-setcookie ${COOKIE}\n"), + + OutputDir = filename:join([proplists:get_value(priv_dir, Config), + rlx_test_utils:create_random_name("relx-output")]), + + {ok, _State} = relx:do([{relname, foo}, + {relvsn, "0.0.1"}, + {goals, []}, + {lib_dirs, [LibDir1]}, + {log_level, 3}, + {output_dir, OutputDir}, + {config, ConfigFile}], ["release"]), + + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}, + {"VAR1", "v1"}]), + timer:sleep(2000), + {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, "\"v1\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '{ok, V} = application:get_env(goal_app, var1), V.'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, "\"node1\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '[Node,_] = re:split(atom_to_list(node()), \"@\"),binary_to_list(Node).'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, "cookie1"} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval 'erlang:get_cookie().'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + + %% start the node again but this time with different env variables to replace + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}, + {"VAR1", "v2"}]), + timer:sleep(2000), + {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, "\"v2\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '{ok, V} = application:get_env(goal_app, var1), V.'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, "\"node2\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '[Node,_] = re:split(atom_to_list(node()), \"@\"),binary_to_list(Node).'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, "cookie2"} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval 'erlang:get_cookie().'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + ok. + +replace_os_vars_twice(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"]), + SysConfig = filename:join([LibDir1, "sys.config"]), + VmArgs = filename:join([LibDir1, "vm.args"]), + + rlx_test_utils:write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + [goal_app]}, + {lib_dirs, [filename:join(LibDir1, "*")]}, + {sys_config, SysConfig}, + {vm_args, VmArgs}, + {generate_start_script, true}, + {extended_start_script, true} + ]), + + rlx_test_utils:write_config(SysConfig, + [[{goal_app, [{var1, "${VAR1}"}]}]]), + ec_file:write(VmArgs, "-sname node\n\n" + "-setcookie cookie\n"), + + OutputDir = filename:join([proplists:get_value(priv_dir, Config), + rlx_test_utils:create_random_name("relx-output")]), + + {ok, _State} = relx:do([{relname, foo}, + {relvsn, "0.0.1"}, + {goals, []}, + {lib_dirs, [LibDir1]}, + {log_level, 3}, + {output_dir, OutputDir}, + {config, ConfigFile}], ["release"]), + + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"VAR1", "v1"}]), + timer:sleep(2000), + {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), + [{"RELX_REPLACE_OS_VARS", "1"}]), + {ok, "\"v1\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '{ok, V} = application:get_env(goal_app, var1), V.'"]), + [{"RELX_REPLACE_OS_VARS", "1"}]), + {ok, "\"node\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '[Node,_] = re:split(atom_to_list(node()), \"@\"),binary_to_list(Node).'"]), + [{"RELX_REPLACE_OS_VARS", "1"}]), + {ok, "cookie"} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval 'erlang:get_cookie().'"]), + [{"RELX_REPLACE_OS_VARS", "1"}]), + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"]), + [{"RELX_REPLACE_OS_VARS", "1"}]), + + %% start the node again but this time don't replace env variables + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])), + timer:sleep(2000), + {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.'"])), + {ok, "\"node\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '[Node,_] = re:split(atom_to_list(node()), \"@\"),binary_to_list(Node).'"])), + {ok, "cookie"} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval 'erlang:get_cookie().'"])), + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])), + ok. + +replace_os_vars_dev_mode(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"]), + SysConfig = filename:join([LibDir1, "sys.config"]), + VmArgs = filename:join([LibDir1, "vm.args"]), + + rlx_test_utils:write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + [goal_app]}, + {lib_dirs, [filename:join(LibDir1, "*")]}, + {sys_config, SysConfig}, + {vm_args, VmArgs}, + {dev_mode, true}, + {generate_start_script, true}, + {extended_start_script, true} + ]), + + rlx_test_utils:write_config(SysConfig, + [[{goal_app, [{var1, "${VAR1}"}]}]]), + ec_file:write(VmArgs, "-sname ${NODENAME}\n\n" + "-setcookie ${COOKIE}\n"), + + OutputDir = filename:join([proplists:get_value(priv_dir, Config), + rlx_test_utils:create_random_name("relx-output")]), + + {ok, _State} = relx:do([{relname, foo}, + {relvsn, "0.0.1"}, + {goals, []}, + {lib_dirs, [LibDir1]}, + {log_level, 3}, + {output_dir, OutputDir}, + {config, ConfigFile}], ["release"]), + + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}, + {"VAR1", "v1"}]), + timer:sleep(2000), + {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, "\"v1\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '{ok, V} = application:get_env(goal_app, var1), V.'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, "\"node1\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '[Node,_] = re:split(atom_to_list(node()), \"@\"),binary_to_list(Node).'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, "cookie1"} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval 'erlang:get_cookie().'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node1"}, + {"COOKIE", "cookie1"}]), + + %% start the node again but this time with different env variables to replace + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}, + {"VAR1", "v2"}]), + timer:sleep(2000), + {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, "\"v2\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '{ok, V} = application:get_env(goal_app, var1), V.'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, "\"node2\""} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval '[Node,_] = re:split(atom_to_list(node()), \"@\"),binary_to_list(Node).'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, "cookie2"} = sh(filename:join([OutputDir, "foo", "bin", + "foo eval 'erlang:get_cookie().'"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"]), + [{"RELX_REPLACE_OS_VARS", "1"}, + {"NODENAME", "node2"}, + {"COOKIE", "cookie2"}]), + ok. + %%%=================================================================== %%% Helper Functions %%%=================================================================== @@ -327,8 +591,8 @@ sh(Command, Env, Dir) -> case sh_loop(Port) of {ok, Ret} -> {ok, Ret}; - {error, Rc} -> - {error, Rc} + {error, Rc, Msg} -> + {error, Rc, Msg} end. sh_loop(Port) -> @@ -341,7 +605,7 @@ sh_loop(Port, Acc) -> {Port, {exit_status, 0}} -> {ok, Acc}; {Port, {exit_status, Rc}} -> - {error, Rc} + {error, Rc, Acc} end. get_cwd() -> diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl index 20b45ec..a017297 100644 --- a/test/rlx_release_SUITE.erl +++ b/test/rlx_release_SUITE.erl @@ -46,6 +46,7 @@ make_relup_release2/1, make_one_app_top_level_release/1, make_dev_mode_release/1, + make_dev_mode_template_release/1, make_config_script_release/1, make_release_twice/1, make_release_twice_dev_mode/1, @@ -86,7 +87,7 @@ all() -> 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_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, @@ -1012,9 +1013,9 @@ make_dev_mode_release(Config) -> ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_2-0.0.1"]))), ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "lib_dep_1-0.0.1"]))), ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", - "sys.config.orig"]))), + "sys.config"]))), ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", - "vm.args.orig"]))); + "vm.args"]))); {win32, _} -> ?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "non_goal_1-0.0.1"]))), ?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "non_goal_2-0.0.1"]))), @@ -1027,6 +1028,66 @@ make_dev_mode_release(Config) -> "vm.args"]))) end. +make_dev_mode_template_release(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + + 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], []), + + SysConfig = filename:join([LibDir1, "config", "sys.config"]), + SysConfigTerm = [{this_is_a_test, "yup it is"}, + {this_is_an_overlay_var, "{{var1}}"}], + rlx_test_utils:write_config(SysConfig, SysConfigTerm), + + VmArgs = filename:join([LibDir1, "config", "vm.args"]), + ec_file:write(VmArgs, "-sname {{nodename}}"), + + VarsFile1 = filename:join([LibDir1, "config", "vars1.config"]), + rlx_test_utils:write_config(VarsFile1, [{var1, "indeed it is"}, + {nodename, "testnode"}]), + + ConfigFile = filename:join([LibDir1, "relx.config"]), + rlx_test_utils:write_config(ConfigFile, + [{dev_mode, true}, + {sys_config, SysConfig}, + {vm_args, VmArgs}, + {overlay_vars, [VarsFile1]}, + {overlay, [ + {template, "config/sys.config", + "releases/{{release_version}}/sys.config"}, + {template, "config/vm.args", + "releases/{{release_version}}/vm.args"}]}, + {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, State} = relx:do(undefined, undefined, [], [LibDir1], 3, + OutputDir, ConfigFile), + [{{foo, "0.0.1"}, _Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)), + + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_1-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_2-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_1-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_2-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "lib_dep_1-0.0.1"]))), + ?assert(not ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", + "sys.config"]))), + ?assert(not ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", + "vm.args"]))), + %% ensure that the original sys.config didn't get overwritten + ?assertMatch({ok, SysConfigTerm}, file:consult(SysConfig)), + %% ensure that the original vm.args didn't get overwritten + ?assertMatch({ok, <<"-sname {{nodename}}">>}, ec_file:read(VmArgs)). + make_config_script_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), FooRoot = filename:join([LibDir1, "foodir1", "foodir2"]), -- cgit v1.2.3