erlbox 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION.yml +2 -2
- data/erlbox.gemspec +9 -3
- data/lib/erlbox/release.rb +124 -29
- data/lib/erlbox/reltools/erl.sh +20 -0
- data/lib/erlbox/reltools/make-rel +108 -0
- data/lib/erlbox/reltools/nodetool +79 -0
- data/lib/erlbox/reltools/runner +130 -0
- data/lib/erlbox/reltools/runner.erb +130 -0
- data/lib/erlbox/utils.rb +14 -0
- metadata +8 -3
data/VERSION.yml
CHANGED
data/erlbox.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{erlbox}
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.6.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Phillip Toland"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-07-27}
|
10
10
|
s.default_executable = %q{erlbox}
|
11
11
|
s.description = %q{Rake tasks and helper scripts for building Erlang applications.}
|
12
12
|
s.email = %q{phil.toland@gmail.com}
|
@@ -35,15 +35,21 @@ Gem::Specification.new do |s|
|
|
35
35
|
"lib/erlbox/install.rb",
|
36
36
|
"lib/erlbox/recurse.rb",
|
37
37
|
"lib/erlbox/release.rb",
|
38
|
+
"lib/erlbox/reltools/erl.sh",
|
39
|
+
"lib/erlbox/reltools/make-rel",
|
40
|
+
"lib/erlbox/reltools/nodetool",
|
41
|
+
"lib/erlbox/reltools/runner",
|
42
|
+
"lib/erlbox/reltools/runner.erb",
|
38
43
|
"lib/erlbox/snmp.rb",
|
39
44
|
"lib/erlbox/test.rb",
|
40
45
|
"lib/erlbox/utils.rb"
|
41
46
|
]
|
47
|
+
s.has_rdoc = false
|
42
48
|
s.homepage = %q{http://github.com/toland/erlbox}
|
43
49
|
s.rdoc_options = ["--charset=UTF-8"]
|
44
50
|
s.require_paths = ["lib"]
|
45
51
|
s.rubyforge_project = %q{erlbox}
|
46
|
-
s.rubygems_version = %q{1.3.
|
52
|
+
s.rubygems_version = %q{1.3.5}
|
47
53
|
s.summary = %q{Erlang Toolbox}
|
48
54
|
|
49
55
|
if s.respond_to? :specification_version then
|
data/lib/erlbox/release.rb
CHANGED
@@ -22,51 +22,146 @@
|
|
22
22
|
## THE SOFTWARE.
|
23
23
|
##
|
24
24
|
## -------------------------------------------------------------------
|
25
|
+
require 'erb'
|
25
26
|
require 'rake/clean'
|
27
|
+
require 'erlbox/utils'
|
28
|
+
require 'yaml'
|
26
29
|
include FileUtils
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
def build_node(nodefile)
|
32
|
+
# Load the YAML descriptor
|
33
|
+
node_desc = load_node_yaml(nodefile)
|
31
34
|
|
32
|
-
|
35
|
+
# Pull out vars we'll need often
|
36
|
+
relname = node_desc['release']
|
37
|
+
relvers = node_desc['version']
|
38
|
+
relid = "#{relname}-#{relvers}"
|
39
|
+
erts_vsn = erts_version()
|
33
40
|
|
34
|
-
|
41
|
+
# Merge list of apps into a space separated string
|
42
|
+
apps = node_desc['apps'].join(' ')
|
35
43
|
|
36
|
-
|
37
|
-
|
38
|
-
|
44
|
+
# Run the make-rel script -- this will yield the following files:
|
45
|
+
# <relname>-<relver>.[boot, rel, script, .tar.gz]
|
46
|
+
reltools_dir = File.join(File.dirname(__FILE__), "reltools")
|
47
|
+
script = File.join(reltools_dir, "make-rel")
|
48
|
+
cmd = "#{script} #{relname} #{relvers} #{node_desc['code_path']} #{apps}"
|
49
|
+
sh cmd
|
39
50
|
|
40
|
-
|
51
|
+
# Unpack the systool generated tarball
|
52
|
+
FileUtils.remove_dir(relname, force = true)
|
53
|
+
FileUtils.mkdir(relname)
|
54
|
+
sh "tar -xzf #{relid}.tar.gz -C #{relname}"
|
41
55
|
|
42
|
-
|
56
|
+
# Cleanup interstitial files from systools
|
57
|
+
FileUtils.remove(["#{relid}.boot", "#{relid}.script", "#{relid}.rel", "#{relid}.tar.gz"])
|
43
58
|
|
59
|
+
# Create release file
|
60
|
+
File.open("#{relname}/releases/start_erl.data", 'w') { |f| f.write("#{erts_vsn} #{relvers}\n") }
|
44
61
|
|
45
|
-
|
46
|
-
|
47
|
-
sh "
|
62
|
+
# Copy overlay into place (if present)
|
63
|
+
if node_desc.has_key?('overlay')
|
64
|
+
sh "cp -R #{node_desc['overlay']}/* #{relname}" # Had issues with FileUtils.cp_r doing wrong thing
|
48
65
|
end
|
49
|
-
end
|
50
66
|
|
51
|
-
|
52
|
-
|
53
|
-
sh "
|
67
|
+
# Remove any files from the erts bin/ that are scripts -- we want only executables
|
68
|
+
erts_bin = File.join(relname, "erts-" + erts_vsn, "bin")
|
69
|
+
sh "rm -f `file #{erts_bin}/* |grep Bourne|awk -F: '{print $1}'`"
|
70
|
+
|
71
|
+
# Copy nodetool into erts-<vsn>/bin
|
72
|
+
FileUtils.cp(File.join(reltools_dir, "nodetool"), erts_bin)
|
73
|
+
|
74
|
+
# Copy our custom erl.sh and the necessary .boot file into erts-<vsn>/bin. This is necessary
|
75
|
+
# to enable escript to work properly
|
76
|
+
FileUtils.cp(File.join(reltools_dir, "erl.sh"), File.join(erts_bin, "erl"))
|
77
|
+
FileUtils.cp(File.join(erl_root(), "bin", "start.boot"), File.join(erts_bin, "erl.boot"))
|
78
|
+
|
79
|
+
# Create any requested empty-dirs
|
80
|
+
if node_desc.has_key?('empty_dirs')
|
81
|
+
node_desc['empty_dirs'].each { |d| FileUtils.mkdir_p(File.join(relname, d)) }
|
82
|
+
end
|
83
|
+
|
84
|
+
# Make sure bin directory exists and copy the runner
|
85
|
+
FileUtils.mkdir_p File.join(relname, "bin")
|
86
|
+
cp File.join(reltools_dir, "runner"), File.join(relname, "bin", relname)
|
87
|
+
chmod 0755, File.join(relname, "bin", relname)
|
88
|
+
|
54
89
|
end
|
55
90
|
|
56
|
-
task :prepare => [REL_APPNAME, :make_rel] do
|
57
|
-
sh "tar -xzf #{REL_FULLNAME}.tar.gz -C #{REL_APPNAME}"
|
58
|
-
rm "#{REL_FULLNAME}.tar.gz"
|
59
91
|
|
60
|
-
|
61
|
-
|
92
|
+
def load_node_yaml(file)
|
93
|
+
# Load the YAML file
|
94
|
+
filename = File.expand_path(file)
|
95
|
+
fail "Node descriptor #{filename} does not exit!" if not File.exist?(filename)
|
96
|
+
node = YAML::load(File.read(filename))
|
97
|
+
|
98
|
+
# Make sure a release name and version are specified
|
99
|
+
if !node.has_key?('release') or !node.has_key?('version')
|
100
|
+
fail "Node descriptor must have a release and version specified."
|
101
|
+
end
|
102
|
+
|
103
|
+
# Make sure code path is swathed with quotes so that wildcards won't get processed by
|
104
|
+
# shell
|
105
|
+
if node.has_key?('code_path')
|
106
|
+
node['code_path'] = "\'#{node['code_path']}\'"
|
107
|
+
else
|
108
|
+
# If no code path is specified set an empty one
|
109
|
+
node['code_path'] = '""'
|
110
|
+
end
|
111
|
+
|
112
|
+
return node
|
62
113
|
end
|
63
114
|
|
64
|
-
desc "Stage the application into a directory"
|
65
|
-
task :stage => [:clean, :build_app, :prepare]
|
66
115
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
116
|
+
## Setup a series of dynamic targets, based on the information available in the .node file.
|
117
|
+
FileList['*.node'].each do |src|
|
118
|
+
name = src.pathmap("%X")
|
119
|
+
node_desc = load_node_yaml(src)
|
120
|
+
|
121
|
+
if node_desc != nil
|
122
|
+
relname = node_desc['release']
|
123
|
+
relvers = node_desc['version']
|
124
|
+
target = "#{relname}/releases/#{relname}-#{relvers}.rel"
|
125
|
+
deps_target = "#{relname}:deps"
|
126
|
+
|
127
|
+
# Setup an empty deps target -- caller can override with their own definition
|
128
|
+
# to do something useful
|
129
|
+
desc "Build dependencies for #{relname} node"
|
130
|
+
task deps_target
|
131
|
+
|
132
|
+
# Construct task with base node name -- depends on the .rel file
|
133
|
+
desc "Builds #{relname} node"
|
134
|
+
task name => deps_target
|
135
|
+
task name => target
|
136
|
+
|
137
|
+
# .rel file is used for detecting if .node file changes and forcing a rebuild
|
138
|
+
file target => [src] do
|
139
|
+
build_node(src)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Add release target (creates a tarball)
|
143
|
+
desc "Package #{relname} into a tarball"
|
144
|
+
task "#{name}:package" => [name] do
|
145
|
+
mv(name, "#{relname}-#{relvers}")
|
146
|
+
sh "tar -cjf #{relname}-#{relvers}-#{RUBY_PLATFORM}.tar.bz2 #{relname}-#{relvers}"
|
147
|
+
rm_rf("#{relname}-#{relvers}")
|
148
|
+
end
|
149
|
+
|
150
|
+
# Add cleanup target
|
151
|
+
desc "Clean #{relname} node"
|
152
|
+
task "#{name}:clean" do
|
153
|
+
FileUtils.remove_dir "#{relname}", true
|
154
|
+
FileUtils.remove Dir.glob("#{relname}-#{relvers}.*")
|
155
|
+
end
|
156
|
+
|
157
|
+
# Register cleanup stuff with clobber
|
158
|
+
CLOBBER.include << "#{relname}" << "#{relname}-#{relvers}.*"
|
159
|
+
end
|
72
160
|
end
|
161
|
+
|
162
|
+
# task :build_app do
|
163
|
+
# cd "../apps" do
|
164
|
+
# sh "rake"
|
165
|
+
# end
|
166
|
+
# end
|
167
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
RUNNER_BASE_DIR=`pwd`
|
4
|
+
|
5
|
+
# Parse out release and erts info
|
6
|
+
START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
|
7
|
+
ERTS_VSN=${START_ERL% *}
|
8
|
+
APP_VSN=${START_ERL#* }
|
9
|
+
|
10
|
+
ROOTDIR=$RUNNER_BASE_DIR
|
11
|
+
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
|
12
|
+
EMU=beam
|
13
|
+
PROGNAME=`echo $0 | sed 's/.*\///'`
|
14
|
+
CMD="$BINDIR/erlexec"
|
15
|
+
export EMU
|
16
|
+
export ROOTDIR
|
17
|
+
export BINDIR
|
18
|
+
export PROGNAME
|
19
|
+
|
20
|
+
exec $CMD -boot $ROOTDIR/erts-$ERTS_VSN/bin/erl ${1+"$@"}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env escript
|
2
|
+
%% -*- erlang -*-
|
3
|
+
|
4
|
+
main([RelName, RelVer, CodePath | AppNames]) ->
|
5
|
+
%% Convert the app names into atom
|
6
|
+
Apps = [list_to_atom(A) || A <- AppNames],
|
7
|
+
case Apps of
|
8
|
+
[] ->
|
9
|
+
io:format("No applications provided for release!\n"),
|
10
|
+
halt(1);
|
11
|
+
_ ->
|
12
|
+
ok
|
13
|
+
end,
|
14
|
+
|
15
|
+
%% Setup code path so we can see all the apps
|
16
|
+
update_path(CodePath),
|
17
|
+
|
18
|
+
%% Identify dependencies across all apps
|
19
|
+
Deps = get_all_deps(Apps),
|
20
|
+
|
21
|
+
%% Get version info for all deps
|
22
|
+
DepVers = get_all_vers(Deps),
|
23
|
+
|
24
|
+
%% Validate modules for each dep
|
25
|
+
check_modules(Deps),
|
26
|
+
|
27
|
+
%% Determine the erts version
|
28
|
+
ErtsVsn = erlang:system_info(version),
|
29
|
+
|
30
|
+
%% Generate the tuple for the release file
|
31
|
+
RelTuple = {release, {RelName, RelVer}, {erts, ErtsVsn}, DepVers},
|
32
|
+
|
33
|
+
%% Write the .rel file
|
34
|
+
RelId = rel_id(RelName, RelVer),
|
35
|
+
{ok, F} = file:open([RelId, ".rel"], [write]),
|
36
|
+
ok = io:fwrite(F, "~p.\n", [RelTuple]),
|
37
|
+
|
38
|
+
%% Generate the boot script
|
39
|
+
ok = systools:make_script(RelId, [no_module_tests]),
|
40
|
+
|
41
|
+
%% Construct the tar
|
42
|
+
ok = systools:make_tar(RelId, [no_module_tests, {dirs, [mibs, src, include]}, {erts, code:root_dir()}]).
|
43
|
+
|
44
|
+
|
45
|
+
update_path(CodePath) ->
|
46
|
+
case re:split(CodePath, ":", [{return, list}]) of
|
47
|
+
[[]] ->
|
48
|
+
ok;
|
49
|
+
Components ->
|
50
|
+
[ok = code:add_pathsa(filelib:wildcard(C)) || C <- Components]
|
51
|
+
end.
|
52
|
+
|
53
|
+
get_all_vers(Apps) ->
|
54
|
+
[ {A, get_app_key(A, vsn)} || A <- Apps ].
|
55
|
+
|
56
|
+
get_app_key(App, Key) ->
|
57
|
+
application:load(App),
|
58
|
+
case application:get_key(App, Key) of
|
59
|
+
{ok, Value} ->
|
60
|
+
Value;
|
61
|
+
_Error ->
|
62
|
+
io:format("Error getting key ~p for app: ~p\n", [Key, App]),
|
63
|
+
halt(1)
|
64
|
+
end.
|
65
|
+
|
66
|
+
get_all_deps(Apps) ->
|
67
|
+
Deps = get_deps(Apps, []),
|
68
|
+
|
69
|
+
%% Consolidate the list so that there are no dups
|
70
|
+
sets:to_list(sets:from_list(lists:flatten([Apps | Deps]))).
|
71
|
+
|
72
|
+
|
73
|
+
get_deps([], Acc) ->
|
74
|
+
Acc;
|
75
|
+
get_deps([App | Rest], Acc) ->
|
76
|
+
Apps = get_app_key(App, applications),
|
77
|
+
Deps = get_deps(Apps, Apps),
|
78
|
+
get_deps(Rest, [Deps | Acc]).
|
79
|
+
|
80
|
+
|
81
|
+
format(Str, Args) ->
|
82
|
+
lists:flatten(io_lib:format(Str, Args)).
|
83
|
+
|
84
|
+
|
85
|
+
rel_id(RelName, RelVer) ->
|
86
|
+
format("~s-~s", [RelName, RelVer]).
|
87
|
+
|
88
|
+
|
89
|
+
check_modules([]) ->
|
90
|
+
ok;
|
91
|
+
check_modules([App | Rest]) ->
|
92
|
+
ModuleSet = ordsets:from_list(get_app_key(App, modules)),
|
93
|
+
Beams = filelib:wildcard(filename:join(code:lib_dir(App, ebin), "*.beam")),
|
94
|
+
BeamSet = ordsets:from_list([list_to_atom(filename:basename(F, ".beam")) || F <- Beams]),
|
95
|
+
case ordsets:subtract(BeamSet, ModuleSet) of
|
96
|
+
[] ->
|
97
|
+
ok;
|
98
|
+
MissingModules ->
|
99
|
+
[io:format("WARNING: ~s.app does not list ~s.beam as a module\n", [App, M]) || M <- MissingModules]
|
100
|
+
end,
|
101
|
+
|
102
|
+
case ordsets:subtract(ModuleSet, BeamSet) of
|
103
|
+
[] ->
|
104
|
+
ok;
|
105
|
+
MissingBeams ->
|
106
|
+
[io:format("WARNING: ~s.app does not have a ~s.beam\n", [App, B]) || B <- MissingBeams]
|
107
|
+
end,
|
108
|
+
check_modules(Rest).
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env escript
|
2
|
+
%% -*- erlang -*-
|
3
|
+
%% -------------------------------------------------------------------
|
4
|
+
%%
|
5
|
+
%% nodetool: Helper Script for interacting with live nodes
|
6
|
+
%% Copyright (c) 2008 The Hive. All rights reserved.
|
7
|
+
%%
|
8
|
+
%% -------------------------------------------------------------------
|
9
|
+
|
10
|
+
main(Args) ->
|
11
|
+
%% Extract the args
|
12
|
+
{RestArgs, TargetNode} = process_args(Args, [], undefined),
|
13
|
+
|
14
|
+
%% See if the node is currently running -- if it's not, we'll bail
|
15
|
+
case net_adm:ping(TargetNode) of
|
16
|
+
pong ->
|
17
|
+
ok;
|
18
|
+
pang ->
|
19
|
+
io:format("Node ~p not responding to pings.\n", [TargetNode]),
|
20
|
+
halt(1)
|
21
|
+
end,
|
22
|
+
|
23
|
+
case RestArgs of
|
24
|
+
["ping"] ->
|
25
|
+
%% If we got this far, the node already responsed to a ping, so just dump
|
26
|
+
%% a "pong"
|
27
|
+
io:format("pong\n");
|
28
|
+
["stop"] ->
|
29
|
+
io:format("~p\n", [rpc:call(TargetNode, init, stop, [], 60000)]);
|
30
|
+
["restart"] ->
|
31
|
+
io:format("~p\n", [rpc:call(TargetNode, init, restart, [], 60000)]);
|
32
|
+
["reboot"] ->
|
33
|
+
io:format("~p\n", [rpc:call(TargetNode, init, reboot, [], 60000)]);
|
34
|
+
["rpc", Module, Function | RpcArgs] ->
|
35
|
+
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), [RpcArgs], 60000) of
|
36
|
+
{badrpc, Reason} ->
|
37
|
+
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]);
|
38
|
+
_ ->
|
39
|
+
ok
|
40
|
+
end;
|
41
|
+
Other ->
|
42
|
+
io:format("Other: ~p\n", [Other]),
|
43
|
+
io:format("Usage: nodetool {ping|stop|restart|reboot}\n")
|
44
|
+
end,
|
45
|
+
net_kernel:stop().
|
46
|
+
|
47
|
+
process_args([], Acc, TargetNode) ->
|
48
|
+
{lists:reverse(Acc), TargetNode};
|
49
|
+
process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) ->
|
50
|
+
erlang:set_cookie(node(), list_to_atom(Cookie)),
|
51
|
+
process_args(Rest, Acc, TargetNode);
|
52
|
+
process_args(["-name", TargetName | Rest], Acc, _) ->
|
53
|
+
ThisNode = append_node_suffix(TargetName, "_maint_"),
|
54
|
+
{ok, _} = net_kernel:start([ThisNode, longnames]),
|
55
|
+
process_args(Rest, Acc, nodename(TargetName));
|
56
|
+
process_args(["-sname", TargetName | Rest], Acc, _) ->
|
57
|
+
ThisNode = append_node_suffix(TargetName, "_maint_"),
|
58
|
+
{ok, _} = net_kernel:start([ThisNode, shortnames]),
|
59
|
+
process_args(Rest, Acc, nodename(TargetName));
|
60
|
+
process_args([Arg | Rest], Acc, Opts) ->
|
61
|
+
process_args(Rest, [Arg | Acc], Opts).
|
62
|
+
|
63
|
+
|
64
|
+
nodename(Name) ->
|
65
|
+
case string:tokens(Name, "@") of
|
66
|
+
[_Node, _Host] ->
|
67
|
+
list_to_atom(Name);
|
68
|
+
[Node] ->
|
69
|
+
[_, Host] = string:tokens(atom_to_list(node()), "@"),
|
70
|
+
list_to_atom(lists:concat([Node, "@", Host]))
|
71
|
+
end.
|
72
|
+
|
73
|
+
append_node_suffix(Name, Suffix) ->
|
74
|
+
case string:tokens(Name, "@") of
|
75
|
+
[Node, Host] ->
|
76
|
+
list_to_atom(lists:concat([Node, Suffix, os:getpid(), "@", Host]));
|
77
|
+
[Node] ->
|
78
|
+
list_to_atom(lists:concat([Node, Suffix, os:getpid()]))
|
79
|
+
end.
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
RUNNER_BASE_DIR=.
|
4
|
+
|
5
|
+
# If the base directory is specified as current directory, resolve to
|
6
|
+
# fully qualified path
|
7
|
+
if [ "$RUNNER_BASE_DIR" == "." ]; then
|
8
|
+
RUNNER_BASE_DIR=`pwd`
|
9
|
+
fi
|
10
|
+
|
11
|
+
RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc
|
12
|
+
RUNNER_LOG_DIR=$RUNNER_BASE_DIR/log
|
13
|
+
RUNNER_USER=
|
14
|
+
|
15
|
+
# Make sure this script is running as the appropriate user
|
16
|
+
if [ ! -z "$RUNNER_USER" ] && [ `whoami` != "$RUNNER_USER" ]; then
|
17
|
+
exec sudo -u $RUNNER_USER -i $0 $@
|
18
|
+
fi
|
19
|
+
|
20
|
+
# Make sure log directory exists
|
21
|
+
mkdir -p $RUNNER_LOG_DIR
|
22
|
+
|
23
|
+
# Extract the target node name from node.args
|
24
|
+
NAME_ARG=`grep -e '-[s]*name' $RUNNER_ETC_DIR/node.args`
|
25
|
+
if [ -z "$NAME_ARG" ]; then
|
26
|
+
echo "node.args needs to have either -name or -sname parameter."
|
27
|
+
exit 1
|
28
|
+
fi
|
29
|
+
|
30
|
+
# Extract the target cookie
|
31
|
+
COOKIE_ARG=`grep -e '-setcookie' $RUNNER_ETC_DIR/node.args`
|
32
|
+
if [ -z "$COOKIE_ARG" ]; then
|
33
|
+
echo "node.args needs to have a -setcookie parameter."
|
34
|
+
exit 1
|
35
|
+
fi
|
36
|
+
|
37
|
+
# Identify the script name
|
38
|
+
SCRIPT=`basename $0`
|
39
|
+
|
40
|
+
# Parse out release and erts info
|
41
|
+
START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
|
42
|
+
ERTS_VSN=${START_ERL% *}
|
43
|
+
APP_VSN=${START_ERL#* }
|
44
|
+
|
45
|
+
# Add ERTS bin dir to our path
|
46
|
+
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
|
47
|
+
|
48
|
+
# Setup command to control the node
|
49
|
+
NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
|
50
|
+
|
51
|
+
# Check the first argument for instructions
|
52
|
+
case "$1" in
|
53
|
+
start)
|
54
|
+
# Make sure there is not already a node running
|
55
|
+
RES=`$NODETOOL ping`
|
56
|
+
if [ "$RES" == "pong" ]; then
|
57
|
+
echo "Node is already running!"
|
58
|
+
exit 1
|
59
|
+
fi
|
60
|
+
export HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT start"
|
61
|
+
$ERTS_PATH/run_erl -daemon /tmp/ $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT console" 2>&1
|
62
|
+
;;
|
63
|
+
|
64
|
+
stop)
|
65
|
+
# Wait for the node to completely stop...
|
66
|
+
PID=`ps -ef|grep "$RUNNER_BASE_DIR/.*/[b]eam.smp|awk '{print $2}'"`
|
67
|
+
$NODETOOL stop
|
68
|
+
while `kill -0 $PID 2>/dev/null`;
|
69
|
+
do
|
70
|
+
sleep 1
|
71
|
+
done
|
72
|
+
;;
|
73
|
+
|
74
|
+
restart)
|
75
|
+
## Restart the VM without exiting the process
|
76
|
+
$NODETOOL restart
|
77
|
+
;;
|
78
|
+
|
79
|
+
reboot)
|
80
|
+
## Restart the VM completely (uses heart to restart it)
|
81
|
+
$NODETOOL reboot
|
82
|
+
;;
|
83
|
+
|
84
|
+
ping)
|
85
|
+
## See if the VM is alive
|
86
|
+
$NODETOOL ping
|
87
|
+
;;
|
88
|
+
|
89
|
+
attach)
|
90
|
+
# Make sure a node IS running
|
91
|
+
RES=`$NODETOOL ping`
|
92
|
+
if [ "$RES" != "pong" ]; then
|
93
|
+
echo "Node is not running!"
|
94
|
+
exit 1
|
95
|
+
fi
|
96
|
+
|
97
|
+
shift
|
98
|
+
$ERTS_PATH/to_erl $@
|
99
|
+
;;
|
100
|
+
|
101
|
+
console)
|
102
|
+
# Setup beam-required vars
|
103
|
+
ROOTDIR=$RUNNER_BASE_DIR
|
104
|
+
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
|
105
|
+
EMU=beam
|
106
|
+
PROGNAME=`echo $0 | sed 's/.*\///'`
|
107
|
+
CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/start -embedded -config $RUNNER_ETC_DIR/app.config -args_file $RUNNER_ETC_DIR/node.args"
|
108
|
+
export EMU
|
109
|
+
export ROOTDIR
|
110
|
+
export BINDIR
|
111
|
+
export PROGNAME
|
112
|
+
|
113
|
+
# Dump environment info for logging purposes
|
114
|
+
echo "Exec: $CMD"
|
115
|
+
echo "Root: $ROOTDIR"
|
116
|
+
|
117
|
+
# Log the startup
|
118
|
+
logger -t "$SCRIPT[$$]" "Starting up"
|
119
|
+
|
120
|
+
# Start the VM
|
121
|
+
exec $CMD
|
122
|
+
;;
|
123
|
+
|
124
|
+
*)
|
125
|
+
echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach}"
|
126
|
+
exit 1
|
127
|
+
;;
|
128
|
+
esac
|
129
|
+
|
130
|
+
exit 0
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
RUNNER_BASE_DIR=<%= runner_base_dir %>
|
4
|
+
|
5
|
+
# If the base directory is specified as current directory, resolve to
|
6
|
+
# fully qualified path
|
7
|
+
if [ "$RUNNER_BASE_DIR" == "." ]; then
|
8
|
+
RUNNER_BASE_DIR=`pwd`
|
9
|
+
fi
|
10
|
+
|
11
|
+
RUNNER_ETC_DIR=<%= runner_etc_dir %>
|
12
|
+
RUNNER_LOG_DIR=<%= runner_log_dir %>
|
13
|
+
RUNNER_USER=<%= runner_user %>
|
14
|
+
|
15
|
+
# Make sure this script is running as the appropriate user
|
16
|
+
if [ ! -z "$RUNNER_USER"] && [ `whoami` != "$RUNNER_USER" ]; then
|
17
|
+
exec sudo -u $RUNNER_USER -i $0 $@
|
18
|
+
fi
|
19
|
+
|
20
|
+
# Make sure log directory exists
|
21
|
+
mkdir -p $RUNNER_LOG_DIR
|
22
|
+
|
23
|
+
# Extract the target node name from node.args
|
24
|
+
NAME_ARG=`grep -e '-[s]*name' $RUNNER_ETC_DIR/node.args`
|
25
|
+
if [ -z "$NAME_ARG" ]; then
|
26
|
+
echo "node.args needs to have either -name or -sname parameter."
|
27
|
+
exit 1
|
28
|
+
fi
|
29
|
+
|
30
|
+
# Extract the target cookie
|
31
|
+
COOKIE_ARG=`grep -e '-setcookie' $RUNNER_ETC_DIR/node.args`
|
32
|
+
if [ -z "$COOKIE_ARG" ]; then
|
33
|
+
echo "node.args needs to have a -setcookie parameter."
|
34
|
+
exit 1
|
35
|
+
fi
|
36
|
+
|
37
|
+
# Identify the script name
|
38
|
+
SCRIPT=`basename $0`
|
39
|
+
|
40
|
+
# Parse out release and erts info
|
41
|
+
START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
|
42
|
+
ERTS_VSN=${START_ERL% *}
|
43
|
+
APP_VSN=${START_ERL#* }
|
44
|
+
|
45
|
+
# Add ERTS bin dir to our path
|
46
|
+
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
|
47
|
+
|
48
|
+
# Setup command to control the node
|
49
|
+
NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
|
50
|
+
|
51
|
+
# Check the first argument for instructions
|
52
|
+
case "$1" in
|
53
|
+
start)
|
54
|
+
# Make sure there is not already a node running
|
55
|
+
RES=`$NODETOOL ping`
|
56
|
+
if [ "$RES" == "pong" ]; then
|
57
|
+
echo "Node is already running!"
|
58
|
+
exit 1
|
59
|
+
fi
|
60
|
+
export HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT start"
|
61
|
+
$ERTS_PATH/run_erl -daemon /tmp/ $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT console" 2>&1
|
62
|
+
;;
|
63
|
+
|
64
|
+
stop)
|
65
|
+
# Wait for the node to completely stop...
|
66
|
+
PID=`ps -ef|grep "$RUNNER_BASE_DIR/.*/[b]eam.smp|awk '{print $2}'"`
|
67
|
+
$NODETOOL stop
|
68
|
+
while `kill -0 $PID 2>/dev/null`;
|
69
|
+
do
|
70
|
+
sleep 1
|
71
|
+
done
|
72
|
+
;;
|
73
|
+
|
74
|
+
restart)
|
75
|
+
## Restart the VM without exiting the process
|
76
|
+
$NODETOOL restart
|
77
|
+
;;
|
78
|
+
|
79
|
+
reboot)
|
80
|
+
## Restart the VM completely (uses heart to restart it)
|
81
|
+
$NODETOOL reboot
|
82
|
+
;;
|
83
|
+
|
84
|
+
ping)
|
85
|
+
## See if the VM is alive
|
86
|
+
$NODETOOL ping
|
87
|
+
;;
|
88
|
+
|
89
|
+
attach)
|
90
|
+
# Make sure a node IS running
|
91
|
+
RES=`$NODETOOL ping`
|
92
|
+
if [ "$RES" != "pong" ]; then
|
93
|
+
echo "Node is not running!"
|
94
|
+
exit 1
|
95
|
+
fi
|
96
|
+
|
97
|
+
shift
|
98
|
+
$ERTS_PATH/to_erl $@
|
99
|
+
;;
|
100
|
+
|
101
|
+
console)
|
102
|
+
# Setup beam-required vars
|
103
|
+
ROOTDIR=$RUNNER_BASE_DIR
|
104
|
+
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
|
105
|
+
EMU=beam
|
106
|
+
PROGNAME=`echo $0 | sed 's/.*\///'`
|
107
|
+
CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/start -embedded -config $RUNNER_ETC_DIR/app.config -args_file $RUNNER_ETC_DIR/node.args"
|
108
|
+
export EMU
|
109
|
+
export ROOTDIR
|
110
|
+
export BINDIR
|
111
|
+
export PROGNAME
|
112
|
+
|
113
|
+
# Dump environment info for logging purposes
|
114
|
+
echo "Exec: $CMD"
|
115
|
+
echo "Root: $ROOTDIR"
|
116
|
+
|
117
|
+
# Log the startup
|
118
|
+
logger -t "$SCRIPT[$$]" "Starting up"
|
119
|
+
|
120
|
+
# Start the VM
|
121
|
+
exec $CMD
|
122
|
+
;;
|
123
|
+
|
124
|
+
*)
|
125
|
+
echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach}"
|
126
|
+
exit 1
|
127
|
+
;;
|
128
|
+
esac
|
129
|
+
|
130
|
+
exit 0
|
data/lib/erlbox/utils.rb
CHANGED
@@ -58,6 +58,13 @@ def erl_run(script, args = "", extra_args = {})
|
|
58
58
|
`#{cmd} -eval '#{script}' -s erlang halt #{args} -noshell 2>&1`.strip
|
59
59
|
end
|
60
60
|
|
61
|
+
def erts_version()
|
62
|
+
script = <<-ERL
|
63
|
+
io:format("~s\n", [erlang:system_info(version)]).
|
64
|
+
ERL
|
65
|
+
erl_run(script)
|
66
|
+
end
|
67
|
+
|
61
68
|
def erl_where(lib, dir = 'include')
|
62
69
|
script = <<-ERL
|
63
70
|
io:format("~s\n", [filename:join(code:lib_dir(#{lib}), #{dir})])
|
@@ -65,6 +72,13 @@ def erl_where(lib, dir = 'include')
|
|
65
72
|
erl_run(script)
|
66
73
|
end
|
67
74
|
|
75
|
+
def erl_root()
|
76
|
+
script = <<-ERL
|
77
|
+
io:format("~s\n", [code:root_dir()])
|
78
|
+
ERL
|
79
|
+
erl_run(script)
|
80
|
+
end
|
81
|
+
|
68
82
|
def erl_app_version(app, extra_args = {})
|
69
83
|
script = <<-ERL
|
70
84
|
ok = application:load(#{app}),
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erlbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phillip Toland
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-27 00:00:00 -05:00
|
13
13
|
default_executable: erlbox
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -50,6 +50,11 @@ files:
|
|
50
50
|
- lib/erlbox/install.rb
|
51
51
|
- lib/erlbox/recurse.rb
|
52
52
|
- lib/erlbox/release.rb
|
53
|
+
- lib/erlbox/reltools/erl.sh
|
54
|
+
- lib/erlbox/reltools/make-rel
|
55
|
+
- lib/erlbox/reltools/nodetool
|
56
|
+
- lib/erlbox/reltools/runner
|
57
|
+
- lib/erlbox/reltools/runner.erb
|
53
58
|
- lib/erlbox/snmp.rb
|
54
59
|
- lib/erlbox/test.rb
|
55
60
|
- lib/erlbox/utils.rb
|
@@ -77,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
82
|
requirements: []
|
78
83
|
|
79
84
|
rubyforge_project: erlbox
|
80
|
-
rubygems_version: 1.3.
|
85
|
+
rubygems_version: 1.3.5
|
81
86
|
signing_key:
|
82
87
|
specification_version: 3
|
83
88
|
summary: Erlang Toolbox
|