%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 92 -*-
%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
%%%
%%% This file is provided to you under the Apache License,
%%% Version 2.0 (the "License"); you may not use this file
%%% except in compliance with the License. You may obtain
%%% a copy of the License at
%%%
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Unless required by applicable law or agreed to in writing,
%%% software distributed under the License is distributed on an
%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%%% KIND, either express or implied. See the License for the
%%% specific language governing permissions and limitations
%%% under the License.
%%%-------------------------------------------------------------------
-module(rlx_extended_bin_SUITE).
-export([suite/0,
init_per_suite/1,
end_per_suite/1,
init_per_testcase/2,
all/0,
ping/1,
attach/1,
pid/1,
restart/1,
reboot/1,
escript/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").
-include_lib("kernel/include/file.hrl").
suite() ->
[{timetrap,{seconds,30}}].
init_per_suite(Config) ->
Config.
end_per_suite(_Config) ->
ok.
init_per_testcase(_, Config) ->
DataDir = filename:join(proplists:get_value(priv_dir, Config), ?MODULE),
LibDir1 = filename:join([DataDir, rlx_test_utils:create_random_name("lib_dir1_")]),
ok = rlx_util:mkdir_p(LibDir1),
State = rlx_state:new([], [{lib_dirs, [LibDir1]}], [release]),
{ok, State1} = rlx_config:do(State),
[{lib1, LibDir1},
{state, State1} | Config].
all() ->
[ping, attach, pid, restart, reboot, escript,
remote_console, replace_os_vars, replace_os_vars_dev_mode].
ping(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}
]),
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"]),
%% 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),
{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"])).
attach(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}
]),
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"]),
%% 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),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{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"])).
pid(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}
]),
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"]),
%% check for a valid pid
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
timer:sleep(2000),
{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"])).
restart(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}
]),
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"]),
%% 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),
{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),
{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"])),
?assertEqual(Pid1, Pid2).
reboot(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}
]),
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"]),
%% a reboot involves stopping the emulator, it needs to be restarted
%% though
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
timer:sleep(2000),
{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),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
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"])),
?assertNotEqual(Pid1, Pid2).
escript(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}
]),
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 = ec_file:write(filename:join([OutputDir, "foo", "script.erl"]),
[rlx_test_utils:escript_contents()]),
%% 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),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
[ExpectedOutput] = io_lib:format("~s",
[filename:join([OutputDir, "foo"])]),
{ok, Output} = sh(filename:join([OutputDir, "foo", "bin", "foo escript script.erl"])),
?assertEqual(ExpectedOutput, Output).
remote_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}
]),
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"]),
%% 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),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo remote_console &"])),
timer:sleep(2000),
{ok, NodesStr} = sh(filename:join([OutputDir, "foo", "bin", "foo eval 'nodes(connected).'"])),
Nodes = rlx_test_utils:list_to_term(NodesStr),
?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
%%%===================================================================
sh(Command) ->
sh(Command, []).
sh(Command, Env) ->
sh(Command, Env, get_cwd()).
sh(Command, Env, Dir) ->
Port = open_port({spawn, lists:flatten(Command)},
[{cd, Dir},
{env, Env},
exit_status,
{line, 16384},
use_stdio, stderr_to_stdout]),
case sh_loop(Port) of
{ok, Ret} ->
{ok, Ret};
{error, Rc, Msg} ->
{error, Rc, Msg}
end.
sh_loop(Port) ->
sh_loop(Port, "").
sh_loop(Port, Acc) ->
receive
{Port, {data, {_, Line}}} ->
sh_loop(Port, Acc ++ Line);
{Port, {exit_status, 0}} ->
{ok, Acc};
{Port, {exit_status, Rc}} ->
{error, Rc, Acc}
end.
get_cwd() ->
{ok, Dir} = file:get_cwd(),
Dir.