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,77 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
[ $UID -eq 0 ] || { echo "Run with root user."; exit 1; }
|
4
|
+
|
5
|
+
apt-get update;
|
6
|
+
apt-get -y upgrade;
|
7
|
+
|
8
|
+
apt-get -y install apache2-mpm-prefork libapache2-mod-rpaf
|
9
|
+
apt-get -y install mysql-server mysql-client
|
10
|
+
apt-get -y install erlang-nox
|
11
|
+
apt-get -y install unzip zip rsync libopenssl-ruby libhmac-ruby rubygems irb ri rdoc sysstat
|
12
|
+
|
13
|
+
apt-get clean
|
14
|
+
|
15
|
+
(cd /tmp;
|
16
|
+
wget http://www.rabbitmq.com/releases/rabbitmq-server/v1.5.4/rabbitmq-server_1.5.4-1_all.deb;
|
17
|
+
dpkg -i rabbitmq-server_1.5.4-1_all.deb;
|
18
|
+
)
|
19
|
+
|
20
|
+
|
21
|
+
if ! getent group wakame >/dev/null; then
|
22
|
+
addgroup --system wakame
|
23
|
+
fi
|
24
|
+
|
25
|
+
if ! getent passwd wakame >/dev/null; then
|
26
|
+
adduser --system --ingroup wakame --disabled-password wakame
|
27
|
+
fi
|
28
|
+
|
29
|
+
mkdir /home/wakame/config
|
30
|
+
chown wakame:wakame /home/wakame/config
|
31
|
+
mkdir /home/wakame/mysql
|
32
|
+
mkdir /home/wakame/mysql/data
|
33
|
+
mkdir /home/wakame/mysql/data-slave
|
34
|
+
chown mysql:mysql /home/wakame/mysql/data /home/wakame/mysql/data-slave
|
35
|
+
|
36
|
+
if ! grep GEM_HOME /etc/environemnt >/dev/null; then
|
37
|
+
cat <<EOF > /etc/environment
|
38
|
+
GEM_HOME=/usr/local/gems
|
39
|
+
EOF
|
40
|
+
fi
|
41
|
+
|
42
|
+
cat <<EOF > /etc/default/wakame
|
43
|
+
WAKAME_HOME=/home/wakame/corelib
|
44
|
+
GEM_HOME=/usr/local/gems
|
45
|
+
EOF
|
46
|
+
|
47
|
+
update-rc.d -f apache2 remove
|
48
|
+
update-rc.d -f mysql remove
|
49
|
+
update-rc.d -f mysql-ndb remove
|
50
|
+
update-rc.d -f mysql-ndb-mgm remove
|
51
|
+
# Disable apparmor
|
52
|
+
update-rc.d -f apparmor remove
|
53
|
+
|
54
|
+
cat <<EOF > /usr/local/bin/passenger_ruby.sh
|
55
|
+
#!/bin/sh
|
56
|
+
export GEM_PATH="/usr/local/gems"
|
57
|
+
exec /usr/bin/ruby $@
|
58
|
+
EOF
|
59
|
+
chmod 755 /usr/local/bin/passenger_ruby.sh
|
60
|
+
|
61
|
+
# Create root ssh key
|
62
|
+
ssh-keygen -t rsa -N '' -f /home/wakame/config/root.id_rsa
|
63
|
+
chown wakame:wakame /home/wakame/config/root.id_rsa /home/wakame/config/root.id_rsa.pub
|
64
|
+
cat /home/wakame/config/root.id_rsa.pub >> /root/.ssh/authorized_keys
|
65
|
+
|
66
|
+
#gem install rake rails eventmachine amqp log4r daemons passenger hoe amazon-ec2 --no-ri --no-rdoc
|
67
|
+
#(cd $GEM_HOME/gems/passenger-*; rake)
|
68
|
+
|
69
|
+
#update-rc.d wakame-master defaults 41
|
70
|
+
#update-rc.d wakame-agent defaults 40
|
71
|
+
|
72
|
+
#
|
73
|
+
# /root/.ssh/authorized_keys /root/.bash_history
|
74
|
+
# /home/ubuntu/.ssh/authorized_keys /home/ubuntu/.bash_history
|
75
|
+
# Clear logs
|
76
|
+
# logrotate -f /etc/logrotate.conf
|
77
|
+
# rm -f /var/log/apache2/* /var/log/rabbitmq/* /var/log/wakame-* /var/log/*.gz /var/log/*.0 /var/log/*.1
|
@@ -0,0 +1,86 @@
|
|
1
|
+
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module EventMachine
|
5
|
+
# def self::defer op, callback = nil
|
6
|
+
# @need_threadqueue ||= 0
|
7
|
+
# if @need_threadqueue == 0
|
8
|
+
# @need_threadqueue = 1
|
9
|
+
# require 'thread'
|
10
|
+
# @threadqueue = Queue.new
|
11
|
+
# @resultqueue = Queue.new
|
12
|
+
# @thread_g = ThreadGroup.new
|
13
|
+
# 20.times {|ix|
|
14
|
+
# t = Thread.new {
|
15
|
+
# my_ix = ix
|
16
|
+
# loop {
|
17
|
+
# op,cback = @threadqueue.pop
|
18
|
+
# begin
|
19
|
+
# result = op.call
|
20
|
+
# @resultqueue << [result, cback]
|
21
|
+
# rescue => e
|
22
|
+
# puts "#{e} in EM defer thread pool : #{Thread.current}"
|
23
|
+
# raise e
|
24
|
+
# ensure
|
25
|
+
# EventMachine.signal_loopbreak
|
26
|
+
# end
|
27
|
+
# }
|
28
|
+
# }
|
29
|
+
# @thread_g.add(t)
|
30
|
+
# }
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# @threadqueue << [op,callback]
|
34
|
+
# end
|
35
|
+
|
36
|
+
# Redefine EM's threadpool
|
37
|
+
def self.spawn_threadpool
|
38
|
+
until @threadpool.size == 20
|
39
|
+
thread = Thread.new {
|
40
|
+
loop {
|
41
|
+
op, cback = *@threadqueue.pop
|
42
|
+
begin
|
43
|
+
result = op.call
|
44
|
+
@resultqueue << [result, cback]
|
45
|
+
rescue => e
|
46
|
+
puts "#{e} in EM defer thread pool : #{Thread.current}"
|
47
|
+
ensure
|
48
|
+
EventMachine.signal_loopbreak
|
49
|
+
end
|
50
|
+
}
|
51
|
+
}
|
52
|
+
@threadpool << thread
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.barrier(&blk)
|
57
|
+
# Presumably, Thread.main will return the EM main loop thread.
|
58
|
+
if EM.reactor_thread?
|
59
|
+
return blk.call
|
60
|
+
end
|
61
|
+
|
62
|
+
raise "Eventmachine is not ready to accept the next_tick() call." unless self.reactor_running?
|
63
|
+
|
64
|
+
@q ||= ::Queue.new
|
65
|
+
time_start = ::Time.now
|
66
|
+
|
67
|
+
self.next_tick {
|
68
|
+
#self.add_timer(0) {
|
69
|
+
begin
|
70
|
+
res = blk.call
|
71
|
+
@q << [true, res]
|
72
|
+
rescue => e
|
73
|
+
@q << [false, e]
|
74
|
+
end
|
75
|
+
}
|
76
|
+
|
77
|
+
res = @q.shift
|
78
|
+
time_elapsed = ::Time.now - time_start
|
79
|
+
Wakame.log.debug("EM.barrier: elapsed time for #{blk}: #{time_elapsed} sec (#{$eventmachine_library})") if time_elapsed > 0.05
|
80
|
+
if res[0] == false && res[1].is_a?(Exception)
|
81
|
+
raise res[1]
|
82
|
+
end
|
83
|
+
res[1]
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
#
|
2
|
+
# shellwords.rb: Manipulates strings a la UNIX Bourne shell
|
3
|
+
#
|
4
|
+
|
5
|
+
#
|
6
|
+
# This module manipulates strings according to the word parsing rules
|
7
|
+
# of the UNIX Bourne shell.
|
8
|
+
#
|
9
|
+
# The shellwords() function was originally a port of shellwords.pl,
|
10
|
+
# but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).
|
11
|
+
#
|
12
|
+
# Authors:
|
13
|
+
# - Wakou Aoyama
|
14
|
+
# - Akinori MUSHA <knu@iDaemons.org>
|
15
|
+
#
|
16
|
+
# Contact:
|
17
|
+
# - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
|
18
|
+
#
|
19
|
+
module Shellwords
|
20
|
+
#
|
21
|
+
# Splits a string into an array of tokens in the same way the UNIX
|
22
|
+
# Bourne shell does.
|
23
|
+
#
|
24
|
+
# argv = Shellwords.split('here are "two words"')
|
25
|
+
# argv #=> ["here", "are", "two words"]
|
26
|
+
#
|
27
|
+
# +String#shellsplit+ is a shorthand for this function.
|
28
|
+
#
|
29
|
+
# argv = 'here are "two words"'.shellsplit
|
30
|
+
# argv #=> ["here", "are", "two words"]
|
31
|
+
#
|
32
|
+
def shellsplit(line)
|
33
|
+
line = String.new(line) rescue
|
34
|
+
raise(ArgumentError, "Argument must be a string")
|
35
|
+
line.lstrip!
|
36
|
+
words = []
|
37
|
+
until line.empty?
|
38
|
+
field = ''
|
39
|
+
loop do
|
40
|
+
if line.sub!(/\A"(([^"\\]|\\.)*)"/, '') then
|
41
|
+
snippet = $1.gsub(/\\(.)/, '\1')
|
42
|
+
elsif line =~ /\A"/ then
|
43
|
+
raise ArgumentError, "Unmatched double quote: #{line}"
|
44
|
+
elsif line.sub!(/\A'([^']*)'/, '') then
|
45
|
+
snippet = $1
|
46
|
+
elsif line =~ /\A'/ then
|
47
|
+
raise ArgumentError, "Unmatched single quote: #{line}"
|
48
|
+
elsif line.sub!(/\A\\(.)?/, '') then
|
49
|
+
snippet = $1 || '\\'
|
50
|
+
elsif line.sub!(/\A([^\s\\'"]+)/, '') then
|
51
|
+
snippet = $1
|
52
|
+
else
|
53
|
+
line.lstrip!
|
54
|
+
break
|
55
|
+
end
|
56
|
+
field.concat(snippet)
|
57
|
+
end
|
58
|
+
words.push(field)
|
59
|
+
end
|
60
|
+
words
|
61
|
+
end
|
62
|
+
|
63
|
+
alias shellwords shellsplit
|
64
|
+
|
65
|
+
module_function :shellsplit, :shellwords
|
66
|
+
|
67
|
+
class << self
|
68
|
+
alias split shellsplit
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Escapes a string so that it can be safely used in a Bourne shell
|
73
|
+
# command line.
|
74
|
+
#
|
75
|
+
# Note that a resulted string should be used unquoted and is not
|
76
|
+
# intended for use in double quotes nor in single quotes.
|
77
|
+
#
|
78
|
+
# open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
|
79
|
+
# # ...
|
80
|
+
# }
|
81
|
+
#
|
82
|
+
# +String#shellescape+ is a shorthand for this function.
|
83
|
+
#
|
84
|
+
# open("| grep #{pattern.shellescape} file") { |pipe|
|
85
|
+
# # ...
|
86
|
+
# }
|
87
|
+
#
|
88
|
+
def shellescape(str)
|
89
|
+
# An empty argument will be skipped, so return empty quotes.
|
90
|
+
return "''" if str.empty?
|
91
|
+
|
92
|
+
str = str.dup
|
93
|
+
|
94
|
+
# Process as a single byte sequence because not all shell
|
95
|
+
# implementations are multibyte aware.
|
96
|
+
str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
|
97
|
+
|
98
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
99
|
+
# combo is regarded as line continuation and simply ignored.
|
100
|
+
str.gsub!(/\n/, "'\n'")
|
101
|
+
|
102
|
+
return str
|
103
|
+
end
|
104
|
+
|
105
|
+
module_function :shellescape
|
106
|
+
|
107
|
+
class << self
|
108
|
+
alias escape shellescape
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Builds a command line string from an argument list +array+ joining
|
113
|
+
# all elements escaped for Bourne shell and separated by a space.
|
114
|
+
#
|
115
|
+
# open('|' + Shellwords.join(['grep', pattern, *files])) { |pipe|
|
116
|
+
# # ...
|
117
|
+
# }
|
118
|
+
#
|
119
|
+
# +Array#shelljoin+ is a shorthand for this function.
|
120
|
+
#
|
121
|
+
# open('|' + ['grep', pattern, *files].shelljoin) { |pipe|
|
122
|
+
# # ...
|
123
|
+
# }
|
124
|
+
#
|
125
|
+
def shelljoin(array)
|
126
|
+
array.map { |arg| shellescape(arg) }.join(' ')
|
127
|
+
end
|
128
|
+
|
129
|
+
module_function :shelljoin
|
130
|
+
|
131
|
+
class << self
|
132
|
+
alias join shelljoin
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class String
|
137
|
+
#
|
138
|
+
# call-seq:
|
139
|
+
# str.shellsplit => array
|
140
|
+
#
|
141
|
+
# Splits +str+ into an array of tokens in the same way the UNIX
|
142
|
+
# Bourne shell does. See +Shellwords::shellsplit+ for details.
|
143
|
+
#
|
144
|
+
def shellsplit
|
145
|
+
Shellwords.split(self)
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# call-seq:
|
150
|
+
# str.shellescape => string
|
151
|
+
#
|
152
|
+
# Escapes +str+ so that it can be safely used in a Bourne shell
|
153
|
+
# command line. See +Shellwords::shellescape+ for details.
|
154
|
+
#
|
155
|
+
def shellescape
|
156
|
+
Shellwords.escape(self)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class Array
|
161
|
+
#
|
162
|
+
# call-seq:
|
163
|
+
# array.shelljoin => string
|
164
|
+
#
|
165
|
+
# Builds a command line string from an argument list +array+ joining
|
166
|
+
# all elements escaped for Bourne shell and separated by a space.
|
167
|
+
# See +Shellwords::shelljoin+ for details.
|
168
|
+
#
|
169
|
+
def shelljoin
|
170
|
+
Shellwords.join(self)
|
171
|
+
end
|
172
|
+
end
|
data/lib/ext/uri.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
module Wakame
|
2
|
+
class Action
|
3
|
+
include AttributeHelper
|
4
|
+
include ThreadImmutable
|
5
|
+
|
6
|
+
def_attribute :job_id
|
7
|
+
def_attribute :status, :ready
|
8
|
+
def_attribute :completion_status
|
9
|
+
def_attribute :parent_action
|
10
|
+
def_attribute :acquire_lock, false
|
11
|
+
|
12
|
+
attr_reader :trigger
|
13
|
+
|
14
|
+
def master
|
15
|
+
trigger.master
|
16
|
+
end
|
17
|
+
|
18
|
+
def agent_monitor
|
19
|
+
trigger.agent_monitor
|
20
|
+
end
|
21
|
+
|
22
|
+
def service_cluster
|
23
|
+
trigger.service_cluster
|
24
|
+
end
|
25
|
+
def status=(status)
|
26
|
+
if @status != status
|
27
|
+
@status = status
|
28
|
+
# Notify to observers after updating the attribute
|
29
|
+
notify
|
30
|
+
end
|
31
|
+
@status
|
32
|
+
end
|
33
|
+
thread_immutable_methods :status=
|
34
|
+
|
35
|
+
def subactions
|
36
|
+
@subactions ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
def bind_triggered_rule(trigger)
|
40
|
+
@trigger = trigger
|
41
|
+
end
|
42
|
+
|
43
|
+
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
|
+
subactions << subaction
|
49
|
+
subaction.parent_action = self
|
50
|
+
#subaction.observers << self
|
51
|
+
|
52
|
+
async_trigger_action(subaction, succ_proc, fail_proc)
|
53
|
+
end
|
54
|
+
|
55
|
+
def flush_subactions(sec=nil)
|
56
|
+
job_context = trigger.rule_engine.active_jobs[self.job_id]
|
57
|
+
return if job_context.nil?
|
58
|
+
|
59
|
+
timeout(sec.nil? ? nil : sec) {
|
60
|
+
until all_subactions_complete?
|
61
|
+
#Wakame.log.debug "#{self.class} all_subactions_complete?=#{all_subactions_complete?}"
|
62
|
+
src = notify_queue.deq
|
63
|
+
# Exit the current action when a subaction notified exception.
|
64
|
+
if src.is_a?(Exception)
|
65
|
+
raise src
|
66
|
+
end
|
67
|
+
#Wakame.log.debug "#{self.class} notified by #{src.class}, all_subactions_complete?=#{all_subactions_complete?}"
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def all_subactions_complete?
|
73
|
+
subactions.each { |a|
|
74
|
+
#Wakame.log.debug("#{a.class}.status=#{a.status}")
|
75
|
+
return false unless a.status == :complete && a.all_subactions_complete?
|
76
|
+
}
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def notify_queue
|
81
|
+
@notify_queue ||= ::Queue.new
|
82
|
+
end
|
83
|
+
|
84
|
+
def notify(src=nil)
|
85
|
+
#Wakame.log.debug("#{self.class}.notify() has been called")
|
86
|
+
src = self if src.nil?
|
87
|
+
if status == :complete && parent_action
|
88
|
+
# Escalate the notification to parent if the action is finished.
|
89
|
+
parent_action.notify(src)
|
90
|
+
else
|
91
|
+
notify_queue.clear if notify_queue.size > 0
|
92
|
+
notify_queue.enq(src) #if notify_queue.num_waiting > 0
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
def walk_subactions(&blk)
|
98
|
+
blk.call(self)
|
99
|
+
self.subactions.each{ |a|
|
100
|
+
a.walk_subactions(&blk)
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
def actor_request(agent_id, path, *args, &blk)
|
105
|
+
request = master.actor_request(agent_id, path, *args)
|
106
|
+
if blk
|
107
|
+
request.request
|
108
|
+
blk.call(request)
|
109
|
+
end
|
110
|
+
request
|
111
|
+
end
|
112
|
+
|
113
|
+
def sync_actor_request(agent_id, path, *args)
|
114
|
+
request = actor_request(agent_id, path, *args).request
|
115
|
+
request.wait
|
116
|
+
end
|
117
|
+
|
118
|
+
def notes
|
119
|
+
trigger.rule_engine.active_jobs[self.job_id][:notes]
|
120
|
+
end
|
121
|
+
|
122
|
+
def run
|
123
|
+
raise NotImplementedError
|
124
|
+
end
|
125
|
+
|
126
|
+
def on_failed
|
127
|
+
end
|
128
|
+
|
129
|
+
def on_canceled
|
130
|
+
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
|
+
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
class DestroyInstances < Action
|
4
|
+
def initialize(svc_prop)
|
5
|
+
@svc_prop = svc_prop
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
svc_to_stop=[]
|
10
|
+
|
11
|
+
EM.barrier {
|
12
|
+
online_svc = []
|
13
|
+
service_cluster.each_instance(@svc_prop.class) { |svc_inst|
|
14
|
+
if svc_inst.status == Service::STATUS_ONLINE
|
15
|
+
online_svc << svc_inst
|
16
|
+
end
|
17
|
+
}
|
18
|
+
|
19
|
+
svc_count = service_cluster.instance_count(@svc_prop)
|
20
|
+
if svc_count < online_svc.size
|
21
|
+
online_svc.delete_if { |svc|
|
22
|
+
svc.agent.agent_id == master.attr[:instance_id]
|
23
|
+
}
|
24
|
+
|
25
|
+
((online_svc.size - svc_count) + 1).times {
|
26
|
+
svc_to_stop << online_svc.shift
|
27
|
+
}
|
28
|
+
Wakame.log.debug("#{self.class}: online_svc.size=#{online_svc.size}, svc_to_stop.size=#{svc_to_stop.size}")
|
29
|
+
end
|
30
|
+
}
|
31
|
+
|
32
|
+
svc_to_stop.each { |svc_inst|
|
33
|
+
trigger_action(StopService.new(svc_inst))
|
34
|
+
}
|
35
|
+
flush_subactions
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Wakame
|
2
|
+
module Actions
|
3
|
+
class LaunchCluster < Action
|
4
|
+
def initialize
|
5
|
+
@acquire_lock = true
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
if service_cluster.status == Service::ServiceCluster::STATUS_ONLINE
|
10
|
+
Wakame.log.info("The service cluster is up & running already")
|
11
|
+
raise CancelActionError
|
12
|
+
end
|
13
|
+
|
14
|
+
EM.barrier {
|
15
|
+
service_cluster.launch
|
16
|
+
}
|
17
|
+
|
18
|
+
Wakame.log.debug("#{self.class}: Resource Launch Order: " + service_cluster.dg.levels.collect {|lv| '['+ lv.collect{|prop| "#{prop.class}" }.join(', ') + ']' }.join(', '))
|
19
|
+
|
20
|
+
service_cluster.dg.levels.each { |lv|
|
21
|
+
lv.each { |svc_prop|
|
22
|
+
trigger_action(PropagateInstances.new(svc_prop))
|
23
|
+
}
|
24
|
+
flush_subactions
|
25
|
+
Wakame.log.debug("#{self.class}: DG level next")
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
require 'wakame/actions/util'
|
3
|
+
|
4
|
+
module Wakame
|
5
|
+
module Actions
|
6
|
+
class MigrateService < Action
|
7
|
+
include Actions::Util
|
8
|
+
|
9
|
+
def initialize(service_instance, dest_agent=nil)
|
10
|
+
@service_instance = service_instance
|
11
|
+
@destination_agent = dest_agent
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
raise CancelActionError if @service_instance.status == Service::STATUS_MIGRATING
|
16
|
+
|
17
|
+
EM.barrier {
|
18
|
+
@service_instance.update_status(Service::STATUS_MIGRATING)
|
19
|
+
}
|
20
|
+
prop = @service_instance.property
|
21
|
+
if prop.duplicable
|
22
|
+
clone_service(prop)
|
23
|
+
flush_subactions
|
24
|
+
trigger_action(StopService.new(@service_instance))
|
25
|
+
else
|
26
|
+
|
27
|
+
trigger_action(StopService.new(@service_instance))
|
28
|
+
flush_subactions
|
29
|
+
clone_service(prop)
|
30
|
+
end
|
31
|
+
flush_subactions
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def clone_service(resource)
|
36
|
+
new_svc = nil
|
37
|
+
EM.barrier {
|
38
|
+
new_svc = service_cluster.propagate(resource, true)
|
39
|
+
}
|
40
|
+
|
41
|
+
agent = @destination_agent
|
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))
|
61
|
+
new_svc
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|