public
anonymous / appctl.erl
Last active

  • Download Gist
appctl.erl
Erlang
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#!/usr/bin/env escript
 
config() ->
[{app_node, app@localhost},
{appctl_node, appctl@localhost},
{cookie, app},
{timeout, 100}].
 
main(Args) ->
ScriptDir = filename:dirname(filename:absname(escript:script_name())),
code:add_path(filename:join(ScriptDir, "ebin")),
 
{AppCtlNode, Cookie} = get_values([appctl_node, cookie]),
 
os:cmd("epmd -daemon"),
net_kernel:start([AppCtlNode, shortnames]),
erlang:set_cookie(node(), Cookie),
 
try process(Args, ScriptDir)
catch
error:{cant_start, already_running} ->
error("Error: can't start because App is already running");
error:{cant_stop, isnt_running} ->
error("Error: can't stop because App is not running");
_:Reason ->
Message = io_lib:format("Unknown error occured.~n"
"Reason: ~p.~n"
"Stack trace: ~p",
[Reason, erlang:get_stacktrace()]),
error(Message)
end.
 
process([Arg], ScriptDir) ->
{AppNode, Cookie} = get_values([app_node, cookie]),
if
Arg =:= "--start"; Arg =:= "-s" ->
start(AppNode, Cookie, ScriptDir);
Arg =:= "--stop"; Arg =:= "-q" ->
stop(AppNode);
Arg =:= "--restart"; Arg =:= "-r" ->
stop(AppNode),
start(AppNode, Cookie, ScriptDir);
true ->
usage()
end;
process(_, _) ->
usage().
 
start(AppNode, Cookie, ScriptDir) ->
case net_adm:ping(AppNode) of
pong -> erlang:error({cant_start, already_running});
pang -> ok
end,
 
Deps = string:join(lists:foldl(fun(Dep, Acc) ->
["-pa", filename:join(ScriptDir, Dep) | Acc]
end, [], ["ebin", "deps/*/ebin"]), " "),
 
Cmd = io_lib:format("erl -detached -sname ~p -setcookie ~p "
"+K true "
"-boot start_sasl -config log "
"~s "
"-s app",
[AppNode, Cookie, Deps]),
os:cmd(Cmd).
 
stop(AppNode) ->
case net_adm:ping(AppNode) of
pong -> ok;
pang -> erlang:error({cant_stop, isnt_running})
end,
 
rpc:call(AppNode, init, stop, []),
wait_for_stop(AppNode, get_value(timeout)).
 
wait_for_stop(AppNode, Timeout) ->
case net_adm:ping(AppNode) of
pong ->
timer:sleep(Timeout),
wait_for_stop(AppNode, Timeout);
pang ->
ok
end.
 
usage() ->
io:format("Usage: ~s [--start | -s] [--stop | -q] [--restart | -r]~n",
[escript:script_name()]).
 
get_value(Key) ->
proplists:get_value(Key, config()).
 
get_values(Keys) ->
get_values(Keys, config()).
get_values(Keys, Config) when is_tuple(Keys) ->
get_values(tuple_to_list(Keys), Config);
get_values(Keys, Config) when is_list (Keys) ->
Values = lists:foldl(fun(Key, Values) ->
[proplists:get_value(Key, Config) | Values]
end, [], Keys),
list_to_tuple(lists:reverse(Values)).
 
error(Message) ->
io:format(Message ++ ".~n"),
halt(1).

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.