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
@@ -0,0 +1,95 @@
|
|
1
|
+
|
2
|
+
require 'wakame/actions/util'
|
3
|
+
|
4
|
+
module Wakame
|
5
|
+
module Actions
|
6
|
+
class PropagateInstances < Action
|
7
|
+
include Actions::Util
|
8
|
+
|
9
|
+
def initialize(svc_prop, propagate_num=0)
|
10
|
+
raise ArgumentError unless svc_prop.is_a?(Wakame::Service::Resource)
|
11
|
+
@svc_prop = svc_prop
|
12
|
+
@propagate_num = propagate_num
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
svc_to_start = []
|
17
|
+
|
18
|
+
EM.barrier {
|
19
|
+
@propagate_num.times {
|
20
|
+
service_cluster.propagate(@svc_prop)
|
21
|
+
}
|
22
|
+
|
23
|
+
# First, look for the service instances which are already created in the cluster. Then they will be scheduled to start the services later.
|
24
|
+
online_svc = []
|
25
|
+
service_cluster.each_instance(@svc_prop.class) { |svc_inst|
|
26
|
+
if svc_inst.status == Service::STATUS_ONLINE || svc_inst.status == Service::STATUS_STARTING
|
27
|
+
online_svc << svc_inst
|
28
|
+
else
|
29
|
+
svc_to_start << svc_inst
|
30
|
+
end
|
31
|
+
}
|
32
|
+
|
33
|
+
# The list is empty means that this action is called to propagate a new service instance instead of just starting scheduled instances.
|
34
|
+
svc_count = service_cluster.instance_count(@svc_prop)
|
35
|
+
if svc_count > online_svc.size + svc_to_start.size
|
36
|
+
Wakame.log.debug("#{self.class}: @svc_prop.instance_count - online_svc.size=#{svc_count - online_svc.size}")
|
37
|
+
(svc_count - (online_svc.size + svc_to_start.size)).times {
|
38
|
+
svc_to_start << service_cluster.propagate(@svc_prop.class)
|
39
|
+
}
|
40
|
+
end
|
41
|
+
}
|
42
|
+
|
43
|
+
svc_to_start.each { |svc|
|
44
|
+
if svc.property.require_agent
|
45
|
+
# Try to arrange agent from existing agent pool.
|
46
|
+
if svc.agent.nil?
|
47
|
+
EM.barrier {
|
48
|
+
arrange_agent(svc)
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# If the agent pool is empty, will start a new VM slice.
|
53
|
+
if svc.agent.nil?
|
54
|
+
inst_id = start_instance(master.attr[:ami_id], @svc_prop.vm_spec.current.attrs)
|
55
|
+
EM.barrier {
|
56
|
+
arrange_agent(svc, inst_id)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
if svc.agent.nil?
|
61
|
+
Wakame.log.error("Failed to arrange the agent #{svc.instance_id} (#{svc.property.class})")
|
62
|
+
raise "Failed to arrange the agent #{@svc_prop.class}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
trigger_action(StartService.new(svc))
|
67
|
+
}
|
68
|
+
flush_subactions
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
# Arrange an agent for the paticular service instance which does not have agent.
|
73
|
+
def arrange_agent(svc, vm_inst_id=nil)
|
74
|
+
agent = nil
|
75
|
+
if vm_inst_id
|
76
|
+
agent = agent_monitor.registered_agents[vm_inst_id]
|
77
|
+
raise "Cound not find the specified VM instance \"#{vm_inst_id}\"" if agent.nil?
|
78
|
+
raise "Same service is running" if agent.has_service_type? @svc_prop.class
|
79
|
+
else
|
80
|
+
agent_monitor.each_online { |ag|
|
81
|
+
Wakame.log.debug "has_service_type?(#{@svc_prop.class}): #{ag.has_service_type?(@svc_prop.class)}"
|
82
|
+
if test_agent_candidate(@svc_prop, ag)
|
83
|
+
agent = ag
|
84
|
+
break
|
85
|
+
end
|
86
|
+
}
|
87
|
+
end
|
88
|
+
if agent
|
89
|
+
svc.bind_agent(agent)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
class ReloadService < Action
|
4
|
+
def initialize(service_instance)
|
5
|
+
@service_instance = service_instance
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
raise "Agent is not bound on this service : #{@service_instance}" if @service_instance.agent.nil?
|
10
|
+
raise "The assigned agent for the service instance #{@service_instance.instance_id} is not online." unless @service_instance.agent.status == Service::Agent::STATUS_ONLINE
|
11
|
+
|
12
|
+
# Skip to act when the service is having below status.
|
13
|
+
#if @service_instance.status == Service::STATUS_STARTING || @service_instance.status == Service::STATUS_ONLINE
|
14
|
+
# raise "Canceled as the service is being or already ONLINE: #{@service_instance.property}"
|
15
|
+
#end
|
16
|
+
|
17
|
+
master.send_agent_command(Packets::ServiceReload.new(@service_instance.instance_id), @service_instance.agent.agent_id)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Triggers
|
3
|
+
class ScaleoutWhenHighLoad < Trigger
|
4
|
+
def initialize
|
5
|
+
end
|
6
|
+
|
7
|
+
def register_hooks
|
8
|
+
event_subscribe(LoadHistoryMonitor::AgentLoadHighEvent) { |event|
|
9
|
+
if service_cluster.status != Service::ServiceCluster::STATUS_ONLINE
|
10
|
+
Wakame.log.info("Service Cluster is not online yet. Skip to scaling out")
|
11
|
+
next
|
12
|
+
end
|
13
|
+
Wakame.log.debug("Got load high avg: #{event.agent.agent_id}")
|
14
|
+
|
15
|
+
propagate_svc = nil
|
16
|
+
event.agent.services.each { |id, svc|
|
17
|
+
if svc.property.class == Service::Apache_APP
|
18
|
+
propagate_svc = svc
|
19
|
+
break
|
20
|
+
end
|
21
|
+
}
|
22
|
+
|
23
|
+
unless propagate_svc.nil?
|
24
|
+
trigger_action(Actions::PropagateInstancesAction.new(propagate_svc.property))
|
25
|
+
end
|
26
|
+
}
|
27
|
+
|
28
|
+
event_subscribe(LoadHistoryMonitor::AgentLoadNormalEvent) { |event|
|
29
|
+
next
|
30
|
+
|
31
|
+
if service_cluster.status != Service::ServiceCluster::STATUS_ONLINE
|
32
|
+
Wakame.log.info("Service Cluster is not online yet.")
|
33
|
+
next
|
34
|
+
end
|
35
|
+
Wakame.log.debug("Back to normal load: #{event.agent.agent_id}")
|
36
|
+
event.agent.services.each { |id, svc|
|
37
|
+
trigger_action(Actions::StopService.new(svc))
|
38
|
+
}
|
39
|
+
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
class ShutdownCluster < Action
|
4
|
+
def run
|
5
|
+
levels = service_cluster.dg.levels
|
6
|
+
|
7
|
+
levels.reverse.each { |lv|
|
8
|
+
lv.each { |svc_prop|
|
9
|
+
service_cluster.each_instance(svc_prop.class) { |svc_inst|
|
10
|
+
trigger_action(StopService.new(svc_inst))
|
11
|
+
}
|
12
|
+
}
|
13
|
+
flush_subactions
|
14
|
+
}
|
15
|
+
|
16
|
+
agent_monitor.registered_agents.each { |id, agent|
|
17
|
+
trigger_action(ShutdownVM.new(agent))
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
class ShutdownVM < Action
|
4
|
+
def initialize(agent)
|
5
|
+
@agent = agent
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
|
10
|
+
if @agent.agent_id == master.master_local_agent_id
|
11
|
+
Wakame.log.info("Skip to shutdown VM as the master is running on this node: #{@agent.agent_id}")
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
VmManipulator.create.stop_instance(@agent[:instance_id])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
require 'wakame/rule'
|
3
|
+
|
4
|
+
module Wakame
|
5
|
+
module Actions
|
6
|
+
class StartService < Action
|
7
|
+
def initialize(service_instance)
|
8
|
+
@acquire_lock = true
|
9
|
+
@service_instance = service_instance
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
if @service_instance.property.require_agent
|
14
|
+
raise "Agent is not bound on this service : #{@service_instance}" if @service_instance.agent.nil?
|
15
|
+
raise "The assigned agent for the service instance #{@service_instance.instance_id} is not online." unless @service_instance.agent.status == Service::Agent::STATUS_ONLINE
|
16
|
+
end
|
17
|
+
|
18
|
+
# Skip to act when the service is having below status.
|
19
|
+
if @service_instance.status == Service::STATUS_STARTING || @service_instance.status == Service::STATUS_ONLINE
|
20
|
+
raise "Canceled as the service is being or already ONLINE: #{@service_instance.property}"
|
21
|
+
end
|
22
|
+
EM.barrier {
|
23
|
+
@service_instance.update_status(Service::STATUS_STARTING)
|
24
|
+
}
|
25
|
+
|
26
|
+
if @service_instance.property.require_agent
|
27
|
+
Rule::BasicActionSet.deploy_configuration(@service_instance)
|
28
|
+
end
|
29
|
+
|
30
|
+
@service_instance.resource.start(@service_instance, self)
|
31
|
+
|
32
|
+
EM.barrier {
|
33
|
+
Wakame.log.debug("Child nodes: #{@service_instance.property.class}: " + service_cluster.dg.children(@service_instance.property.class).inspect)
|
34
|
+
service_cluster.dg.children(@service_instance.property.class).each { |svc_prop|
|
35
|
+
Wakame.log.debug("Spreading DG child changed: #{@service_instance.property.class} -> #{svc_prop.class}")
|
36
|
+
trigger_action(Actions::CallChildChangeAction.new(svc_prop))
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def on_failed
|
43
|
+
EM.barrier {
|
44
|
+
@service_instance.update_status(Service::STATUS_FAIL)
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class CallChildChangeAction < Action
|
50
|
+
def initialize(resource)
|
51
|
+
@resource = resource
|
52
|
+
#@parent_instance = parent_instance
|
53
|
+
end
|
54
|
+
|
55
|
+
def run
|
56
|
+
Wakame.log.debug("CallChildChangeAction: run: #{@resource.class}")
|
57
|
+
service_cluster.each_instance(@resource.class) { |svc_inst|
|
58
|
+
next if svc_inst.status != Service::STATUS_ONLINE
|
59
|
+
@resource.on_parent_changed(svc_inst, self)
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
class StopService < Action
|
4
|
+
def initialize(service_instance)
|
5
|
+
@acquire_lock = true
|
6
|
+
@service_instance = service_instance
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def run
|
11
|
+
raise "Agent is not bound on this service : #{@service_instance}" if @service_instance.property.require_agent && @service_instance.agent.nil?
|
12
|
+
|
13
|
+
# Skip to act when the service is having below status.
|
14
|
+
if @service_instance.status == Service::STATUS_STOPPING || @service_instance.status == Service::STATUS_OFFLINE
|
15
|
+
raise CancelActionError, "Canceled as the service is being or already OFFLINE: #{@service_instance.property}"
|
16
|
+
end
|
17
|
+
|
18
|
+
EM.barrier {
|
19
|
+
@service_instance.update_status(Service::STATUS_STOPPING)
|
20
|
+
}
|
21
|
+
|
22
|
+
EM.barrier {
|
23
|
+
Wakame.log.debug("Child nodes: #{@service_instance.property.class}: " + service_cluster.dg.children(@service_instance.property.class).inspect)
|
24
|
+
service_cluster.dg.children(@service_instance.property.class).each { |svc_prop|
|
25
|
+
trigger_action(CallChildChangeAction.new(svc_prop))
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
flush_subactions()
|
30
|
+
|
31
|
+
if @service_instance.status == Service::STATUS_ONLINE
|
32
|
+
@service_instance.property.stop(@service_instance, self)
|
33
|
+
else
|
34
|
+
end
|
35
|
+
|
36
|
+
EM.barrier {
|
37
|
+
service_cluster.destroy(@service_instance.instance_id)
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_failed
|
42
|
+
EM.barrier {
|
43
|
+
@service_instance.update_status(Service::STATUS_FAIL)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
module Util
|
4
|
+
|
5
|
+
def deploy_configuration(service_instance)
|
6
|
+
Wakame.log.debug("Begin: #{self}.deploy_configuration(#{service_instance.property.class})")
|
7
|
+
|
8
|
+
begin
|
9
|
+
tmpl = Wakame::Template.new(service_instance)
|
10
|
+
tmpl.render_config
|
11
|
+
|
12
|
+
agent = service_instance.agent
|
13
|
+
src_path = tmpl.tmp_basedir.dup
|
14
|
+
src_path.sub!('/$', '') if File.directory? src_path
|
15
|
+
|
16
|
+
dest_path = File.expand_path("tmp/config/" + File.basename(tmpl.basedir), service_instance.agent.root_path)
|
17
|
+
Wakame::Util.exec("rsync -e 'ssh -i #{Wakame.config.ssh_private_key} -o \"UserKnownHostsFile #{Wakame.config.ssh_known_hosts}\"' -au #{src_path}/ root@#{agent.agent_ip}:#{dest_path}")
|
18
|
+
#Util.exec("rsync -au #{src_path}/ #{dest_path}")
|
19
|
+
|
20
|
+
ensure
|
21
|
+
tmpl.cleanup if tmpl
|
22
|
+
end
|
23
|
+
|
24
|
+
Wakame.log.debug("End: #{self}.deploy_configuration(#{service_instance.property.class})")
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_agent_candidate(svc_prop, agent)
|
28
|
+
return false if agent.has_service_type?(svc_prop.class)
|
29
|
+
svc_prop.vm_spec.current.satisfy?(agent)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Arrange an agent for the paticular service instance from agent pool.
|
33
|
+
def arrange_agent(svc_prop)
|
34
|
+
agent = nil
|
35
|
+
agent_monitor.each_online { |ag|
|
36
|
+
if test_agent_candidate(svc_prop, ag)
|
37
|
+
agent = ag
|
38
|
+
break
|
39
|
+
end
|
40
|
+
}
|
41
|
+
agent = agent[1] if agent
|
42
|
+
|
43
|
+
agent
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def start_instance(image_id, attr={})
|
48
|
+
Wakame.log.debug("#{self.class} called start_instance(#{image_id})")
|
49
|
+
|
50
|
+
attr[:user_data] = "node=agent\namqp_server=amqp://#{master.attr[:local_ipv4]}/"
|
51
|
+
Wakame.log.debug("user_data: #{attr[:user_data]}")
|
52
|
+
vm_manipulator = VmManipulator.create
|
53
|
+
res = vm_manipulator.start_instance(image_id, attr)
|
54
|
+
inst_id = res[:instance_id]
|
55
|
+
|
56
|
+
ConditionalWait.wait { | cond |
|
57
|
+
cond.wait_event(Event::AgentMonitored) { |event|
|
58
|
+
event.agent.attr[:instance_id] == inst_id
|
59
|
+
}
|
60
|
+
|
61
|
+
cond.poll(5, 100) {
|
62
|
+
vm_manipulator.check_status(inst_id, :online)
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
inst_id
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
require 'shellwords'
|
3
|
+
require 'ext/shellwords' unless Shellwords.respond_to? :shellescape
|
4
|
+
|
5
|
+
class Wakame::Actor::Daemon
|
6
|
+
include Wakame::Actor
|
7
|
+
|
8
|
+
|
9
|
+
def start(resource_dir, cmd)
|
10
|
+
Wakame::Util.exec("/usr/bin/env #{env_opts} '#{cmd_abs_path(resource_dir, cmd.dup)}' start")
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop(resource_dir, cmd)
|
14
|
+
Wakame::Util.exec("/usr/bin/env #{env_opts} '#{cmd_abs_path(resource_dir, cmd.dup)}' stop")
|
15
|
+
end
|
16
|
+
|
17
|
+
def reload(resource_dir, cmd)
|
18
|
+
Wakame::Util.exec("/usr/bin/env #{env_opts} '#{cmd_abs_path(resource_dir, cmd.dup)}' reload")
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def env_opts
|
23
|
+
{'WAKAME_ROOT'=>Wakame.config.root_path}.map {|k,v|
|
24
|
+
"#{k}='#{v}'"
|
25
|
+
}.join(' ')
|
26
|
+
end
|
27
|
+
|
28
|
+
def resource_path(resource_dir)
|
29
|
+
sprintf("%s/%s", Wakame.config.config_root, resource_dir)
|
30
|
+
end
|
31
|
+
|
32
|
+
def cmd_abs_path(resource_dir, cmd)
|
33
|
+
Shellwords.shellescape(File.expand_path(cmd.sub(%r{^/}, ''), resource_path(resource_dir)))
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
class Wakame::Actor::ServiceMonitor
|
3
|
+
include Wakame::Actor
|
4
|
+
|
5
|
+
expose '/service_monitor/register', :register
|
6
|
+
def register(svc_id, type, *args)
|
7
|
+
EM.barrier {
|
8
|
+
svcmon = agent.monitor_registry.find_monitor('/service')
|
9
|
+
svcmon.register(svc_id, type, *args)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
expose '/service_monitor/unregister', :unregister
|
14
|
+
def unregister(svc_id)
|
15
|
+
EM.barrier {
|
16
|
+
svcmon = agent.monitor_registry.find_monitor('/service')
|
17
|
+
svcmon.unregister(svc_id)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
require 'ext/shellwords' unless Shellwords.respond_to? :shellescape
|
5
|
+
|
6
|
+
class Wakame::Actor::System
|
7
|
+
include Wakame::Actor
|
8
|
+
|
9
|
+
def mount(dev, path, opts={})
|
10
|
+
raise "#{path} does not exist or not directory." unless File.directory?(path)
|
11
|
+
|
12
|
+
mount_point_dev=`/bin/df "#{path}" | /usr/bin/awk 'NR==2 {print $1}'`.strip
|
13
|
+
|
14
|
+
#mount_point_dev=`/bin/mount | /usr/bin/awk '$3==path {print $1}' path="#{path}"`.strip
|
15
|
+
Wakame.log.debug("#{mount_point_dev}: #{dev}, /bin/mount | awk '$3==path {print $1}' path=\"#{path}\"")
|
16
|
+
if mount_point_dev != dev
|
17
|
+
Wakame.log.debug("Mounting volume: #{dev} as #{path} (with options: #{opts})")
|
18
|
+
Wakame::Util.exec("/bin/mount -o #{mount_opts(opts)} '#{Shellwords.shellescape(dev)}' '#{Shellwords.shellescape(path)}'")
|
19
|
+
# sync
|
20
|
+
3.times do |i|
|
21
|
+
system("/bin/sync")
|
22
|
+
sleep 1.0
|
23
|
+
end
|
24
|
+
else
|
25
|
+
Wakame.log.debug("Mounting EBS volume: #{dev} as #{path} (with options: #{opts})")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def umount(path)
|
30
|
+
raise "#{path} does not exist or not directory." unless File.directory?(path)
|
31
|
+
|
32
|
+
mount_point_dev=`/bin/df "#{path}" | awk 'NR==2 {print $1}'`
|
33
|
+
Wakame.log.debug("Unmounting volume: #{mount_point_dev} on #{path}")
|
34
|
+
Wakame::Util.exec("/bin/umount '#{Shellwords.shellescape(path)}'")
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def mount_opts(opts)
|
39
|
+
out = opts.collect { |k,v|
|
40
|
+
v.nil? ? k : "#{k}=#{v}"
|
41
|
+
}.join(',')
|
42
|
+
Shellwords.shellescape(out)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
data/lib/wakame/actor.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Wakame
|
4
|
+
module Actor
|
5
|
+
STATUS_RUNNING = 1
|
6
|
+
STATUS_SUCCESS = 2
|
7
|
+
STATUS_FAILED = 0
|
8
|
+
STATUS_CANCELED = 3
|
9
|
+
|
10
|
+
def self.included(klass)
|
11
|
+
klass.extend ClassMethods
|
12
|
+
klass.class_eval {
|
13
|
+
attr_accessor :agent
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def expose(path, meth)
|
19
|
+
@exposed ||= {}
|
20
|
+
@exposed[path]=meth
|
21
|
+
end
|
22
|
+
|
23
|
+
def map_path
|
24
|
+
@map_path ||= Util.snake_case(self.to_s.split('::').last)
|
25
|
+
end
|
26
|
+
|
27
|
+
def map_path=(name)
|
28
|
+
@map_path=name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|