erlbox 1.5.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|