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.
- 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
|