bud 0.0.8 → 0.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -10
- data/bin/budplot +1 -2
- data/docs/cheat.md +2 -15
- data/examples/basics/paths.rb +7 -7
- data/lib/bud/aggs.rb +15 -19
- data/lib/bud/bud_meta.rb +165 -77
- data/lib/bud/bust/bust.rb +11 -4
- data/lib/bud/collections.rb +643 -280
- data/lib/bud/depanalysis.rb +50 -25
- data/lib/bud/executor/elements.rb +592 -0
- data/lib/bud/executor/group.rb +104 -0
- data/lib/bud/executor/join.rb +638 -0
- data/lib/bud/graphs.rb +12 -11
- data/lib/bud/joins.rb +2 -1
- data/lib/bud/meta_algebra.rb +5 -4
- data/lib/bud/metrics.rb +9 -3
- data/lib/bud/monkeypatch.rb +131 -23
- data/lib/bud/rebl.rb +41 -28
- data/lib/bud/rewrite.rb +112 -440
- data/lib/bud/server.rb +3 -2
- data/lib/bud/source.rb +109 -0
- data/lib/bud/state.rb +16 -9
- data/lib/bud/storage/dbm.rb +62 -16
- data/lib/bud/storage/zookeeper.rb +2 -2
- data/lib/bud/viz.rb +8 -4
- data/lib/bud/viz_util.rb +10 -9
- data/lib/bud.rb +413 -199
- metadata +40 -55
- data/examples/deploy/tokenring-ec2.rb +0 -26
- data/examples/deploy/tokenring-fork.rb +0 -15
- data/examples/deploy/tokenring-thread.rb +0 -15
- data/examples/deploy/tokenring.rb +0 -47
- data/lib/bud/deploy/deployer.rb +0 -67
- data/lib/bud/deploy/ec2deploy.rb +0 -199
- data/lib/bud/deploy/forkdeploy.rb +0 -90
- data/lib/bud/deploy/threaddeploy.rb +0 -38
- data/lib/bud/storage/tokyocabinet.rb +0 -190
- data/lib/bud/stratify.rb +0 -85
metadata
CHANGED
@@ -1,27 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 1923831995
|
5
|
+
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
-
|
10
|
-
|
10
|
+
- pre
|
11
|
+
- 1
|
12
|
+
version: 0.1.0.pre1
|
11
13
|
platform: ruby
|
12
14
|
authors:
|
13
15
|
- Peter Alvaro
|
14
16
|
- Neil Conway
|
15
17
|
- Joseph M. Hellerstein
|
16
18
|
- William R. Marczak
|
19
|
+
- Sriram Srinivasan
|
17
20
|
autorequire:
|
18
21
|
bindir: bin
|
19
22
|
cert_chain: []
|
20
23
|
|
21
|
-
date:
|
24
|
+
date: 2012-03-14 00:00:00 Z
|
22
25
|
dependencies:
|
23
26
|
- !ruby/object:Gem::Dependency
|
24
|
-
name:
|
27
|
+
name: eventmachine
|
25
28
|
prerelease: false
|
26
29
|
requirement: &id001 !ruby/object:Gem::Requirement
|
27
30
|
none: false
|
@@ -35,7 +38,7 @@ dependencies:
|
|
35
38
|
type: :runtime
|
36
39
|
version_requirements: *id001
|
37
40
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
41
|
+
name: fastercsv
|
39
42
|
prerelease: false
|
40
43
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
44
|
none: false
|
@@ -49,7 +52,7 @@ dependencies:
|
|
49
52
|
type: :runtime
|
50
53
|
version_requirements: *id002
|
51
54
|
- !ruby/object:Gem::Dependency
|
52
|
-
name:
|
55
|
+
name: gchart
|
53
56
|
prerelease: false
|
54
57
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
58
|
none: false
|
@@ -63,7 +66,7 @@ dependencies:
|
|
63
66
|
type: :runtime
|
64
67
|
version_requirements: *id003
|
65
68
|
- !ruby/object:Gem::Dependency
|
66
|
-
name:
|
69
|
+
name: getopt
|
67
70
|
prerelease: false
|
68
71
|
requirement: &id004 !ruby/object:Gem::Requirement
|
69
72
|
none: false
|
@@ -77,7 +80,7 @@ dependencies:
|
|
77
80
|
type: :runtime
|
78
81
|
version_requirements: *id004
|
79
82
|
- !ruby/object:Gem::Dependency
|
80
|
-
name:
|
83
|
+
name: i18n
|
81
84
|
prerelease: false
|
82
85
|
requirement: &id005 !ruby/object:Gem::Requirement
|
83
86
|
none: false
|
@@ -91,7 +94,7 @@ dependencies:
|
|
91
94
|
type: :runtime
|
92
95
|
version_requirements: *id005
|
93
96
|
- !ruby/object:Gem::Dependency
|
94
|
-
name:
|
97
|
+
name: json
|
95
98
|
prerelease: false
|
96
99
|
requirement: &id006 !ruby/object:Gem::Requirement
|
97
100
|
none: false
|
@@ -105,7 +108,7 @@ dependencies:
|
|
105
108
|
type: :runtime
|
106
109
|
version_requirements: *id006
|
107
110
|
- !ruby/object:Gem::Dependency
|
108
|
-
name:
|
111
|
+
name: minitest
|
109
112
|
prerelease: false
|
110
113
|
requirement: &id007 !ruby/object:Gem::Requirement
|
111
114
|
none: false
|
@@ -147,7 +150,7 @@ dependencies:
|
|
147
150
|
type: :runtime
|
148
151
|
version_requirements: *id009
|
149
152
|
- !ruby/object:Gem::Dependency
|
150
|
-
name:
|
153
|
+
name: ruby-graphviz
|
151
154
|
prerelease: false
|
152
155
|
requirement: &id010 !ruby/object:Gem::Requirement
|
153
156
|
none: false
|
@@ -160,24 +163,10 @@ dependencies:
|
|
160
163
|
version: "0"
|
161
164
|
type: :runtime
|
162
165
|
version_requirements: *id010
|
163
|
-
- !ruby/object:Gem::Dependency
|
164
|
-
name: ruby-graphviz
|
165
|
-
prerelease: false
|
166
|
-
requirement: &id011 !ruby/object:Gem::Requirement
|
167
|
-
none: false
|
168
|
-
requirements:
|
169
|
-
- - ">="
|
170
|
-
- !ruby/object:Gem::Version
|
171
|
-
hash: 3
|
172
|
-
segments:
|
173
|
-
- 0
|
174
|
-
version: "0"
|
175
|
-
type: :runtime
|
176
|
-
version_requirements: *id011
|
177
166
|
- !ruby/object:Gem::Dependency
|
178
167
|
name: ruby2ruby
|
179
168
|
prerelease: false
|
180
|
-
requirement: &
|
169
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
181
170
|
none: false
|
182
171
|
requirements:
|
183
172
|
- - <
|
@@ -189,11 +178,11 @@ dependencies:
|
|
189
178
|
- 1
|
190
179
|
version: 1.3.1
|
191
180
|
type: :runtime
|
192
|
-
version_requirements: *
|
181
|
+
version_requirements: *id011
|
193
182
|
- !ruby/object:Gem::Dependency
|
194
|
-
name:
|
183
|
+
name: ruby_parser
|
195
184
|
prerelease: false
|
196
|
-
requirement: &
|
185
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
197
186
|
none: false
|
198
187
|
requirements:
|
199
188
|
- - ">="
|
@@ -203,11 +192,11 @@ dependencies:
|
|
203
192
|
- 0
|
204
193
|
version: "0"
|
205
194
|
type: :runtime
|
206
|
-
version_requirements: *
|
195
|
+
version_requirements: *id012
|
207
196
|
- !ruby/object:Gem::Dependency
|
208
|
-
name:
|
197
|
+
name: superators19
|
209
198
|
prerelease: false
|
210
|
-
requirement: &
|
199
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
211
200
|
none: false
|
212
201
|
requirements:
|
213
202
|
- - ">="
|
@@ -217,11 +206,11 @@ dependencies:
|
|
217
206
|
- 0
|
218
207
|
version: "0"
|
219
208
|
type: :runtime
|
220
|
-
version_requirements: *
|
209
|
+
version_requirements: *id013
|
221
210
|
- !ruby/object:Gem::Dependency
|
222
211
|
name: syntax
|
223
212
|
prerelease: false
|
224
|
-
requirement: &
|
213
|
+
requirement: &id014 !ruby/object:Gem::Requirement
|
225
214
|
none: false
|
226
215
|
requirements:
|
227
216
|
- - ">="
|
@@ -231,11 +220,11 @@ dependencies:
|
|
231
220
|
- 0
|
232
221
|
version: "0"
|
233
222
|
type: :runtime
|
234
|
-
version_requirements: *
|
223
|
+
version_requirements: *id014
|
235
224
|
- !ruby/object:Gem::Dependency
|
236
225
|
name: uuid
|
237
226
|
prerelease: false
|
238
|
-
requirement: &
|
227
|
+
requirement: &id015 !ruby/object:Gem::Requirement
|
239
228
|
none: false
|
240
229
|
requirements:
|
241
230
|
- - ">="
|
@@ -245,7 +234,7 @@ dependencies:
|
|
245
234
|
- 0
|
246
235
|
version: "0"
|
247
236
|
type: :runtime
|
248
|
-
version_requirements: *
|
237
|
+
version_requirements: *id015
|
249
238
|
description: A prototype of the Bloom distributed programming language, as a Ruby DSL.
|
250
239
|
email:
|
251
240
|
- bloomdevs@gmail.com
|
@@ -267,11 +256,10 @@ files:
|
|
267
256
|
- lib/bud/collections.rb
|
268
257
|
- lib/bud/depanalysis.rb
|
269
258
|
- lib/bud/deploy/countatomicdelivery.rb
|
270
|
-
- lib/bud/deploy/deployer.rb
|
271
|
-
- lib/bud/deploy/ec2deploy.rb
|
272
|
-
- lib/bud/deploy/forkdeploy.rb
|
273
|
-
- lib/bud/deploy/threaddeploy.rb
|
274
259
|
- lib/bud/errors.rb
|
260
|
+
- lib/bud/executor/elements.rb
|
261
|
+
- lib/bud/executor/group.rb
|
262
|
+
- lib/bud/executor/join.rb
|
275
263
|
- lib/bud/graphs.rb
|
276
264
|
- lib/bud/joins.rb
|
277
265
|
- lib/bud/meta_algebra.rb
|
@@ -281,11 +269,10 @@ files:
|
|
281
269
|
- lib/bud/rewrite.rb
|
282
270
|
- lib/bud/rtrace.rb
|
283
271
|
- lib/bud/server.rb
|
272
|
+
- lib/bud/source.rb
|
284
273
|
- lib/bud/state.rb
|
285
274
|
- lib/bud/storage/dbm.rb
|
286
|
-
- lib/bud/storage/tokyocabinet.rb
|
287
275
|
- lib/bud/storage/zookeeper.rb
|
288
|
-
- lib/bud/stratify.rb
|
289
276
|
- lib/bud/viz.rb
|
290
277
|
- lib/bud/viz_util.rb
|
291
278
|
- lib/bud.rb
|
@@ -317,10 +304,6 @@ files:
|
|
317
304
|
- examples/chat/chat_protocol.rb
|
318
305
|
- examples/chat/chat_server.rb
|
319
306
|
- examples/chat/README.md
|
320
|
-
- examples/deploy/tokenring-ec2.rb
|
321
|
-
- examples/deploy/tokenring-fork.rb
|
322
|
-
- examples/deploy/tokenring-thread.rb
|
323
|
-
- examples/deploy/tokenring.rb
|
324
307
|
- examples/README
|
325
308
|
- README
|
326
309
|
- LICENSE
|
@@ -335,7 +318,7 @@ require_paths:
|
|
335
318
|
required_ruby_version: !ruby/object:Gem::Requirement
|
336
319
|
none: false
|
337
320
|
requirements:
|
338
|
-
- -
|
321
|
+
- - ">="
|
339
322
|
- !ruby/object:Gem::Version
|
340
323
|
hash: 57
|
341
324
|
segments:
|
@@ -346,16 +329,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
346
329
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
347
330
|
none: false
|
348
331
|
requirements:
|
349
|
-
- - "
|
332
|
+
- - ">"
|
350
333
|
- !ruby/object:Gem::Version
|
351
|
-
hash:
|
334
|
+
hash: 25
|
352
335
|
segments:
|
353
|
-
-
|
354
|
-
|
336
|
+
- 1
|
337
|
+
- 3
|
338
|
+
- 1
|
339
|
+
version: 1.3.1
|
355
340
|
requirements: []
|
356
341
|
|
357
342
|
rubyforge_project: bloom-lang
|
358
|
-
rubygems_version: 1.8.
|
343
|
+
rubygems_version: 1.8.17
|
359
344
|
signing_key:
|
360
345
|
specification_version: 3
|
361
346
|
summary: A prototype Bloom DSL for distributed programming.
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bud'
|
3
|
-
require 'bud/deploy/ec2deploy'
|
4
|
-
require 'tokenring'
|
5
|
-
|
6
|
-
class RingEC2
|
7
|
-
include Bud
|
8
|
-
include TokenRing
|
9
|
-
include EC2Deploy
|
10
|
-
|
11
|
-
deploystrap do
|
12
|
-
raise "keys.rb must exist in the current directory" unless File.exists? "keys.rb"
|
13
|
-
eval(IO.read('keys.rb'), binding)
|
14
|
-
node_count << [10]
|
15
|
-
ruby_command << ["ruby tokenring-ec2.rb"]
|
16
|
-
init_dir << ["."]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
ip, port = ARGV[0].split(':')
|
21
|
-
ext_ip, ext_port = ARGV[1].split(':')
|
22
|
-
RingEC2.new(:ip => ip,
|
23
|
-
:port => port,
|
24
|
-
:ext_ip => ext_ip,
|
25
|
-
:ext_port => ext_port,
|
26
|
-
:deploy => ARGV[2]).run_fg
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bud'
|
3
|
-
|
4
|
-
module TokenRing
|
5
|
-
state do
|
6
|
-
table :next_node, [] => [:addr]
|
7
|
-
channel :next_node_chan, [:@loc] => [:next]
|
8
|
-
scratch :send_next_node, [:node, :next]
|
9
|
-
table :sent_next_node, [:addr]
|
10
|
-
channel :token, [:@loc]
|
11
|
-
table :token_persist, [:loc]
|
12
|
-
end
|
13
|
-
|
14
|
-
bloom :make_ring do
|
15
|
-
# Once a node and its successor have both been computed, send a message to
|
16
|
-
# the node with the address of its successor
|
17
|
-
send_next_node <= (node * node * node_ready).combos do |n1, n2, nr|
|
18
|
-
succ_id = (n1.uid + 1) % node_count[[]].num
|
19
|
-
if n2.uid == succ_id and not sent_next_node.has_key? [n1.uid]
|
20
|
-
[n1.addr, n2.addr]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
next_node_chan <~ send_next_node
|
24
|
-
sent_next_node <+ send_next_node {|n| [n.node]}
|
25
|
-
|
26
|
-
next_node <= next_node_chan {|n| [n.next]}
|
27
|
-
|
28
|
-
# The deployer sends an initial message to the node with ID 0
|
29
|
-
token <~ (node_ready * node).rights(:uid => :uid) do |n|
|
30
|
-
[n.addr] if (@options[:deploy] and n.uid == 0)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
bloom :pass_token do
|
35
|
-
# Persist the token for as long as necessary
|
36
|
-
token_persist <= token
|
37
|
-
token_persist <- (token_persist * next_node).lefts
|
38
|
-
# Pass on the token
|
39
|
-
token <~ (token_persist * next_node).rights do |nn|
|
40
|
-
[nn.addr]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
bloom :print_token do
|
45
|
-
stdio <~ token {["#{@node_id}: Got token! (@ #{ip_port})"]}
|
46
|
-
end
|
47
|
-
end
|
data/lib/bud/deploy/deployer.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bud'
|
3
|
-
require 'bud/deploy/countatomicdelivery'
|
4
|
-
|
5
|
-
class Module
|
6
|
-
def deploystrap(&block)
|
7
|
-
meth_name = "__deploystrap__#{Module.get_class_name(self)}".to_sym
|
8
|
-
define_method(meth_name, &block)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
module Deployer # :nodoc: all
|
13
|
-
include CountAtomicDelivery
|
14
|
-
|
15
|
-
state do
|
16
|
-
table :node, [:uid] => [:addr]
|
17
|
-
table :node_count, [] => [:num]
|
18
|
-
# At the deployer node, this collection will contain a fact for the first
|
19
|
-
# tick in which the given node is ready
|
20
|
-
scratch :node_ready, [:uid]
|
21
|
-
|
22
|
-
table :initial_data, [:uid, :pred, :data]
|
23
|
-
channel :dont_care, [:@loc]
|
24
|
-
table :dead, [:dead]
|
25
|
-
end
|
26
|
-
|
27
|
-
def depl_idempotent(r) (dead.include? r) ? false : dead.insert(r) end
|
28
|
-
|
29
|
-
def do_deploystrap
|
30
|
-
self.class.ancestors.each do |anc|
|
31
|
-
anc.instance_methods(false).each do |m|
|
32
|
-
if /^__deploystrap__/.match m
|
33
|
-
self.method(m.to_sym).call
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def initialize(opt={})
|
40
|
-
super
|
41
|
-
do_deploystrap if opt[:deploy]
|
42
|
-
end
|
43
|
-
|
44
|
-
# Distribute the EDB to each node.
|
45
|
-
#
|
46
|
-
# XXX: this may break coordination protocols that assume the EDB is present
|
47
|
-
# before any messages are received. In order to fix this, we would probably
|
48
|
-
# need to globally synchronize to ensure that "timestamp 0" gets "fully
|
49
|
-
# evaluated" before any messages can be sent.
|
50
|
-
bloom :distribute_data do
|
51
|
-
atomic_data_in <= (node_ready * node * initial_data).combos(node_ready.uid => node.uid, node.uid => initial_data.uid) do |nr, n, i|
|
52
|
-
[n.addr, [i.pred, i.data]]
|
53
|
-
end
|
54
|
-
|
55
|
-
# Add all tuples at once.
|
56
|
-
dont_care <~ atomic_data_out do |a|
|
57
|
-
a.tuple[1].map do |d|
|
58
|
-
eval a.tuple[0].to_s + " <+ [" + d.inspect + "]"
|
59
|
-
end
|
60
|
-
[ip_port]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
bloom :print_ready do
|
65
|
-
stdio <~ node_ready {|nr| ["Child node ready: #{nr.uid}"]}
|
66
|
-
end
|
67
|
-
end
|
data/lib/bud/deploy/ec2deploy.rb
DELETED
@@ -1,199 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'AWS'
|
3
|
-
require 'pp'
|
4
|
-
require 'net/ssh'
|
5
|
-
require 'net/scp'
|
6
|
-
require 'bud'
|
7
|
-
require 'bud/deploy/deployer'
|
8
|
-
|
9
|
-
# Logic to deploy Bloom programs on EC2
|
10
|
-
# TODO:
|
11
|
-
# * add support for deploy_child_opts
|
12
|
-
# * avoid blocking I/O calls
|
13
|
-
# * emit "node_ready" event when each node is ready
|
14
|
-
module EC2Deploy
|
15
|
-
include Deployer
|
16
|
-
|
17
|
-
state do
|
18
|
-
table :access_key_id, [] => [:key]
|
19
|
-
table :secret_access_key, [] => [:key]
|
20
|
-
table :image_id, [] => [:img]
|
21
|
-
table :key_name, [] => [:name]
|
22
|
-
table :ec2_key_location, [] => [:loc]
|
23
|
-
table :ec2_conn, [] => [:conn]
|
24
|
-
table :ec2_insts, [] => [:insts]
|
25
|
-
table :reservation_id, [] => [:rid]
|
26
|
-
periodic :spinup_timer, 6
|
27
|
-
scratch :the_reservation, [] => [:reservation]
|
28
|
-
scratch :the_reservation_next, [] => [:reservation]
|
29
|
-
scratch :node_up, [:node] => [:bool]
|
30
|
-
table :init_dir, [] => [:dir]
|
31
|
-
table :temp_node, [:uid, :node, :localip]
|
32
|
-
table :all_up, [:bool]
|
33
|
-
table :ruby_command, [] => [:cmd]
|
34
|
-
table :deploy_node, [:uid] => [:node]
|
35
|
-
channel :ready, [:@loc, :sender]
|
36
|
-
table :ready_tab, [:sender]
|
37
|
-
scratch :ready_count, [:num]
|
38
|
-
end
|
39
|
-
|
40
|
-
deploystrap do
|
41
|
-
# Write the IP & port to a file; we'll send this to each EC2 node.
|
42
|
-
File.open("deploy_ip_port", "w") do |f|
|
43
|
-
f.puts ip_port
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
bootstrap do
|
48
|
-
# The official BUD AMI.
|
49
|
-
image_id <= [["ami-f434c99d"]]
|
50
|
-
unless @options[:deploy]
|
51
|
-
# Send message to the deployer telling 'em we's up.
|
52
|
-
File.open("deploy_ip_port", "r") do |f|
|
53
|
-
ready <~ [[f.readline.rstrip, ip_port]]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
bloom :spinup do
|
59
|
-
ec2_conn <= (access_key_id * secret_access_key).pairs do
|
60
|
-
if depl_idempotent [:ec2_comm]
|
61
|
-
[AWS::EC2::Base.new(:access_key_id => access_key_id[[]].key,
|
62
|
-
:secret_access_key => secret_access_key[[]].key)]
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
ec2_insts <= (image_id * node_count * key_name * ec2_conn).combos do
|
67
|
-
if depl_idempotent [:ec2_insts]
|
68
|
-
print "Starting up EC2 instances"
|
69
|
-
$stdout.flush
|
70
|
-
# First, we create the security group.
|
71
|
-
begin
|
72
|
-
ec2_conn[[]].conn.create_security_group(:group_name => "bud", :group_description => "bud")
|
73
|
-
rescue AWS::InvalidGroupDuplicate
|
74
|
-
# Group already exists; ok, maybe we created it previously.
|
75
|
-
else
|
76
|
-
# Add SSH permission.
|
77
|
-
ec2_conn[[]].conn.authorize_security_group_ingress(:group_name => "bud",
|
78
|
-
:ip_protocol => "tcp",
|
79
|
-
:from_port => 22,
|
80
|
-
:to_port => 22,
|
81
|
-
:cidr_ip => "0.0.0.0/0")
|
82
|
-
# Add unlimited UDP permission from any node not in the security group.
|
83
|
-
# XXX: make this more restrictive?
|
84
|
-
ec2_conn[[]].conn.authorize_security_group_ingress(:group_name => "bud",
|
85
|
-
:ip_protocol => "udp",
|
86
|
-
:from_port => 0,
|
87
|
-
:to_port => 65535,
|
88
|
-
:cidr_ip => "0.0.0.0/0")
|
89
|
-
end
|
90
|
-
|
91
|
-
# Finally, start up the instances.
|
92
|
-
[ec2_conn[[]].conn.run_instances(:image_id => image_id[[]].img,
|
93
|
-
:min_count => node_count[[]].num,
|
94
|
-
:max_count => node_count[[]].num,
|
95
|
-
:key_name => key_name[[]].name,
|
96
|
-
:security_group => "bud")]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
the_reservation <= (spinup_timer * ec2_conn * ec2_insts).combos do |t,c,i|
|
101
|
-
if depl_idempotent [[:the_reservation, t.val]] and not all_up.include? [true]
|
102
|
-
to_ret = nil
|
103
|
-
begin
|
104
|
-
to_ret = [ec2_conn[[]].conn.describe_instances()["reservationSet"]["item"].find do |j|
|
105
|
-
j["reservationId"] == ec2_insts[[]].insts["reservationId"]
|
106
|
-
end]
|
107
|
-
rescue SocketError
|
108
|
-
print "E"
|
109
|
-
else
|
110
|
-
print "."
|
111
|
-
end
|
112
|
-
$stdout.flush
|
113
|
-
to_ret
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
# XXX: No upsert operator, so we have to do this.
|
118
|
-
the_reservation_next <+ the_reservation
|
119
|
-
|
120
|
-
node_up <= (((ec2_insts * the_reservation).pairs do
|
121
|
-
if not all_up.include? [true]
|
122
|
-
the_reservation[[]].reservation["instancesSet"]["item"].map do |i|
|
123
|
-
[i, i["instanceState"]["code"] == "16"]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end)[0] or [])
|
127
|
-
|
128
|
-
all_up <+ node_up do
|
129
|
-
if node_up.find {|n1| n1.bool == false} == nil and node_up.find {|n2| n2.bool == true} != nil
|
130
|
-
if depl_idempotent [:nodes_all_up]
|
131
|
-
puts "done"
|
132
|
-
$stdout.flush
|
133
|
-
[true]
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
# XXX: Fixed port 54321
|
139
|
-
temp_node <= (all_up * the_reservation_next).pairs do
|
140
|
-
break(((0..(the_reservation_next[[]].reservation["instancesSet"]["item"].size-1)).to_a.zip(the_reservation_next[[]].reservation["instancesSet"]["item"].map {|i| [i["ipAddress"], i["privateIpAddress"]]})).map {|n,ips| [n, ips[0] + ":54321", ips[1] + ":54321"]})
|
141
|
-
end
|
142
|
-
|
143
|
-
deploy_node <= (temp_node * init_dir * ruby_command).combos do |t, i, r|
|
144
|
-
if depl_idempotent [[:node_startup, t.node]]
|
145
|
-
ip = t.node.split(":")[0]
|
146
|
-
port = t.node.split(":")[1]
|
147
|
-
print "Deploying to #{ip} (#{t.uid}/#{node_count[[]].num-1})."
|
148
|
-
$stdout.flush
|
149
|
-
|
150
|
-
# Upload files and run commands.
|
151
|
-
ctr = 0
|
152
|
-
while ctr < 10
|
153
|
-
begin
|
154
|
-
Net::SSH.start(ip, 'ec2-user', :keys => [ec2_key_location[[]].loc],
|
155
|
-
:timeout => 5, :paranoid => false) do |session|
|
156
|
-
# Upload init_dir, and the IP and port of the deployer
|
157
|
-
session.scp.upload!("deploy_ip_port", "/home/ec2-user")
|
158
|
-
session.scp.upload!(init_dir[[]].dir, "/home/ec2-user",
|
159
|
-
:recursive => true)
|
160
|
-
# Update the Bud gem
|
161
|
-
channel = session.open_channel do |ch|
|
162
|
-
channel.request_pty do |_, success|
|
163
|
-
raise "couldn't open a PTY on #{t.node}" if !success
|
164
|
-
end
|
165
|
-
channel.exec("sudo gem update --no-ri --no-rdoc bud")
|
166
|
-
end
|
167
|
-
channel.wait
|
168
|
-
# Run the ruby_command
|
169
|
-
session.exec!('nohup ' + ruby_command[[]].cmd + ' ' + t.localip +
|
170
|
-
' ' + t.node + ' >metarecv.out 2>metarecv.err </dev/null &')
|
171
|
-
end
|
172
|
-
break true
|
173
|
-
rescue Exception
|
174
|
-
ctr += 1
|
175
|
-
print "."
|
176
|
-
$stdout.flush
|
177
|
-
sleep 10
|
178
|
-
next
|
179
|
-
end
|
180
|
-
end or raise "EC2 SSH failed after 10 retries"
|
181
|
-
|
182
|
-
puts "done"
|
183
|
-
[t.uid, t.node]
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
bloom :all_nodes do
|
189
|
-
stdio <~ ready {|_,s| ["Ready: #{s}"]}
|
190
|
-
# Persist ready messages
|
191
|
-
ready_tab <= ready {|_, s| [s]}
|
192
|
-
# Compute a count of ready messages
|
193
|
-
ready_count <= ready_tab.group(nil, count)
|
194
|
-
# Copy deploy_node into node when all nodes are up
|
195
|
-
node <= (ready_count * node_count).pairs(:num => :num) do
|
196
|
-
break deploy_node
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|