wakame 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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