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 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
- rack package
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
- job "manband.node"+options[:queue] do |args|
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 'mb-minion'
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
- Minion.enqueue("manband.master", { "operation" => "new", "msg" => msg.to_json })
85
+
86
+
87
+ Utils.publish('manband.master',{ "operation" => "new", "msg" => msg.to_json })
88
+
89
+ urlconfig = FlowConfig.config()
90
+
91
+
92
+
93
+
@@ -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
- job "manband.master" do |args|
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
- def savemessage(id,operation,msg)
186
- if @@options[:debug] == false
187
- return
188
- end
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
+
@@ -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
- Minion.enqueue("manband.master", { "operation" => OP_SKIP, "msg" => msg })
137
+ Utils.publish("manband.master", { "operation" => OP_SKIP, "msg" => msg })
140
138
  else
141
- Minion.enqueue("manband.master", { "operation" => OP_START, "msg" => msg })
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
- job.sendmessage(OP_START,jobmsg)
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
 
@@ -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 'mb-minion'
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
- system(cmd)
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
- Minion.enqueue(queue, { "operation" => operation, "msg" => msg })
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
@@ -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: 9
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
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-16 00:00:00 Z
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-minion
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: mb-aws-s3
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