aboutsummaryrefslogtreecommitdiffstats
path: root/src/rcl_prv_assembler.erl
diff options
context:
space:
mode:
authorEric <[email protected]>2013-05-09 17:04:18 -0700
committerEric <[email protected]>2013-05-09 17:04:18 -0700
commitefbdfbe117939cd50d0252a210b9b7634de42bb4 (patch)
tree74b0bad39d3a5b25bd4199728c16c0b1a4ade703 /src/rcl_prv_assembler.erl
parent0d5a803a28010cc956948b614408b9d38997e9a1 (diff)
downloadrelx-efbdfbe117939cd50d0252a210b9b7634de42bb4.tar.gz
relx-efbdfbe117939cd50d0252a210b9b7634de42bb4.tar.bz2
relx-efbdfbe117939cd50d0252a210b9b7634de42bb4.zip
Basic file rename from rcl to rlx
Diffstat (limited to 'src/rcl_prv_assembler.erl')
-rw-r--r--src/rcl_prv_assembler.erl1003
1 files changed, 0 insertions, 1003 deletions
diff --git a/src/rcl_prv_assembler.erl b/src/rcl_prv_assembler.erl
deleted file mode 100644
index aca783d..0000000
--- a/src/rcl_prv_assembler.erl
+++ /dev/null
@@ -1,1003 +0,0 @@
-%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
-%%% 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.
-%%%---------------------------------------------------------------------------
-%%% @author Eric Merritt <[email protected]>
-%%% @copyright (C) 2012 Erlware, LLC.
-%%%
-%%% @doc Given a complete built release this provider assembles that release
-%%% into a release directory.
--module(rcl_prv_assembler).
-
--behaviour(rcl_provider).
-
--export([init/1,
- do/1,
- format_error/1]).
-
--include_lib("relcool/include/relcool.hrl").
-
-%%============================================================================
-%% API
-%%============================================================================
--spec init(rcl_state:t()) -> {ok, rcl_state:t()}.
-init(State) ->
- {ok, State}.
-
-%% @doc recursively dig down into the library directories specified in the state
-%% looking for OTP Applications
--spec do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
-do(State) ->
- {RelName, RelVsn} = rcl_state:default_configured_release(State),
- Release = rcl_state:get_realized_release(State, RelName, RelVsn),
- OutputDir = rcl_state:output_dir(State),
- case create_output_dir(OutputDir) of
- ok ->
- case rcl_release:realized(Release) of
- true ->
- copy_app_directories_to_output(State, Release, OutputDir);
- false ->
- ?RCL_ERROR({unresolved_release, RelName, RelVsn})
- end;
- Error ->
- Error
- end.
-
--spec format_error(ErrorDetail::term()) -> iolist().
-format_error({unresolved_release, RelName, RelVsn}) ->
- io_lib:format("The release has not been resolved ~p-~s", [RelName, RelVsn]);
-format_error({ec_file_error, AppDir, TargetDir, E}) ->
- io_lib:format("Unable to copy OTP App from ~s to ~s due to ~p",
- [AppDir, TargetDir, E]);
-format_error({config_does_not_exist, Path}) ->
- io_lib:format("The config file specified for this release (~s) does not exist!",
- [Path]);
-format_error({specified_erts_does_not_exist, ErtsVersion}) ->
- io_lib:format("Specified version of erts (~s) does not exist",
- [ErtsVersion]);
-format_error({release_script_generation_error, RelFile}) ->
- io_lib:format("Unknown internal release error generating the release file to ~s",
- [RelFile]);
-format_error({release_script_generation_warning, Module, Warnings}) ->
- ["Warnings generating release \s",
- rcl_util:indent(1), Module:format_warning(Warnings)];
-format_error({unable_to_create_output_dir, OutputDir}) ->
- io_lib:format("Unable to create output directory (possible permissions issue): ~s",
- [OutputDir]);
-format_error({release_script_generation_error, Module, Errors}) ->
- ["Errors generating release \n",
- rcl_util:indent(1), Module:format_error(Errors)];
-format_error({relup_generation_error, CurrentName, UpFromName}) ->
- io_lib:format("Unknown internal release error generating the relup from ~s to ~s",
- [UpFromName, CurrentName]);
-format_error({relup_generation_warning, Module, Warnings}) ->
- ["Warnings generating relup \s",
- rcl_util:indent(1), Module:format_warning(Warnings)];
-format_error({relup_script_generation_error,
- {relupcript_generation_error, systools_relup,
- {missing_sasl, _}}}) ->
- "Unfortunately, due to requirements in systools, you need to have the sasl application "
- "in both the current release and the release to upgrade from.";
-format_error({relup_script_generation_error, Module, Errors}) ->
- ["Errors generating relup \n",
- rcl_util:indent(1), Module:format_error(Errors)];
-format_error({unable_to_make_symlink, AppDir, TargetDir, Reason}) ->
- io_lib:format("Unable to symlink directory ~s to ~s because \n~s~s",
- [AppDir, TargetDir, rcl_util:indent(1),
- file:format_error(Reason)]).
-
-%%%===================================================================
-%%% Internal Functions
-%%%===================================================================
--spec create_output_dir(file:name()) ->
- ok | {error, Reason::term()}.
-create_output_dir(OutputDir) ->
- case filelib:is_dir(OutputDir) of
- false ->
- case rcl_util:mkdir_p(OutputDir) of
- ok ->
- ok;
- {error, _} ->
- ?RCL_ERROR({unable_to_create_output_dir, OutputDir})
- end;
- true ->
- ok
- end.
-
-copy_app_directories_to_output(State, Release, OutputDir) ->
- LibDir = filename:join([OutputDir, "lib"]),
- ok = ec_file:mkdir_p(LibDir),
- Apps = rcl_release:application_details(Release),
- Result = lists:filter(fun({error, _}) ->
- true;
- (_) ->
- false
- end,
- lists:flatten(ec_plists:map(fun(App) ->
- copy_app(LibDir, App)
- end, Apps))),
- case Result of
- [E | _] ->
- E;
- [] ->
- create_release_info(State, Release, OutputDir)
- end.
-
-copy_app(LibDir, App) ->
- AppName = erlang:atom_to_list(rcl_app_info:name(App)),
- AppVsn = rcl_app_info:vsn_as_string(App),
- AppDir = rcl_app_info:dir(App),
- TargetDir = filename:join([LibDir, AppName ++ "-" ++ AppVsn]),
- if
- AppDir == TargetDir ->
- %% No need to do anything here, discover found something already in
- %% a release dir
- ok;
- true ->
- copy_app(App, AppDir, TargetDir)
- end.
-
-copy_app(App, AppDir, TargetDir) ->
- remove_symlink_or_directory(TargetDir),
- case rcl_app_info:link(App) of
- true ->
- link_directory(AppDir, TargetDir);
- false ->
- copy_directory(AppDir, TargetDir)
- end.
-
-remove_symlink_or_directory(TargetDir) ->
- case ec_file:is_symlink(TargetDir) of
- true ->
- ec_file:remove(TargetDir);
- false ->
- case filelib:is_dir(TargetDir) of
- true ->
- ok = ec_file:remove(TargetDir, [recursive]);
- false ->
- ok
- end
- end.
-
-link_directory(AppDir, TargetDir) ->
- case file:make_symlink(AppDir, TargetDir) of
- {error, Reason} ->
- ?RCL_ERROR({unable_to_make_symlink, AppDir, TargetDir, Reason});
- ok ->
- ok
- end.
-
-copy_directory(AppDir, TargetDir) ->
- ec_plists:map(fun(SubDir) ->
- copy_dir(AppDir, TargetDir, SubDir)
- end, ["ebin",
- "include",
- "priv",
- "src",
- "c_src",
- "README",
- "LICENSE"]).
-
-copy_dir(AppDir, TargetDir, SubDir) ->
- SubSource = filename:join(AppDir, SubDir),
- SubTarget = filename:join(TargetDir, SubDir),
- case filelib:is_dir(SubSource) of
- true ->
- ok = rcl_util:mkdir_p(SubTarget),
- case ec_file:copy(SubSource, SubTarget, [recursive]) of
- {error, E} ->
- ?RCL_ERROR({ec_file_error, AppDir, SubTarget, E});
- ok ->
- ok
- end;
- false ->
- ok
- end.
-
-create_release_info(State0, Release0, OutputDir) ->
- RelName = erlang:atom_to_list(rcl_release:name(Release0)),
- ReleaseDir = release_output_dir(State0, Release0),
- ReleaseFile = filename:join([ReleaseDir, RelName ++ ".rel"]),
- ok = ec_file:mkdir_p(ReleaseDir),
- Release1 = rcl_release:relfile(Release0, ReleaseFile),
- State1 = rcl_state:update_realized_release(State0, Release1),
- case rcl_release:metadata(Release1) of
- {ok, Meta} ->
- ok = ec_file:write_term(ReleaseFile, Meta),
- write_bin_file(State1, Release1, OutputDir, ReleaseDir);
- E ->
- E
- end.
-
-
-write_bin_file(State, Release, OutputDir, RelDir) ->
- RelName = erlang:atom_to_list(rcl_release:name(Release)),
- RelVsn = rcl_release:vsn(Release),
- BinDir = filename:join([OutputDir, "bin"]),
- ok = ec_file:mkdir_p(BinDir),
- VsnRel = filename:join(BinDir, rcl_release:canonical_name(Release)),
- BareRel = filename:join(BinDir, RelName),
- ErlOpts = rcl_state:get(State, erl_opts, ""),
- StartFile = case rcl_state:get(State, extended_start_script, false) of
- false ->
- bin_file_contents(RelName, RelVsn,
- rcl_release:erts(Release),
- ErlOpts);
- true ->
- extended_bin_file_contents(RelName, RelVsn, rcl_release:erts(Release), ErlOpts)
- end,
- %% We generate the start script by default, unless the user
- %% tells us not too
- case rcl_state:get(State, generate_start_script, true) of
- false ->
- ok;
- _ ->
- ok = file:write_file(VsnRel, StartFile),
- ok = file:change_mode(VsnRel, 8#777),
- ok = file:write_file(BareRel, StartFile),
- ok = file:change_mode(BareRel, 8#777)
- end,
- ok = file:write_file(filename:join(RelDir, "vm.args"), vm_args_file(RelName)),
- copy_or_generate_sys_config_file(State, Release, OutputDir, RelDir).
-
-%% @doc copy config/sys.config or generate one to releases/VSN/sys.config
--spec copy_or_generate_sys_config_file(rcl_state:t(), rcl_release:t(),
- file:name(), file:name()) ->
- {ok, rcl_state:t()} | relcool:error().
-copy_or_generate_sys_config_file(State, Release, OutputDir, RelDir) ->
- RelSysConfPath = filename:join([RelDir, "sys.config"]),
- case rcl_state:sys_config(State) of
- undefined ->
- ok = generate_sys_config_file(RelSysConfPath),
- include_erts(State, Release, OutputDir, RelDir);
- ConfigPath ->
- case filelib:is_regular(ConfigPath) of
- false ->
- ?RCL_ERROR({config_does_not_exist, ConfigPath});
- true ->
- ok = ec_file:copy(ConfigPath, RelSysConfPath),
- include_erts(State, Release, OutputDir, RelDir)
- end
- end.
-
-%% @doc write a generic sys.config to the path RelSysConfPath
--spec generate_sys_config_file(string()) -> ok.
-generate_sys_config_file(RelSysConfPath) ->
- {ok, Fd} = file:open(RelSysConfPath, [write]),
- io:format(Fd,
- "%% Thanks to Ulf Wiger at Ericcson for these comments:~n"
- "%%~n"
- "%% This file is identified via the erl command line option -config File.~n"
- "%% Note that File should have no extension, e.g.~n"
- "%% erl -config .../sys (if this file is called sys.config)~n"
- "%%~n"
- "%% In this file, you can redefine application environment variables.~n"
- "%% This way, you don't have to modify the .app files of e.g. OTP applications.~n"
- "[].~n", []),
- file:close(Fd).
-
-%% @doc Optionally add erts directory to release, if defined.
--spec include_erts(rcl_state:t(), rcl_release:t(), file:name(), file:name()) -> {ok, rcl_state:t()} | relcool:error().
-include_erts(State, Release, OutputDir, RelDir) ->
- case rcl_state:get(State, include_erts, true) of
- true ->
- Prefix = code:root_dir(),
- ErtsVersion = rcl_release:erts(Release),
- ErtsDir = filename:join([Prefix, "erts-" ++ ErtsVersion]),
- LocalErts = filename:join([OutputDir, "erts-" ++ ErtsVersion]),
- case filelib:is_dir(ErtsDir) of
- false ->
- ?RCL_ERROR({specified_erts_does_not_exist, ErtsVersion});
- true ->
- ok = ec_file:mkdir_p(LocalErts),
- ok = ec_file:copy(ErtsDir, LocalErts, [recursive]),
- ok = ec_file:remove(filename:join([LocalErts, "bin", "erl"])),
- ok = file:write_file(filename:join([LocalErts, "bin", "erl"]), erl_script(ErtsVersion)),
- case rcl_state:get(State, extended_start_script, false) of
- true ->
- ok = ec_file:copy(filename:join([Prefix, "bin", "start_clean.boot"]),
- filename:join([OutputDir, "bin", "start_clean.boot"])),
- NodeToolFile = nodetool_contents(),
- NodeTool = filename:join([LocalErts, "bin", "nodetool"]),
- ok = file:write_file(NodeTool, NodeToolFile),
- ok = file:change_mode(NodeTool, 8#755);
- false ->
- ok
- end,
- make_boot_script(State, Release, OutputDir, RelDir)
- end;
- _ ->
- make_boot_script(State, Release, OutputDir, RelDir)
- end.
-
-
--spec make_boot_script(rcl_state:t(), rcl_release:t(), file:name(), file:name()) ->
- {ok, rcl_state:t()} | relcool:error().
-make_boot_script(State, Release, OutputDir, RelDir) ->
- Options = [{path, [RelDir | get_code_paths(Release, OutputDir)]},
- {outdir, RelDir},
- no_module_tests, silent],
- Name = erlang:atom_to_list(rcl_release:name(Release)),
- ReleaseFile = filename:join([RelDir, Name ++ ".rel"]),
- case make_script(Options,
- fun(CorrectedOptions) ->
- systools:make_script(Name, CorrectedOptions)
- end) of
- ok ->
- rcl_log:error(rcl_state:log(State),
- "release successfully created!"),
- make_relup(State, Release);
- error ->
- ?RCL_ERROR({release_script_generation_error, ReleaseFile});
- {ok, _, []} ->
- rcl_log:error(rcl_state:log(State),
- "release successfully created!"),
- make_relup(State, Release);
- {ok,Module,Warnings} ->
- ?RCL_ERROR({release_script_generation_warn, Module, Warnings});
- {error,Module,Error} ->
- ?RCL_ERROR({release_script_generation_error, Module, Error})
- end.
-
--spec make_script([term()],
- fun(([term()]) -> Res)) -> Res.
-make_script(Options, RunFun) ->
- %% Erts 5.9 introduced a non backwards compatible option to
- %% erlang this takes that into account
- Erts = erlang:system_info(version),
- case ec_semver:gte(Erts, "5.9") of
- true ->
- RunFun([no_warn_sasl | Options]);
- _ ->
- RunFun(Options)
- end.
-
-make_relup(State, Release) ->
- case rcl_state:action(State) of
- relup ->
- UpFrom =
- case rcl_state:upfrom(State) of
- undefined ->
- get_last_release(State, Release);
- Vsn ->
- get_up_release(State, Release, Vsn)
- end,
- case UpFrom of
- undefined ->
- ?RCL_ERROR(no_upfrom_release_found);
- _ ->
- make_upfrom_script(State, Release, UpFrom)
- end;
- _ ->
- {ok, State}
- end.
-
-make_upfrom_script(State, Release, UpFrom) ->
- OutputDir = rcl_state:output_dir(State),
- Options = [{outdir, OutputDir},
- {path, get_code_paths(Release, OutputDir) ++
- get_code_paths(UpFrom, OutputDir)},
- silent],
- CurrentRel = strip_rel(rcl_release:relfile(Release)),
- UpFromRel = strip_rel(rcl_release:relfile(UpFrom)),
- rcl_log:debug(rcl_state:log(State),
- "systools:make_relup(~p, ~p, ~p, ~p)",
- [CurrentRel, UpFromRel, UpFromRel, Options]),
- case make_script(Options,
- fun(CorrectOptions) ->
- systools:make_relup(CurrentRel, [UpFromRel], [UpFromRel], CorrectOptions)
- end) of
- ok ->
- rcl_log:error(rcl_state:log(State),
- "relup from ~s to ~s successfully created!",
- [UpFromRel, CurrentRel]),
- {ok, State};
- error ->
- ?RCL_ERROR({relup_script_generation_error, CurrentRel, UpFromRel});
- {ok, RelUp, _, []} ->
- rcl_log:error(rcl_state:log(State),
- "relup successfully created!"),
- write_relup_file(State, Release, RelUp),
- {ok, State};
- {ok,_, Module,Warnings} ->
- ?RCL_ERROR({relup_script_generation_warn, Module, Warnings});
- {error,Module,Errors} ->
- ?RCL_ERROR({relupcript_generation_error, Module, Errors})
- end.
-
-write_relup_file(State, Release, Relup) ->
- OutDir = release_output_dir(State, Release),
- RelName = rcl_util:to_string(rcl_release:name(Release)),
- RelupFile = filename:join(OutDir, RelName ++ ".relup"),
- ok = ec_file:write_term(RelupFile, Relup).
-
-strip_rel(Name) ->
- rcl_util:to_string(filename:join(filename:dirname(Name),
- filename:basename(Name, ".rel"))).
-
-
-get_up_release(State, Release, Vsn) ->
- Name = rcl_release:name(Release),
- try
- ec_dictionary:get({Name, Vsn}, rcl_state:realized_releases(State))
- catch
- throw:notfound ->
- undefined
- end.
-
-get_last_release(State, Release) ->
- Releases0 = [Rel || {{_, _}, Rel} <- ec_dictionary:to_list(rcl_state:realized_releases(State))],
- Releases1 = lists:sort(fun(R1, R2) ->
- ec_semver:lte(rcl_release:vsn(R1),
- rcl_release:vsn(R2))
- end, Releases0),
- Res = lists:foldl(fun(_Rel, R = {found, _}) ->
- R;
- (Rel, Prev) ->
- case rcl_release:vsn(Rel) == rcl_release:vsn(Release) of
- true ->
- {found, Prev};
- false ->
- Rel
- end
- end, undefined, Releases1),
- case Res of
- {found, R} ->
- R;
- Else ->
- Else
- end.
-
--spec release_output_dir(rcl_state:t(), rcl_release:t()) -> string().
-release_output_dir(State, Release) ->
- OutputDir = rcl_state:output_dir(State),
- filename:join([OutputDir,
- "releases",
- rcl_release:canonical_name(Release)]).
-
-%% @doc Generates the correct set of code paths for the system.
--spec get_code_paths(rcl_release:t(), file:name()) -> [file:name()].
-get_code_paths(Release, OutDir) ->
- LibDir = filename:join(OutDir, "lib"),
- [filename:join([LibDir,
- erlang:atom_to_list(rcl_app_info:name(App)) ++ "-" ++
- rcl_app_info:vsn_as_string(App), "ebin"]) ||
- App <- rcl_release:application_details(Release)].
-
-erl_script(ErtsVsn) ->
- [<<"#!/bin/sh
-set -e
-
-SCRIPT_DIR=`dirname $0`
-ROOTDIR=`cd $SCRIPT_DIR/../../ && pwd`
-BINDIR=$ROOTDIR/erts-">>, ErtsVsn, <<"/bin
-EMU=beam
-PROGNAME=`echo $0 | sed 's/.*\\///'`
-export EMU
-export ROOTDIR
-export BINDIR
-export PROGNAME
-exec \"$BINDIR/erlexec\" ${1+\"$@\"}
-">>].
-
-bin_file_contents(RelName, RelVsn, ErtsVsn, ErlOpts) ->
- [<<"#!/bin/sh
-
-set -e
-
-SCRIPT_DIR=`dirname $0`
-RELEASE_ROOT_DIR=`cd $SCRIPT_DIR/.. && pwd`
-REL_NAME=">>, RelName, <<"
-REL_VSN=">>, RelVsn, <<"
-ERTS_VSN=">>, ErtsVsn, <<"
-REL_DIR=$RELEASE_ROOT_DIR/releases/$REL_NAME-$REL_VSN
-ERL_OPTS=">>, ErlOpts, <<"
-
-find_erts_dir() {
- local erts_dir=$RELEASE_ROOT_DIR/erts-$ERTS_VSN
- if [ -d \"$erts_dir\" ]; then
- ERTS_DIR=$erts_dir;
- ROOTDIR=$RELEASE_ROOT_DIR
- else
- local erl=`which erl`
- local erl_root=`$erl -noshell -eval \"io:format(\\\"~s\\\", [code:root_dir()]).\" -s init stop`
- ERTS_DIR=$erl_root/erts-$ERTS_VSN
- ROOTDIR=$erl_root
- fi
-
-}
-
-find_sys_config() {
- local possible_sys=$REL_DIR/sys.config
- if [ -f \"$possible_sys\" ]; then
- SYS_CONFIG=\"-config $possible_sys\"
- fi
-}
-
-find_erts_dir
-find_sys_config
-export ROOTDIR=$RELEASE_ROOT_DIR
-export BINDIR=$ERTS_DIR/bin
-export EMU=beam
-export PROGNAME=erl
-export LD_LIBRARY_PATH=$ERTS_DIR/lib
-
-cd $ROOTDIR
-
-$BINDIR/erlexec $ERL_OPTS $SYS_CONFIG -boot $REL_DIR/$REL_NAME $@">>].
-
-extended_bin_file_contents(RelName, RelVsn, ErtsVsn, ErlOpts) ->
- [<<"#!/bin/sh
-
-set -e
-
-SCRIPT_DIR=`dirname $0`
-RELEASE_ROOT_DIR=`cd $SCRIPT_DIR/.. && pwd`
-REL_NAME=">>, RelName, <<"
-REL_VSN=">>, RelVsn, <<"
-ERTS_VSN=">>, ErtsVsn, <<"
-REL_DIR=$RELEASE_ROOT_DIR/releases/$REL_NAME-$REL_VSN
-ERL_OPTS=">>, ErlOpts, <<"
-PIPE_DIR=/tmp/$REL_DIR/
-
-find_erts_dir() {
- local erts_dir=$RELEASE_ROOT_DIR/erts-$ERTS_VSN
- if [ -d \"$erts_dir\" ]; then
- ERTS_DIR=$erts_dir;
- ROOTDIR=$RELEASE_ROOT_DIR
- else
- local erl=`which erl`
- local erl_root=`$erl -noshell -eval \"io:format(\\\"~s\\\", [code:root_dir()]).\" -s init stop`
- ERTS_DIR=$erl_root/erts-$ERTS_VSN
- ROOTDIR=$erl_root
- fi
-
-}
-
-find_sys_config() {
- local possible_sys=$REL_DIR/sys.config
- if [ -f \"$possible_sys\" ]; then
- SYS_CONFIG=\"-config $possible_sys\"
- fi
-}
-
-# Use $CWD/vm.args if exists, otherwise releases/APP_VSN/vm.args, or else etc/vm.args
-if [ -e \"$CALLER_DIR/vm.args\" ]; then
- VMARGS_PATH=$CALLER_DIR/vm.args
- USE_DIR=$CALLER_DIR
-else
- USE_DIR=$REL_DIR
- if [ -e \"$REL_DIR/vm.args\" ]; then
- VMARGS_PATH=\"$REL_DIR/vm.args\"
- else
- VMARGS_PATH=\"$REL_DIR/vm.args\"
- fi
-fi
-
-RUNNER_LOG_DIR=$USE_DIR/log
-# Make sure log directory exists
-mkdir -p $RUNNER_LOG_DIR
-
-# Use releases/VSN/sys.config if it exists otherwise use etc/app.config
-if [ -e \"$USE_DIR/sys.config\" ]; then
- CONFIG_PATH=\"$USE_DIR/sys.config\"
-else
- if [ -e \"$REL_DIR/sys.config\" ]; then
- CONFIG_PATH=\"$REL_DIR/sys.config\"
- else
- CONFIG_PATH=\"$REL_DIR/app.config\"
- fi
-fi
-
-# Extract the target node name from node.args
-NAME_ARG=`egrep '^-s?name' $VMARGS_PATH`
-if [ -z \"$NAME_ARG\" ]; then
- echo \"vm.args needs to have either -name or -sname parameter.\"
- exit 1
-fi
-
-# Extract the name type and name from the NAME_ARG for REMSH
-REMSH_TYPE=`echo $NAME_ARG | awk '{print $1}'`
-REMSH_NAME=`echo $NAME_ARG | awk '{print $2}'`
-
-# Note the `date +%s`, used to allow multiple remsh to the same node transparently
-REMSH_NAME_ARG=\"$REMSH_TYPE remsh`date +%s`@`echo $REMSH_NAME | awk -F@ '{print $2}'`\"
-REMSH_REMSH_ARG=\"-remsh $REMSH_NAME\"
-
-# Extract the target cookie
-COOKIE_ARG=`grep '^-setcookie' $VMARGS_PATH`
-if [ -z \"$COOKIE_ARG\" ]; then
- echo \"vm.args needs to have a -setcookie parameter.\"
- exit 1
-fi
-
-# Setup remote shell command to control node
-REMSH=\"$ERTS_PATH/erl $REMSH_NAME_ARG $REMSH_REMSH_ARG $COOKIE_ARG\"
-
-find_erts_dir
-find_sys_config
-export ROOTDIR=$RELEASE_ROOT_DIR
-export BINDIR=$ERTS_DIR/bin
-export EMU=beam
-export PROGNAME=erl
-export LD_LIBRARY_PATH=$ERTS_DIR/lib
-
-cd $ROOTDIR
-
-# Setup command to control the node
-NODETOOL=\"$ERTS_DIR/bin/escript $ERTS_DIR/bin/nodetool $NAME_ARG $COOKIE_ARG\"
-
-# Check the first argument for instructions
-case \"$1\" in
- start|start_boot)
-
- # Make sure there is not already a node running
- #RES=`$NODETOOL ping`
- #if [ \"$RES\" = \"pong\" ]; then
- # echo \"Node is already running!\"
- # exit 1
- #fi
- case \"$1\" in
- start)
- shift
- START_OPTION=\"console\"
- HEART_OPTION=\"start\"
- ;;
- start_boot)
- shift
- START_OPTION=\"console_boot\"
- HEART_OPTION=\"start_boot\"
- ;;
- esac
- RUN_PARAM=$(printf \"'%s' \" \"$@\")
- HEART_COMMAND=\"$SCRIPT_DIR/bin/$REL_NAME $HEART_OPTION $RUN_PARAM\"
- export HEART_COMMAND
- mkdir -p $PIPE_DIR
- $ERTS_DIR/bin/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR \"exec $RELEASE_ROOT_DIR/bin/$REL_NAME $START_OPTION $RUN_PARAM\" 2>&1
- ;;
-
- stop)
- # Wait for the node to completely stop...
- case `uname -s` in
- Linux|Darwin|FreeBSD|DragonFly|NetBSD|OpenBSD)
- # PID COMMAND
- PID=`ps ax -o pid= -o command=|
- grep \"$SCRIPT_DIR/.*/[b]eam\"|awk '{print $1}'`
- ;;
- SunOS)
- # PID COMMAND
- PID=`ps -ef -o pid= -o args=|
- grep \"$SCRIPT_DIR/.*/[b]eam\"|awk '{print $1}'`
- ;;
- CYGWIN*)
- # UID PID PPID TTY STIME COMMAND
- PID=`ps -efW|grep \"$SCRIPT_DIR/.*/[b]eam\"|awk '{print $2}'`
- ;;
- esac
- $NODETOOL stop
- ES=$?
- if [ \"$ES\" -ne 0 ]; then
- exit $ES
- fi
- while `kill -0 $PID 2>/dev/null`;
- do
- sleep 1
- done
- ;;
-
- restart)
- ## Restart the VM without exiting the process
- $NODETOOL restart
- ES=$?
- if [ \"$ES\" -ne 0 ]; then
- exit $ES
- fi
- ;;
-
- reboot)
- ## Restart the VM completely (uses heart to restart it)
- $NODETOOL reboot
- ES=$?
- if [ \"$ES\" -ne 0 ]; then
- exit $ES
- fi
- ;;
-
- ping)
- ## See if the VM is alive
- $NODETOOL ping
- ES=$?
- if [ \"$ES\" -ne 0 ]; then
- exit $ES
- fi
- ;;
-
- attach)
- # Make sure a node IS running
- RES=`$NODETOOL ping`
- ES=$?
- if [ \"$ES\" -ne 0 ]; then
- echo \"Node is not running!\"
- exit $ES
- fi
-
- shift
- exec $ERTS_DIR/bin/to_erl $PIPE_DIR
- ;;
-
- remote_console)
- # Make sure a node IS running
- RES=`$NODETOOL ping`
- ES=$?
- if [ \"$ES\" -ne 0 ]; then
- echo \"Node is not running!\"
- exit $ES
- fi
-
- shift
- exec $REMSH
- ;;
-
- upgrade)
- if [ -z \"$2\" ]; then
- echo \"Missing upgrade package argument\"
- echo \"Usage: $REL_NAME upgrade {package base name}\"
- echo \"NOTE {package base name} MUST NOT include the .tar.gz suffix\"
- exit 1
- fi
-
- # Make sure a node IS running
- RES=`$NODETOOL ping`
- ES=$?
- if [ \"$ES\" -ne 0 ]; then
- echo \"Node is not running!\"
- exit $ES
- fi
-
- node_name=`echo $NAME_ARG | awk '{print $2}'`
- erlang_cookie=`echo $COOKIE_ARG | awk '{print $2}'`
-
- $ERTS_DIR/bin/escript $SCRIPT_DIR/bin/install_upgrade.escript $node_name $erlang_cookie $2
- ;;
-
- console|console_clean|console_boot)
- # .boot file typically just $REL_NAME (ie, the app name)
- # however, for debugging, sometimes start_clean.boot is useful.
- # For e.g. 'setup', one may even want to name another boot script.
- case \"$1\" in
- console) BOOTFILE=$REL_NAME ;;
- console_clean) BOOTFILE=start_clean ;;
- console_boot)
- shift
- BOOTFILE=\"$1\"
- shift
- ;;
- esac
- # Setup beam-required vars
- ROOTDIR=$RELEASE_ROOT_DIR
- BINDIR=$RELEASE_ROOT_DIR/erts-$ERTS_VSN/bin
- EMU=beam
- PROGNAME=`echo $0 | sed 's/.*\\///'`
- CMD=\"$BINDIR/erlexec -boot $REL_DIR/$BOOTFILE -mode embedded -config $CONFIG_PATH -args_file $VMARGS_PATH\"
- export EMU
- export ROOTDIR
- export BINDIR
- export PROGNAME
-
- # Dump environment info for logging purposes
- echo \"Exec: $CMD\" -- ${1+\"$@\"}
- echo \"Root: $ROOTDIR\"
-
- # Log the startup
- logger -t \"$REL_NAME[$$]\" \"Starting up\"
-
- # Start the VM
- exec $CMD -- ${1+\"$@\"}
- ;;
-
- foreground)
- # start up the release in the foreground for use by runit
- # or other supervision services
-
- BOOTFILE=$REL_NAME
- FOREGROUNDOPTIONS=\"-noinput +Bd\"
-
- # Setup beam-required vars
- ROOTDIR=$RELEASE_ROOT_DIR
- BINDIR=$RELEASE_ROOT_DIR/erts-$ERTS_VSN/bin
- EMU=beam
- PROGNAME=`echo $0 | sed 's/.*///'`
- CMD=\"$BINDIR/erlexec $FOREGROUNDOPTIONS -boot $REL_DIR/$BOOTFILE -config $CONFIG_PATH -args_file $VMARGS_PATH\"
- export EMU
- export ROOTDIR
- export BINDIR
- export PROGNAME
-
- # Dump environment info for logging purposes
- echo \"Exec: $CMD\" -- ${1+\"$@\"}
- echo \"Root: $ROOTDIR\"
-
- # Start the VM
- exec $CMD -- ${1+\"$@\"}
- ;;
- *)
- echo \"Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade}\"
- exit 1
- ;;
-esac
-
-exit 0">>].
-
-nodetool_contents() ->
- [<<"%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ft=erlang ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% nodetool: Helper Script for interacting with live nodes
-%%
-%% -------------------------------------------------------------------
-
-main(Args) ->
- ok = start_epmd(),
- %% Extract the args
- {RestArgs, TargetNode} = process_args(Args, [], undefined),
-
- %% 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
- {true, pong} ->
- ok;
- {_, pang} ->
- io:format(\"Node ~p not responding to pings.\n\", [TargetNode]),
- halt(1)
- end,
-
- case RestArgs of
- [\"ping\"] ->
- %% If we got this far, the node already responsed to a ping, so just dump
- %% a \"pong\"
- io:format(\"pong\n\");
- [\"stop\"] ->
- io:format(\"~p\n\", [rpc:call(TargetNode, init, stop, [], 60000)]);
- [\"restart\"] ->
- io:format(\"~p\n\", [rpc:call(TargetNode, init, restart, [], 60000)]);
- [\"reboot\"] ->
- io:format(\"~p\n\", [rpc:call(TargetNode, init, reboot, [], 60000)]);
- [\"rpc\", Module, Function | RpcArgs] ->
- case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
- [RpcArgs], 60000) of
- ok ->
- ok;
- {badrpc, Reason} ->
- io:format(\"RPC to ~p failed: ~p\n\", [TargetNode, Reason]),
- halt(1);
- _ ->
- halt(1)
- end;
- [\"rpcterms\", Module, Function, ArgsAsString] ->
- case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
- consult(ArgsAsString), 60000) of
- {badrpc, Reason} ->
- io:format(\"RPC to ~p failed: ~p\n\", [TargetNode, Reason]),
- halt(1);
- Other ->
- io:format(\"~p\n\", [Other])
- end;
- Other ->
- io:format(\"Other: ~p\n\", [Other]),
- io:format(\"Usage: nodetool {ping|stop|restart|reboot}\n\")
- end,
- net_kernel:stop().
-
-process_args([], Acc, TargetNode) ->
- {lists:reverse(Acc), TargetNode};
-process_args([\"-setcookie\", Cookie | Rest], Acc, TargetNode) ->
- erlang:set_cookie(node(), list_to_atom(Cookie)),
- process_args(Rest, Acc, TargetNode);
-process_args([\"-name\", TargetName | Rest], Acc, _) ->
- ThisNode = append_node_suffix(TargetName, \"_maint_\"),
- {ok, _} = net_kernel:start([ThisNode, longnames]),
- process_args(Rest, Acc, nodename(TargetName));
-process_args([\"-sname\", TargetName | Rest], Acc, _) ->
- 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).
-
-
-start_epmd() ->
- [] = os:cmd(epmd_path() ++ \" -daemon\"),
- ok.
-
-epmd_path() ->
- ErtsBinDir = filename:dirname(escript:script_name()),
- Name = \"epmd\",
- case os:find_executable(Name, ErtsBinDir) of
- false ->
- case os:find_executable(Name) of
- false ->
- io:format(\"Could not find epmd.~n\"),
- halt(1);
- GlobalEpmd ->
- GlobalEpmd
- end;
- Epmd ->
- Epmd
- end.
-
-
-nodename(Name) ->
- case string:tokens(Name, \"@\") of
- [_Node, _Host] ->
- list_to_atom(Name);
- [Node] ->
- [_, Host] = string:tokens(atom_to_list(node()), \"@\"),
- list_to_atom(lists:concat([Node, \"@\", Host]))
- end.
-
-append_node_suffix(Name, Suffix) ->
- case string:tokens(Name, \"@\") of
- [Node, Host] ->
- list_to_atom(lists:concat([Node, Suffix, os:getpid(), \"@\", Host]));
- [Node] ->
- list_to_atom(lists:concat([Node, Suffix, os:getpid()]))
- end.
-
-
-%%
-%% Given a string or binary, parse it into a list of terms, ala file:consult/0
-%%
-consult(Str) when is_list(Str) ->
- consult([], Str, []);
-consult(Bin) when is_binary(Bin)->
- consult([], binary_to_list(Bin), []).
-
-consult(Cont, Str, Acc) ->
- case erl_scan:tokens(Cont, Str, 0) of
- {done, Result, Remaining} ->
- case Result of
- {ok, Tokens, _} ->
- {ok, Term} = erl_parse:parse_term(Tokens),
- consult([], Remaining, [Term | Acc]);
- {eof, _Other} ->
- lists:reverse(Acc);
- {error, Info, _} ->
- {error, Info}
- end;
- {more, Cont1} ->
- consult(Cont1, eof, Acc)
- end.">>].
-
-vm_args_file(RelName) ->
- [<<"## Name of the node
--name ">>, RelName, <<"@127.0.0.1
-
-## Cookie for distributed erlang
--setcookie ">>, RelName, <<"
-
-## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive
-## (Disabled by default..use with caution!)
-##-heart
-
-## Enable kernel poll and a few async threads
-##+K true
-##+A 5
-
-## Increase number of concurrent ports/sockets
-##-env ERL_MAX_PORTS 4096
-
-## Tweak GC to run more often
-##-env ERL_FULLSWEEP_AFTER 10">>].