wakame 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/History.txt +4 -0
  2. data/LICENSE +202 -0
  3. data/Rakefile +11 -12
  4. data/VERSION +1 -1
  5. data/app_generators/wakame/templates/bin/wakame-agent +1 -1
  6. data/app_generators/wakame/templates/bin/wakame-master +1 -1
  7. data/app_generators/wakame/templates/config/cluster.rb +32 -24
  8. data/app_generators/wakame/templates/config/init.d/centos/wakame-agent +40 -0
  9. data/app_generators/wakame/templates/config/init.d/centos/wakame-master +40 -0
  10. data/app_generators/wakame/templates/config/init.d/wakame-master +1 -1
  11. data/lib/ext/eventmachine.rb +5 -5
  12. data/lib/wakame.rb +12 -0
  13. data/lib/wakame/action.rb +10 -11
  14. data/lib/wakame/actions/deploy_application.rb +61 -0
  15. data/lib/wakame/actions/deploy_config.rb +1 -3
  16. data/lib/wakame/actions/freeze_cluster.rb +15 -0
  17. data/lib/wakame/actions/launch_cluster.rb +1 -3
  18. data/lib/wakame/actions/launch_vm.rb +1 -1
  19. data/lib/wakame/actions/migrate_service.rb +4 -3
  20. data/lib/wakame/actions/notify_child_changed.rb +3 -6
  21. data/lib/wakame/actions/notify_parent_changed.rb +4 -7
  22. data/lib/wakame/actions/propagate_resource.rb +1 -3
  23. data/lib/wakame/actions/propagate_service.rb +1 -3
  24. data/lib/wakame/actions/register_agent.rb +43 -0
  25. data/lib/wakame/actions/reload_service.rb +2 -2
  26. data/lib/wakame/actions/shutdown_cluster.rb +4 -6
  27. data/lib/wakame/actions/shutdown_vm.rb +27 -6
  28. data/lib/wakame/actions/start_service.rb +40 -32
  29. data/lib/wakame/actions/stop_service.rb +8 -10
  30. data/lib/wakame/actions/unfreeze_cluster.rb +15 -0
  31. data/lib/wakame/actor.rb +2 -5
  32. data/lib/wakame/actor/deploy.rb +110 -0
  33. data/lib/wakame/actor/monitor.rb +14 -0
  34. data/lib/wakame/actor/s3fs.rb +45 -0
  35. data/lib/wakame/actor/service_monitor.rb +0 -17
  36. data/lib/wakame/actor/system.rb +5 -1
  37. data/lib/wakame/agent.rb +29 -179
  38. data/lib/wakame/agent_manager.rb +11 -0
  39. data/lib/wakame/agent_managers/actor_manager.rb +101 -0
  40. data/lib/wakame/agent_managers/monitor_manager.rb +48 -0
  41. data/lib/wakame/command.rb +4 -7
  42. data/lib/wakame/command/actor.rb +9 -12
  43. data/lib/wakame/command/agent_status.rb +2 -2
  44. data/lib/wakame/command/control_service.rb +66 -0
  45. data/lib/wakame/command/deploy_application.rb +18 -0
  46. data/lib/wakame/command/deploy_config.rb +16 -0
  47. data/lib/wakame/command/launch_cluster.rb +1 -1
  48. data/lib/wakame/command/launch_vm.rb +1 -1
  49. data/lib/wakame/command/propagate_resource.rb +1 -1
  50. data/lib/wakame/command/propagate_service.rb +5 -3
  51. data/lib/wakame/command/reload_service.rb +1 -1
  52. data/lib/wakame/command/shutdown_cluster.rb +1 -1
  53. data/lib/wakame/command/shutdown_vm.rb +37 -11
  54. data/lib/wakame/command/start_service.rb +1 -1
  55. data/lib/wakame/command/status.rb +6 -4
  56. data/lib/wakame/command/stop_service.rb +1 -1
  57. data/lib/wakame/configuration.rb +5 -0
  58. data/lib/wakame/event.rb +85 -33
  59. data/lib/wakame/event_dispatcher.rb +2 -2
  60. data/lib/wakame/initializer.rb +97 -31
  61. data/lib/wakame/master.rb +23 -346
  62. data/lib/wakame/master_manager.rb +11 -0
  63. data/lib/wakame/master_managers/action_manager.rb +321 -0
  64. data/lib/wakame/master_managers/agent_monitor.rb +166 -0
  65. data/lib/wakame/master_managers/cluster_manager.rb +176 -0
  66. data/lib/wakame/master_managers/command_queue.rb +133 -0
  67. data/lib/wakame/models/agent_pool.rb +113 -0
  68. data/lib/wakame/models/application_repository.rb +34 -0
  69. data/lib/wakame/models/object_store.rb +32 -0
  70. data/lib/wakame/models/service_cluster_pool.rb +36 -0
  71. data/lib/wakame/monitor.rb +3 -6
  72. data/lib/wakame/monitor/agent.rb +9 -6
  73. data/lib/wakame/monitor/service.rb +56 -29
  74. data/lib/wakame/runner/administrator_command.rb +210 -24
  75. data/lib/wakame/runner/agent.rb +2 -0
  76. data/lib/wakame/runner/master.rb +2 -1
  77. data/lib/wakame/service.rb +140 -130
  78. data/lib/wakame/status_db.rb +101 -121
  79. data/lib/wakame/util.rb +26 -15
  80. data/tests/setup_master.rb +1 -0
  81. data/tests/test_master.rb +0 -2
  82. data/tests/test_model_agent_pool.rb +21 -0
  83. data/tests/test_service.rb +14 -8
  84. data/tests/test_status_db.rb +2 -0
  85. data/tests/test_util.rb +12 -1
  86. data/wakame_generators/resource/templates/apache_app/apache_app.rb +20 -11
  87. data/wakame_generators/resource/templates/apache_app/conf/vh/aaa.test.conf +1 -1
  88. data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +7 -7
  89. data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +6 -4
  90. data/wakame_generators/resource/templates/apache_www/apache_www.rb +15 -13
  91. data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +17 -17
  92. data/wakame_generators/resource/templates/ec2_elb/ec2_elb.rb +22 -15
  93. data/wakame_generators/resource/templates/mongodb/conf/mongodb.conf +95 -0
  94. data/wakame_generators/resource/templates/mongodb/init.d/mongodb +244 -0
  95. data/wakame_generators/resource/templates/mongodb/mongodb.rb +64 -0
  96. data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +17 -21
  97. data/wakame_generators/resource/templates/nginx/conf/nginx.conf +4 -0
  98. data/wakame_generators/resource/templates/nginx/conf/vh/ec2_elb_common.conf +19 -0
  99. data/wakame_generators/resource/templates/nginx/init.d/nginx +6 -0
  100. data/wakame_generators/resource/templates/nginx/init.d/spawn-fcgi +46 -0
  101. data/wakame_generators/resource/templates/nginx/nginx.rb +15 -10
  102. data/wakame_generators/resource/templates/nginx_passenger/conf/nginx-passenger.conf +39 -0
  103. data/wakame_generators/resource/templates/nginx_passenger/conf/vh/ec2_elb_common.conf +10 -0
  104. data/wakame_generators/resource/templates/nginx_passenger/init.d/nginx-passenger +70 -0
  105. data/wakame_generators/resource/templates/nginx_passenger/nginx_passenger.rb +71 -0
  106. data/wakame_generators/resource/templates/s3fs/s3fs.rb +24 -0
  107. metadata +195 -74
  108. data/lib/wakame/action_manager.rb +0 -303
  109. data/lib/wakame/command/clone_service.rb +0 -12
  110. data/lib/wakame/command_queue.rb +0 -135
  111. data/lib/wakame/vm_manipulator.rb +0 -187
@@ -1,303 +0,0 @@
1
-
2
- require 'thread'
3
- require 'timeout'
4
-
5
- module Wakame
6
- class CancelActionError < StandardError; end
7
- class CancelBroadcast < StandardError; end
8
- class GlobalLockError < StandardError; end
9
-
10
- class ActionManager
11
- include Manager
12
- attr_reader :active_jobs, :lock_queue
13
-
14
- def master
15
- Wakame::Master.instance
16
- end
17
-
18
- def command_queue
19
- master.command_queue
20
- end
21
-
22
- def agent_monitor
23
- master.agent_monitor
24
- end
25
-
26
- def initialize()
27
- @active_jobs = {}
28
- @job_history = []
29
- @lock_queue = LockQueue.new
30
- end
31
-
32
- def init
33
- end
34
-
35
- def terminate
36
- end
37
-
38
- def cancel_action(job_id)
39
- job_context = @active_jobs[job_id]
40
- if job_context.nil?
41
- Wakame.log.warn("JOB ID #{job_id} was not running.")
42
- return
43
- end
44
-
45
- return if job_context[:complete_at]
46
-
47
- root_act = job_context[:root_action]
48
-
49
- walk_subactions = proc { |a|
50
- if a.status == :running && (a.target_thread && a.target_thread.alive?) && a.target_thread != Thread.current
51
- Wakame.log.debug "Raising CancelBroadcast exception: #{a.class} #{a.target_thread}(#{a.target_thread.status}), current=#{Thread.current}"
52
- # Broadcast the special exception to all
53
- a.target_thread.raise(CancelBroadcast, "It's broadcasted from #{a.class}")
54
- # IMPORTANT: Ensure the worker thread to handle the exception.
55
- #Thread.pass
56
- end
57
- a.subactions.each { |n|
58
- walk_subactions.call(n)
59
- }
60
- }
61
-
62
- begin
63
- Thread.critical = true
64
- walk_subactions.call(root_act)
65
- ensure
66
- Thread.critical = false
67
- # IMPORTANT: Ensure the worker thread to handle the exception.
68
- Thread.pass
69
- end
70
- end
71
-
72
- def trigger_action(action)
73
- raise ArguemntError unless action.is_a?(Action)
74
- context = create_job_context(action)
75
- action.action_manager = self
76
- action.job_id = context[:job_id]
77
-
78
- run_action(action)
79
- action.job_id
80
- end
81
-
82
-
83
- def run_action(action)
84
- raise ArguemntError unless action.is_a?(Action)
85
- job_context = @active_jobs[action.job_id]
86
- raise "The job session is killed.: job_id=#{action.job_id}" if job_context.nil?
87
-
88
- EM.next_tick {
89
-
90
- begin
91
-
92
- if job_context[:start_at].nil?
93
- job_context[:start_at] = Time.new
94
- ED.fire_event(Event::JobStart.new(action.job_id))
95
- end
96
-
97
- EM.defer proc {
98
- res = nil
99
- begin
100
- action.bind_thread(Thread.current)
101
- action.status = :running
102
- Wakame.log.debug("Start action : #{action.class.to_s} #{action.parent_action.nil? ? '' : ('sub-action of ' + action.parent_action.class.to_s)}")
103
- ED.fire_event(Event::ActionStart.new(action))
104
- begin
105
- action.run
106
- action.completion_status = :succeeded
107
- Wakame.log.debug("Complete action : #{action.class.to_s}")
108
- ED.fire_event(Event::ActionComplete.new(action))
109
- end
110
- rescue CancelBroadcast => e
111
- Wakame.log.info("Received cancel signal: #{e}")
112
- action.completion_status = :canceled
113
- begin
114
- action.on_canceled
115
- rescue => e
116
- Wakame.log.error(e)
117
- end
118
- ED.fire_event(Event::ActionFailed.new(action, e))
119
- res = e
120
- rescue => e
121
- Wakame.log.error("Failed action : #{action.class.to_s} due to #{e}")
122
- Wakame.log.error(e)
123
- action.completion_status = :failed
124
- begin
125
- action.on_failed
126
- rescue => e
127
- Wakame.log.error(e)
128
- end
129
- ED.fire_event(Event::ActionFailed.new(action, e))
130
- # Escalate the cancelation event to parents.
131
- unless action.parent_action.nil?
132
- action.parent_action.notify(e)
133
- end
134
- # Force to cancel the current job when the root action ignored the elevated exception.
135
- if action === job_context[:root_action]
136
- Wakame.log.warn("The escalated exception (#{e.class}) has reached to the root action (#{action.class}). Forcing to cancel the current job #{job_context[:job_id]}")
137
- cancel_action(job_context[:job_id]) #rescue Wakame.log.error($!)
138
- end
139
- res = e
140
- ensure
141
- action.status = :complete
142
- action.bind_thread(nil)
143
- end
144
-
145
- res
146
- }, proc { |res|
147
- unless @active_jobs.has_key?(job_context[:job_id])
148
- next
149
- end
150
-
151
- actary = []
152
- job_context[:root_action].walk_subactions {|a| actary << a }
153
- #Wakame.log.debug(actary.collect{|a| {a.class.to_s=>a.status}}.inspect)
154
-
155
- if res.is_a?(Exception)
156
- job_context[:exception]=res
157
- end
158
-
159
- if actary.all? { |act| act.status == :complete }
160
-
161
- if actary.all? { |act| act.completion_status == :succeeded }
162
- ED.fire_event(Event::JobComplete.new(action.job_id))
163
- else
164
- ED.fire_event(Event::JobFailed.new(action.job_id, res))
165
- end
166
-
167
- job_context[:complete_at]=Time.now
168
- @job_history << job_context
169
- @active_jobs.delete(job_context[:job_id])
170
- @lock_queue.quit(job_context[:job_id])
171
- end
172
- }
173
- rescue => e
174
- Wakame.log.error(e)
175
- end
176
- }
177
- end
178
-
179
- private
180
- def create_job_context(root_action)
181
- raise ArguemntError unless root_action.is_a?(Action)
182
- root_action.job_id = job_id = Wakame.gen_id
183
-
184
- @active_jobs[job_id] = {
185
- :job_id=>job_id,
186
- :create_at=>Time.now,
187
- :start_at=>nil,
188
- :complete_at=>nil,
189
- :root_action=>root_action,
190
- :notes=>{}
191
- }
192
- end
193
-
194
- end
195
-
196
- class LockQueue
197
- def initialize()
198
- @locks = {}
199
- @id2res = {}
200
-
201
- @queue_by_thread = {}
202
- @qbt_m = ::Mutex.new
203
- end
204
-
205
- def set(resource, id)
206
- # Ths Job ID already holds/reserves the lock regarding the resource.
207
- return if @id2res.has_key?(id) && @id2res[id].has_key?(resource.to_s)
208
-
209
- # Need to use EM.barrier while RuleEngine is using EventMachine's threads.
210
- #StatusDB.barrier {
211
- EM.barrier {
212
- @locks[resource.to_s] ||= []
213
- @id2res[id] ||= {}
214
-
215
- @id2res[id][resource.to_s]=1
216
- @locks[resource.to_s] << id
217
- }
218
- Wakame.log.debug("#{self.class}: set(#{resource.to_s}, #{id})" + "\n#{self.inspect}")
219
- end
220
-
221
- def reset()
222
- @locks.keys { |k|
223
- @locks[k].clear
224
- }
225
- @id2res.clear
226
- end
227
-
228
- def test(id)
229
- reslist = @id2res[id]
230
- return :pass if reslist.nil? || reslist.empty?
231
-
232
- #
233
- if reslist.keys.all? { |r| id == @locks[r.to_s][0] }
234
- return :runnable
235
- else
236
- return :wait
237
- end
238
- end
239
-
240
- def wait(id, tout=60*30)
241
- @qbt_m.synchronize { @queue_by_thread[Thread.current] = ::Queue.new }
242
-
243
- timeout(tout) {
244
- while test(id) == :wait
245
- Wakame.log.debug("#{self.class}: Job #{id} waits for locked resouces: #{@id2res[id].keys.join(', ')}")
246
- break if id == @queue_by_thread[Thread.current].deq
247
- end
248
- }
249
- ensure
250
- @qbt_m.synchronize { @queue_by_thread.delete(Thread.current) }
251
- end
252
-
253
- def quit(id)
254
- # Need to use EM.barrier while RuleEngine is using EventMachine's threads.
255
- #StatusDB.barrier {
256
- EM.barrier {
257
- case test(id)
258
- when :runnable, :wait
259
- @id2res[id].keys.each { |r| @locks[r.to_s].delete_if{ |i| i == id } }
260
- @locks.delete_if{ |k,v| v.nil? || v.empty? }
261
-
262
- @qbt_m.synchronize {
263
- @queue_by_thread.each {|t, q| q.enq(id) }
264
- }
265
- end
266
-
267
- @id2res.delete(id)
268
- }
269
- Wakame.log.debug("#{self.class}: quit(#{id})" + "\n#{self.inspect}")
270
- end
271
-
272
- def clear_resource(resource)
273
- end
274
-
275
- def inspect
276
- output = @locks.collect { |k, lst|
277
- [k, lst].flatten
278
- }
279
- return "" if output.empty?
280
-
281
- # Table display
282
- maxcolws = (0..(output.size)).zip(*output).collect { |i| i.shift; i.map!{|i| (i.nil? ? "" : i).length }.max }
283
- maxcol = maxcolws.size
284
- maxcolws.reverse.each { |i|
285
- break if i > 0
286
- maxcol -= 1
287
- }
288
-
289
- textrows = output.collect { |x|
290
- buf=""
291
- maxcol.times { |n|
292
- buf << "|" + (x[n] || "").ljust(maxcolws[n])
293
- }
294
- buf << "|"
295
- }
296
-
297
- "+" + (["-"] * (textrows[0].length - 2)).join('') + "+\n" + \
298
- textrows.join("\n") + \
299
- "\n+" + (["-"] * (textrows[0].length - 2)).join('')+ "+"
300
- end
301
- end
302
-
303
- end
@@ -1,12 +0,0 @@
1
-
2
- class Wakame::Command::CloneService
3
- include Wakame::Command
4
-
5
- attr_reader :prop_name
6
-
7
- def parser(args)
8
- raise CommandArgumentError, "Property name has to be given " if args.size < 1
9
- @prop_name = args.shift
10
- end
11
-
12
- end
@@ -1,135 +0,0 @@
1
-
2
- require 'uri'
3
- require 'thin'
4
- require 'thread'
5
- require 'json'
6
- #require 'openssl'
7
- #require 'base64'
8
-
9
- module Wakame
10
- class CommandQueue
11
- include Manager
12
-
13
- def initialize()
14
- @queue = Queue.new
15
- @result_queue = Queue.new
16
- @statistics = {
17
- :total_command_count => 0
18
- }
19
- end
20
-
21
- def init
22
- @command_thread = Thread.new {
23
- Wakame.log.info("#{self.class}: Started command thread: #{Thread.current}")
24
- while cmd = @queue.deq
25
- begin
26
- unless cmd.kind_of?(Wakame::Command)
27
- Wakame.log.warn("#{self.class}: Incompatible type of object has been sent to ProcessCommand thread. #{cmd.class}")
28
- next
29
- end
30
-
31
- res = nil
32
- StatusDB.barrier {
33
- Wakame.log.debug("#{self.class}: Being processed the command: #{cmd.class}")
34
- res = cmd.run
35
- res
36
- }
37
- rescue => e
38
- Wakame.log.error(e)
39
- res = e
40
- ensure
41
- @result_queue.enq(res)
42
- end
43
- end
44
- }
45
-
46
- cmdsv_uri = URI.parse(Wakame.config.http_command_server_uri)
47
-
48
- @thin_server = Thin::Server.new(cmdsv_uri.host, cmdsv_uri.port, Adapter.new(self))
49
- @thin_server.threaded = true
50
- @thin_server.start
51
- end
52
-
53
- def terminate
54
- @thin_server.stop
55
- @command_thread.kill
56
- end
57
-
58
- def send_cmd(cmd)
59
- begin
60
- @queue.enq(cmd)
61
-
62
- ED.fire_event(Event::CommandReceived.new(cmd))
63
-
64
- return @result_queue.deq()
65
- rescue => e
66
- Wakame.log.error("#{self.class}:")
67
- Wakame.log.error(e)
68
- end
69
- end
70
-
71
-
72
- class Adapter
73
-
74
- def initialize(command_queue)
75
- @command_queue = command_queue
76
- end
77
-
78
- def call(env)
79
- req = Rack::Request.new(env)
80
- begin
81
- unless req.get?().to_s == "true"
82
- raise "No Support Response"
83
- end
84
- query = req.query_string()
85
- params = req.params()
86
- if Wakame.config.enable_authentication == "true"
87
- auth = authentication(params, query)
88
- end
89
- cname = params["action"].split("_")
90
- begin
91
- cmd = eval("Command::#{(cname.collect{|c| c.capitalize}).join}").new
92
- cmd.options = params
93
- command = @command_queue.send_cmd(cmd)
94
-
95
- if command.is_a?(Exception)
96
- status = 500
97
- body = json_encode(status, command.message)
98
- else
99
- status = 200
100
- body = json_encode(status, "OK", command)
101
- end
102
- rescue => e
103
- status = 404
104
- body = json_encode(status, e)
105
- end
106
- rescue => e
107
- status = 403
108
- body = json_encode(status, e)
109
- Wakame.log.error(e)
110
- end
111
- [ status, {'Content-Type' => 'text/javascript+json'}, body]
112
- end
113
-
114
- def authentication(path, query)
115
- key = Wakame.config.private_key
116
- req = query.split(/\&signature\=/)
117
- hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, key, req[0])
118
- hmac = Base64.encode64(hash).gsub(/\+/, "").gsub(/\n/, "").to_s
119
- if hmac != path["signature"]
120
- raise "Authentication failed"
121
- end
122
- end
123
-
124
- def json_encode(status, message, data=nil)
125
- if status == 200 && data.is_a?(Hash)
126
- body = [{:status=>status, :message=>message}, {:data=>data}].to_json
127
- else
128
- body = [{:status=>status, :message=>message}].to_json
129
- end
130
- body
131
- end
132
- end
133
-
134
- end
135
- end