manband 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +5 -1
- data/bin/jobhandler.rb +32 -3
- data/bin/manband.rb +1 -0
- data/bin/remoteband.rb +15 -3
- data/bin/workflowhandler.rb +45 -10
- data/lib/manband/bandmanager.rb +6 -5
- data/lib/manband/flowconfig.rb +16 -0
- data/lib/manband/job.rb +11 -5
- data/lib/manband/util.rb +50 -0
- metadata +8 -21
data/README
CHANGED
@@ -102,7 +102,11 @@ By default, bucket used is "manband". It can be specified in command-line.
|
|
102
102
|
## Gem creation
|
103
103
|
|
104
104
|
Execute:
|
105
|
-
|
105
|
+
rake package
|
106
106
|
|
107
107
|
Gem is created in pkg directory
|
108
108
|
Webband may use this gem, or use current files with same hierarchy
|
109
|
+
|
110
|
+
## History
|
111
|
+
|
112
|
+
0.6.0: Remove mb-minion dependency. New bunny gem is incompatible now, code has been rewriten to remove the dependency and use only amqp.
|
data/bin/jobhandler.rb
CHANGED
@@ -3,9 +3,7 @@ require 'yaml'
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'amqp'
|
5
5
|
require 'json'
|
6
|
-
require 'mb-minion'
|
7
6
|
|
8
|
-
include Minion
|
9
7
|
|
10
8
|
# The program manages job commands. Master nodes (workflow handler) sends
|
11
9
|
# messages to jobhandler instances. Each instance manages one and
|
@@ -93,7 +91,33 @@ end
|
|
93
91
|
|
94
92
|
log.info "Start handler "+handler
|
95
93
|
|
96
|
-
|
94
|
+
urlconfig = FlowConfig.config()
|
95
|
+
|
96
|
+
|
97
|
+
EventMachine.run do
|
98
|
+
connection = AMQP.connect(FlowConfig.config())
|
99
|
+
|
100
|
+
show_stopper = Proc.new do
|
101
|
+
$stdout.puts "Stopping..."
|
102
|
+
connection.close {
|
103
|
+
EventMachine.stop { exit }
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
Signal.trap 'INT', show_stopper
|
108
|
+
Signal.trap 'TERM', show_stopper
|
109
|
+
|
110
|
+
channel_exception_handler = Proc.new { |ch, channel_close| EventMachine.stop; raise "channel error: #{channel_close.reply_text}" }
|
111
|
+
|
112
|
+
channel = AMQP::Channel.new(connection)
|
113
|
+
#channel.on_error(&channel_exception_handler)
|
114
|
+
channel.prefetch(1)
|
115
|
+
|
116
|
+
exchange = channel.direct()
|
117
|
+
queue = channel.queue('manband.node'+options[:queue], :auto_delete => false, :durable => true)
|
118
|
+
queue.bind(exchange).subscribe(:ack => true) do |metadata, message|
|
119
|
+
puts "##DEBUG "+message
|
120
|
+
args = JSON.parse(message)
|
97
121
|
msg = JSON.parse(args["msg"])
|
98
122
|
if args["operation"] == OP_DESTROY
|
99
123
|
myworkflow = WorkFlow.get(msg["id"])
|
@@ -127,5 +151,10 @@ job "manband.node"+options[:queue] do |args|
|
|
127
151
|
end
|
128
152
|
end
|
129
153
|
end
|
154
|
+
|
155
|
+
|
156
|
+
channel.acknowledge(metadata.delivery_tag, false)
|
157
|
+
end
|
158
|
+
|
130
159
|
end
|
131
160
|
|
data/bin/manband.rb
CHANGED
@@ -13,6 +13,7 @@ require 'manband/workflow.rb'
|
|
13
13
|
require 'manband/flowconfig.rb'
|
14
14
|
require 'manband/job.rb'
|
15
15
|
require 'manband/bandmanager.rb'
|
16
|
+
require 'manband/util.rb'
|
16
17
|
|
17
18
|
# The program sends a workflow execution request to manband orchestrator.
|
18
19
|
# Author: Olivier Sallou <olivier.sallou@irisa.fr>
|
data/bin/remoteband.rb
CHANGED
@@ -3,9 +3,13 @@ require 'yaml'
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'amqp'
|
5
5
|
require 'json'
|
6
|
-
require '
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
$:.push File.expand_path("../lib")
|
9
|
+
|
10
|
+
require 'manband/flowconfig.rb'
|
11
|
+
require 'manband/util.rb'
|
7
12
|
|
8
|
-
include Minion
|
9
13
|
|
10
14
|
# The program sends a workflow execution request to manband orchestrator.
|
11
15
|
# This program does not need database credentials but does not get workflow id in return
|
@@ -78,4 +82,12 @@ msg["wfile"]=options[:workflow]
|
|
78
82
|
msg["var"]=options[:var]
|
79
83
|
msg["uid"]=options[:uid]
|
80
84
|
msg["bucket"]=options[:bucket]
|
81
|
-
|
85
|
+
|
86
|
+
|
87
|
+
Utils.publish('manband.master',{ "operation" => "new", "msg" => msg.to_json })
|
88
|
+
|
89
|
+
urlconfig = FlowConfig.config()
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
data/bin/workflowhandler.rb
CHANGED
@@ -3,9 +3,7 @@ require 'yaml'
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'amqp'
|
5
5
|
require 'json'
|
6
|
-
require 'mb-minion'
|
7
6
|
|
8
|
-
include Minion
|
9
7
|
|
10
8
|
# The program s the main orchestrator of the workflow.
|
11
9
|
# It starts with a workflow execution request and sends messages to job
|
@@ -26,6 +24,7 @@ end
|
|
26
24
|
|
27
25
|
$:.push File.expand_path("../lib")
|
28
26
|
|
27
|
+
require 'manband/flowconfig.rb'
|
29
28
|
require 'manband/workflow.rb'
|
30
29
|
require 'manband/job.rb'
|
31
30
|
require 'manband/bandmanager.rb'
|
@@ -33,8 +32,17 @@ require 'manband/bandmanager.rb'
|
|
33
32
|
log = Logger.new(STDOUT)
|
34
33
|
log.level = Logger::INFO
|
35
34
|
|
35
|
+
|
36
36
|
@@options = {}
|
37
37
|
|
38
|
+
def savemessage(id,operation,msg)
|
39
|
+
if @@options[:debug] == false
|
40
|
+
return
|
41
|
+
end
|
42
|
+
bmsg = BandMessage.new(:wid => id, :message => '{ "operation" => '+operation+', "msg" => '+msg+' }' )
|
43
|
+
bmsg.save
|
44
|
+
end
|
45
|
+
|
38
46
|
optparse = OptionParser.new do|opts|
|
39
47
|
|
40
48
|
# This displays the help screen, all programs are
|
@@ -75,8 +83,37 @@ if @@options[:conf]!=nil
|
|
75
83
|
FlowConfig.setworkdir(conf["workdir"])
|
76
84
|
end
|
77
85
|
|
78
|
-
|
86
|
+
|
87
|
+
EventMachine.run do
|
88
|
+
connection = AMQP.connect(FlowConfig.config())
|
89
|
+
|
90
|
+
show_stopper = Proc.new do
|
91
|
+
$stdout.puts "Stopping..."
|
92
|
+
connection.close {
|
93
|
+
EventMachine.stop { exit }
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
Signal.trap 'INT', show_stopper
|
98
|
+
Signal.trap 'TERM', show_stopper
|
99
|
+
|
100
|
+
channel_exception_handler = Proc.new { |ch, channel_close| EventMachine.stop; raise "channel error: #{channel_close.reply_text}" }
|
101
|
+
|
102
|
+
channel = AMQP::Channel.new(connection)
|
103
|
+
#channel.on_error(&channel_exception_handler)
|
104
|
+
channel.prefetch(1)
|
105
|
+
|
106
|
+
exchange = channel.direct()
|
107
|
+
queue = channel.queue('manband.master', :auto_delete => false, :durable => true)
|
108
|
+
queue.bind(exchange).subscribe(:ack => true) do |metadata, message|
|
109
|
+
|
110
|
+
begin
|
111
|
+
args = JSON.parse(message)
|
79
112
|
msg = JSON.parse(args["msg"])
|
113
|
+
rescue Exception => e
|
114
|
+
log.error("Could not parse message "+args["msg"])
|
115
|
+
channel.acknowledge(metadata.delivery_tag, false)
|
116
|
+
end
|
80
117
|
if args["operation"] == OP_NEW
|
81
118
|
BandManager.launch(msg["wfile"],msg["var"],msg["uid"],msg["bucket"])
|
82
119
|
end
|
@@ -180,12 +217,10 @@ job "manband.master" do |args|
|
|
180
217
|
curjob.resume
|
181
218
|
end
|
182
219
|
end
|
183
|
-
end
|
184
220
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
bmsg = BandMessage.new(:wid => id, :message => '{ "operation" => '+operation+', "msg" => '+msg+' }' )
|
190
|
-
bmsg.save
|
221
|
+
|
222
|
+
channel.acknowledge(metadata.delivery_tag, false)
|
223
|
+
end
|
224
|
+
|
191
225
|
end
|
226
|
+
|
data/lib/manband/bandmanager.rb
CHANGED
@@ -3,10 +3,8 @@ require 'yaml'
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'amqp'
|
5
5
|
require 'json'
|
6
|
-
require 'mb-minion'
|
7
6
|
require 'fileutils'
|
8
7
|
|
9
|
-
include Minion
|
10
8
|
|
11
9
|
require 'manband/workflow.rb'
|
12
10
|
require 'manband/flowconfig.rb'
|
@@ -136,9 +134,9 @@ class BandManager
|
|
136
134
|
# Request workflow management
|
137
135
|
msg = '{ "id" : "'+workflow.id.to_s+'", "root" : "'+rootjob.id.to_s+'"}'
|
138
136
|
if debug
|
139
|
-
|
137
|
+
Utils.publish("manband.master", { "operation" => OP_SKIP, "msg" => msg })
|
140
138
|
else
|
141
|
-
|
139
|
+
Utils.publish("manband.master", { "operation" => OP_START, "msg" => msg })
|
142
140
|
end
|
143
141
|
end
|
144
142
|
end
|
@@ -153,7 +151,10 @@ class BandManager
|
|
153
151
|
newworkflow.parse('root',rootjob.id)
|
154
152
|
jobmsg = '{ "id" : "'+newworkflow.id.to_s+'", "root" : "'+rootjob.id.to_s+'"}'
|
155
153
|
job = Job.new(:wid => newworkflow.id, :node => "fake", :command => "", :status => STATUS_FAKE, :instances => 0, :workdir => '')
|
156
|
-
|
154
|
+
|
155
|
+
Utils.publish('manband.master', { "operation" => OP_START, "msg" => jobmsg })
|
156
|
+
job.logMessage(OP_START,jobmsg)
|
157
|
+
|
157
158
|
return newworkflow.id
|
158
159
|
end
|
159
160
|
|
data/lib/manband/flowconfig.rb
CHANGED
@@ -113,6 +113,22 @@ class FlowConfig
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
+
def self.config
|
117
|
+
url ||= (ENV["AMQP_URL"] || "amqp://guest:guest@localhost/")
|
118
|
+
uri = URI.parse(url)
|
119
|
+
{
|
120
|
+
:vhost => uri.path,
|
121
|
+
:host => uri.host,
|
122
|
+
:user => uri.user,
|
123
|
+
:port => (uri.port || 5672),
|
124
|
+
:pass => uri.password,
|
125
|
+
:heartbeat => 0
|
126
|
+
}
|
127
|
+
rescue Object => e
|
128
|
+
raise("invalid AMQP_URL: #{uri.inspect} (#{e})")
|
129
|
+
end
|
130
|
+
|
131
|
+
|
116
132
|
|
117
133
|
end
|
118
134
|
|
data/lib/manband/job.rb
CHANGED
@@ -3,10 +3,9 @@ require 'dm-migrations'
|
|
3
3
|
require 'yaml'
|
4
4
|
require 'manband/workflow.rb'
|
5
5
|
require 'manband/flowconfig.rb'
|
6
|
-
require '
|
6
|
+
require 'manband/util.rb'
|
7
7
|
require 'logger'
|
8
8
|
|
9
|
-
include Minion
|
10
9
|
|
11
10
|
#DataMapper.setup(:default, 'sqlite:///home/osallou/Desktop/genflow/project.db')
|
12
11
|
DataMapper.setup(:default, ENV['MYSQL_URL'])
|
@@ -68,6 +67,7 @@ class Job
|
|
68
67
|
if instance>0
|
69
68
|
workdir = workdir + "/node" + instance.to_s
|
70
69
|
end
|
70
|
+
EventMachine.defer do
|
71
71
|
err = runcommand(workdir,instance)
|
72
72
|
if err == nil || err == false
|
73
73
|
# An error occured
|
@@ -82,6 +82,7 @@ class Job
|
|
82
82
|
jobmsg = '{ "workflow" : "'+@wid.to_s+'" , "node" : "'+@node+'", "id" : "'+@id.to_s+'", "handler" : "'+curhandler.to_s+'", "instance" : "'+instance.to_s+'" }'
|
83
83
|
sendmessage(OP_FINISH,jobmsg)
|
84
84
|
end
|
85
|
+
end # End EventMachine
|
85
86
|
end
|
86
87
|
|
87
88
|
# Skip treatment, just answer, for debug
|
@@ -117,7 +118,7 @@ class Job
|
|
117
118
|
cmd = "sudo -u "+wflow.uid+" '"+script+"'"
|
118
119
|
end
|
119
120
|
@@log.debug cmd
|
120
|
-
|
121
|
+
system(cmd)
|
121
122
|
end
|
122
123
|
|
123
124
|
# Change instance counter
|
@@ -292,12 +293,17 @@ class Job
|
|
292
293
|
queue = "manband.node"+jobqueue
|
293
294
|
end
|
294
295
|
if queue != nil
|
295
|
-
|
296
|
+
Utils.enqueue(queue, { "operation" => operation, "msg" => msg })
|
297
|
+
logMessage(operation,msg)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
# If debug, log the message in the database
|
302
|
+
def logMessage(operation,msg)
|
296
303
|
if @@debug == true
|
297
304
|
bmsg = BandMessage.new(:wid => @wid, :message => '{ "operation" => '+operation+', "msg" => '+msg+' }' )
|
298
305
|
bmsg.save
|
299
306
|
end
|
300
|
-
end
|
301
307
|
end
|
302
308
|
|
303
309
|
end
|
data/lib/manband/util.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'manband/flowconfig.rb'
|
2
|
+
require 'amqp'
|
3
|
+
|
4
|
+
# Utility classes
|
5
|
+
class Utils
|
6
|
+
|
7
|
+
|
8
|
+
@@connection = nil
|
9
|
+
@@channel = nil
|
10
|
+
@@exchange = nil
|
11
|
+
|
12
|
+
def self.setcontext()
|
13
|
+
if(@@connection==nil)
|
14
|
+
@@connection = AMQP.connect(FlowConfig.config())
|
15
|
+
@@channel = AMQP::Channel.new(@@connection)
|
16
|
+
@@exchange = @@channel.direct()
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Send a message in context
|
21
|
+
# args:
|
22
|
+
# dest name of destination queue
|
23
|
+
# msg message to send. Message is a hash with keys operation and msg.
|
24
|
+
def self.enqueue(dest,data= {})
|
25
|
+
Utils.setcontext()
|
26
|
+
msg = data.to_json
|
27
|
+
queue = @@channel.queue(dest, :auto_delete => false, :durable => true)
|
28
|
+
queue.bind(@@exchange)
|
29
|
+
@@exchange.publish(msg)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Creates a context and sends a message
|
33
|
+
# args:
|
34
|
+
# dest name of destination queue
|
35
|
+
# msg message to send. Message is a hash with keys operation and msg.
|
36
|
+
def self.publish(dest,data= {})
|
37
|
+
msg = data.to_json
|
38
|
+
EventMachine.run do
|
39
|
+
connection = AMQP.connect(FlowConfig.config())
|
40
|
+
channel = AMQP::Channel.new(connection)
|
41
|
+
exchange = channel.direct()
|
42
|
+
queue = channel.queue(dest, :auto_delete => false, :durable => true)
|
43
|
+
queue.bind(exchange)
|
44
|
+
exchange.publish(msg) do
|
45
|
+
connection.close { EventMachine.stop }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manband
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 6
|
9
|
+
- 0
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Olivier Sallou
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-07-
|
18
|
+
date: 2012-07-17 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: amqp
|
@@ -88,7 +88,7 @@ dependencies:
|
|
88
88
|
type: :runtime
|
89
89
|
version_requirements: *id005
|
90
90
|
- !ruby/object:Gem::Dependency
|
91
|
-
name: mb-
|
91
|
+
name: mb-aws-s3
|
92
92
|
prerelease: false
|
93
93
|
requirement: &id006 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
@@ -102,7 +102,7 @@ dependencies:
|
|
102
102
|
type: :runtime
|
103
103
|
version_requirements: *id006
|
104
104
|
- !ruby/object:Gem::Dependency
|
105
|
-
name:
|
105
|
+
name: uuid
|
106
106
|
prerelease: false
|
107
107
|
requirement: &id007 !ruby/object:Gem::Requirement
|
108
108
|
none: false
|
@@ -115,20 +115,6 @@ dependencies:
|
|
115
115
|
version: "0"
|
116
116
|
type: :runtime
|
117
117
|
version_requirements: *id007
|
118
|
-
- !ruby/object:Gem::Dependency
|
119
|
-
name: uuid
|
120
|
-
prerelease: false
|
121
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
122
|
-
none: false
|
123
|
-
requirements:
|
124
|
-
- - ">="
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
hash: 3
|
127
|
-
segments:
|
128
|
-
- 0
|
129
|
-
version: "0"
|
130
|
-
type: :runtime
|
131
|
-
version_requirements: *id008
|
132
118
|
description:
|
133
119
|
email: olivier.sallou@irisa.fr
|
134
120
|
executables: []
|
@@ -148,6 +134,7 @@ files:
|
|
148
134
|
- lib/manband/bandmanager.rb
|
149
135
|
- lib/manband/user.rb
|
150
136
|
- lib/manband/workflow.rb
|
137
|
+
- lib/manband/util.rb
|
151
138
|
- lib/manband/job.rb
|
152
139
|
- lib/manband/flowconfig.rb
|
153
140
|
- README
|