bud 0.0.8 → 0.1.0.pre1
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/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
|