wakame 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/History.txt +20 -0
  2. data/README.rdoc +63 -0
  3. data/Rakefile +86 -0
  4. data/VERSION +1 -0
  5. data/app_generators/wakame/templates/README +0 -0
  6. data/app_generators/wakame/templates/Rakefile +18 -0
  7. data/app_generators/wakame/templates/bin/wakame-agent +9 -0
  8. data/app_generators/wakame/templates/bin/wakame-master +9 -0
  9. data/app_generators/wakame/templates/bin/wakameadm +9 -0
  10. data/app_generators/wakame/templates/cluster/resources/apache_app/apache_app.rb +54 -0
  11. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/apache2.conf +46 -0
  12. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/envvars-app +7 -0
  13. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/sites-app.conf +23 -0
  14. data/app_generators/wakame/templates/cluster/resources/apache_app/conf/system-app.conf +67 -0
  15. data/app_generators/wakame/templates/cluster/resources/apache_app/init.d/apache2-app +192 -0
  16. data/app_generators/wakame/templates/cluster/resources/apache_lb/apache_lb.rb +56 -0
  17. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/apache2.conf +46 -0
  18. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/envvars-lb +6 -0
  19. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/sites-lb.conf +54 -0
  20. data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/system-lb.conf +75 -0
  21. data/app_generators/wakame/templates/cluster/resources/apache_lb/init.d/apache2-lb +192 -0
  22. data/app_generators/wakame/templates/cluster/resources/apache_www/apache_www.rb +50 -0
  23. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/apache2.conf +47 -0
  24. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/envvars-www +7 -0
  25. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/sites-www.conf +23 -0
  26. data/app_generators/wakame/templates/cluster/resources/apache_www/conf/system-www.conf +63 -0
  27. data/app_generators/wakame/templates/cluster/resources/apache_www/init.d/apache2-www +192 -0
  28. data/app_generators/wakame/templates/cluster/resources/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
  29. data/app_generators/wakame/templates/cluster/resources/mysql_master/conf/my.cnf +154 -0
  30. data/app_generators/wakame/templates/cluster/resources/mysql_master/init.d/mysql +185 -0
  31. data/app_generators/wakame/templates/cluster/resources/mysql_master/mysql_master.rb +174 -0
  32. data/app_generators/wakame/templates/config/boot.rb +85 -0
  33. data/app_generators/wakame/templates/config/cluster.rb +64 -0
  34. data/app_generators/wakame/templates/config/environments/common.rb +0 -0
  35. data/app_generators/wakame/templates/config/environments/ec2.rb +3 -0
  36. data/app_generators/wakame/templates/config/environments/stand_alone.rb +0 -0
  37. data/app_generators/wakame/templates/config/init.d/wakame-agent +72 -0
  38. data/app_generators/wakame/templates/config/init.d/wakame-master +73 -0
  39. data/app_generators/wakame/wakame_generator.rb +124 -0
  40. data/bin/wakame +18 -0
  41. data/contrib/imagesetup.sh +77 -0
  42. data/lib/ext/eventmachine.rb +86 -0
  43. data/lib/ext/shellwords.rb +172 -0
  44. data/lib/ext/uri.rb +15 -0
  45. data/lib/wakame/action.rb +156 -0
  46. data/lib/wakame/actions/destroy_instances.rb +39 -0
  47. data/lib/wakame/actions/launch_cluster.rb +31 -0
  48. data/lib/wakame/actions/migrate_service.rb +65 -0
  49. data/lib/wakame/actions/propagate_instances.rb +95 -0
  50. data/lib/wakame/actions/reload_service.rb +21 -0
  51. data/lib/wakame/actions/scaleout_when_high_load.rb +44 -0
  52. data/lib/wakame/actions/shutdown_cluster.rb +22 -0
  53. data/lib/wakame/actions/shutdown_vm.rb +19 -0
  54. data/lib/wakame/actions/start_service.rb +64 -0
  55. data/lib/wakame/actions/stop_service.rb +49 -0
  56. data/lib/wakame/actions/util.rb +71 -0
  57. data/lib/wakame/actor/daemon.rb +37 -0
  58. data/lib/wakame/actor/service_monitor.rb +21 -0
  59. data/lib/wakame/actor/system.rb +46 -0
  60. data/lib/wakame/actor.rb +33 -0
  61. data/lib/wakame/agent.rb +226 -0
  62. data/lib/wakame/amqp_client.rb +219 -0
  63. data/lib/wakame/command/action_status.rb +62 -0
  64. data/lib/wakame/command/actor.rb +23 -0
  65. data/lib/wakame/command/clone_service.rb +12 -0
  66. data/lib/wakame/command/launch_cluster.rb +15 -0
  67. data/lib/wakame/command/migrate_service.rb +21 -0
  68. data/lib/wakame/command/propagate_service.rb +24 -0
  69. data/lib/wakame/command/shutdown_cluster.rb +15 -0
  70. data/lib/wakame/command/status.rb +81 -0
  71. data/lib/wakame/command.rb +31 -0
  72. data/lib/wakame/command_queue.rb +44 -0
  73. data/lib/wakame/configuration.rb +93 -0
  74. data/lib/wakame/daemonize.rb +96 -0
  75. data/lib/wakame/event.rb +232 -0
  76. data/lib/wakame/event_dispatcher.rb +154 -0
  77. data/lib/wakame/graph.rb +79 -0
  78. data/lib/wakame/initializer.rb +162 -0
  79. data/lib/wakame/instance_counter.rb +78 -0
  80. data/lib/wakame/logger.rb +12 -0
  81. data/lib/wakame/manager/commands.rb +134 -0
  82. data/lib/wakame/master.rb +369 -0
  83. data/lib/wakame/monitor/agent.rb +50 -0
  84. data/lib/wakame/monitor/service.rb +183 -0
  85. data/lib/wakame/monitor.rb +69 -0
  86. data/lib/wakame/packets.rb +160 -0
  87. data/lib/wakame/queue_declare.rb +14 -0
  88. data/lib/wakame/rule.rb +116 -0
  89. data/lib/wakame/rule_engine.rb +202 -0
  90. data/lib/wakame/runner/administrator_command.rb +112 -0
  91. data/lib/wakame/runner/agent.rb +81 -0
  92. data/lib/wakame/runner/master.rb +93 -0
  93. data/lib/wakame/scheduler.rb +251 -0
  94. data/lib/wakame/service.rb +914 -0
  95. data/lib/wakame/template.rb +189 -0
  96. data/lib/wakame/trigger.rb +66 -0
  97. data/lib/wakame/triggers/instance_count_update.rb +45 -0
  98. data/lib/wakame/triggers/load_history.rb +107 -0
  99. data/lib/wakame/triggers/maintain_ssh_known_hosts.rb +43 -0
  100. data/lib/wakame/triggers/process_command.rb +34 -0
  101. data/lib/wakame/triggers/shutdown_unused_vm.rb +16 -0
  102. data/lib/wakame/util.rb +569 -0
  103. data/lib/wakame/vm_manipulator.rb +186 -0
  104. data/lib/wakame.rb +59 -0
  105. data/tasks/ec2.rake +127 -0
  106. data/tests/cluster.json +3 -0
  107. data/tests/conf/a +1 -0
  108. data/tests/conf/b +1 -0
  109. data/tests/conf/c +1 -0
  110. data/tests/setup_agent.rb +39 -0
  111. data/tests/setup_master.rb +28 -0
  112. data/tests/test_actor.rb +54 -0
  113. data/tests/test_agent.rb +218 -0
  114. data/tests/test_amqp_client.rb +94 -0
  115. data/tests/test_graph.rb +36 -0
  116. data/tests/test_master.rb +167 -0
  117. data/tests/test_monitor.rb +47 -0
  118. data/tests/test_rule_engine.rb +127 -0
  119. data/tests/test_scheduler.rb +123 -0
  120. data/tests/test_service.rb +60 -0
  121. data/tests/test_template.rb +67 -0
  122. data/tests/test_uri_amqp.rb +19 -0
  123. data/tests/test_util.rb +71 -0
  124. data/wakame_generators/resource/resource_generator.rb +54 -0
  125. data/wakame_generators/resource/templates/apache_app/apache_app.rb +60 -0
  126. data/wakame_generators/resource/templates/apache_app/conf/apache2.conf +46 -0
  127. data/wakame_generators/resource/templates/apache_app/conf/envvars-app +7 -0
  128. data/wakame_generators/resource/templates/apache_app/conf/sites-app.conf +23 -0
  129. data/wakame_generators/resource/templates/apache_app/conf/system-app.conf +67 -0
  130. data/wakame_generators/resource/templates/apache_app/init.d/apache2-app +192 -0
  131. data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +67 -0
  132. data/wakame_generators/resource/templates/apache_lb/conf/apache2.conf +46 -0
  133. data/wakame_generators/resource/templates/apache_lb/conf/envvars-lb +6 -0
  134. data/wakame_generators/resource/templates/apache_lb/conf/sites-lb.conf +54 -0
  135. data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +75 -0
  136. data/wakame_generators/resource/templates/apache_lb/init.d/apache2-lb +192 -0
  137. data/wakame_generators/resource/templates/apache_www/apache_www.rb +56 -0
  138. data/wakame_generators/resource/templates/apache_www/conf/apache2.conf +47 -0
  139. data/wakame_generators/resource/templates/apache_www/conf/envvars-www +7 -0
  140. data/wakame_generators/resource/templates/apache_www/conf/sites-www.conf +23 -0
  141. data/wakame_generators/resource/templates/apache_www/conf/system-www.conf +63 -0
  142. data/wakame_generators/resource/templates/apache_www/init.d/apache2-www +192 -0
  143. data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +39 -0
  144. data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +154 -0
  145. data/wakame_generators/resource/templates/mysql_master/init.d/mysql +185 -0
  146. data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +119 -0
  147. 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,15 @@
1
+ require 'uri/generic'
2
+
3
+ module URI
4
+ class AMQP < Generic
5
+ COMPONENT = [
6
+ :scheme,
7
+ :userinfo, :host, :port,
8
+ :path
9
+ ].freeze
10
+
11
+ alias :vhost :path
12
+ end
13
+
14
+ @@schemes['AMQP'] = AMQP
15
+ end
@@ -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