wakame 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/History.txt +8 -0
  2. data/Rakefile +3 -3
  3. data/VERSION +1 -1
  4. data/app_generators/wakame/templates/cluster/resources/markers/http_application_server.rb +3 -0
  5. data/app_generators/wakame/templates/cluster/resources/markers/http_asset_server.rb +2 -0
  6. data/app_generators/wakame/templates/cluster/resources/markers/http_server.rb +9 -0
  7. data/app_generators/wakame/templates/config/cluster.rb +36 -99
  8. data/app_generators/wakame/templates/config/init.d/wakame-agent +3 -3
  9. data/app_generators/wakame/templates/config/init.d/wakame-master +3 -3
  10. data/app_generators/wakame/wakame_generator.rb +5 -1
  11. data/contrib/imagesetup.sh +9 -5
  12. data/lib/ext/uri.rb +13 -0
  13. data/lib/wakame/action.rb +46 -21
  14. data/lib/wakame/{rule_engine.rb → action_manager.rb} +148 -36
  15. data/lib/wakame/actions/deploy_config.rb +35 -0
  16. data/lib/wakame/actions/launch_cluster.rb +8 -10
  17. data/lib/wakame/actions/launch_vm.rb +26 -20
  18. data/lib/wakame/actions/migrate_service.rb +30 -19
  19. data/lib/wakame/actions/notify_child_changed.rb +34 -0
  20. data/lib/wakame/actions/notify_parent_changed.rb +34 -0
  21. data/lib/wakame/actions/propagate_resource.rb +27 -0
  22. data/lib/wakame/actions/propagate_service.rb +27 -0
  23. data/lib/wakame/actions/reload_service.rb +21 -9
  24. data/lib/wakame/actions/shutdown_cluster.rb +3 -3
  25. data/lib/wakame/actions/shutdown_vm.rb +14 -5
  26. data/lib/wakame/actions/start_service.rb +53 -47
  27. data/lib/wakame/actions/stop_service.rb +35 -23
  28. data/lib/wakame/actor/system.rb +6 -3
  29. data/lib/wakame/agent.rb +29 -7
  30. data/lib/wakame/amqp_client.rb +26 -5
  31. data/lib/wakame/command/action_status.rb +7 -7
  32. data/lib/wakame/command/actor.rb +10 -10
  33. data/lib/wakame/command/import_cluster_config.rb +10 -0
  34. data/lib/wakame/command/launch_cluster.rb +2 -2
  35. data/lib/wakame/command/launch_vm.rb +3 -3
  36. data/lib/wakame/command/migrate_service.rb +7 -7
  37. data/lib/wakame/command/propagate_resource.rb +42 -0
  38. data/lib/wakame/command/propagate_service.rb +21 -19
  39. data/lib/wakame/command/reload_service.rb +3 -13
  40. data/lib/wakame/command/shutdown_cluster.rb +2 -2
  41. data/lib/wakame/command/start_service.rb +14 -0
  42. data/lib/wakame/command/status.rb +32 -10
  43. data/lib/wakame/command/stop_service.rb +27 -21
  44. data/lib/wakame/command.rb +19 -3
  45. data/lib/wakame/command_queue.rb +87 -67
  46. data/lib/wakame/configuration.rb +6 -0
  47. data/lib/wakame/event.rb +17 -0
  48. data/lib/wakame/event_dispatcher.rb +32 -23
  49. data/lib/wakame/graph.rb +2 -1
  50. data/lib/wakame/initializer.rb +11 -8
  51. data/lib/wakame/master.rb +327 -209
  52. data/lib/wakame/monitor/agent.rb +5 -1
  53. data/lib/wakame/monitor/service.rb +6 -5
  54. data/lib/wakame/packets.rb +13 -21
  55. data/lib/wakame/runner/administrator_command.rb +383 -264
  56. data/lib/wakame/runner/agent.rb +1 -5
  57. data/lib/wakame/runner/master.rb +0 -3
  58. data/lib/wakame/service.rb +817 -538
  59. data/lib/wakame/status_db.rb +383 -0
  60. data/lib/wakame/template.rb +27 -130
  61. data/lib/wakame/trigger.rb +10 -18
  62. data/lib/wakame/triggers/instance_count_update.rb +1 -1
  63. data/lib/wakame/triggers/load_history.rb +1 -1
  64. data/lib/wakame/triggers/maintain_ssh_known_hosts.rb +8 -5
  65. data/lib/wakame/triggers/shutdown_unused_vm.rb +1 -1
  66. data/lib/wakame/util.rb +64 -55
  67. data/lib/wakame.rb +4 -0
  68. data/tests/test_action_manager.rb +111 -0
  69. data/tests/test_service.rb +128 -23
  70. data/tests/test_status_db.rb +82 -0
  71. data/tests/test_uri_amqp.rb +10 -0
  72. data/wakame_generators/resource/templates/apache_app/apache_app.rb +19 -18
  73. data/wakame_generators/resource/templates/apache_app/conf/apache2.conf +14 -2
  74. data/wakame_generators/resource/templates/apache_app/conf/system-app.conf +1 -1
  75. data/wakame_generators/resource/templates/apache_app/conf/vh/aaa.test.conf +9 -0
  76. data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +21 -20
  77. data/wakame_generators/resource/templates/apache_lb/conf/apache2.conf +14 -2
  78. data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +17 -2
  79. data/wakame_generators/resource/templates/apache_lb/conf/vh/aaa.test.conf +37 -0
  80. data/wakame_generators/resource/templates/apache_www/apache_www.rb +20 -18
  81. data/wakame_generators/resource/templates/apache_www/conf/apache2.conf +14 -2
  82. data/wakame_generators/resource/templates/apache_www/conf/system-www.conf +1 -1
  83. data/wakame_generators/resource/templates/apache_www/conf/vh/aaa.test.conf +9 -0
  84. data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +6 -8
  85. data/wakame_generators/resource/templates/ec2_elb/ec2_elb.rb +7 -6
  86. data/wakame_generators/resource/templates/memcached/conf/memcached.conf +47 -0
  87. data/wakame_generators/resource/templates/memcached/init.d/memcached +61 -0
  88. data/wakame_generators/resource/templates/memcached/memcached.rb +73 -0
  89. data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +5 -7
  90. data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +35 -34
  91. data/wakame_generators/resource/templates/mysql_slave/conf/my.cnf +6 -6
  92. data/wakame_generators/resource/templates/mysql_slave/mysql_slave.rb +21 -24
  93. data/wakame_generators/resource/templates/nginx/conf/nginx.conf +17 -27
  94. data/wakame_generators/resource/templates/nginx/conf/vh/aaa.test.conf +30 -0
  95. data/wakame_generators/resource/templates/nginx/nginx.rb +18 -18
  96. metadata +34 -21
  97. data/lib/wakame/actions/propagate_instances.rb +0 -70
  98. data/lib/wakame/manager/commands.rb +0 -134
  99. data/lib/wakame/rule.rb +0 -116
  100. data/lib/wakame/triggers/process_command.rb +0 -41
  101. data/tests/test_rule_engine.rb +0 -127
  102. data/wakame_generators/resource/templates/apache_app/conf/sites-app.conf +0 -23
  103. data/wakame_generators/resource/templates/apache_lb/conf/sites-lb.conf +0 -54
  104. data/wakame_generators/resource/templates/apache_www/conf/sites-www.conf +0 -23
data/lib/wakame/master.rb CHANGED
@@ -3,63 +3,84 @@
3
3
  require 'rubygems'
4
4
 
5
5
  require 'wakame'
6
- require 'wakame/packets'
7
- require 'wakame/service'
8
6
  require 'wakame/queue_declare'
9
- require 'wakame/vm_manipulator'
10
7
 
11
8
  module Wakame
12
9
 
10
+ module Manager
11
+ attr_accessor :master
12
+
13
+ def init
14
+ end
15
+
16
+ def start
17
+ end
18
+
19
+ def stop
20
+ end
21
+
22
+ def reload
23
+ end
24
+
25
+ def terminate
26
+ end
27
+ end
28
+
29
+
13
30
  class AgentMonitor
31
+ include Manager
14
32
  include ThreadImmutable
15
- attr_reader :registered_agents, :unregistered_agents, :master, :gc_period
16
33
 
17
-
18
- def initialize(master)
19
- bind_thread
20
- @master = master
21
- @registered_agents = {}
22
- @unregistered_agents = {}
34
+ def init
23
35
  @agent_timeout = 31.to_f
24
36
  @agent_kill_timeout = @agent_timeout * 2
25
37
  @gc_period = 20.to_f
26
38
 
39
+ Service::AgentPool.reset
40
+
27
41
  # GC event trigger for agent timer & status
28
- calc_agent_timeout = proc {
29
- #Wakame.log.debug("Started agent GC : agents.size=#{@registered_agents.size}")
30
- kill_list=[]
31
- registered_agents.each { |agent_id, agent|
32
- next if agent.status == Service::Agent::STATUS_OFFLINE
33
- diff_time = Time.now - agent.last_ping_at
34
- #Wakame.log.debug "AgentMonitor GC : #{agent_id}: #{diff_time}"
35
- if diff_time > @agent_timeout.to_f
36
- agent.status = Service::Agent::STATUS_TIMEOUT
37
- end
42
+ @agent_timeout_timer = EM::PeriodicTimer.new(@gc_period) {
43
+ StatusDB.pass {
44
+ #Wakame.log.debug("Started agent GC : agents.size=#{@registered_agents.size}")
45
+ [self.agent_pool.group_active.keys, self.agent_pool.group_observed.keys].flatten.uniq.each { |agent_id|
46
+ agent = Service::Agent.find(agent_id)
47
+ #next if agent.status == Service::Agent::STATUS_OFFLINE
48
+
49
+ diff_time = Time.now - agent.last_ping_at_time
50
+ #Wakame.log.debug "AgentMonitor GC : #{agent_id}: #{diff_time}"
51
+ if diff_time > @agent_timeout.to_f
52
+ agent.update_status(Service::Agent::STATUS_TIMEOUT)
53
+ end
54
+
55
+ if diff_time > @agent_kill_timeout.to_f
56
+ agent_pool.unregister(agent)
57
+ end
58
+ }
38
59
 
39
- if diff_time > @agent_kill_timeout.to_f
40
- kill_list << agent_id
41
- end
42
- }
43
-
44
- kill_list.each { |agent_id|
45
- agent = @registered_agents.delete(agent_id)
46
- ED.fire_event(Event::AgentUnMonitored.new(agent)) unless agent.nil?
60
+ #Wakame.log.debug("Finished agent GC")
47
61
  }
48
- #Wakame.log.debug("Finished agent GC")
49
62
  }
50
63
 
51
- @agent_timeout_timer = EventMachine::PeriodicTimer.new(@gc_period, calc_agent_timeout)
52
64
 
53
65
  master.add_subscriber('registry') { |data|
54
66
  data = eval(data)
67
+
68
+ StatusDB.pass {
69
+ agent_id = data[:agent_id]
70
+
71
+ agent = agent_pool.create_or_find(agent_id)
72
+
73
+ case data[:class_type]
74
+ when 'Wakame::Packets::Register'
75
+ agent.root_path = data[:root_path]
76
+ agent.vm_attr = data[:attrs]
77
+ agent.save
78
+ agent_pool.register(agent)
79
+ when 'Wakame::Packets::UnRegister'
80
+ agent_pool.unregister(agent)
81
+ end
82
+ }
55
83
 
56
- agent_id = data[:agent_id]
57
- case data[:type]
58
- when 'Wakame::Packets::Register'
59
- register_agent(data)
60
- when 'Wakame::Packets::UnRegister'
61
- unregister_agent(agent_id)
62
- end
63
84
  }
64
85
 
65
86
  master.add_subscriber('ping') { |data|
@@ -69,232 +90,329 @@ module Wakame
69
90
 
70
91
  # Variable update function for the common members
71
92
  set_report_values = proc { |agent|
72
- agent.status = Service::Agent::STATUS_ONLINE
73
- agent.uptime = 0
74
- agent.last_ping_at = Time.parse(ping[:responded_at])
75
-
76
- agent.attr = ping[:attrs]
77
-
78
- agent.services.clear
79
- ping.services.each { |svc_id, i|
80
- agent.services[svc_id] = master.service_cluster.instances[svc_id]
81
- }
93
+ agent.last_ping_at = ping[:responded_at]
94
+ agent.vm_attr = ping[:attrs]
95
+
96
+ agent.renew_reported_services(ping[:services])
97
+ agent.save
98
+
99
+ agent.update_status(Service::Agent::STATUS_ONLINE)
82
100
  }
83
101
 
84
- agent = agent(ping[:agent_id])
85
- if agent.nil?
86
- agent = Service::Agent.new(ping[:agent_id])
87
-
88
- set_report_values.call(agent)
102
+ StatusDB.pass {
103
+ agent = Service::Agent.find(ping[:agent_id])
104
+ if agent.nil?
105
+ agent = Service::Agent.new
106
+ agent.id = ping[:agent_id]
107
+
108
+ set_report_values.call(agent)
109
+
110
+ agent_pool.register_as_observed(agent)
111
+ else
112
+ set_report_values.call(agent)
113
+ end
89
114
 
90
- unregistered_agents[ping[:agent_id]]=agent
91
- else
92
- set_report_values.call(agent)
93
- end
94
-
95
-
96
- ED.fire_event(Event::AgentPong.new(agent))
115
+ EventDispatcher.fire_event(Event::AgentPong.new(agent))
116
+ }
97
117
  }
98
118
 
99
119
  master.add_subscriber('agent_event') { |data|
100
120
  response = eval(data)
101
- #p response
102
- case response[:type]
103
- when 'Wakame::Packets::ServiceStatusChanged'
104
- svc_inst = Service::ServiceInstance.instance_collection[response[:svc_id]]
105
- if svc_inst
106
- response_time = Time.parse(response[:responded_at])
107
- svc_inst.update_status(response[:new_status], response_time, response[:fail_message])
108
-
109
- # tmp_event = Event::ServiceStatusChanged.new(response[:svc_id], svc_inst.property, response[:status], response[:previous_status])
110
- # tmp_event.time = response_time
111
- # ED.fire_event(tmp_event)
112
-
113
- # if response[:previous_status] != Service::STATUS_ONLINE && response[:new_status] == Service::STATUS_ONLINE
114
- # tmp_event = Event::ServiceOnline.new(tmp_event.instance_id, svc_inst.property)
115
- # tmp_event.time = response_time
116
- # ED.fire_event(tmp_event)
117
- # elsif response[:previous_status] != Service::STATUS_OFFLINE && response[:new_status] == Service::STATUS_OFFLINE
118
- # tmp_event = Event::ServiceOffline.new(tmp_event.instance_id, svc_inst.property)
119
- # tmp_event.time = response_time
120
- # ED.fire_event(tmp_event)
121
- # elsif response[:previous_status] != Service::STATUS_FAIL && response[:new_status] == Service::STATUS_FAIL
122
- # tmp_event = Event::ServiceFailed.new(tmp_event.instance_id, svc_inst.property, response[:fail_message])
123
- # tmp_event.time = response_time
124
- # ED.fire_event(tmp_event)
125
- # end
126
- end
127
- when 'Wakame::Packets::ActorResponse'
128
- case response[:status]
129
- when Actor::STATUS_RUNNING
130
- ED.fire_event(Event::ActorProgress.new(response[:agent_id], response[:token], 0))
121
+ StatusDB.pass {
122
+ case response[:class_type]
123
+ when 'Wakame::Packets::StatusCheckResult'
124
+ svc_inst = Service::ServiceInstance.find(response[:svc_id])
125
+ if svc_inst
126
+ svc_inst.monitor_status = response[:status]
127
+ svc_inst.save
128
+ else
129
+ Wakame.log.error("#{self.class}: Unknown service ID: #{response[:svc_id]}")
130
+ end
131
+ when 'Wakame::Packets::ServiceStatusChanged'
132
+ svc_inst = Service::ServiceInstance.find(response[:svc_id])
133
+ if svc_inst
134
+ response_time = Time.parse(response[:responded_at])
135
+ svc_inst.update_status(response[:new_status], response_time, response[:fail_message])
136
+ end
137
+ when 'Wakame::Packets::ActorResponse'
138
+ case response[:status]
139
+ when Actor::STATUS_RUNNING
140
+ EventDispatcher.fire_event(Event::ActorProgress.new(response[:agent_id], response[:token], 0))
141
+ when Actor::STATUS_FAILED
142
+ EventDispatcher.fire_event(Event::ActorComplete.new(response[:agent_id], response[:token], response[:status], nil))
143
+ else
144
+ EventDispatcher.fire_event(Event::ActorComplete.new(response[:agent_id], response[:token], response[:status], response[:opts][:return_value]))
145
+ end
131
146
  else
132
- ED.fire_event(Event::ActorComplete.new(response[:agent_id], response[:token], response[:status], response[:opts][:return_value]))
147
+ Wakame.log.warn("#{self.class}: Unhandled agent response: #{response[:class_type]}")
133
148
  end
134
- else
135
- Wakame.log.warn("#{self.class}: Unhandled agent response: #{response[:type]}")
136
- end
149
+ }
137
150
  }
138
-
139
- end
140
151
 
141
-
142
- def agent(agent_id)
143
- registered_agents[agent_id] || unregistered_agents[agent_id]
144
152
  end
145
153
 
146
- def register_agent(data)
147
- agent_id = data[:agent_id]
148
- agent = registered_agents[agent_id]
149
- if agent.nil?
150
- agent = unregistered_agents[agent_id]
151
- if agent.nil?
152
- # The agent is going to be registered at first time.
153
- agent = Service::Agent.new(agent_id)
154
- registered_agents[agent_id] = agent
155
- else
156
- # Move the reference from unregistered group to the registered group.
157
- registered_agents[agent_id] = unregistered_agents[agent_id]
158
- unregistered_agents.delete(agent_id)
159
- end
160
- Wakame.log.debug("The Agent has been registered: #{data.inspect}")
161
- #Wakame.log.debug(unregistered_agents)
162
- ED.fire_event(Event::AgentMonitored.new(agent))
163
- end
164
- agent.root_path = data[:root_path]
165
- agent.attr = data[:attrs]
154
+ def terminate
155
+ @agent_timeout_timer.cancel
166
156
  end
167
157
 
168
- def unregister_agent(agent_id)
169
- agent = registered_agents[agent_id]
170
- if agent
171
- unregistered_agents[agent_id] = registered_agents[agent_id]
172
- registered_agents.delete(agent_id)
173
- ED.fire_event(Event::AgentUnMonitored.new(agent))
174
- end
158
+ def agent_pool
159
+ Service::AgentPool.instance
175
160
  end
176
161
 
162
+ end
177
163
 
178
- # def bind_agent(service_instance, &filter)
179
- # agent_id, agent = @agents.find { |agent_id, agent|
180
164
 
181
- # next false if agent.has_service_type?(service_instance.property.class)
182
- # filter.call(agent)
183
- # }
184
- # return nil if agent.nil?
185
- # service_instance.bind_agent(agent)
186
- # agent
187
- # end
188
165
 
189
- # def unbind_agent(service_instance)
190
- # service_instance.unbind_agent
191
- # end
192
-
193
- # Retruns the master local agent object
194
- def master_local
195
- agent = registered_agents[@master.master_local_agent_id]
196
- puts "#{agent} = registered_agents[#{@master.master_local_agent_id}]"
197
- raise "Master does not identify the master local agent yet." if agent.nil?
198
- agent
199
- end
166
+ class ClusterManager
167
+ include Manager
168
+
169
+ class ClusterConfigLoader
170
+
171
+ def load(cluster_rb_path=Wakame.config.cluster_config_path)
172
+ Wakame.log.info("#{self.class}: Loading cluster.rb: #{cluster_rb_path}")
173
+ @loaded_cluster_names = {}
174
+
175
+ eval(File.readlines(cluster_rb_path).join(''), binding)
176
+
177
+ # Clear uninitialized cluster data in the store.
178
+ Service::ServiceCluster.find_all.each { |cluster|
179
+ cluster.delete unless @loaded_cluster_names.has_key?(cluster.name)
180
+ }
181
+
182
+ @loaded_cluster_names
183
+ end
200
184
 
201
- def each_online(&blk)
202
- registered_agents.each { |k, v|
203
- next if v.status != Service::Agent::STATUS_ONLINE
204
- blk.call(v)
205
- }
206
- end
207
185
 
208
- def dump_status
209
- ag = []
210
- res = {:registered=>[], :unregistered=>[]}
186
+ private
187
+ def define_cluster(name, &blk)
188
+ cluster = Service::ServiceCluster.find(Service::ServiceCluster.id(name))
189
+ if cluster.nil?
190
+ cluster = Service::ServiceCluster.new
191
+ cluster.name = name
192
+ end
193
+
194
+ Service::AgentPool.reset
195
+ cluster.reset
196
+
197
+ blk.call(cluster)
198
+
199
+ cluster.save
200
+
201
+ Wakame.log.info("#{self.class}: Loaded Service Cluster: #{cluster.name}")
202
+ @loaded_cluster_names[name]=cluster.id
203
+ end
204
+
205
+ end
206
+
207
+ def init
208
+ # Periodical cluster status updater
209
+ @status_check_timer = EM::PeriodicTimer.new(5) {
210
+ StatusDB.pass {
211
+ clusters.each { |cluster_id|
212
+ Service::ServiceCluster.find(cluster_id).update_cluster_status
213
+ }
214
+ }
215
+ }
211
216
 
212
- @registered_agents.each { |key, a|
213
- res[:registered] << a.dump_status
217
+ # Event based cluster status updater
218
+ @check_event_tickets = []
219
+ [Event::ServiceOnline, Event::ServiceOffline, Event::ServiceFailed].each { |evclass|
220
+ @check_event_tickets << EventDispatcher.subscribe(evclass) { |event|
221
+ StatusDB.pass {
222
+ clusters.each { |cluster_id|
223
+ Service::ServiceCluster.find(cluster_id).update_cluster_status
224
+ }
225
+ }
226
+ }
214
227
  }
215
- @unregistered_agents.each { |key, a|
216
- res[:unregistered] << a.dump_status
228
+
229
+ end
230
+
231
+ def reload
232
+ end
233
+
234
+ def terminate
235
+ @status_check_timer.cancel
236
+ @check_event_tickets.each { |t|
237
+ EventDispatcher.unsubscribe(t)
217
238
  }
218
- res
219
239
  end
220
- end
221
240
 
222
- class Master
223
- include Wakame::AMQPClient
224
- include Wakame::QueueDeclare
241
+ def clusters
242
+ ServiceClusterPool.all.map{|r| r.service_cluster_id }
243
+ end
244
+
245
+ def register(cluster)
246
+ raise ArgumentError unless cluster.is_a?(Service::ServiceCluster)
247
+ ServiceClusterPool.register_cluster(cluster.name)
248
+ end
225
249
 
226
- define_queue 'agent_event', 'agent_event'
227
- define_queue 'ping', 'ping'
228
- define_queue 'registry', 'registry'
250
+ def unregister(cluster_id)
251
+ @clusters.delete(cluster_id)
252
+ end
229
253
 
230
- attr_reader :command_queue, :agent_monitor, :configuration, :service_cluster, :started_at
254
+ def load_config_cluster
255
+ ClusterConfigLoader.new.load.each { |name, id|
256
+ ServiceClusterPool.register_cluster(name)
257
+ }
258
+ resolve_template_vm_attr
259
+ end
231
260
 
232
- def initialize(opts={})
233
- pre_setup
234
261
 
235
- connect(opts) {
236
- post_setup
237
- }
238
- Wakame.log.info("Started master process : WAKAME_ROOT=#{Wakame.config.root_path} WAKAME_ENV=#{Wakame.config.environment}")
262
+ private
263
+ def resolve_template_vm_attr
264
+ ServiceClusterPool.each_cluster { |cluster|
265
+ cluster_id = cluster.id
266
+
267
+ if cluster.template_vm_attr.nil? || cluster.template_vm_attr.empty?
268
+ update_template_spec = lambda { |agent|
269
+ raise ArgumentError unless agent.is_a?(Service::Agent)
270
+
271
+ require 'right_aws'
272
+ ec2 = RightAws::Ec2.new(Wakame.config.aws_access_key, Wakame.config.aws_secret_key)
273
+
274
+ ref_attr = ec2.describe_instances([agent.vm_attr[:instance_id]])
275
+ ref_attr = ref_attr[0]
276
+
277
+ cluster = Service::ServiceCluster.find(cluster_id)
278
+ spec = cluster.template_vm_spec
279
+ Service::VmSpec::EC2.vm_attr_defs.each { |k, v|
280
+ spec.attrs[k] = ref_attr[v[:right_aws_key]]
281
+ }
282
+ cluster.save
283
+
284
+ Wakame.log.debug("ServiceCluster \"#{cluster.name}\" template_vm_attr based on VM \"#{agent.vm_attr[:instance_id]}\" : #{spec.attrs.inspect}")
285
+ }
286
+
287
+
288
+ agent_id = Service::AgentPool.instance.group_active.keys.first
289
+ if agent_id.nil?
290
+ # Set a single shot event handler to set the template values up from the first connected agent.
291
+ EventDispatcher.subscribe_once(Event::AgentMonitored) { |event|
292
+ StatusDB.pass {
293
+ update_template_spec.call(event.agent)
294
+ }
295
+ }
296
+ else
297
+ StatusDB.pass {
298
+ update_template_spec.call(Service::Agent.find(agent_id))
299
+ }
300
+ end
301
+ end
302
+
303
+ if cluster.advertised_amqp_servers.nil?
304
+ StatusDB.pass {
305
+ cluster = Service::ServiceCluster.find(cluster_id)
306
+ cluster.advertised_amqp_servers = master.amqp_server_uri.to_s
307
+ cluster.save
308
+ Wakame.log.debug("ServiceCluster \"#{cluster.name}\" advertised_amqp_servers: #{cluster.advertised_amqp_servers}")
309
+ }
310
+ end
311
+
312
+ }
313
+ end
314
+
315
+
316
+ class ServiceClusterPool < Sequel::Model
317
+ plugin :schema
318
+
319
+ def self.initialize_table
320
+ set_schema do
321
+ primary_key :id, :type => Integer
322
+ varchar :service_cluster_id
323
+ end
324
+ create_table unless table_exists?
325
+ end
326
+
327
+
328
+ def self.register_cluster(name)
329
+ id = Service::ServiceCluster.id(name)
330
+
331
+ self.find_or_create(:service_cluster_id=>id)
332
+ end
333
+
334
+ def self.unregister_cluster(name)
335
+ id = Service::ServiceCluster.id(name)
336
+ self.delete(:service_cluster_id=>id)
337
+ end
338
+
339
+ def self.each_cluster(&blk)
340
+ self.all.each { |m|
341
+ cluster = Service::ServiceCluster.find(m.service_cluster_id)
342
+ blk.call(cluster)
343
+ }
344
+ end
239
345
  end
240
346
 
347
+ ServiceClusterPool.initialize_table
348
+ end
241
349
 
242
- # def send_agent_command(command, agent_id=nil)
243
- # raise TypeError unless command.is_a? Packets::RequestBase
244
- # EM.next_tick {
245
- # if agent_id
246
- # publish_to('agent_command', "agent_id.#{agent_id}", Marshal.dump(command))
247
- # else
248
- # publish_to('agent_command', '*', Marshal.dump(command))
249
- # end
250
- # }
251
- # end
350
+ class Master
351
+ include Wakame::AMQPClient
352
+ include Wakame::QueueDeclare
252
353
 
253
- def actor_request(agent_id, path, *args)
254
- request = Wakame::Packets::ActorRequest.new(agent_id, Util.gen_id, path, *args)
255
- ActorRequest.new(self, request)
354
+ define_queue 'agent_event', 'agent_event'
355
+ define_queue 'ping', 'ping'
356
+ define_queue 'registry', 'registry'
357
+
358
+ attr_reader :command_queue, :agent_monitor, :cluster_manager, :action_manager, :started_at
359
+ attr_reader :managers
360
+
361
+ def initialize(opts={})
362
+ pre_setup
256
363
  end
257
364
 
258
365
 
259
- def attr
260
- agent_monitor.master_local.attr
366
+ def actor_request(agent_id, path, *args)
367
+ request = Wakame::Packets::ActorRequest.new(agent_id, Util.gen_id, path, *args)
368
+ ActorRequest.new(self, request)
261
369
  end
262
370
 
263
371
 
264
372
  def cleanup
373
+ @managers.each { |m| m.terminate }
265
374
  @command_queue.shutdown
266
375
  end
267
376
 
268
- def master_local_agent_id
269
- @master_local_agent_id
377
+ def register_manager(manager)
378
+ raise ArgumentError unless manager.kind_of? Manager
379
+ manager.master = self
380
+ @managers << manager
381
+ manager
270
382
  end
271
383
 
272
- private
273
- def determine_agent_id
274
- if Wakame.config.environment == :EC2
275
- @master_local_agent_id = VmManipulator::EC2::MetadataService.query_metadata_uri('instance-id')
276
- else
277
- @master_local_agent_id = VmManipulator::StandAlone::INSTANCE_ID
278
- end
384
+ # post_setup
385
+ def init
386
+ raise 'has to be put in EM.run context' unless EM.reactor_running?
387
+ @command_queue = register_manager(CommandQueue.new)
388
+
389
+ # WorkerThread has to run earlier than other managers.
390
+ @agent_monitor = register_manager(AgentMonitor.new)
391
+ @cluster_manager = register_manager(ClusterManager.new)
392
+ @action_manager = register_manager(ActionManager.new)
393
+
394
+ @managers.each {|m|
395
+ Wakame.log.debug("Initializing Manager Module: #{m.class}")
396
+ m.init
397
+ }
398
+
399
+ Wakame.log.info("Started master process : WAKAME_ROOT=#{Wakame.config.root_path} WAKAME_ENV=#{Wakame.config.environment}")
279
400
  end
280
401
 
402
+
403
+ private
281
404
  def pre_setup
282
- determine_agent_id
283
405
  @started_at = Time.now
406
+ @managers = []
407
+
408
+ StatusDB::WorkerThread.init
284
409
 
285
- EM.barrier {
410
+ StatusDB.pass {
286
411
  Wakame.log.debug("Binding thread info to EventDispatcher.")
287
412
  EventDispatcher.instance.bind_thread(Thread.current)
288
413
  }
289
414
  end
290
415
 
291
- def post_setup
292
- raise 'has to be put in EM.run context' unless EM.reactor_running?
293
- @command_queue = CommandQueue.new(self)
294
- @agent_monitor = AgentMonitor.new(self)
295
-
296
- @service_cluster = Util.new_(Wakame.config.cluster_class, self)
297
- end
298
416
 
299
417
  end
300
418
 
@@ -317,12 +435,12 @@ module Wakame
317
435
  def request
318
436
  raise "The request has already been sent." if @requested
319
437
 
320
- @event_ticket = ED.subscribe(Event::ActorComplete) { |event|
438
+ @event_ticket = EventDispatcher.subscribe(Event::ActorComplete) { |event|
321
439
  if event.token == @packet.token
322
440
 
323
441
  # Any of status except RUNNING are accomplishment of the actor request.
324
442
  Wakame.log.debug("#{self.class}: The actor request has been completed: token=#{self.token}, status=#{event.status}, return_value=#{event.return_value}")
325
- ED.unsubscribe(@event_ticket)
443
+ EventDispatcher.unsubscribe(@event_ticket)
326
444
  @return_value = event.return_value
327
445
  @wait_lock.enq([event.status, event.return_value])
328
446
  end
@@ -364,7 +482,7 @@ module Wakame
364
482
  }
365
483
  end
366
484
  alias :wait :wait_completion
367
-
485
+
368
486
  private
369
487
  def check_requested?
370
488
  raise "The request has not been sent yet." unless @requested
@@ -23,7 +23,11 @@ class Wakame::Monitor::Agent
23
23
 
24
24
 
25
25
  def check
26
- attrs = Wakame::VmManipulator.create.fetch_local_attrs
26
+ if Wakame.config.environment == :EC2
27
+ attrs = Wakame::Agent.ec2_fetch_local_attrs
28
+ else
29
+ attrs = {}
30
+ end
27
31
 
28
32
  res = {:attrs=>attrs, :monitors=>[], :actors=>[], :services=>{}}
29
33
  EM.barrier {