wakame 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +20 -0
- data/README.rdoc +63 -0
- data/Rakefile +86 -0
- data/VERSION +1 -0
- data/app_generators/wakame/templates/README +0 -0
- data/app_generators/wakame/templates/Rakefile +18 -0
- data/app_generators/wakame/templates/bin/wakame-agent +9 -0
- data/app_generators/wakame/templates/bin/wakame-master +9 -0
- data/app_generators/wakame/templates/bin/wakameadm +9 -0
- data/app_generators/wakame/templates/cluster/resources/apache_app/apache_app.rb +54 -0
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/apache2.conf +46 -0
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/envvars-app +7 -0
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/sites-app.conf +23 -0
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/system-app.conf +67 -0
- data/app_generators/wakame/templates/cluster/resources/apache_app/init.d/apache2-app +192 -0
- data/app_generators/wakame/templates/cluster/resources/apache_lb/apache_lb.rb +56 -0
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/apache2.conf +46 -0
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/envvars-lb +6 -0
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/sites-lb.conf +54 -0
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/system-lb.conf +75 -0
- data/app_generators/wakame/templates/cluster/resources/apache_lb/init.d/apache2-lb +192 -0
- data/app_generators/wakame/templates/cluster/resources/apache_www/apache_www.rb +50 -0
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/apache2.conf +47 -0
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/envvars-www +7 -0
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/sites-www.conf +23 -0
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/system-www.conf +63 -0
- data/app_generators/wakame/templates/cluster/resources/apache_www/init.d/apache2-www +192 -0
- data/app_generators/wakame/templates/cluster/resources/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
- data/app_generators/wakame/templates/cluster/resources/mysql_master/conf/my.cnf +154 -0
- data/app_generators/wakame/templates/cluster/resources/mysql_master/init.d/mysql +185 -0
- data/app_generators/wakame/templates/cluster/resources/mysql_master/mysql_master.rb +174 -0
- data/app_generators/wakame/templates/config/boot.rb +85 -0
- data/app_generators/wakame/templates/config/cluster.rb +64 -0
- data/app_generators/wakame/templates/config/environments/common.rb +0 -0
- data/app_generators/wakame/templates/config/environments/ec2.rb +3 -0
- data/app_generators/wakame/templates/config/environments/stand_alone.rb +0 -0
- data/app_generators/wakame/templates/config/init.d/wakame-agent +72 -0
- data/app_generators/wakame/templates/config/init.d/wakame-master +73 -0
- data/app_generators/wakame/wakame_generator.rb +124 -0
- data/bin/wakame +18 -0
- data/contrib/imagesetup.sh +77 -0
- data/lib/ext/eventmachine.rb +86 -0
- data/lib/ext/shellwords.rb +172 -0
- data/lib/ext/uri.rb +15 -0
- data/lib/wakame/action.rb +156 -0
- data/lib/wakame/actions/destroy_instances.rb +39 -0
- data/lib/wakame/actions/launch_cluster.rb +31 -0
- data/lib/wakame/actions/migrate_service.rb +65 -0
- data/lib/wakame/actions/propagate_instances.rb +95 -0
- data/lib/wakame/actions/reload_service.rb +21 -0
- data/lib/wakame/actions/scaleout_when_high_load.rb +44 -0
- data/lib/wakame/actions/shutdown_cluster.rb +22 -0
- data/lib/wakame/actions/shutdown_vm.rb +19 -0
- data/lib/wakame/actions/start_service.rb +64 -0
- data/lib/wakame/actions/stop_service.rb +49 -0
- data/lib/wakame/actions/util.rb +71 -0
- data/lib/wakame/actor/daemon.rb +37 -0
- data/lib/wakame/actor/service_monitor.rb +21 -0
- data/lib/wakame/actor/system.rb +46 -0
- data/lib/wakame/actor.rb +33 -0
- data/lib/wakame/agent.rb +226 -0
- data/lib/wakame/amqp_client.rb +219 -0
- data/lib/wakame/command/action_status.rb +62 -0
- data/lib/wakame/command/actor.rb +23 -0
- data/lib/wakame/command/clone_service.rb +12 -0
- data/lib/wakame/command/launch_cluster.rb +15 -0
- data/lib/wakame/command/migrate_service.rb +21 -0
- data/lib/wakame/command/propagate_service.rb +24 -0
- data/lib/wakame/command/shutdown_cluster.rb +15 -0
- data/lib/wakame/command/status.rb +81 -0
- data/lib/wakame/command.rb +31 -0
- data/lib/wakame/command_queue.rb +44 -0
- data/lib/wakame/configuration.rb +93 -0
- data/lib/wakame/daemonize.rb +96 -0
- data/lib/wakame/event.rb +232 -0
- data/lib/wakame/event_dispatcher.rb +154 -0
- data/lib/wakame/graph.rb +79 -0
- data/lib/wakame/initializer.rb +162 -0
- data/lib/wakame/instance_counter.rb +78 -0
- data/lib/wakame/logger.rb +12 -0
- data/lib/wakame/manager/commands.rb +134 -0
- data/lib/wakame/master.rb +369 -0
- data/lib/wakame/monitor/agent.rb +50 -0
- data/lib/wakame/monitor/service.rb +183 -0
- data/lib/wakame/monitor.rb +69 -0
- data/lib/wakame/packets.rb +160 -0
- data/lib/wakame/queue_declare.rb +14 -0
- data/lib/wakame/rule.rb +116 -0
- data/lib/wakame/rule_engine.rb +202 -0
- data/lib/wakame/runner/administrator_command.rb +112 -0
- data/lib/wakame/runner/agent.rb +81 -0
- data/lib/wakame/runner/master.rb +93 -0
- data/lib/wakame/scheduler.rb +251 -0
- data/lib/wakame/service.rb +914 -0
- data/lib/wakame/template.rb +189 -0
- data/lib/wakame/trigger.rb +66 -0
- data/lib/wakame/triggers/instance_count_update.rb +45 -0
- data/lib/wakame/triggers/load_history.rb +107 -0
- data/lib/wakame/triggers/maintain_ssh_known_hosts.rb +43 -0
- data/lib/wakame/triggers/process_command.rb +34 -0
- data/lib/wakame/triggers/shutdown_unused_vm.rb +16 -0
- data/lib/wakame/util.rb +569 -0
- data/lib/wakame/vm_manipulator.rb +186 -0
- data/lib/wakame.rb +59 -0
- data/tasks/ec2.rake +127 -0
- data/tests/cluster.json +3 -0
- data/tests/conf/a +1 -0
- data/tests/conf/b +1 -0
- data/tests/conf/c +1 -0
- data/tests/setup_agent.rb +39 -0
- data/tests/setup_master.rb +28 -0
- data/tests/test_actor.rb +54 -0
- data/tests/test_agent.rb +218 -0
- data/tests/test_amqp_client.rb +94 -0
- data/tests/test_graph.rb +36 -0
- data/tests/test_master.rb +167 -0
- data/tests/test_monitor.rb +47 -0
- data/tests/test_rule_engine.rb +127 -0
- data/tests/test_scheduler.rb +123 -0
- data/tests/test_service.rb +60 -0
- data/tests/test_template.rb +67 -0
- data/tests/test_uri_amqp.rb +19 -0
- data/tests/test_util.rb +71 -0
- data/wakame_generators/resource/resource_generator.rb +54 -0
- data/wakame_generators/resource/templates/apache_app/apache_app.rb +60 -0
- data/wakame_generators/resource/templates/apache_app/conf/apache2.conf +46 -0
- data/wakame_generators/resource/templates/apache_app/conf/envvars-app +7 -0
- data/wakame_generators/resource/templates/apache_app/conf/sites-app.conf +23 -0
- data/wakame_generators/resource/templates/apache_app/conf/system-app.conf +67 -0
- data/wakame_generators/resource/templates/apache_app/init.d/apache2-app +192 -0
- data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +67 -0
- data/wakame_generators/resource/templates/apache_lb/conf/apache2.conf +46 -0
- data/wakame_generators/resource/templates/apache_lb/conf/envvars-lb +6 -0
- data/wakame_generators/resource/templates/apache_lb/conf/sites-lb.conf +54 -0
- data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +75 -0
- data/wakame_generators/resource/templates/apache_lb/init.d/apache2-lb +192 -0
- data/wakame_generators/resource/templates/apache_www/apache_www.rb +56 -0
- data/wakame_generators/resource/templates/apache_www/conf/apache2.conf +47 -0
- data/wakame_generators/resource/templates/apache_www/conf/envvars-www +7 -0
- data/wakame_generators/resource/templates/apache_www/conf/sites-www.conf +23 -0
- data/wakame_generators/resource/templates/apache_www/conf/system-www.conf +63 -0
- data/wakame_generators/resource/templates/apache_www/init.d/apache2-www +192 -0
- data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
- data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +154 -0
- data/wakame_generators/resource/templates/mysql_master/init.d/mysql +185 -0
- data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +119 -0
- metadata +289 -0
data/lib/wakame/agent.rb
ADDED
@@ -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,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,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
|