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,7 +1,7 @@
1
1
  class Wakame::Command::StartService
2
2
  include Wakame::Command
3
3
 
4
- command_name='start_service'
4
+ command_name 'start_service'
5
5
 
6
6
  def run
7
7
  svc = service_cluster.find_service(params[:service_id])
@@ -14,9 +14,12 @@ class Wakame::Command::Status
14
14
  :cloud_hosts=>{}
15
15
  }
16
16
 
17
- res[:agent_pool] = AgentPool.instance.dump_attrs
18
- AgentPool.instance.group_active.keys.each { |id|
19
- res[:agents][id] = Agent.find(id).dump_attrs
17
+ res[:agent_pool] = {
18
+ :group_active => Wakame::Models::AgentPool.instance.group_active,
19
+ :group_observed => Wakame::Models::AgentPool.instance.group_observed
20
+ }
21
+ Wakame::Models::AgentPool.instance.dataset.all.each { |row|
22
+ res[:agents][row[:agent_id]] = Agent.find(row[:agent_id]).dump_attrs
20
23
  }
21
24
 
22
25
  cluster_id = master.cluster_manager.clusters.first
@@ -35,7 +38,6 @@ class Wakame::Command::Status
35
38
  res[:cloud_hosts][id]=CloudHost.find(id).dump_attrs
36
39
  }
37
40
  end
38
- #p res[:cluster]
39
41
  res
40
42
  }
41
43
 
@@ -1,7 +1,7 @@
1
1
  class Wakame::Command::StopService
2
2
  include Wakame::Command
3
3
 
4
- command_name='stop_service'
4
+ command_name 'stop_service'
5
5
 
6
6
  # terminate
7
7
  # service_id or resource_name
@@ -22,6 +22,7 @@ module Wakame
22
22
 
23
23
  def initialize(env=WAKAME_ENV)
24
24
  super(PARAMS)
25
+
25
26
  if root_path.nil?
26
27
  root_path = Object.const_defined?(:WAKAME_ROOT) ? WAKAME_ROOT : '../'
27
28
  end
@@ -44,6 +45,10 @@ module Wakame
44
45
  ::WAKAME_ROOT
45
46
  end
46
47
 
48
+ def cluster_env
49
+ ENV['WAKAME_CLUSTER_ENV'] ? ENV['WAKAME_CLUSTER_ENV'] : 'development'
50
+ end
51
+
47
52
  def tmp_path
48
53
  File.join(root_path, 'tmp')
49
54
  end
@@ -28,19 +28,58 @@ module Wakame
28
28
 
29
29
  end
30
30
 
31
+ class ClusterFrozen < Base
32
+ attr_reader :cluster_id
33
+ def initialize(cluster_id)
34
+ super()
35
+ @cluster_id = cluster_id
36
+ end
37
+
38
+ def log_message
39
+ "#{@cluster_id}, frozen"
40
+ end
41
+ end
42
+
43
+ class ClusterUnfrozen < Base
44
+ attr_reader :cluster_id
45
+ def initialize(cluster_id)
46
+ super()
47
+ @cluster_id = cluster_id
48
+ end
49
+
50
+ def log_message
51
+ "#{@cluster_id}, unfrozen"
52
+ end
53
+ end
54
+
31
55
  class ServiceStatus < Base
32
- attr_reader :instance_id, :property
33
- def initialize(instance_id, property)
56
+ attr_reader :instance_id
57
+ def initialize(instance_id)
34
58
  super()
35
59
  @instance_id = instance_id
36
- @property = property
37
60
  end
38
61
  end
39
62
 
63
+ # Event class for the change of ServiceInstance#status
40
64
  class ServiceStatusChanged < ServiceStatus
41
65
  attr_reader :status, :previous_status
42
- def initialize(instance_id, property, new_status, prev_status)
43
- super(instance_id, property)
66
+ def initialize(instance_id, new_status, prev_status)
67
+ super(instance_id)
68
+ @status = new_status
69
+ @previous_status = prev_status
70
+ end
71
+
72
+ def log_message
73
+ "#{instance_id}, #{@previous_status} -> #{@status}"
74
+ end
75
+ end
76
+
77
+
78
+ # Event class for the change of ServiceInstance#monitor_status
79
+ class ServiceMonitorStatusChanged < ServiceStatus
80
+ attr_reader :status, :previous_status
81
+ def initialize(instance_id, new_status, prev_status)
82
+ super(instance_id)
44
83
  @status = new_status
45
84
  @previous_status = prev_status
46
85
  end
@@ -56,12 +95,34 @@ module Wakame
56
95
  end
57
96
  class ServiceFailed < ServiceStatus
58
97
  attr_reader :message
59
- def initialize(instance_id, property, message)
60
- super(instance_id, property)
98
+ def initialize(instance_id, message)
99
+ super(instance_id)
61
100
  @message = message
62
101
  end
63
102
  end
64
103
 
104
+ class ServicePropagated < ServiceStatus
105
+ end
106
+ class ServiceDestroied < ServiceStatus
107
+ end
108
+
109
+ class AgentMappedCloudHost < Base
110
+ attr_reader :agent_id, :cloud_host_id
111
+ def initialize(cloud_host_id, agent_id)
112
+ super()
113
+ @agent_id = agent_id
114
+ @cloud_host_id = cloud_host_id
115
+ end
116
+ end
117
+ class AgentUnmappedCloudHost < Base
118
+ attr_reader :agent_id, :cloud_host_id
119
+ def initialize(cloud_host_id, agent_id)
120
+ super()
121
+ @agent_id = agent_id
122
+ @cloud_host_id = cloud_host_id
123
+ end
124
+ end
125
+
65
126
  class AgentEvent < Base
66
127
  attr_reader :agent
67
128
  def initialize(agent)
@@ -100,20 +161,20 @@ module Wakame
100
161
  end
101
162
  end
102
163
 
103
- class ServiceUnboundHost < Base
104
- attr_reader :service, :host
105
- def initialize(service, host)
164
+ class ServiceUnboundCloudHost < Base
165
+ attr_reader :svc_id, :cloud_host_id
166
+ def initialize(svc_id, cloud_host_id)
106
167
  super()
107
- @service = service
108
- @host = host
168
+ @svc_id = svc_id
169
+ @cloud_host_id = cloud_host_id
109
170
  end
110
171
  end
111
- class ServiceBoundHost < Base
112
- attr_reader :service, :host
113
- def initialize(service, host)
172
+ class ServiceBoundCloudHost < Base
173
+ attr_reader :svc_id, :cloud_host_id
174
+ def initialize(svc_id, cloud_host_id)
114
175
  super()
115
- @service = service
116
- @host = host
176
+ @svc_id = svc_id
177
+ @cloud_host_id = cloud_host_id
117
178
  end
118
179
  end
119
180
 
@@ -135,22 +196,6 @@ module Wakame
135
196
  end
136
197
  end
137
198
 
138
- class ServiceDestroied < Base
139
- attr_reader :service
140
- def initialize(svc_inst)
141
- super()
142
- @service = svc_inst
143
- end
144
- end
145
-
146
- class ServicePropagated < Base
147
- attr_reader :service
148
- def initialize(svc_inst)
149
- super()
150
- @service = svc_inst
151
- end
152
- end
153
-
154
199
  class CommandReceived < Base
155
200
  attr_reader :command
156
201
  def initialize(command)
@@ -197,6 +242,13 @@ module Wakame
197
242
  class JobStart < JobEvent
198
243
  end
199
244
  class JobComplete < JobEvent
245
+ attr_reader :status
246
+ def initialize(job_id, status)
247
+ super(job_id)
248
+ @status = status
249
+ end
250
+ end
251
+ class JobSuccess < JobEvent
200
252
  end
201
253
  class JobFailed < JobEvent
202
254
  attr_reader :exception
@@ -100,8 +100,8 @@ module Wakame
100
100
  def fire_event(event_obj)
101
101
  raise ArgumentError unless event_obj.is_a?(Event::Base)
102
102
 
103
- if Wakame.log.level == 'DEBUG' && !FIRE_EVENT_LOG_IGNORE_EVENTS.member?(event_obj.class)
104
- Wakame.log.debug("Event #{event_obj.class} has been fired:" + (event_obj.log_message.nil? ? "" : event_obj.log_message) )
103
+ if Wakame.log.level == 0 && !FIRE_EVENT_LOG_IGNORE_EVENTS.member?(event_obj.class)
104
+ Wakame.log.debug("Event #{event_obj.class} has been fired:" + (event_obj.log_message.nil? ? '' : (' ' + event_obj.log_message)) )
105
105
  end
106
106
  tlist = @event_handlers[event_obj.class]
107
107
  return if tlist.nil?
@@ -13,6 +13,10 @@ module Wakame
13
13
  def instance
14
14
  @instance
15
15
  end
16
+
17
+ def loaded_classes
18
+ @loaded_classes ||= []
19
+ end
16
20
  end
17
21
 
18
22
  attr_reader :configuration
@@ -28,7 +32,7 @@ module Wakame
28
32
  end
29
33
 
30
34
  def process_master
31
- process
35
+ require 'wakame/master'
32
36
  setup_database
33
37
  load_resources
34
38
  load_core_commands
@@ -37,8 +41,9 @@ module Wakame
37
41
  end
38
42
 
39
43
  def process_agent
40
- process
44
+ require 'wakame/agent'
41
45
  load_actors
46
+ load_monitors
42
47
  end
43
48
 
44
49
  def process_cli
@@ -86,16 +91,9 @@ module Wakame
86
91
  # end
87
92
  # }
88
93
 
89
- $LOAD_PATH.each{ |d|
90
- Dir.glob("#{d}/wakame/command/**/*.rb").each{ |f|
91
- f =~ %r{(wakame/command/.+)\.rb\Z}
92
- require "#{$1}"
93
- }
94
- }
95
-
96
- #%w(launch_cluster shutdown_cluster status action_status actor).each { |f|
97
- # require "wakame/command/#{f}"
98
- #}
94
+ load_framework('wakame/command/**/*.rb', lambda{ |f|
95
+ Wakame.log.debug("Loading Core Commands: #{f}")
96
+ })
99
97
  end
100
98
 
101
99
 
@@ -130,35 +128,103 @@ module Wakame
130
128
  end
131
129
 
132
130
  def load_actors
133
- load_path = File.expand_path('cluster/actors', configuration.root_path)
134
- Dir.glob("#{load_path}/*.rb").sort.each do |file|
135
- if file =~ %r{\A#{Regexp.escape(load_path)}/([^/]+)\.rb\Z}
136
- Wakame.log.debug("Loading Actor: #{file}")
137
- load file
138
- end
139
- end
131
+ load_framework('wakame/actor/**/*.rb', lambda{ |f|
132
+ Wakame.log.debug("Loading Core Actor: #{f}")
133
+ })
134
+
135
+ load_project('cluster/actors/*.rb', lambda{ |f|
136
+ Wakame.log.debug("Loading Project Actor: #{f}")
137
+ })
138
+ end
139
+
140
+ def load_monitors
141
+ load_framework('wakame/monitor/**/*.rb', lambda{ |f|
142
+ Wakame.log.debug("Loading Core Monitor: #{f}")
143
+ })
144
+
145
+ #load_project('cluster/monitors/*.rb', lambda{ |f|
146
+ # Wakame.log.debug("Loading Project Monitor: #{f}")
147
+ # })
140
148
  end
141
149
 
142
150
  def load_core_triggers
143
- $LOAD_PATH.each{ |d|
144
- Dir.glob("#{d}/wakame/triggers/**/*.rb").each{ |f|
145
- f =~ %r{(wakame/triggers/.+)\.rb\Z}
146
- require "#{$1}"
147
- }
148
- }
151
+ load_framework("wakame/triggers/**/*.rb", lambda{ |f|
152
+ Wakame.log.debug("Loading Core triggers: #{f}")
153
+ })
149
154
  end
150
155
 
151
156
  def load_core_actions
152
- $LOAD_PATH.each{ |d|
153
- Dir.glob("#{d}/wakame/actions/**/*.rb").each{ |f|
154
- f =~ %r{(wakame/actions/.+)\.rb\Z}
155
- require "#{$1}"
157
+ load_framework("wakame/actions/**/*.rb", lambda{ |f|
158
+ Wakame.log.debug("Loading Core Actions: #{f}")
159
+ })
160
+ end
161
+
162
+ def setup_database
163
+ require 'sequel'
164
+
165
+ #db = Sequel.connect(Wakame.config.status_db_dsn, {:logger=>Wakame.log})
166
+ #db = Sequel.connect(Wakame.config.status_db_dsn, {:timeout=>15000})
167
+ db = Sequel.connect(Wakame.config.status_db_dsn)
168
+ if db.uri =~ /\Asqlite:/
169
+ orig_proc = db.pool.connection_proc
170
+ db.pool.connection_proc = proc { |svr|
171
+ con = orig_proc.call(svr)
172
+ con.busy_handler {|data, retries|
173
+ if retries > 5
174
+ Wakame.log.fatal("Detected the SQLite's busy lock: #{Thread.current}, data=#{data}, retries=#{retries}")
175
+ exit 100
176
+ end
177
+ sleep 8
178
+ true
179
+ }
180
+ con
156
181
  }
182
+ end
183
+
184
+ load_framework('wakame/models/*.rb',
185
+ lambda {|path| self.class.loaded_classes.clear},
186
+ lambda {|path|
187
+
188
+ self.class.loaded_classes.each { |model_class|
189
+ next unless model_class.is_a?(Class) && model_class < Sequel::Model
190
+
191
+ model_class.create_table?
192
+ }
193
+
194
+ })
195
+
196
+
197
+ if db.table_exists?(:metadata)
198
+ else
199
+ db.create_table? :metadata do
200
+ primary_key :id
201
+ column :version, :string
202
+ column :created_at, :datetime
203
+ end
204
+ db[:metadata].insert(:version=>'0.4', :created_at=>Time.now)
205
+ end
206
+
207
+ end
208
+
209
+ def load_framework(glob_pat, pre_hook=nil, post_hook=nil)
210
+ if Wakame::Bootstrap.boot_type == Wakame::Bootstrap::VendorBoot
211
+ rbfiles = Dir.glob(File.expand_path(glob_pat, File.join(configuration.framework_root_path, 'lib')))
212
+ else
213
+ rbfiles = Gem.find_files(glob_pat)
214
+ end
215
+ rbfiles.sort.each{ |f|
216
+ pre_hook.call(f) if pre_hook
217
+ load f
218
+ post_hook.call(f) if post_hook
157
219
  }
158
220
  end
159
221
 
160
- def setup_database
161
- Wakame::StatusDB.adapter
222
+ def load_project(glob_pat, pre_hook=nil, post_hook=nil)
223
+ Dir.glob(File.expand_path(glob_pat, configuration.root_path)).sort.each{ |f|
224
+ (pre_hook.call(f) || next) if pre_hook
225
+ load f
226
+ post_hook.call(f) if post_hook
227
+ }
162
228
  end
163
229
 
164
230
  end
@@ -7,346 +7,6 @@ require 'wakame/queue_declare'
7
7
 
8
8
  module Wakame
9
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
-
30
- class AgentMonitor
31
- include Manager
32
- include ThreadImmutable
33
-
34
- def init
35
- @agent_timeout = 31.to_f
36
- @agent_kill_timeout = @agent_timeout * 2
37
- @gc_period = 20.to_f
38
-
39
- Service::AgentPool.reset
40
-
41
- # GC event trigger for agent timer & status
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
- }
59
-
60
- #Wakame.log.debug("Finished agent GC")
61
- }
62
- }
63
-
64
-
65
- master.add_subscriber('registry') { |data|
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
- }
83
-
84
- }
85
-
86
- master.add_subscriber('ping') { |data|
87
- ping = eval(data)
88
- # Skip the old ping responses before starting master node.
89
- next if Time.parse(ping[:responded_at]) < master.started_at
90
-
91
- # Variable update function for the common members
92
- set_report_values = proc { |agent|
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)
100
- }
101
-
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
114
-
115
- EventDispatcher.fire_event(Event::AgentPong.new(agent))
116
- }
117
- }
118
-
119
- master.add_subscriber('agent_event') { |data|
120
- response = eval(data)
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
146
- else
147
- Wakame.log.warn("#{self.class}: Unhandled agent response: #{response[:class_type]}")
148
- end
149
- }
150
- }
151
-
152
- end
153
-
154
- def terminate
155
- @agent_timeout_timer.cancel
156
- end
157
-
158
- def agent_pool
159
- Service::AgentPool.instance
160
- end
161
-
162
- end
163
-
164
-
165
-
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
184
-
185
-
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
- }
216
-
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
- }
227
- }
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)
238
- }
239
- end
240
-
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
249
-
250
- def unregister(cluster_id)
251
- @clusters.delete(cluster_id)
252
- end
253
-
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
260
-
261
-
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
345
- end
346
-
347
- ServiceClusterPool.initialize_table
348
- end
349
-
350
10
  class Master
351
11
  include Wakame::AMQPClient
352
12
  include Wakame::QueueDeclare
@@ -375,7 +35,7 @@ module Wakame
375
35
  end
376
36
 
377
37
  def register_manager(manager)
378
- raise ArgumentError unless manager.kind_of? Manager
38
+ raise ArgumentError unless manager.kind_of? MasterManager
379
39
  manager.master = self
380
40
  @managers << manager
381
41
  manager
@@ -384,22 +44,39 @@ module Wakame
384
44
  # post_setup
385
45
  def init
386
46
  raise 'has to be put in EM.run context' unless EM.reactor_running?
387
- @command_queue = register_manager(CommandQueue.new)
47
+ @command_queue = register_manager(MasterManagers::CommandQueue.new)
388
48
 
389
49
  # 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)
50
+ @agent_monitor = register_manager(MasterManagers::AgentMonitor.new)
51
+ @cluster_manager = register_manager(MasterManagers::ClusterManager.new)
52
+ @action_manager = register_manager(MasterManagers::ActionManager.new)
393
53
 
394
54
  @managers.each {|m|
395
55
  Wakame.log.debug("Initializing Manager Module: #{m.class}")
396
56
  m.init
397
57
  }
398
58
 
399
- Wakame.log.info("Started master process : WAKAME_ROOT=#{Wakame.config.root_path} WAKAME_ENV=#{Wakame.config.environment}")
59
+ Wakame.log.info("Started master process : AMQP Server=#{amqp_server_uri.to_s} WAKAME_ROOT=#{Wakame.config.root_path} WAKAME_ENV=#{Wakame.config.environment} WAKAME_CLUSTER_ENV=#{Wakame.config.cluster_env}")
400
60
  end
401
61
 
402
62
 
63
+ def self.ec2_query_metadata_uri(key)
64
+ require 'open-uri'
65
+ open("http://169.254.169.254/2008-02-01/meta-data/#{key}"){|f|
66
+ return f.readline
67
+ }
68
+ end
69
+
70
+ def self.ec2_fetch_local_attrs
71
+ attrs = {}
72
+ %w[instance-id instance-type local-ipv4 local-hostname public-hostname public-ipv4 ami-id].each{|key|
73
+ rkey = key.tr('-', '_')
74
+ attrs[rkey.to_sym]=ec2_query_metadata_uri(key)
75
+ }
76
+ attrs[:availability_zone]=ec2_query_metadata_uri('placement/availability-zone')
77
+ attrs
78
+ end
79
+
403
80
  private
404
81
  def pre_setup
405
82
  @started_at = Time.now