wakame 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +18 -0
- data/README.rdoc +2 -4
- data/Rakefile +4 -1
- data/VERSION +1 -1
- data/app_generators/wakame/templates/config/cluster.rb +36 -0
- data/app_generators/wakame/wakame_generator.rb +1 -0
- data/lib/wakame/action.rb +19 -34
- data/lib/wakame/actions/launch_cluster.rb +6 -3
- data/lib/wakame/actions/launch_vm.rb +57 -0
- data/lib/wakame/actions/migrate_service.rb +6 -25
- data/lib/wakame/actions/propagate_instances.rb +16 -41
- data/lib/wakame/actions/reload_service.rb +2 -2
- data/lib/wakame/actions/shutdown_cluster.rb +4 -0
- data/lib/wakame/actions/start_service.rb +30 -9
- data/lib/wakame/actions/stop_service.rb +1 -4
- data/lib/wakame/actions/util.rb +0 -24
- data/lib/wakame/actor/mysql.rb +106 -0
- data/lib/wakame/actor/service_monitor.rb +10 -0
- data/lib/wakame/actor/system.rb +19 -9
- data/lib/wakame/actor.rb +1 -1
- data/lib/wakame/agent.rb +23 -17
- data/lib/wakame/command/action_status.rb +7 -38
- data/lib/wakame/command/agent_status.rb +18 -0
- data/lib/wakame/command/launch_cluster.rb +0 -4
- data/lib/wakame/command/launch_vm.rb +11 -0
- data/lib/wakame/command/migrate_service.rb +12 -9
- data/lib/wakame/command/propagate_service.rb +15 -7
- data/lib/wakame/command/reload_service.rb +21 -0
- data/lib/wakame/command/shutdown_cluster.rb +0 -5
- data/lib/wakame/command/shutdown_vm.rb +20 -0
- data/lib/wakame/command/status.rb +6 -66
- data/lib/wakame/command/stop_service.rb +31 -0
- data/lib/wakame/command.rb +3 -0
- data/lib/wakame/command_queue.rb +76 -5
- data/lib/wakame/configuration.rb +6 -1
- data/lib/wakame/event.rb +6 -5
- data/lib/wakame/event_dispatcher.rb +5 -3
- data/lib/wakame/initializer.rb +1 -1
- data/lib/wakame/master.rb +14 -10
- data/lib/wakame/monitor/agent.rb +1 -6
- data/lib/wakame/monitor/service.rb +13 -1
- data/lib/wakame/packets.rb +51 -13
- data/lib/wakame/rule_engine.rb +7 -18
- data/lib/wakame/runner/administrator_command.rb +517 -46
- data/lib/wakame/service.rb +104 -173
- data/lib/wakame/trigger.rb +1 -10
- data/lib/wakame/triggers/process_command.rb +9 -2
- data/lib/wakame/util.rb +21 -21
- data/lib/wakame/vm_manipulator.rb +1 -0
- data/tests/test_service.rb +30 -6
- data/wakame_generators/resource/templates/ec2_elb/ec2_elb.rb +80 -0
- data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +3 -1
- data/wakame_generators/resource/templates/mysql_master/init.d/mysql +3 -3
- data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +11 -12
- data/{app_generators/wakame/templates/cluster/resources/mysql_master → wakame_generators/resource/templates/mysql_slave}/conf/my.cnf +19 -9
- data/{app_generators/wakame/templates/cluster/resources/mysql_master/init.d/mysql → wakame_generators/resource/templates/mysql_slave/init.d/mysql-slave} +4 -4
- data/wakame_generators/resource/templates/mysql_slave/mysql_slave.rb +123 -0
- data/wakame_generators/resource/templates/nginx/conf/nginx.conf +166 -0
- data/wakame_generators/resource/templates/nginx/init.d/nginx +70 -0
- data/{app_generators/wakame/templates/cluster/resources/apache_lb/apache_lb.rb → wakame_generators/resource/templates/nginx/nginx.rb} +28 -17
- metadata +46 -27
- data/app_generators/wakame/templates/cluster/resources/apache_app/apache_app.rb +0 -54
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/apache2.conf +0 -46
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/envvars-app +0 -7
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/sites-app.conf +0 -23
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/system-app.conf +0 -67
- data/app_generators/wakame/templates/cluster/resources/apache_app/init.d/apache2-app +0 -192
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/apache2.conf +0 -46
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/envvars-lb +0 -6
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/sites-lb.conf +0 -54
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/system-lb.conf +0 -75
- data/app_generators/wakame/templates/cluster/resources/apache_lb/init.d/apache2-lb +0 -192
- data/app_generators/wakame/templates/cluster/resources/apache_www/apache_www.rb +0 -50
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/apache2.conf +0 -47
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/envvars-www +0 -7
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/sites-www.conf +0 -23
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/system-www.conf +0 -63
- data/app_generators/wakame/templates/cluster/resources/apache_www/init.d/apache2-www +0 -192
- data/app_generators/wakame/templates/cluster/resources/ec2_elastic_ip/ec2_elastic_ip.rb +0 -39
- data/app_generators/wakame/templates/cluster/resources/mysql_master/mysql_master.rb +0 -174
- data/tests/conf/a +0 -1
- data/tests/conf/b +0 -1
- data/tests/conf/c +0 -1
data/History.txt
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
== 0.4.2 2009-07-24
|
2
|
+
|
3
|
+
* Add Web API for master control. (Note that the API design is not fixed yet)
|
4
|
+
|
5
|
+
* Rewrote the CLI to use HTTP instead of old DRb interface.
|
6
|
+
|
7
|
+
* Add support for agent less resource.
|
8
|
+
|
9
|
+
* Add LockQueue to avoid confliction when multiple actions run.
|
10
|
+
|
11
|
+
* Add MySQL_Slave resource.
|
12
|
+
|
13
|
+
* Add Elastic IP resource.
|
14
|
+
|
15
|
+
* Add Elastic Load Balancer resource.
|
16
|
+
|
17
|
+
* Add Nginx resource.
|
18
|
+
|
1
19
|
== 0.4.1 2009-06-29
|
2
20
|
|
3
21
|
* Fixed the packaging bugs.
|
data/README.rdoc
CHANGED
@@ -6,10 +6,6 @@
|
|
6
6
|
|
7
7
|
* Wakame is a framework to simplify the complex virtual machine manipulation over multiple instances in Clound envrionment. This project aims to provide the management/monitoring services with server/daemon configuration set to build scalable web applications.
|
8
8
|
|
9
|
-
== SYNOPSIS:
|
10
|
-
|
11
|
-
*
|
12
|
-
|
13
9
|
== REQUIREMENTS:
|
14
10
|
|
15
11
|
* eventmachine
|
@@ -19,6 +15,8 @@
|
|
19
15
|
* right_aws
|
20
16
|
* log4r
|
21
17
|
* jeweler
|
18
|
+
* thin
|
19
|
+
* json
|
22
20
|
|
23
21
|
== INSTALL:
|
24
22
|
|
data/Rakefile
CHANGED
@@ -25,7 +25,10 @@ __END__
|
|
25
25
|
['daemons', '>= 1.0.10'],
|
26
26
|
['rubigen', '>= 1.5.2'],
|
27
27
|
['open4', '>= 0.9.6'],
|
28
|
-
['jeweler', '>= 1.0.0']
|
28
|
+
['jeweler', '>= 1.0.0'],
|
29
|
+
['rack', '>= 1.0.0'],
|
30
|
+
['thin', '>= 1.2.2'],
|
31
|
+
['json', '>= 1.1.7']
|
29
32
|
].each { |i|
|
30
33
|
gem.add_dependency(i[0], i[1])
|
31
34
|
}
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.2
|
@@ -13,11 +13,13 @@ class WebCluster < Wakame::Service::ServiceCluster
|
|
13
13
|
c.add_resource(Apache_APP.new)
|
14
14
|
c.add_resource(Apache_LB.new)
|
15
15
|
c.add_resource(MySQL_Master.new)
|
16
|
+
#c.add_resource(MySQL_Slave.new)
|
16
17
|
|
17
18
|
c.set_dependency(Apache_LB, Ec2ElasticIp)
|
18
19
|
c.set_dependency(Apache_WWW, Apache_LB)
|
19
20
|
c.set_dependency(Apache_APP, Apache_LB)
|
20
21
|
c.set_dependency(MySQL_Master, Apache_APP)
|
22
|
+
#c.set_dependency(MySQL_Master, MySQL_Slave)
|
21
23
|
}
|
22
24
|
|
23
25
|
define_rule { |r|
|
@@ -61,4 +63,38 @@ class WebCluster < Wakame::Service::ServiceCluster
|
|
61
63
|
}
|
62
64
|
end
|
63
65
|
|
66
|
+
def each_mysql_master(&blk)
|
67
|
+
each_instance(MySQL_Master) { |n|
|
68
|
+
blk.call(n)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def fetch_mysql_master_ip
|
73
|
+
mysql_master_ip = nil
|
74
|
+
each_mysql_master do |mysql|
|
75
|
+
mysql_master_ip = mysql.agent.agent_ip
|
76
|
+
end
|
77
|
+
mysql_master_ip
|
78
|
+
end
|
79
|
+
|
80
|
+
def each_mysql_slave(&blk)
|
81
|
+
each_instance(MySQL_Slave) { |n|
|
82
|
+
blk.call(n)
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def fetch_mysql_slave_ip
|
87
|
+
mysql_slave_ips = []
|
88
|
+
each_mysql_slave do |mysql|
|
89
|
+
mysql_slave_ips << mysql.agent.agent_ip
|
90
|
+
end
|
91
|
+
mysql_master_ips
|
92
|
+
end
|
93
|
+
|
94
|
+
# def each_postgresql(&blk)
|
95
|
+
# each_instance(PostgreSQL_Master) { |n|
|
96
|
+
# blk.call(n)
|
97
|
+
# }
|
98
|
+
# end
|
99
|
+
|
64
100
|
end
|
data/lib/wakame/action.rb
CHANGED
@@ -7,7 +7,6 @@ module Wakame
|
|
7
7
|
def_attribute :status, :ready
|
8
8
|
def_attribute :completion_status
|
9
9
|
def_attribute :parent_action
|
10
|
-
def_attribute :acquire_lock, false
|
11
10
|
|
12
11
|
attr_reader :trigger
|
13
12
|
|
@@ -36,20 +35,17 @@ module Wakame
|
|
36
35
|
@subactions ||= []
|
37
36
|
end
|
38
37
|
|
39
|
-
def
|
38
|
+
def bind_trigger(trigger)
|
40
39
|
@trigger = trigger
|
41
40
|
end
|
42
41
|
|
43
42
|
def trigger_action(subaction, opts={})
|
44
|
-
if opts.is_a? Hash
|
45
|
-
succ_proc = opts[:success] || opts[:succ]
|
46
|
-
fail_proc = opts[:fail]
|
47
|
-
end
|
48
43
|
subactions << subaction
|
49
44
|
subaction.parent_action = self
|
50
|
-
|
45
|
+
subaction.job_id = self.job_id
|
46
|
+
subaction.bind_trigger(self.trigger)
|
51
47
|
|
52
|
-
|
48
|
+
trigger.rule_engine.run_action(subaction)
|
53
49
|
end
|
54
50
|
|
55
51
|
def flush_subactions(sec=nil)
|
@@ -92,8 +88,8 @@ module Wakame
|
|
92
88
|
notify_queue.enq(src) #if notify_queue.num_waiting > 0
|
93
89
|
end
|
94
90
|
end
|
95
|
-
|
96
|
-
|
91
|
+
|
92
|
+
# Recursively iterate the sub action descendants.
|
97
93
|
def walk_subactions(&blk)
|
98
94
|
blk.call(self)
|
99
95
|
self.subactions.each{ |a|
|
@@ -118,6 +114,18 @@ module Wakame
|
|
118
114
|
def notes
|
119
115
|
trigger.rule_engine.active_jobs[self.job_id][:notes]
|
120
116
|
end
|
117
|
+
|
118
|
+
# Set the lock flags to resources
|
119
|
+
def acquire_lock(&blk)
|
120
|
+
EM.barrier {
|
121
|
+
reslist = []
|
122
|
+
blk.call(reslist)
|
123
|
+
reslist.flatten!
|
124
|
+
reslist.each {|r| service_cluster.lock_queue.set(r.to_s, self.job_id) }
|
125
|
+
}
|
126
|
+
|
127
|
+
service_cluster.lock_queue.wait(self.job_id)
|
128
|
+
end
|
121
129
|
|
122
130
|
def run
|
123
131
|
raise NotImplementedError
|
@@ -128,29 +136,6 @@ module Wakame
|
|
128
136
|
|
129
137
|
def on_canceled
|
130
138
|
end
|
131
|
-
|
132
|
-
private
|
133
|
-
def sync_trigger_action(action, succ_proc, fail_proc)
|
134
|
-
action.job_id = self.job_id
|
135
|
-
action.bind_triggered_rule(self.trigger)
|
136
|
-
|
137
|
-
Wakame.log.debug("Start nested action in SYNC: #{action.class.to_s}")
|
138
|
-
begin
|
139
|
-
action.run
|
140
|
-
succ_proc.call if succ_proc
|
141
|
-
rescue => e
|
142
|
-
fail_proc.call if fail_proc
|
143
|
-
raise
|
144
|
-
end
|
145
|
-
Wakame.log.debug("Complete nested action : #{action.class.to_s}")
|
146
|
-
end
|
147
|
-
|
148
|
-
def async_trigger_action(action, succ_proc, fail_proc)
|
149
|
-
action.job_id = self.job_id
|
150
|
-
action.bind_triggered_rule(self.trigger)
|
151
|
-
|
152
|
-
trigger.rule_engine.run_action(action)
|
153
|
-
end
|
154
|
-
|
139
|
+
|
155
140
|
end
|
156
141
|
end
|
@@ -14,10 +14,13 @@ module Wakame
|
|
14
14
|
EM.barrier {
|
15
15
|
service_cluster.launch
|
16
16
|
}
|
17
|
+
levels = service_cluster.dg.levels
|
18
|
+
Wakame.log.debug("#{self.class}: Resource launch order: " + levels.collect {|lv| '['+ lv.collect{|prop| "#{prop.class}" }.join(', ') + ']' }.join(', '))
|
19
|
+
acquire_lock { |list|
|
20
|
+
levels.each {|lv| list << lv.collect{|res| res.class } }
|
21
|
+
}
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
service_cluster.dg.levels.each { |lv|
|
23
|
+
levels.each { |lv|
|
21
24
|
lv.each { |svc_prop|
|
22
25
|
trigger_action(PropagateInstances.new(svc_prop))
|
23
26
|
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
class LaunchVM < Action
|
4
|
+
def initialize(notes_key, ref_agent=nil)
|
5
|
+
@ref_agent = ref_agent
|
6
|
+
@notes_key = notes_key
|
7
|
+
end
|
8
|
+
|
9
|
+
USER_DATA_TMPL=<<__END__
|
10
|
+
node=agent
|
11
|
+
amqp_server=amqp://%s/
|
12
|
+
agent_id=%s
|
13
|
+
__END__
|
14
|
+
|
15
|
+
def run
|
16
|
+
require 'right_aws'
|
17
|
+
ec2 = RightAws::Ec2.new(Wakame.config.aws_access_key, Wakame.config.aws_secret_key, {:cache=>false})
|
18
|
+
|
19
|
+
# Fetch the reference vm slice attributes.
|
20
|
+
@ref_agent ||= master.agent_monitor.master_local
|
21
|
+
ref_attr = ec2.describe_instances([@ref_agent.attr[:instance_id]])
|
22
|
+
ref_attr = ref_attr[0]
|
23
|
+
|
24
|
+
|
25
|
+
user_data = sprintf(USER_DATA_TMPL, master.attr[:local_ipv4], '')
|
26
|
+
Wakame.log.debug("#{self.class}: Lauching VM: #{ref_attr.inspect}\nuser_data: #{user_data}")
|
27
|
+
res = ec2.run_instances(ref_attr[:aws_image_id], 1, 1,
|
28
|
+
ref_attr[:aws_groups],
|
29
|
+
ref_attr[:ssh_key_name],
|
30
|
+
user_data,
|
31
|
+
'public', # addressing_type
|
32
|
+
ref_attr[:aws_instance_type], # instance_type
|
33
|
+
nil, # kernel_id
|
34
|
+
nil, # ramdisk_id
|
35
|
+
ref_attr[:aws_availability_zone], # availability_zone
|
36
|
+
nil # block_device_mappings
|
37
|
+
)[0]
|
38
|
+
inst_id = res[:aws_instance_id]
|
39
|
+
|
40
|
+
ConditionalWait.wait { | cond |
|
41
|
+
cond.wait_event(Event::AgentMonitored) { |event|
|
42
|
+
event.agent.attr[:instance_id] == inst_id
|
43
|
+
}
|
44
|
+
|
45
|
+
cond.poll(5, 100) {
|
46
|
+
d = ec2.describe_instances([inst_id])[0]
|
47
|
+
Wakame.log.debug("#{self.class}: Polling describe_instances(#{inst_id}): #{d[:aws_state]} ")
|
48
|
+
d[:aws_state] == "running"
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
notes[@notes_key] = inst_id
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,23 +1,23 @@
|
|
1
1
|
|
2
|
-
require 'wakame/actions/util'
|
3
|
-
|
4
2
|
module Wakame
|
5
3
|
module Actions
|
6
4
|
class MigrateService < Action
|
7
|
-
include Actions::Util
|
8
|
-
|
9
5
|
def initialize(service_instance, dest_agent=nil)
|
10
6
|
@service_instance = service_instance
|
11
7
|
@destination_agent = dest_agent
|
12
8
|
end
|
13
9
|
|
14
10
|
def run
|
11
|
+
acquire_lock { |list|
|
12
|
+
list << @service_instance.resource.class
|
13
|
+
}
|
14
|
+
|
15
15
|
raise CancelActionError if @service_instance.status == Service::STATUS_MIGRATING
|
16
16
|
|
17
17
|
EM.barrier {
|
18
18
|
@service_instance.update_status(Service::STATUS_MIGRATING)
|
19
19
|
}
|
20
|
-
prop = @service_instance.
|
20
|
+
prop = @service_instance.resource
|
21
21
|
if prop.duplicable
|
22
22
|
clone_service(prop)
|
23
23
|
flush_subactions
|
@@ -38,26 +38,7 @@ module Wakame
|
|
38
38
|
new_svc = service_cluster.propagate(resource, true)
|
39
39
|
}
|
40
40
|
|
41
|
-
|
42
|
-
if agent.nil?
|
43
|
-
EM.barrier {
|
44
|
-
agent = arrange_agent(resource)
|
45
|
-
}
|
46
|
-
if agent.nil?
|
47
|
-
inst_id = start_instance(master.attr[:ami_id], resource.vm_spec.current.attrs)
|
48
|
-
agent = agent_monitor.registered_agents[inst_id]
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
if !(agent && test_agent_candidate(resource, agent))
|
53
|
-
raise "Found confiction(s) when the agent is assigned to sevice: #{resource} #{agent} "
|
54
|
-
end
|
55
|
-
|
56
|
-
EM.barrier {
|
57
|
-
new_svc.bind_agent(agent)
|
58
|
-
}
|
59
|
-
|
60
|
-
trigger_action(StartService.new(new_svc))
|
41
|
+
trigger_action(StartService.new(new_svc, @destination_agent))
|
61
42
|
new_svc
|
62
43
|
end
|
63
44
|
end
|
@@ -1,10 +1,6 @@
|
|
1
|
-
|
2
|
-
require 'wakame/actions/util'
|
3
|
-
|
4
1
|
module Wakame
|
5
2
|
module Actions
|
6
3
|
class PropagateInstances < Action
|
7
|
-
include Actions::Util
|
8
4
|
|
9
5
|
def initialize(svc_prop, propagate_num=0)
|
10
6
|
raise ArgumentError unless svc_prop.is_a?(Wakame::Service::Resource)
|
@@ -40,56 +36,35 @@ module Wakame
|
|
40
36
|
end
|
41
37
|
}
|
42
38
|
|
39
|
+
acquire_lock { |ary|
|
40
|
+
svc_to_start.each { |svc|
|
41
|
+
ary << svc.resource.class
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
43
45
|
svc_to_start.each { |svc|
|
46
|
+
target_agent = nil
|
44
47
|
if svc.property.require_agent
|
45
48
|
# Try to arrange agent from existing agent pool.
|
46
49
|
if svc.agent.nil?
|
47
50
|
EM.barrier {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
inst_id = start_instance(master.attr[:ami_id], @svc_prop.vm_spec.current.attrs)
|
55
|
-
EM.barrier {
|
56
|
-
arrange_agent(svc, inst_id)
|
51
|
+
agent_monitor.each_online { |ag|
|
52
|
+
if !ag.has_service_type?(@svc_prop.class) && @svc_prop.vm_spec.current.satisfy?(ag)
|
53
|
+
target_agent = ag
|
54
|
+
break
|
55
|
+
end
|
56
|
+
}
|
57
57
|
}
|
58
58
|
end
|
59
|
-
|
60
|
-
|
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
|
59
|
+
|
60
|
+
Wakame.log.debug("#{self.class}: arranged agent for #{svc.resource.class}: #{target_agent ? target_agent.agent_id : nil}")
|
64
61
|
end
|
65
62
|
|
66
|
-
trigger_action(StartService.new(svc))
|
63
|
+
trigger_action(StartService.new(svc, target_agent))
|
67
64
|
}
|
68
65
|
flush_subactions
|
69
66
|
end
|
70
67
|
|
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
68
|
end
|
94
69
|
end
|
95
70
|
end
|
@@ -13,8 +13,8 @@ module Wakame
|
|
13
13
|
#if @service_instance.status == Service::STATUS_STARTING || @service_instance.status == Service::STATUS_ONLINE
|
14
14
|
# raise "Canceled as the service is being or already ONLINE: #{@service_instance.property}"
|
15
15
|
#end
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
@service_instance.resource.reload(@service_instance, self)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -3,6 +3,10 @@ module Wakame
|
|
3
3
|
class ShutdownCluster < Action
|
4
4
|
def run
|
5
5
|
levels = service_cluster.dg.levels
|
6
|
+
Wakame.log.debug("#{self.class}: Resource shutdown order: " + levels.collect {|lv| '['+ lv.collect{|prop| "#{prop.class}" }.join(', ') + ']' }.join(', '))
|
7
|
+
acquire_lock { |list|
|
8
|
+
levels.each {|lv| list << lv.collect{|res| res.class } }
|
9
|
+
}
|
6
10
|
|
7
11
|
levels.reverse.each { |lv|
|
8
12
|
lv.each { |svc_prop|
|
@@ -4,36 +4,57 @@ require 'wakame/rule'
|
|
4
4
|
module Wakame
|
5
5
|
module Actions
|
6
6
|
class StartService < Action
|
7
|
-
def initialize(service_instance)
|
8
|
-
@acquire_lock = true
|
7
|
+
def initialize(service_instance, target_agent=nil)
|
9
8
|
@service_instance = service_instance
|
9
|
+
@target_agent = target_agent
|
10
10
|
end
|
11
11
|
|
12
12
|
def run
|
13
|
-
if @service_instance.
|
13
|
+
if @service_instance.resource.require_agent
|
14
|
+
|
15
|
+
if @service_instance.agent.nil?
|
16
|
+
# Start new VM when the target agent is nil.
|
17
|
+
if @target_agent.nil?
|
18
|
+
inst_id_key = "new_inst_id_" + Wakame::Util.gen_id
|
19
|
+
trigger_action(LaunchVM.new(inst_id_key))
|
20
|
+
flush_subactions
|
21
|
+
|
22
|
+
EM.barrier {
|
23
|
+
@target_agent = agent_monitor.registered_agents[notes[inst_id_key]]
|
24
|
+
raise "Cound not find the specified VM instance \"#{notes[inst_id_key]}\"" if @target_agent.nil?
|
25
|
+
raise "Same service is running" if @target_agent.has_service_type? @service_instance.resource.class
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
EM.barrier {
|
30
|
+
@service_instance.bind_agent(@target_agent)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
|
14
35
|
raise "Agent is not bound on this service : #{@service_instance}" if @service_instance.agent.nil?
|
15
36
|
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
37
|
end
|
17
38
|
|
18
39
|
# Skip to act when the service is having below status.
|
19
40
|
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.
|
41
|
+
raise "Canceled as the service is being or already ONLINE: #{@service_instance.resource}"
|
21
42
|
end
|
22
43
|
EM.barrier {
|
23
44
|
@service_instance.update_status(Service::STATUS_STARTING)
|
24
45
|
}
|
25
46
|
|
26
|
-
if @service_instance.
|
47
|
+
if @service_instance.resource.require_agent
|
27
48
|
Rule::BasicActionSet.deploy_configuration(@service_instance)
|
28
49
|
end
|
29
50
|
|
30
51
|
@service_instance.resource.start(@service_instance, self)
|
31
52
|
|
32
53
|
EM.barrier {
|
33
|
-
Wakame.log.debug("Child nodes: #{@service_instance.
|
34
|
-
service_cluster.dg.children(@service_instance.
|
35
|
-
Wakame.log.debug("Spreading DG child changed: #{@service_instance.
|
36
|
-
trigger_action(Actions::CallChildChangeAction.new(
|
54
|
+
Wakame.log.debug("Child nodes: #{@service_instance.resource.class}: " + service_cluster.dg.children(@service_instance.property.class).inspect)
|
55
|
+
service_cluster.dg.children(@service_instance.resource.class).each { |svc_res|
|
56
|
+
Wakame.log.debug("Spreading DG child changed: #{@service_instance.resource.class} -> #{svc_res.class}")
|
57
|
+
trigger_action(Actions::CallChildChangeAction.new(svc_res))
|
37
58
|
}
|
38
59
|
}
|
39
60
|
|
@@ -28,10 +28,7 @@ module Wakame
|
|
28
28
|
|
29
29
|
flush_subactions()
|
30
30
|
|
31
|
-
|
32
|
-
@service_instance.property.stop(@service_instance, self)
|
33
|
-
else
|
34
|
-
end
|
31
|
+
@service_instance.property.stop(@service_instance, self)
|
35
32
|
|
36
33
|
EM.barrier {
|
37
34
|
service_cluster.destroy(@service_instance.instance_id)
|
data/lib/wakame/actions/util.rb
CHANGED
@@ -42,30 +42,6 @@ module Wakame
|
|
42
42
|
|
43
43
|
agent
|
44
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
45
|
end
|
70
46
|
end
|
71
47
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
class Wakame::Actor::MySQL
|
2
|
+
include Wakame::Actor
|
3
|
+
|
4
|
+
# for Amazon EC2
|
5
|
+
def take_master_snapshot(opt_map)
|
6
|
+
Wakame.log.debug("take_master_snapshot: #{opt_map.inspect}")
|
7
|
+
|
8
|
+
mysql_client = "/usr/bin/mysql -h#{opt_map[:master_ip]} -P#{opt_map[:master_port]} -u#{opt_map[:repl_user]} -p#{opt_map[:repl_pass]} -s"
|
9
|
+
|
10
|
+
# master info
|
11
|
+
Wakame::Util.exec("echo 'FLUSH TABLES WITH READ LOCK;' | #{mysql_client}")
|
12
|
+
master_status = `echo show master status | #{mysql_client}`.to_s.split(/\t/)[0..1]
|
13
|
+
|
14
|
+
# mysql/data/master.info
|
15
|
+
master_infos = []
|
16
|
+
master_infos << 14
|
17
|
+
master_infos << master_status[0]
|
18
|
+
master_infos << master_status[1]
|
19
|
+
master_infos << opt_map[:master_ip]
|
20
|
+
master_infos << opt_map[:repl_user]
|
21
|
+
master_infos << opt_map[:repl_pass]
|
22
|
+
master_infos << opt_map[:master_port]
|
23
|
+
master_infos << 60
|
24
|
+
master_infos << 0
|
25
|
+
master_infos << ""
|
26
|
+
master_infos << ""
|
27
|
+
master_infos << ""
|
28
|
+
master_infos << ""
|
29
|
+
master_infos << ""
|
30
|
+
master_infos << ""
|
31
|
+
Wakame.log.debug(master_infos)
|
32
|
+
|
33
|
+
master_info = File.expand_path('master.info', opt_map[:master_mysqld_datadir])
|
34
|
+
Wakame.log.debug("master_info : #{master_info}")
|
35
|
+
file = File.new(master_info, "w")
|
36
|
+
file.puts(master_infos.join("\n"))
|
37
|
+
file.chmod(0664)
|
38
|
+
file.close
|
39
|
+
|
40
|
+
require 'fileutils'
|
41
|
+
FileUtils.chown('mysql', 'mysql', master_info)
|
42
|
+
Wakame::Util.exec("/bin/sync")
|
43
|
+
sleep 1.0
|
44
|
+
|
45
|
+
#
|
46
|
+
require 'right_aws'
|
47
|
+
ec2 = RightAws::Ec2.new(opt_map[:aws_access_key], opt_map[:aws_secret_key])
|
48
|
+
|
49
|
+
volume_map = ec2.describe_volumes([opt_map[:master_ebs_volume]])[0]
|
50
|
+
Wakame.log.debug("describe_volume(#{opt_map[:master_ebs_volume]}): #{volume_map.inspect}")
|
51
|
+
if volume_map[:aws_status] == 'in-use'
|
52
|
+
# Nothin to be done
|
53
|
+
else
|
54
|
+
Wakame.log.debug("The EBS volume(slave) is not ready to attach: #{opt_map[:master_ebs_volume]}")
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
# create_snapshot
|
59
|
+
snapshot_map = ec2.create_snapshot(opt_map[:master_ebs_volume])
|
60
|
+
Wakame.log.debug("create_snapshot #{snapshot_map.inspect}")
|
61
|
+
cond = ConditionalWait.new { |c|
|
62
|
+
c.poll {
|
63
|
+
snapshot_map = ec2.describe_snapshots([snapshot_map[:aws_id]])[0]
|
64
|
+
Wakame.log.debug("describe_snapshot #{snapshot_map.inspect}")
|
65
|
+
Wakame::Util.exec("/bin/sync")
|
66
|
+
snapshot_map[:aws_status] == "completed"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
cond.wait
|
70
|
+
|
71
|
+
# unlock
|
72
|
+
Wakame::Util.exec("echo 'UNLOCK TABLES;' | #{mysql_client}")
|
73
|
+
|
74
|
+
# create volume from snapshot
|
75
|
+
created_volume_from_snapshot_map = ec2.create_volume(snapshot_map[:aws_id], volume_map[:aws_size], volume_map[:zone])
|
76
|
+
Wakame.log.debug("create_volume_from_snapshot #{created_volume_from_snapshot_map}")
|
77
|
+
cond = ConditionalWait.new { |c|
|
78
|
+
c.poll {
|
79
|
+
volume_map = ec2.describe_volumes([created_volume_from_snapshot_map[:aws_id]])[0]
|
80
|
+
Wakame.log.debug("describe_volume: #{volume_map.inspect}")
|
81
|
+
Wakame::Util.exec("/bin/sync")
|
82
|
+
volume_map[:aws_status] == "available"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
cond.wait
|
86
|
+
|
87
|
+
# delete_snapshot
|
88
|
+
delete_map = ec2.delete_snapshot(snapshot_map[:aws_id])
|
89
|
+
Wakame.log.debug("delete_map #{delete_map.inspect}")
|
90
|
+
|
91
|
+
# attach_volume
|
92
|
+
Wakame.log.debug("attach-target #{volume_map.inspect}")
|
93
|
+
attach_volume_map = ec2.attach_volume(volume_map[:aws_id], agent.agent_id, opt_map[:ebs_device])
|
94
|
+
Wakame.log.debug("attach_volume_map #{attach_volume_map.inspect}")
|
95
|
+
cond = ConditionalWait.new { |c|
|
96
|
+
c.poll {
|
97
|
+
volume_map = ec2.describe_volumes([attach_volume_map[:aws_id]])[0]
|
98
|
+
Wakame.log.debug("describe_volume #{volume_map.inspect}")
|
99
|
+
Wakame::Util.exec("/bin/sync")
|
100
|
+
volume_map[:aws_status] == "in-use"
|
101
|
+
}
|
102
|
+
}
|
103
|
+
cond.wait
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|