wakame 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/History.txt +20 -0
  2. data/README.rdoc +63 -0
  3. data/Rakefile +86 -0
  4. data/VERSION +1 -0
  5. data/app_generators/wakame/templates/README +0 -0
  6. data/app_generators/wakame/templates/Rakefile +18 -0
  7. data/app_generators/wakame/templates/bin/wakame-agent +9 -0
  8. data/app_generators/wakame/templates/bin/wakame-master +9 -0
  9. data/app_generators/wakame/templates/bin/wakameadm +9 -0
  10. data/app_generators/wakame/templates/cluster/resources/apache_app/apache_app.rb +54 -0
  11. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/apache2.conf +46 -0
  12. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/envvars-app +7 -0
  13. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/sites-app.conf +23 -0
  14. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/system-app.conf +67 -0
  15. data/app_generators/wakame/templates/cluster/resources/apache_app/init.d/apache2-app +192 -0
  16. data/app_generators/wakame/templates/cluster/resources/apache_lb/apache_lb.rb +56 -0
  17. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/apache2.conf +46 -0
  18. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/envvars-lb +6 -0
  19. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/sites-lb.conf +54 -0
  20. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/system-lb.conf +75 -0
  21. data/app_generators/wakame/templates/cluster/resources/apache_lb/init.d/apache2-lb +192 -0
  22. data/app_generators/wakame/templates/cluster/resources/apache_www/apache_www.rb +50 -0
  23. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/apache2.conf +47 -0
  24. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/envvars-www +7 -0
  25. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/sites-www.conf +23 -0
  26. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/system-www.conf +63 -0
  27. data/app_generators/wakame/templates/cluster/resources/apache_www/init.d/apache2-www +192 -0
  28. data/app_generators/wakame/templates/cluster/resources/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
  29. data/app_generators/wakame/templates/cluster/resources/mysql_master/conf/my.cnf +154 -0
  30. data/app_generators/wakame/templates/cluster/resources/mysql_master/init.d/mysql +185 -0
  31. data/app_generators/wakame/templates/cluster/resources/mysql_master/mysql_master.rb +174 -0
  32. data/app_generators/wakame/templates/config/boot.rb +85 -0
  33. data/app_generators/wakame/templates/config/cluster.rb +64 -0
  34. data/app_generators/wakame/templates/config/environments/common.rb +0 -0
  35. data/app_generators/wakame/templates/config/environments/ec2.rb +3 -0
  36. data/app_generators/wakame/templates/config/environments/stand_alone.rb +0 -0
  37. data/app_generators/wakame/templates/config/init.d/wakame-agent +72 -0
  38. data/app_generators/wakame/templates/config/init.d/wakame-master +73 -0
  39. data/app_generators/wakame/wakame_generator.rb +124 -0
  40. data/bin/wakame +18 -0
  41. data/contrib/imagesetup.sh +77 -0
  42. data/lib/ext/eventmachine.rb +86 -0
  43. data/lib/ext/shellwords.rb +172 -0
  44. data/lib/ext/uri.rb +15 -0
  45. data/lib/wakame/action.rb +156 -0
  46. data/lib/wakame/actions/destroy_instances.rb +39 -0
  47. data/lib/wakame/actions/launch_cluster.rb +31 -0
  48. data/lib/wakame/actions/migrate_service.rb +65 -0
  49. data/lib/wakame/actions/propagate_instances.rb +95 -0
  50. data/lib/wakame/actions/reload_service.rb +21 -0
  51. data/lib/wakame/actions/scaleout_when_high_load.rb +44 -0
  52. data/lib/wakame/actions/shutdown_cluster.rb +22 -0
  53. data/lib/wakame/actions/shutdown_vm.rb +19 -0
  54. data/lib/wakame/actions/start_service.rb +64 -0
  55. data/lib/wakame/actions/stop_service.rb +49 -0
  56. data/lib/wakame/actions/util.rb +71 -0
  57. data/lib/wakame/actor/daemon.rb +37 -0
  58. data/lib/wakame/actor/service_monitor.rb +21 -0
  59. data/lib/wakame/actor/system.rb +46 -0
  60. data/lib/wakame/actor.rb +33 -0
  61. data/lib/wakame/agent.rb +226 -0
  62. data/lib/wakame/amqp_client.rb +219 -0
  63. data/lib/wakame/command/action_status.rb +62 -0
  64. data/lib/wakame/command/actor.rb +23 -0
  65. data/lib/wakame/command/clone_service.rb +12 -0
  66. data/lib/wakame/command/launch_cluster.rb +15 -0
  67. data/lib/wakame/command/migrate_service.rb +21 -0
  68. data/lib/wakame/command/propagate_service.rb +24 -0
  69. data/lib/wakame/command/shutdown_cluster.rb +15 -0
  70. data/lib/wakame/command/status.rb +81 -0
  71. data/lib/wakame/command.rb +31 -0
  72. data/lib/wakame/command_queue.rb +44 -0
  73. data/lib/wakame/configuration.rb +93 -0
  74. data/lib/wakame/daemonize.rb +96 -0
  75. data/lib/wakame/event.rb +232 -0
  76. data/lib/wakame/event_dispatcher.rb +154 -0
  77. data/lib/wakame/graph.rb +79 -0
  78. data/lib/wakame/initializer.rb +162 -0
  79. data/lib/wakame/instance_counter.rb +78 -0
  80. data/lib/wakame/logger.rb +12 -0
  81. data/lib/wakame/manager/commands.rb +134 -0
  82. data/lib/wakame/master.rb +369 -0
  83. data/lib/wakame/monitor/agent.rb +50 -0
  84. data/lib/wakame/monitor/service.rb +183 -0
  85. data/lib/wakame/monitor.rb +69 -0
  86. data/lib/wakame/packets.rb +160 -0
  87. data/lib/wakame/queue_declare.rb +14 -0
  88. data/lib/wakame/rule.rb +116 -0
  89. data/lib/wakame/rule_engine.rb +202 -0
  90. data/lib/wakame/runner/administrator_command.rb +112 -0
  91. data/lib/wakame/runner/agent.rb +81 -0
  92. data/lib/wakame/runner/master.rb +93 -0
  93. data/lib/wakame/scheduler.rb +251 -0
  94. data/lib/wakame/service.rb +914 -0
  95. data/lib/wakame/template.rb +189 -0
  96. data/lib/wakame/trigger.rb +66 -0
  97. data/lib/wakame/triggers/instance_count_update.rb +45 -0
  98. data/lib/wakame/triggers/load_history.rb +107 -0
  99. data/lib/wakame/triggers/maintain_ssh_known_hosts.rb +43 -0
  100. data/lib/wakame/triggers/process_command.rb +34 -0
  101. data/lib/wakame/triggers/shutdown_unused_vm.rb +16 -0
  102. data/lib/wakame/util.rb +569 -0
  103. data/lib/wakame/vm_manipulator.rb +186 -0
  104. data/lib/wakame.rb +59 -0
  105. data/tasks/ec2.rake +127 -0
  106. data/tests/cluster.json +3 -0
  107. data/tests/conf/a +1 -0
  108. data/tests/conf/b +1 -0
  109. data/tests/conf/c +1 -0
  110. data/tests/setup_agent.rb +39 -0
  111. data/tests/setup_master.rb +28 -0
  112. data/tests/test_actor.rb +54 -0
  113. data/tests/test_agent.rb +218 -0
  114. data/tests/test_amqp_client.rb +94 -0
  115. data/tests/test_graph.rb +36 -0
  116. data/tests/test_master.rb +167 -0
  117. data/tests/test_monitor.rb +47 -0
  118. data/tests/test_rule_engine.rb +127 -0
  119. data/tests/test_scheduler.rb +123 -0
  120. data/tests/test_service.rb +60 -0
  121. data/tests/test_template.rb +67 -0
  122. data/tests/test_uri_amqp.rb +19 -0
  123. data/tests/test_util.rb +71 -0
  124. data/wakame_generators/resource/resource_generator.rb +54 -0
  125. data/wakame_generators/resource/templates/apache_app/apache_app.rb +60 -0
  126. data/wakame_generators/resource/templates/apache_app/conf/apache2.conf +46 -0
  127. data/wakame_generators/resource/templates/apache_app/conf/envvars-app +7 -0
  128. data/wakame_generators/resource/templates/apache_app/conf/sites-app.conf +23 -0
  129. data/wakame_generators/resource/templates/apache_app/conf/system-app.conf +67 -0
  130. data/wakame_generators/resource/templates/apache_app/init.d/apache2-app +192 -0
  131. data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +67 -0
  132. data/wakame_generators/resource/templates/apache_lb/conf/apache2.conf +46 -0
  133. data/wakame_generators/resource/templates/apache_lb/conf/envvars-lb +6 -0
  134. data/wakame_generators/resource/templates/apache_lb/conf/sites-lb.conf +54 -0
  135. data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +75 -0
  136. data/wakame_generators/resource/templates/apache_lb/init.d/apache2-lb +192 -0
  137. data/wakame_generators/resource/templates/apache_www/apache_www.rb +56 -0
  138. data/wakame_generators/resource/templates/apache_www/conf/apache2.conf +47 -0
  139. data/wakame_generators/resource/templates/apache_www/conf/envvars-www +7 -0
  140. data/wakame_generators/resource/templates/apache_www/conf/sites-www.conf +23 -0
  141. data/wakame_generators/resource/templates/apache_www/conf/system-www.conf +63 -0
  142. data/wakame_generators/resource/templates/apache_www/init.d/apache2-www +192 -0
  143. data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
  144. data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +154 -0
  145. data/wakame_generators/resource/templates/mysql_master/init.d/mysql +185 -0
  146. data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +119 -0
  147. metadata +289 -0
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'rubygems'
4
+
5
+ require 'eventmachine'
6
+ require 'mq'
7
+ require 'thread'
8
+
9
+ require 'wakame'
10
+ require 'wakame/amqp_client'
11
+ require 'wakame/queue_declare'
12
+ require 'wakame/event'
13
+ require 'wakame/vm_manipulator'
14
+
15
+
16
+ module Wakame
17
+ class Agent
18
+ include AMQPClient
19
+ include QueueDeclare
20
+
21
+ #define_queue 'agent_command.%{agent_id}', 'agent_command', {:key=>'agent_id.%{agent_id}', :auto_delete=>true}
22
+ define_queue 'agent_actor.%{agent_id}', 'agent_command', {:key=>'agent_id.%{agent_id}', :auto_delete=>true}
23
+
24
+ attr_reader :actor_registry, :monitor_registry
25
+
26
+ def agent_id
27
+ @agent_id
28
+ end
29
+
30
+ def initialize(opts={})
31
+ determine_agent_id
32
+ @actor_registry = ActorRegistry.new
33
+ @monitor_registry = MonitorRegistry.new
34
+
35
+ connect(opts)
36
+
37
+ setup_monitors
38
+ setup_actors
39
+ setup_dispatcher
40
+
41
+ publish_to('registry', Packets::Register.new(self, Wakame.config.root_path.to_s).marshal)
42
+ Wakame.log.info("Started agent process : WAKAME_ROOT=#{Wakame.config.root_path} WAKAME_ENV=#{Wakame.config.environment}")
43
+ end
44
+
45
+ # def send_event_response(event)
46
+ # Wakame.log.debug("Sending event to master : #{event.class}")
47
+ # publish_to('agent_event', Marshal.dump(Packets::EventResponse.new(self, event)))
48
+ # end
49
+
50
+ def cleanup
51
+ publish_to('registry', Packets::UnRegister.new(self).marshal)
52
+ #@cmd_t.kill
53
+ end
54
+
55
+ def determine_agent_id
56
+ if Wakame.config.environment == :EC2
57
+ @agent_id = VmManipulator::EC2::MetadataService.query_metadata_uri('instance-id')
58
+ else
59
+ @agent_id = VmManipulator::StandAlone::INSTANCE_ID
60
+ end
61
+ end
62
+
63
+
64
+ def setup_monitors
65
+ load_monitors
66
+
67
+ @monitor_registry.register(Monitor::Agent.new, '/agent')
68
+ @monitor_registry.register(Monitor::Service.new, '/service')
69
+
70
+ @monitor_registry.monitors.each { |path, mon|
71
+ mon.agent = self
72
+ mon.setup(path)
73
+ }
74
+ end
75
+
76
+ def load_monitors
77
+ require 'wakame/monitor/agent'
78
+ require 'wakame/monitor/service'
79
+ end
80
+
81
+ def setup_actors
82
+ load_actors
83
+
84
+ @actor_registry.register(Actor::ServiceMonitor.new, '/service_monitor')
85
+ @actor_registry.register(Actor::Daemon.new, '/daemon')
86
+ @actor_registry.register(Actor::System.new, '/system')
87
+ @actor_registry.actors.each { |path, actor|
88
+ # actor.setup(path)
89
+ actor.agent = self
90
+ }
91
+ end
92
+
93
+ def load_actors
94
+ require 'wakame/actor/service_monitor'
95
+ require 'wakame/actor/daemon'
96
+ require 'wakame/actor/system'
97
+ end
98
+
99
+
100
+ def setup_dispatcher
101
+ @dispatcher = Dispatcher.new(self)
102
+
103
+ add_subscriber("agent_actor.#{agent_id}") { |data|
104
+ begin
105
+ request = eval(data)
106
+ @dispatcher.handle_request(request)
107
+ rescue => e
108
+ Wakame.log.error(e)
109
+ agent.publish_to('agent_event', Packets::ActorResponse.new(self, request[:token], Actor::STATUS_FAILED).marshal)
110
+ end
111
+ }
112
+ end
113
+
114
+ end
115
+
116
+
117
+ class ActorRegistry
118
+ attr_reader :actors
119
+ def initialize()
120
+ @actors = {}
121
+ end
122
+
123
+ def register(actor, path=nil)
124
+ raise '' unless actor.kind_of?(Wakame::Actor)
125
+
126
+ if path.nil?
127
+ path = '/' + Util.to_const_path(actor.class.to_s)
128
+ end
129
+
130
+ if @actors.has_key?(path)
131
+ Wakame.log.error("#{self.class}: Duplicate registration: #{path}")
132
+ raise "Duplicate registration: #{path}"
133
+ end
134
+
135
+ @actors[path] = actor
136
+ end
137
+
138
+ def unregister(path)
139
+ @actors.delete(path)
140
+ end
141
+
142
+ def find_actor(path)
143
+ @actors[path]
144
+ end
145
+
146
+ end
147
+
148
+
149
+ class MonitorRegistry
150
+ attr_reader :monitors
151
+ def initialize()
152
+ @monitors = {}
153
+ end
154
+
155
+ def register(monitor, path=nil)
156
+ raise '' unless monitor.kind_of?(Wakame::Monitor)
157
+
158
+ if path.nil?
159
+ path = '/' + Util.to_const_path(monitor.class.to_s)
160
+ end
161
+
162
+ if @monitors.has_key?(path)
163
+ Wakame.log.error("#{self.class}: Duplicate registration: #{path}")
164
+ raise "Duplicate registration: #{path}"
165
+ end
166
+
167
+ @monitors[path] = monitor
168
+ end
169
+
170
+ def unregister(path)
171
+ @monitors.delete(path)
172
+ end
173
+
174
+ def find_monitor(path)
175
+ @monitors[path]
176
+ end
177
+ end
178
+
179
+
180
+ class Dispatcher
181
+ attr_reader :agent
182
+
183
+ def initialize(agent)
184
+ @agent = agent
185
+ end
186
+
187
+ def handle_request(request)
188
+ slash = request[:path].rindex('/')
189
+ raise "Invalid request path: #{request[:path]}" unless slash
190
+
191
+ prefix = request[:path][0, slash]
192
+ action = request[:path][slash+1, request[:path].length]
193
+
194
+ actor = agent.actor_registry.find_actor(prefix)
195
+ unless actor
196
+ Wakame.log.error("No refered actor instance: #{prefix}")
197
+ raise
198
+ end
199
+
200
+ EM.defer(proc {
201
+ return begin
202
+ Wakame.log.debug("#{self.class}: Started to run the actor: #{actor.class}, token=#{request[:token]}")
203
+ agent.publish_to('agent_event', Packets::ActorResponse.new(agent, request[:token], Actor::STATUS_RUNNING).marshal)
204
+ if request[:args].nil?
205
+ actor.send(action)
206
+ else
207
+ actor.send(action, *request[:args])
208
+ end
209
+ Wakame.log.debug("#{self.class}: Finished to run the actor: #{actor.class}, token=#{request[:token]}")
210
+ rescue => e
211
+ Wakame.log.error("#{self.class}: Failed the actor: #{actor.class}, token=#{request[:token]}")
212
+ Wakame.log.error(e)
213
+ e
214
+ end
215
+ }, proc { |res|
216
+ status = Actor::STATUS_SUCCESS
217
+ if res.is_a?(Exception)
218
+ status = Actor::STATUS_FAILED
219
+ end
220
+ agent.publish_to('agent_event', Packets::ActorResponse.new(self.agent, request[:token], status).marshal)
221
+ })
222
+ end
223
+ end
224
+
225
+
226
+ end
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'mutex_m'
4
+
5
+ require 'eventmachine'
6
+ require 'ext/eventmachine'
7
+ require 'amqp'
8
+ require 'mq'
9
+
10
+ module Wakame
11
+ module AMQPClient
12
+
13
+ def self.included(klass)
14
+ klass.extend(ClassMethods)
15
+ klass.class_eval {
16
+ }
17
+ end
18
+
19
+ module ClassMethods
20
+ attr_reader :instance
21
+ attr_reader :defered_setup_calls
22
+
23
+ def start(*opts)
24
+ pr = proc {
25
+ if self.instance.nil?
26
+ @instance = new(*opts)
27
+ end
28
+ @instance
29
+ }
30
+
31
+ if EM.reactor_running?
32
+ return pr.call
33
+ else
34
+ EM.run pr
35
+ end
36
+ end
37
+
38
+
39
+ def stop(&blk)
40
+ #EM.add_timer(1){
41
+ EM.next_tick {
42
+ end_proc = proc {
43
+ EventDispatcher.reset
44
+
45
+ unless blk.nil?
46
+ blk.call
47
+ end
48
+ EM.stop
49
+ }
50
+
51
+ catch(:nop) {
52
+ if @instance.nil?
53
+ end_proc.call
54
+ throw :nop
55
+ end
56
+
57
+ begin
58
+ unless @instance.amqp_client.nil?
59
+ @instance.close { end_proc.call }
60
+ else
61
+ end_proc.call
62
+ end
63
+ ensure
64
+ @instance = nil
65
+ end
66
+ }
67
+ }
68
+ end
69
+
70
+ def amq
71
+ Thread.current[:mq]
72
+ end
73
+
74
+ def publish_to(*args)
75
+ self.instance.publish_to(*args)
76
+ end
77
+
78
+ def add_subscriber(*args)
79
+ self.instance.add_subscriber(*args)
80
+ end
81
+
82
+ def define_exchange(name, type=:fanout)
83
+ def_ex = proc { |inst|
84
+ inst.amq.__send__(type, name)
85
+ }
86
+
87
+ (@defered_setup_calls ||= []) << def_ex
88
+
89
+ #if !@instance.nil? && @instance.connected?
90
+ # def_ex.call(@instance)
91
+ #end
92
+ end
93
+
94
+ def define_queue(name, exchange_name, opts={})
95
+ def_q = proc { |inst|
96
+ inst.define_queue(name, exchange_name, opts)
97
+ }
98
+
99
+ (@defered_setup_calls ||= []) << def_q
100
+
101
+ #if !@instance.nil? && @instance.connected?
102
+ # def_q.call(@instance)
103
+ #end
104
+ end
105
+
106
+ end
107
+
108
+ attr_reader :mq, :amqp_client
109
+
110
+ def connect(*args)
111
+ close() unless connected?
112
+ @amqp_client = AMQP.connect(*args)
113
+ @mq = Thread.current[:mq] = MQ.new(@amqp_client)
114
+
115
+ run_defered_callbacks
116
+ yield if block_given?
117
+ end
118
+
119
+ def connected?
120
+ !@amqp_client.nil?
121
+ end
122
+
123
+ def amq
124
+ raise 'AMQP connection is not established yet' if Thread.current[:mq].nil?
125
+ Thread.current[:mq]
126
+ end
127
+
128
+ def cleanup
129
+ end
130
+
131
+ def close(&blk)
132
+ closing_proc = proc {
133
+ begin
134
+ cleanup
135
+ yield if block_given?
136
+ ensure
137
+ @amqp_client = nil
138
+ @mq = Thread.current[:mq] = nil
139
+ end
140
+ }
141
+
142
+ @amqp_client.close {
143
+ closing_proc.call
144
+ } unless @amqp_client.nil?
145
+ end
146
+
147
+ #
148
+ # When you want to broadcast the data to all bound queues:
149
+ # publish_to('exchange name', 'data')
150
+ # publish_to('exchange name', '*', 'data')
151
+ # When you want to send the data to keyed queue(s):
152
+ # publish_to('exchange name', 'group.1', 'data')
153
+ def publish_to(name, *args)
154
+ publish_proc = proc {
155
+ ex = amq.exchanges[name] || raise("Undefined exchange name : #{name}")
156
+ case ex.type
157
+ when :topic
158
+ if args.size == 1
159
+ key = '*'
160
+ data = args[0]
161
+ else
162
+ key = args[0].to_s
163
+ data = args[1]
164
+ end
165
+ else
166
+ data = args[0]
167
+ end
168
+ ex.publish(data, :key=>key)
169
+ }
170
+
171
+ if Thread.current[:mq].nil?
172
+ EM.next_tick { publish_proc.call }
173
+ else
174
+ publish_proc.call
175
+ end
176
+ end
177
+
178
+ def define_queue(name, exchange_name, opts={})
179
+ name = instance_eval('"' + name.gsub(/%\{/, '#{') + '"')
180
+ opts.each { |k,v|
181
+ if v.is_a? String
182
+ opts[k] = instance_eval('"' + v.gsub(/%\{/, '#{') + '"')
183
+ end
184
+ }
185
+
186
+ @queue_subscribers ||= {}
187
+
188
+ q = amq.queue(name, opts)
189
+ q.bind( exchange_name, opts ).subscribe {|data|
190
+ unless queue_subscribers[name].nil?
191
+ queue_subscribers[name].each { |p|
192
+ p.call(data)
193
+ }
194
+ end
195
+ }
196
+ end
197
+
198
+ attr_reader :queue_subscribers
199
+
200
+ def add_subscriber(queue_name, &blk)
201
+ # @mq object can be used here as it is just for checing the member of defined queues.
202
+ raise "Undefined queue name : #{queue_name}" unless @mq.queues.has_key?(queue_name)
203
+ EM.barrier {
204
+ @queue_subscribers ||= {}
205
+ @queue_subscribers[queue_name] ||= []
206
+
207
+ @queue_subscribers[queue_name] << blk
208
+ }
209
+ end
210
+
211
+ private
212
+ def run_defered_callbacks
213
+ self.class.defered_setup_calls.each { |p|
214
+ p.call(self)
215
+ }
216
+ end
217
+
218
+ end
219
+ end
@@ -0,0 +1,62 @@
1
+
2
+ require 'erb'
3
+
4
+ class Wakame::Command::ActionStatus
5
+ include Wakame::Command
6
+
7
+ ACTION_STATUS_TMPL=<<__E__
8
+ Running Actions : <%= @status.size %> action(s)
9
+ <%- if @status.size > 0 -%>
10
+ <%- @status.each { |id, j| -%>
11
+ JOB <%= id %> :
12
+ start : <%= j[:created_at] %>
13
+ <%= tree_subactions(j[:root_action]) %>
14
+ <%- } -%>
15
+ <%- end -%>
16
+ __E__
17
+
18
+
19
+ def parse(args)
20
+ end
21
+
22
+ def run(rule)
23
+ walk_subactions = proc { |a, level|
24
+ res = a.dump_attrs
25
+ unless a.subactions.empty?
26
+ res[:subactions] = a.subactions.collect { |s|
27
+ walk_subactions.call(s, level + 1)
28
+ }
29
+ end
30
+ res
31
+ }
32
+
33
+ EM.barrier {
34
+ result = {}
35
+ rule.master.service_cluster.rule_engine.active_jobs.each { |id, v|
36
+ result[id]={:actions=>[], :created_at=>v[:created_at], :src_rule=>v[:src_rule].class.to_s}
37
+
38
+ result[id][:root_action] = walk_subactions.call(v[:root_action], 0)
39
+ }
40
+
41
+ @status = result
42
+ }
43
+ end
44
+
45
+ def print_result
46
+ puts ERB.new(ACTION_STATUS_TMPL, nil, '-').result(binding)
47
+ end
48
+
49
+
50
+ private
51
+ def tree_subactions(root, level=0)
52
+ str= (" " * level) + "#{root[:type]} (#{root[:status]})"
53
+ unless root[:subactions].nil?
54
+ root[:subactions].each { |a|
55
+ str << "\n "
56
+ str << tree_subactions(a, level + 1)
57
+ }
58
+ end
59
+ str
60
+ end
61
+
62
+ end
@@ -0,0 +1,23 @@
1
+
2
+ class Wakame::Command::Actor
3
+ include Wakame::Command
4
+
5
+ command_name='launch_cluster'
6
+
7
+ def parse(args)
8
+ raise "Not enugh number of arguments" if args.size < 2
9
+ @agent_id = args.shift
10
+ @path = args.shift
11
+ @args = *args
12
+ end
13
+
14
+ def run(rule)
15
+ request = rule.master.actor_request(@agent_id, @path, *@args).request
16
+ request
17
+ end
18
+
19
+
20
+ def print_result
21
+
22
+ end
23
+ end
@@ -0,0 +1,12 @@
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
@@ -0,0 +1,15 @@
1
+
2
+
3
+ class Wakame::Command::LaunchCluster
4
+ include Wakame::Command
5
+
6
+ command_name='launch_cluster'
7
+
8
+ def parse(args)
9
+ end
10
+
11
+ def run(rule)
12
+ rule.trigger_action(Wakame::Actions::LaunchCluster.new)
13
+ end
14
+
15
+ end
@@ -0,0 +1,21 @@
1
+
2
+ class Wakame::Command::MigrateService
3
+ include Wakame::Command
4
+
5
+ #command_name='launch_cluster'
6
+
7
+ def parse(args)
8
+ @svc_id = args.shift
9
+ end
10
+
11
+ def run(rule)
12
+ svc = nil
13
+ svc = rule.service_cluster.instances[@svc_id]
14
+ if svc.nil?
15
+ raise "Unknown Service ID: #{@svc_id}"
16
+ end
17
+
18
+ rule.trigger_action(Wakame::Actions::MigrateService.new(svc))
19
+ end
20
+
21
+ end
@@ -0,0 +1,24 @@
1
+
2
+ class Wakame::Command::PropagateService
3
+ include Wakame::Command
4
+
5
+ #command_name='launch_cluster'
6
+
7
+ def parse(args)
8
+ @resname = args.shift
9
+ @num = args.shift unless args.empty?
10
+ end
11
+
12
+ def run(rule)
13
+ prop = nil
14
+ prop = rule.service_cluster.properties[@resname.to_s]
15
+ if prop.nil?
16
+ raise "UnknownProperty: #{@resname}"
17
+ end
18
+
19
+ @num ||= 1
20
+
21
+ rule.trigger_action(Wakame::Actions::PropagateInstances.new(prop, @num))
22
+ end
23
+
24
+ end
@@ -0,0 +1,15 @@
1
+
2
+
3
+ class Wakame::Command::ShutdownCluster
4
+ include Wakame::Command
5
+
6
+ command_name='shutdown_cluster'
7
+
8
+ def parse(args)
9
+ end
10
+
11
+ def run(rule)
12
+ rule.trigger_action(Wakame::Actions::ShutdownCluster.new)
13
+ end
14
+
15
+ end
@@ -0,0 +1,81 @@
1
+
2
+ require 'erb'
3
+
4
+ class Wakame::Command::Status
5
+ include Wakame::Command
6
+
7
+ STATUS_TMPL =<<__E__
8
+ Cluster : <%= @service_cluster[:name].to_s %> (<%= @service_cluster[:status].to_s %>)
9
+ <%- @service_cluster[:properties].each { |prop, v| -%>
10
+ <%= v[:type].to_s %> : <current=<%= v[:instance_count] %> min=<%= v[:min_instances] %>, max=<%= v[:max_instances] %>>
11
+ <%- v[:instances].each { |id|
12
+ svc_inst = @service_cluster[:instances][id]
13
+ -%>
14
+ <%= svc_inst[:instance_id] %> (<%= trans_svc_status(svc_inst[:status]) %>)
15
+ <%- } -%>
16
+ <%- } -%>
17
+ <%- if @service_cluster[:instances].size > 0 -%>
18
+
19
+ Instances :
20
+ <%- @service_cluster[:instances].each { |k, v| -%>
21
+ <%= v[:instance_id] %> : <%= v[:property] %> (<%= trans_svc_status(v[:status]) %>)
22
+ <%- if v[:agent_id ] -%>
23
+ On VM instance: <%= v[:agent_id ]%>
24
+ <%- end -%>
25
+ <%- } -%>
26
+ <%- end -%>
27
+ <%- if @agent_monitor[:registered].size > 0 -%>
28
+
29
+ Agents :
30
+ <%- @agent_monitor[:registered].each { |a| -%>
31
+ <%= a[:agent_id] %> : <%= a[:attr][:local_ipv4] %>, <%= a[:attr][:public_ipv4] %> load=<%= a[:attr][:uptime] %>, <%= (Time.now - a[:last_ping_at]).to_i %> sec(s) <%= a[:root_path] %>(<%= a[:status] %>)
32
+ <%- if !a[:services].nil? && a[:services].size > 0 -%>
33
+ Services (<%= a[:services].size %>): <%= a[:services].collect{|id| @service_cluster[:instances][id][:property] }.join(', ') %>
34
+ <%- end -%>
35
+ <%- } -%>
36
+ <%- end -%>
37
+ __E__
38
+
39
+ SVC_STATUS_MSG={
40
+ Wakame::Service::STATUS_OFFLINE=>'Offline',
41
+ Wakame::Service::STATUS_ONLINE=>'ONLINE',
42
+ Wakame::Service::STATUS_UNKNOWN=>'Unknown',
43
+ Wakame::Service::STATUS_FAIL=>'Fail',
44
+ Wakame::Service::STATUS_STARTING=>'Starting...',
45
+ Wakame::Service::STATUS_STOPPING=>'Stopping...',
46
+ Wakame::Service::STATUS_RELOADING=>'Reloading...',
47
+ Wakame::Service::STATUS_MIGRATING=>'Migrating...',
48
+ }
49
+
50
+ def parse(args)
51
+ end
52
+
53
+ def run(rule)
54
+ EM.barrier {
55
+ master = rule.master
56
+
57
+ sc = master.service_cluster
58
+ #result = {
59
+ # :rule_engine => {
60
+ # :rules => sc.rule_engine.rules
61
+ # },
62
+ # :service_cluster => sc.dump_status,
63
+ # :agent_monitor => master.agent_monitor.dump_status
64
+ #}
65
+
66
+ @service_cluster = master.service_cluster.dump_status
67
+ @agent_monitor = master.agent_monitor.dump_status
68
+ }
69
+ end
70
+
71
+ def print_result
72
+ puts ERB.new(STATUS_TMPL, nil, '-').result(binding)
73
+ end
74
+
75
+
76
+ private
77
+ def trans_svc_status(stat)
78
+ SVC_STATUS_MSG[stat]
79
+ end
80
+
81
+ end