wakame 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/History.txt +4 -0
  2. data/LICENSE +202 -0
  3. data/Rakefile +11 -12
  4. data/VERSION +1 -1
  5. data/app_generators/wakame/templates/bin/wakame-agent +1 -1
  6. data/app_generators/wakame/templates/bin/wakame-master +1 -1
  7. data/app_generators/wakame/templates/config/cluster.rb +32 -24
  8. data/app_generators/wakame/templates/config/init.d/centos/wakame-agent +40 -0
  9. data/app_generators/wakame/templates/config/init.d/centos/wakame-master +40 -0
  10. data/app_generators/wakame/templates/config/init.d/wakame-master +1 -1
  11. data/lib/ext/eventmachine.rb +5 -5
  12. data/lib/wakame.rb +12 -0
  13. data/lib/wakame/action.rb +10 -11
  14. data/lib/wakame/actions/deploy_application.rb +61 -0
  15. data/lib/wakame/actions/deploy_config.rb +1 -3
  16. data/lib/wakame/actions/freeze_cluster.rb +15 -0
  17. data/lib/wakame/actions/launch_cluster.rb +1 -3
  18. data/lib/wakame/actions/launch_vm.rb +1 -1
  19. data/lib/wakame/actions/migrate_service.rb +4 -3
  20. data/lib/wakame/actions/notify_child_changed.rb +3 -6
  21. data/lib/wakame/actions/notify_parent_changed.rb +4 -7
  22. data/lib/wakame/actions/propagate_resource.rb +1 -3
  23. data/lib/wakame/actions/propagate_service.rb +1 -3
  24. data/lib/wakame/actions/register_agent.rb +43 -0
  25. data/lib/wakame/actions/reload_service.rb +2 -2
  26. data/lib/wakame/actions/shutdown_cluster.rb +4 -6
  27. data/lib/wakame/actions/shutdown_vm.rb +27 -6
  28. data/lib/wakame/actions/start_service.rb +40 -32
  29. data/lib/wakame/actions/stop_service.rb +8 -10
  30. data/lib/wakame/actions/unfreeze_cluster.rb +15 -0
  31. data/lib/wakame/actor.rb +2 -5
  32. data/lib/wakame/actor/deploy.rb +110 -0
  33. data/lib/wakame/actor/monitor.rb +14 -0
  34. data/lib/wakame/actor/s3fs.rb +45 -0
  35. data/lib/wakame/actor/service_monitor.rb +0 -17
  36. data/lib/wakame/actor/system.rb +5 -1
  37. data/lib/wakame/agent.rb +29 -179
  38. data/lib/wakame/agent_manager.rb +11 -0
  39. data/lib/wakame/agent_managers/actor_manager.rb +101 -0
  40. data/lib/wakame/agent_managers/monitor_manager.rb +48 -0
  41. data/lib/wakame/command.rb +4 -7
  42. data/lib/wakame/command/actor.rb +9 -12
  43. data/lib/wakame/command/agent_status.rb +2 -2
  44. data/lib/wakame/command/control_service.rb +66 -0
  45. data/lib/wakame/command/deploy_application.rb +18 -0
  46. data/lib/wakame/command/deploy_config.rb +16 -0
  47. data/lib/wakame/command/launch_cluster.rb +1 -1
  48. data/lib/wakame/command/launch_vm.rb +1 -1
  49. data/lib/wakame/command/propagate_resource.rb +1 -1
  50. data/lib/wakame/command/propagate_service.rb +5 -3
  51. data/lib/wakame/command/reload_service.rb +1 -1
  52. data/lib/wakame/command/shutdown_cluster.rb +1 -1
  53. data/lib/wakame/command/shutdown_vm.rb +37 -11
  54. data/lib/wakame/command/start_service.rb +1 -1
  55. data/lib/wakame/command/status.rb +6 -4
  56. data/lib/wakame/command/stop_service.rb +1 -1
  57. data/lib/wakame/configuration.rb +5 -0
  58. data/lib/wakame/event.rb +85 -33
  59. data/lib/wakame/event_dispatcher.rb +2 -2
  60. data/lib/wakame/initializer.rb +97 -31
  61. data/lib/wakame/master.rb +23 -346
  62. data/lib/wakame/master_manager.rb +11 -0
  63. data/lib/wakame/master_managers/action_manager.rb +321 -0
  64. data/lib/wakame/master_managers/agent_monitor.rb +166 -0
  65. data/lib/wakame/master_managers/cluster_manager.rb +176 -0
  66. data/lib/wakame/master_managers/command_queue.rb +133 -0
  67. data/lib/wakame/models/agent_pool.rb +113 -0
  68. data/lib/wakame/models/application_repository.rb +34 -0
  69. data/lib/wakame/models/object_store.rb +32 -0
  70. data/lib/wakame/models/service_cluster_pool.rb +36 -0
  71. data/lib/wakame/monitor.rb +3 -6
  72. data/lib/wakame/monitor/agent.rb +9 -6
  73. data/lib/wakame/monitor/service.rb +56 -29
  74. data/lib/wakame/runner/administrator_command.rb +210 -24
  75. data/lib/wakame/runner/agent.rb +2 -0
  76. data/lib/wakame/runner/master.rb +2 -1
  77. data/lib/wakame/service.rb +140 -130
  78. data/lib/wakame/status_db.rb +101 -121
  79. data/lib/wakame/util.rb +26 -15
  80. data/tests/setup_master.rb +1 -0
  81. data/tests/test_master.rb +0 -2
  82. data/tests/test_model_agent_pool.rb +21 -0
  83. data/tests/test_service.rb +14 -8
  84. data/tests/test_status_db.rb +2 -0
  85. data/tests/test_util.rb +12 -1
  86. data/wakame_generators/resource/templates/apache_app/apache_app.rb +20 -11
  87. data/wakame_generators/resource/templates/apache_app/conf/vh/aaa.test.conf +1 -1
  88. data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +7 -7
  89. data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +6 -4
  90. data/wakame_generators/resource/templates/apache_www/apache_www.rb +15 -13
  91. data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +17 -17
  92. data/wakame_generators/resource/templates/ec2_elb/ec2_elb.rb +22 -15
  93. data/wakame_generators/resource/templates/mongodb/conf/mongodb.conf +95 -0
  94. data/wakame_generators/resource/templates/mongodb/init.d/mongodb +244 -0
  95. data/wakame_generators/resource/templates/mongodb/mongodb.rb +64 -0
  96. data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +17 -21
  97. data/wakame_generators/resource/templates/nginx/conf/nginx.conf +4 -0
  98. data/wakame_generators/resource/templates/nginx/conf/vh/ec2_elb_common.conf +19 -0
  99. data/wakame_generators/resource/templates/nginx/init.d/nginx +6 -0
  100. data/wakame_generators/resource/templates/nginx/init.d/spawn-fcgi +46 -0
  101. data/wakame_generators/resource/templates/nginx/nginx.rb +15 -10
  102. data/wakame_generators/resource/templates/nginx_passenger/conf/nginx-passenger.conf +39 -0
  103. data/wakame_generators/resource/templates/nginx_passenger/conf/vh/ec2_elb_common.conf +10 -0
  104. data/wakame_generators/resource/templates/nginx_passenger/init.d/nginx-passenger +70 -0
  105. data/wakame_generators/resource/templates/nginx_passenger/nginx_passenger.rb +71 -0
  106. data/wakame_generators/resource/templates/s3fs/s3fs.rb +24 -0
  107. metadata +195 -74
  108. data/lib/wakame/action_manager.rb +0 -303
  109. data/lib/wakame/command/clone_service.rb +0 -12
  110. data/lib/wakame/command_queue.rb +0 -135
  111. data/lib/wakame/vm_manipulator.rb +0 -187
@@ -0,0 +1,11 @@
1
+ module Wakame
2
+ module AgentManager
3
+ attr_accessor :agent
4
+
5
+ def init; end
6
+ def start; end
7
+ def reload; end
8
+ def stop; end
9
+ def terminate; end
10
+ end
11
+ end
@@ -0,0 +1,101 @@
1
+
2
+ module Wakame
3
+ module AgentManagers
4
+ class ActorManager
5
+ include AgentManager
6
+
7
+ def init
8
+ agent.add_subscriber("agent_actor.#{agent.agent_id}") { |data|
9
+ begin
10
+ request = eval(data)
11
+ handle_request(request)
12
+ rescue => e
13
+ Wakame.log.error(e)
14
+ publish_to('agent_event', Packets::ActorResponse.new(self, request[:token], Actor::STATUS_FAILED, {:message=>e.message, :exclass=>e.class.to_s}).marshal)
15
+ end
16
+ }
17
+
18
+
19
+ register(Actor::ServiceMonitor.new, '/service_monitor')
20
+ register(Actor::Daemon.new, '/daemon')
21
+ register(Actor::System.new, '/system')
22
+ register(Actor::MySQL.new, '/mysql')
23
+ register(Actor::Deploy.new, '/deploy')
24
+ register(Actor::Monitor.new, '/monitor')
25
+ register(Actor::S3fs.new, '/s3fs')
26
+
27
+ end
28
+
29
+ def terminate
30
+ end
31
+
32
+ attr_reader :actors
33
+
34
+ def initialize()
35
+ @actors = {}
36
+ end
37
+
38
+ def register(actor, path=nil)
39
+ raise '' unless actor.kind_of?(Wakame::Actor)
40
+
41
+ if path.nil?
42
+ path = '/' + Util.to_const_path(actor.class.to_s)
43
+ end
44
+
45
+ if @actors.has_key?(path)
46
+ Wakame.log.error("#{self.class}: Duplicate registration: #{path}")
47
+ raise "Duplicate registration: #{path}"
48
+ end
49
+
50
+ actor.agent = self.agent
51
+ @actors[path] = actor
52
+ end
53
+
54
+ def unregister(path)
55
+ @actors.delete(path)
56
+ end
57
+
58
+ def find_actor(path)
59
+ @actors[path]
60
+ end
61
+
62
+
63
+ private
64
+ def handle_request(request)
65
+ slash = request[:path].rindex('/') || raise("Invalid request path: #{request[:path]}")
66
+
67
+ prefix = request[:path][0, slash]
68
+ action = request[:path][slash+1, request[:path].length]
69
+
70
+ actor = find_actor(prefix) || raise("Invalid request path: #{request[:path]}")
71
+
72
+ EM.defer(proc {
73
+ begin
74
+ Wakame.log.debug("#{self.class}: Started to run the actor: #{actor.class}, token=#{request[:token]}")
75
+ agent.publish_to('agent_event', Packets::ActorResponse.new(agent, request[:token], Actor::STATUS_RUNNING).marshal)
76
+ if request[:args].nil?
77
+ actor.send(action)
78
+ else
79
+ actor.send(action, *request[:args])
80
+ end
81
+ Wakame.log.debug("#{self.class}: Finished to run the actor: #{actor.class}, token=#{request[:token]}")
82
+ actor.return_value
83
+ rescue => e
84
+ Wakame.log.error("#{self.class}: Failed the actor: #{actor.class}, token=#{request[:token]}")
85
+ Wakame.log.error(e)
86
+ e
87
+ end
88
+ }, proc { |res|
89
+ status = Actor::STATUS_SUCCESS
90
+ if res.is_a?(Exception)
91
+ status = Actor::STATUS_FAILED
92
+ opts = {:message => res.message, :exclass=>res.class.to_s}
93
+ else
94
+ opts = {:return_value=>res}
95
+ end
96
+ agent.publish_to('agent_event', Packets::ActorResponse.new(self.agent, request[:token], status, opts).marshal)
97
+ })
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,48 @@
1
+ module Wakame
2
+ module AgentManagers
3
+ class MonitorManager
4
+ include AgentManager
5
+
6
+ def init
7
+ agent_mon = register(Monitor::Agent.new, '/agent')
8
+ register(Monitor::Service.new, '/service')
9
+
10
+ agent_mon.reload({:interval=>10})
11
+ end
12
+
13
+ def terminate
14
+ end
15
+
16
+ attr_reader :monitors
17
+
18
+ def initialize()
19
+ @monitors = {}
20
+ end
21
+
22
+ def register(monitor, path=nil)
23
+ raise '' unless monitor.kind_of?(Wakame::Monitor)
24
+
25
+ if path.nil?
26
+ path = '/' + Util.to_const_path(monitor.class.to_s)
27
+ end
28
+
29
+ if @monitors.has_key?(path)
30
+ Wakame.log.error("#{self.class}: Duplicate registration: #{path}")
31
+ raise "Duplicate registration: #{path}"
32
+ end
33
+
34
+ monitor.agent = self.agent
35
+ @monitors[path] = monitor
36
+ end
37
+
38
+ def unregister(path)
39
+ @monitors.delete(path)
40
+ end
41
+
42
+ def find_monitor(path)
43
+ @monitors[path]
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -6,13 +6,10 @@ module Wakame
6
6
  def self.included(klass)
7
7
  klass.class_eval {
8
8
  class << self
9
- def command_name
9
+ def command_name(name=nil)
10
+ @command_name = name if name
10
11
  @command_name ||= Util.snake_case(self.to_s.split('::').last)
11
12
  end
12
-
13
- def command_name=(name)
14
- @command_name=name
15
- end
16
13
  end
17
14
  }
18
15
  end
@@ -34,8 +31,8 @@ module Wakame
34
31
  Master.instance
35
32
  end
36
33
 
37
- def trigger_action(action)
38
- master.action_manager.trigger_action(action)
34
+ def trigger_action(action=nil, &blk)
35
+ master.action_manager.trigger_action(action, &blk)
39
36
  end
40
37
 
41
38
  # Tentative utility method for
@@ -3,21 +3,18 @@ class Wakame::Command::Actor
3
3
  include Wakame::Command
4
4
  include Wakame::Service
5
5
 
6
- command_name='actor'
7
-
8
- def parse(args)
9
- raise "Not enugh number of arguments" if args.size < 2
10
- end
6
+ command_name 'actor'
11
7
 
12
8
  def run
13
- agent = Agent.find(params[:agent_id])
14
- raise "Unknown agent: #{params[:agent_id]}" if agent.nil?
15
- raise "Invalid agent status (Not Online): #{agent.status} #{params[:agent_id]}" if agent.status != Agent::STATUS_ONLINE
16
-
17
- raise "Invalid actor path: #{params[:path]}" if params[:path].nil? || params[:path] == ''
9
+ agent = Agent.find(params['agent_id'])
10
+ raise "Unknown agent: #{params['agent_id']}" if agent.nil?
11
+ raise "Invalid agent status (Not Online): #{agent.status} #{params['agent_id']}" if agent.status != Agent::STATUS_ONLINE
12
+ raise "Invalid actor path: #{params['path']}" if params['path'].nil? || params['path'] == ''
13
+ if params['args'].is_a? String
14
+ params['args'] = eval(params['args'])
15
+ end
18
16
 
19
- request = rule.master.actor_request(params[:agent_id], params[:path], *params[:args]).request
20
- request.wait
17
+ request = master.actor_request(params['agent_id'], params['path'], *params['args']).request
21
18
  end
22
19
 
23
20
  end
@@ -2,7 +2,7 @@
2
2
  class Wakame::Command::AgentStatus
3
3
  include Wakame::Command
4
4
 
5
- command_name='agent_status'
5
+ command_name 'agent_status'
6
6
 
7
7
  def run(rule)
8
8
  EM.barrier {
@@ -15,4 +15,4 @@ class Wakame::Command::AgentStatus
15
15
  res
16
16
  }
17
17
  end
18
- end
18
+ end
@@ -0,0 +1,66 @@
1
+ class Wakame::Command::ControlService
2
+ include Wakame::Command
3
+ include Wakame
4
+
5
+ command_name 'control_service'
6
+
7
+ def run
8
+ num = @options["number"] || 1
9
+ raise "Invalid format of number: #{num}" unless /^(\d+)$/ =~ num.to_s
10
+ num = num.to_i
11
+
12
+ resname = @options["resource"]
13
+ resobj = Service::Resource.find(Service::Resource.id(resname))
14
+
15
+ if num < 1 || resobj.max_instances < num
16
+ raise "The number must be between 1 and #{resobj.max_instances - service_cluster.instance_count(resobj)} (max limit: #{resobj.max_instances})"
17
+ end
18
+ raise "The same number of instances running" if service_cluster.instance_count(resobj) == num
19
+
20
+ if service_cluster.instance_count(resobj) < num
21
+ num = (num - service_cluster.instance_count(resobj)).to_i
22
+ cloud_host_id = nil
23
+ refsvc = service_cluster.find_service(@options["service_id"])
24
+ if refsvc.nil?
25
+ raise("Unknown ServiceInstance ID: #{@options["service_id"]}")
26
+ end
27
+ trigger_action{|action|
28
+ num.times{
29
+ action.trigger_action(Wakame::Actions::PropagateService.new(refsvc, cloud_host_id))
30
+ }
31
+ }
32
+ else
33
+ attrs = Master.ec2_fetch_local_attrs
34
+ agent = Wakame::Models::AgentPool.instance.find_agent(attrs[:instance_id])
35
+ cloud_host_id = agent.cloud_host.id
36
+ num = (service_cluster.instance_count(resobj) - num).to_i
37
+ locksvc = service_cluster.find_service(@options["service_id"])
38
+ refsvc = service_cluster.each_instance(resobj)
39
+ svcs, nsvcs = refsvc.partition{|s| s.id == locksvc.id}
40
+ c = 1
41
+ res = {}
42
+ nsvcs.reverse_each {|svc|
43
+ cloud_host = Service::CloudHost.find(svc.cloud_host_id)
44
+ res[svc.id] = cloud_host.agent.vm_attr
45
+ trigger_action { |action|
46
+ action.trigger_action(Wakame::Actions::StopService.new(svc))
47
+ action.flush_subactions
48
+ action.trigger_action(Wakame::Actions::NotifyParentChanged.new(svc))
49
+ action.flush_subactions
50
+ unless cloud_host.id == cloud_host_id
51
+ action.trigger_action(Wakame::Actions::ShutdownVM.new(cloud_host.agent))
52
+ action.flush_subactions
53
+ Wakame::StatusDB.barrier{
54
+ cluster = Wakame::Service::ServiceCluster.find(cloud_host.cluster_id)
55
+ cloud_host.unmap_agent
56
+ cluster.remove_cloud_host(cloud_host.id)
57
+ }
58
+ end
59
+ }
60
+ c += 1
61
+ break if c > num
62
+ }
63
+ end
64
+ res
65
+ end
66
+ end
@@ -0,0 +1,18 @@
1
+
2
+ class Wakame::Command::DeployApplication
3
+ include Wakame::Command
4
+ include Wakame::Service
5
+
6
+ command_name 'deploy_application'
7
+
8
+ def run
9
+ raise "Invalid application name: \"#{params['app_name']}\"" if params['app_name'].nil? || params['app_name'] !~ /\A[\w\-\.\@]+\Z/
10
+ if Wakame::Models::ApplicationRepository.find(:app_name=>params['app_name']) == nil
11
+ raise "The name of application is not registered: #{params['app_name']}"
12
+ end
13
+
14
+
15
+ trigger_action(Wakame::Actions::DeployApplication.new(params['app_name']))
16
+ end
17
+
18
+ end
@@ -0,0 +1,16 @@
1
+
2
+ class Wakame::Command::DeployConfig
3
+ include Wakame::Command
4
+ include Wakame::Service
5
+
6
+ command_name 'deploy_config'
7
+
8
+ def run
9
+ cluster.each_instance.map { |svc_inst|
10
+ next if svc_inst.cloud_host_id.nil?
11
+ Wakame.log.debug(svc_inst)
12
+ trigger_action(Wakame::Actions::DeployConfig.new(svc_inst))
13
+ }
14
+ end
15
+
16
+ end
@@ -3,7 +3,7 @@
3
3
  class Wakame::Command::LaunchCluster
4
4
  include Wakame::Command
5
5
 
6
- command_name='launch_cluster'
6
+ command_name 'launch_cluster'
7
7
 
8
8
  def run
9
9
  trigger_action(Wakame::Actions::LaunchCluster.new)
@@ -2,7 +2,7 @@
2
2
  class Wakame::Command::LaunchVm
3
3
  include Wakame::Command
4
4
 
5
- command_name='launch_vm'
5
+ command_name 'launch_vm'
6
6
 
7
7
  def run
8
8
  inst_id_key = "new_inst_id_" + Wakame::Util.gen_id
@@ -3,7 +3,7 @@ class Wakame::Command::PropagateResource
3
3
  include Wakame::Command
4
4
  include Wakame
5
5
 
6
- command_name='propagate_resource'
6
+ command_name 'propagate_resource'
7
7
 
8
8
  def run
9
9
  resname = @options["resource"]
@@ -3,7 +3,7 @@ class Wakame::Command::PropagateService
3
3
  include Wakame::Command
4
4
  include Wakame
5
5
 
6
- command_name='propagate_service'
6
+ command_name 'propagate_service'
7
7
 
8
8
  def run
9
9
  refsvc = service_cluster.find_service(@options["service_id"])
@@ -27,8 +27,10 @@ class Wakame::Command::PropagateService
27
27
  raise "The number must be between 1 and #{refsvc.resource.max_instances - service_cluster.instance_count(refsvc.resource)} (max limit: #{refsvc.resource.max_instances})"
28
28
  end
29
29
 
30
- num.times {
31
- trigger_action(Wakame::Actions::PropagateService.new(refsvc, cloud_host_id))
30
+ trigger_action { |action|
31
+ num.times {
32
+ action.trigger_action(Wakame::Actions::PropagateService.new(refsvc, cloud_host_id))
33
+ }
32
34
  }
33
35
  end
34
36
  end
@@ -2,7 +2,7 @@
2
2
  class Wakame::Command::ReloadService
3
3
  include Wakame::Command
4
4
 
5
- command_name='reload_service'
5
+ command_name 'reload_service'
6
6
 
7
7
  def run
8
8
  svc = service_cluster.find_service(options['service_id'])
@@ -2,7 +2,7 @@
2
2
  class Wakame::Command::ShutdownCluster
3
3
  include Wakame::Command
4
4
 
5
- command_name='shutdown_cluster'
5
+ command_name 'shutdown_cluster'
6
6
 
7
7
  def run
8
8
  trigger_action(Wakame::Actions::ShutdownCluster.new)
@@ -2,19 +2,45 @@
2
2
  class Wakame::Command::ShutdownVm
3
3
  include Wakame::Command
4
4
 
5
- command_name='shutdown_vm'
5
+ command_name 'shutdown_vm'
6
6
 
7
- def run(rule)
8
- registered_agents = rule.agent_monitor.registered_agents[@options["agent_id"]]
9
- if !registered_agents.services.nil?
10
- if !@options["force"].nil?
11
- registered_agents.services.each{|id, svc_inst|
12
- rule.trigger_action(Wakame::Actions::StopService.new(svc_inst))
13
- }
7
+ def run
8
+ agent = Wakame::Models::AgentPool.instance.find_agent(@options['agent_id'])
9
+ if agent.cloud_host_id.nil?
10
+ trigger_action(Wakame::Actions::ShutdownVM.new(agent))
11
+ else
12
+ cloud_host = agent.cloud_host
13
+ # Check if the agent has the running service(s).
14
+ live_svcs = cloud_host.assigned_services.find_all {|svc_id|
15
+ Wakame::Service::ServiceInstance.find(svc_id).monitor_status == Wakame::Service::STATUS_ONLINE
16
+ }
17
+ if live_svcs.empty?
18
+ cloud_host.unmap_agent
19
+ trigger_action(Wakame::Actions::ShutdownVM.new(agent))
14
20
  else
15
- raise "Service instances Launched"
21
+ raise "Service(s) are still running on #{agent.id}" unless @options['force']
22
+
23
+ trigger_action { |action|
24
+ live_svcs.each {|svc_id|
25
+ svc = Wakame::Service::ServiceInstance.find(svc_id)
26
+ action.trigger_action(Wakame::Actions::StopService.new(svc))
27
+ }
28
+ action.flush_subactions
29
+
30
+ Wakame::StatusDB.barrier {
31
+ cluster = Wakame::Service::ServiceCluster.find(cloud_host.cluster_id)
32
+ live_svcs.each {|svc_id|
33
+ cluster.destroy(svc_id)
34
+ }
35
+
36
+ cloud_host.unmap_agent
37
+ cluster.remove_cloud_host(cloud_host.id)
38
+ }
39
+
40
+ action.trigger_action(Wakame::Actions::ShutdownVM.new(agent))
41
+ }
16
42
  end
17
43
  end
18
- rule.trigger_action(Wakame::Actions::ShutdownVM.new(registered_agents))
44
+
19
45
  end
20
- end
46
+ end