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