wakame 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/History.txt +8 -0
  2. data/Rakefile +3 -3
  3. data/VERSION +1 -1
  4. data/app_generators/wakame/templates/cluster/resources/markers/http_application_server.rb +3 -0
  5. data/app_generators/wakame/templates/cluster/resources/markers/http_asset_server.rb +2 -0
  6. data/app_generators/wakame/templates/cluster/resources/markers/http_server.rb +9 -0
  7. data/app_generators/wakame/templates/config/cluster.rb +36 -99
  8. data/app_generators/wakame/templates/config/init.d/wakame-agent +3 -3
  9. data/app_generators/wakame/templates/config/init.d/wakame-master +3 -3
  10. data/app_generators/wakame/wakame_generator.rb +5 -1
  11. data/contrib/imagesetup.sh +9 -5
  12. data/lib/ext/uri.rb +13 -0
  13. data/lib/wakame/action.rb +46 -21
  14. data/lib/wakame/{rule_engine.rb → action_manager.rb} +148 -36
  15. data/lib/wakame/actions/deploy_config.rb +35 -0
  16. data/lib/wakame/actions/launch_cluster.rb +8 -10
  17. data/lib/wakame/actions/launch_vm.rb +26 -20
  18. data/lib/wakame/actions/migrate_service.rb +30 -19
  19. data/lib/wakame/actions/notify_child_changed.rb +34 -0
  20. data/lib/wakame/actions/notify_parent_changed.rb +34 -0
  21. data/lib/wakame/actions/propagate_resource.rb +27 -0
  22. data/lib/wakame/actions/propagate_service.rb +27 -0
  23. data/lib/wakame/actions/reload_service.rb +21 -9
  24. data/lib/wakame/actions/shutdown_cluster.rb +3 -3
  25. data/lib/wakame/actions/shutdown_vm.rb +14 -5
  26. data/lib/wakame/actions/start_service.rb +53 -47
  27. data/lib/wakame/actions/stop_service.rb +35 -23
  28. data/lib/wakame/actor/system.rb +6 -3
  29. data/lib/wakame/agent.rb +29 -7
  30. data/lib/wakame/amqp_client.rb +26 -5
  31. data/lib/wakame/command/action_status.rb +7 -7
  32. data/lib/wakame/command/actor.rb +10 -10
  33. data/lib/wakame/command/import_cluster_config.rb +10 -0
  34. data/lib/wakame/command/launch_cluster.rb +2 -2
  35. data/lib/wakame/command/launch_vm.rb +3 -3
  36. data/lib/wakame/command/migrate_service.rb +7 -7
  37. data/lib/wakame/command/propagate_resource.rb +42 -0
  38. data/lib/wakame/command/propagate_service.rb +21 -19
  39. data/lib/wakame/command/reload_service.rb +3 -13
  40. data/lib/wakame/command/shutdown_cluster.rb +2 -2
  41. data/lib/wakame/command/start_service.rb +14 -0
  42. data/lib/wakame/command/status.rb +32 -10
  43. data/lib/wakame/command/stop_service.rb +27 -21
  44. data/lib/wakame/command.rb +19 -3
  45. data/lib/wakame/command_queue.rb +87 -67
  46. data/lib/wakame/configuration.rb +6 -0
  47. data/lib/wakame/event.rb +17 -0
  48. data/lib/wakame/event_dispatcher.rb +32 -23
  49. data/lib/wakame/graph.rb +2 -1
  50. data/lib/wakame/initializer.rb +11 -8
  51. data/lib/wakame/master.rb +327 -209
  52. data/lib/wakame/monitor/agent.rb +5 -1
  53. data/lib/wakame/monitor/service.rb +6 -5
  54. data/lib/wakame/packets.rb +13 -21
  55. data/lib/wakame/runner/administrator_command.rb +383 -264
  56. data/lib/wakame/runner/agent.rb +1 -5
  57. data/lib/wakame/runner/master.rb +0 -3
  58. data/lib/wakame/service.rb +817 -538
  59. data/lib/wakame/status_db.rb +383 -0
  60. data/lib/wakame/template.rb +27 -130
  61. data/lib/wakame/trigger.rb +10 -18
  62. data/lib/wakame/triggers/instance_count_update.rb +1 -1
  63. data/lib/wakame/triggers/load_history.rb +1 -1
  64. data/lib/wakame/triggers/maintain_ssh_known_hosts.rb +8 -5
  65. data/lib/wakame/triggers/shutdown_unused_vm.rb +1 -1
  66. data/lib/wakame/util.rb +64 -55
  67. data/lib/wakame.rb +4 -0
  68. data/tests/test_action_manager.rb +111 -0
  69. data/tests/test_service.rb +128 -23
  70. data/tests/test_status_db.rb +82 -0
  71. data/tests/test_uri_amqp.rb +10 -0
  72. data/wakame_generators/resource/templates/apache_app/apache_app.rb +19 -18
  73. data/wakame_generators/resource/templates/apache_app/conf/apache2.conf +14 -2
  74. data/wakame_generators/resource/templates/apache_app/conf/system-app.conf +1 -1
  75. data/wakame_generators/resource/templates/apache_app/conf/vh/aaa.test.conf +9 -0
  76. data/wakame_generators/resource/templates/apache_lb/apache_lb.rb +21 -20
  77. data/wakame_generators/resource/templates/apache_lb/conf/apache2.conf +14 -2
  78. data/wakame_generators/resource/templates/apache_lb/conf/system-lb.conf +17 -2
  79. data/wakame_generators/resource/templates/apache_lb/conf/vh/aaa.test.conf +37 -0
  80. data/wakame_generators/resource/templates/apache_www/apache_www.rb +20 -18
  81. data/wakame_generators/resource/templates/apache_www/conf/apache2.conf +14 -2
  82. data/wakame_generators/resource/templates/apache_www/conf/system-www.conf +1 -1
  83. data/wakame_generators/resource/templates/apache_www/conf/vh/aaa.test.conf +9 -0
  84. data/wakame_generators/resource/templates/ec2_elastic_ip/ec2_elastic_ip.rb +6 -8
  85. data/wakame_generators/resource/templates/ec2_elb/ec2_elb.rb +7 -6
  86. data/wakame_generators/resource/templates/memcached/conf/memcached.conf +47 -0
  87. data/wakame_generators/resource/templates/memcached/init.d/memcached +61 -0
  88. data/wakame_generators/resource/templates/memcached/memcached.rb +73 -0
  89. data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +5 -7
  90. data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +35 -34
  91. data/wakame_generators/resource/templates/mysql_slave/conf/my.cnf +6 -6
  92. data/wakame_generators/resource/templates/mysql_slave/mysql_slave.rb +21 -24
  93. data/wakame_generators/resource/templates/nginx/conf/nginx.conf +17 -27
  94. data/wakame_generators/resource/templates/nginx/conf/vh/aaa.test.conf +30 -0
  95. data/wakame_generators/resource/templates/nginx/nginx.rb +18 -18
  96. metadata +34 -21
  97. data/lib/wakame/actions/propagate_instances.rb +0 -70
  98. data/lib/wakame/manager/commands.rb +0 -134
  99. data/lib/wakame/rule.rb +0 -116
  100. data/lib/wakame/triggers/process_command.rb +0 -41
  101. data/tests/test_rule_engine.rb +0 -127
  102. data/wakame_generators/resource/templates/apache_app/conf/sites-app.conf +0 -23
  103. data/wakame_generators/resource/templates/apache_lb/conf/sites-lb.conf +0 -54
  104. data/wakame_generators/resource/templates/apache_www/conf/sites-www.conf +0 -23
@@ -1,7 +1,6 @@
1
1
 
2
2
  require 'uri'
3
3
  require 'cgi'
4
- require 'ext/uri'
5
4
  require 'optparse'
6
5
  require 'net/http'
7
6
  require 'json'
@@ -21,23 +20,28 @@ module Wakame
21
20
  def initialize(args)
22
21
  @args = args.dup
23
22
  @options = {
24
- :command_server_uri => Wakame.config.http_command_server_uri
23
+ :command_server_uri => Wakame.config.http_command_server_uri,
24
+ :json_print => false,
25
+ :public_key => '1234567890'
25
26
  }
26
- @public_key = "1234567890"
27
+
28
+ load_subcommands
27
29
  end
28
30
 
29
31
  def parse(args=@args)
30
32
  args = args.dup
31
33
 
32
34
  comm_parser = OptionParser.new { |opts|
33
- opts.version = VERSION
35
+ opts.version = Wakame::VERSION
34
36
  opts.banner = "Usage: wakameadm [options] command [options]"
35
-
36
- opts.separator ""
37
- opts.separator "options:"
37
+ opts.separator " "
38
+ opts.separator "Sub Commands:"
39
+ opts.separator show_subcommand_summary()
40
+ opts.separator " "
41
+ opts.separator "Common Options:"
38
42
  opts.on( "-s", "--server HttpURI", "command server" ) {|str| @options[:command_server_uri] = str }
43
+ opts.on("--dump", "Print corresponded message body for debugging"){|j| @options[:json_print] = true }
39
44
  }
40
-
41
45
 
42
46
  comm_parser.order!(args)
43
47
  @options.freeze
@@ -46,85 +50,146 @@ module Wakame
46
50
  end
47
51
 
48
52
  def run
49
- req = parse
50
- subcommand = req[:command]
51
-
52
- if Wakame.config.enable_authentication == "true"
53
- get_params = authentication(req[:command_server_uri], req[:query_string])
54
- else
55
- get_params = req[:command_server_uri] + req[:query_string]
56
- end
53
+ parse
54
+
55
+ #if Wakame.config.enable_authentication == "true"
56
+ # get_params = authentication(req[:command_server_uri], req[:query_string])
57
+ #else
58
+ # get_params = req[:command_server_uri] + req[:query_string]
59
+ #end
60
+
57
61
  begin
58
- res = subcommand.run(get_params)
59
- res = JSON.parse(res)
62
+ requester = JsonRequester.new(options.dup, {:action=>@subcmd.class.command_name})
63
+ @subcmd.run(requester)
64
+
65
+
66
+ @subcmd.print_result
67
+
68
+ rescue JsonRequester::ResponseError => e
69
+ abort(e)
60
70
  rescue => e
61
- res = STDERR.puts e
62
- exit 1
71
+ abort("Unknown Error: #{e}\n" + e.backtrace.join("\n") )
63
72
  end
64
73
 
65
- unless req[:json_print].nil?
66
- require 'pp'
67
- pp res
68
- else
69
- case res[0]["status"]
70
- when 404
71
- p "Command Error: #{res[0]["message"]}"
72
- when 403
73
- p "Authentication Error: #{res[0]["message"]}"
74
- when 500
75
- p "Server Error: #{res[0]["message"]}"
76
- else
77
- subcommand.print_result(res)
78
- end
79
- end
74
+ exit 0
80
75
  end
81
76
 
82
77
  private
83
78
 
84
79
  def parse_subcommand(args)
85
- @subcmd = args.shift
86
- if @subcmd.nil?
80
+ subcmd_name = args.shift
81
+ if subcmd_name.nil?
87
82
  fail "Please pass a sub command."
88
83
  end
89
- subcommands = {}
84
+ subcommand_class = @subcommand_types[subcmd_name]
85
+ fail "No such sub command: #{subcmd_name}" if subcommand_class.nil?
86
+
87
+ @subcmd = subcommand_class.new
88
+
89
+ options = @subcmd.parse(args)
90
+ end
91
+
92
+ def load_subcommands
93
+ @subcommand_types = {}
90
94
  (Wakame::Cli::Subcommand.constants - $root_constants).each { |c|
91
95
  const = Util.build_const("Wakame::Cli::Subcommand::#{c}")
92
96
  if const.is_a?(Class)
93
- cmdobj = nil
94
- begin
95
- cmdobj = const.new
96
- raise '' unless cmdobj.kind_of?(Wakame::Cli::Subcommand)
97
- rescue => e
98
- next
99
- end
100
- subcommands[cmdobj.class.command_name] = cmdobj
97
+ next unless const < Wakame::Cli::Subcommand
98
+ @subcommand_types[const.command_name] = const
101
99
  end
102
100
  }
103
- subcommand = subcommands[@subcmd]
104
- fail "No such sub command: #{@subcmd}" if subcommand.nil?
105
-
106
- options = subcommand.parse(args)
107
- query_string = CGI.escape('action') + "=" + CGI.escape(@subcmd) + options[:query].to_s
108
- request_params = {
109
- :command => subcommand,
110
- :command_server_uri => @options[:command_server_uri] + "?",
111
- :query_string => query_string,
112
- :json_print => options[:json_print]
101
+ end
102
+
103
+ def show_subcommand_summary
104
+ @subcommand_types.map { |k,v|
105
+ " #{k}: #{v.summary.nil? ? '' : v.summary.to_s}"
113
106
  }
107
+ end
108
+ end
109
+ end
110
+
111
+ class JsonRequester
112
+ class ResponseError < StandardError
113
+ attr_reader :json_hash
114
+ def initialize(json_hash=nil, message_prefix=self.class.to_s)
115
+ super(message_prefix + ":" + json_hash[0]["message"])
116
+ @json_hash = json_hash
117
+ end
118
+ end
114
119
 
115
- request_params
120
+ class CommandError < ResponseError
121
+ def initialize(hash)
122
+ super(hash, "Command Error")
123
+ end
124
+ end
125
+ class AuthenticationError < ResponseError
126
+ def initialize(hash)
127
+ super(hash, "Authentication Error")
128
+ end
129
+ end
130
+ class ServerError < ResponseError
131
+ def initialize(hash)
132
+ super(hash, "Server Error")
133
+ end
134
+ end
135
+
136
+
137
+ def initialize(common_opts, merge_opts={})
138
+ @common_opts = common_opts
139
+ @merge_opts = merge_opts.dup
140
+ end
141
+
142
+ def request(options={})
143
+ request_uri = URI.parse(@common_opts[:command_server_uri])
144
+ @merge_opts[:timestamp] = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
145
+ request_uri.path = (request_uri.path.nil? || request_uri.path == '') ? '/' : request_uri.path
146
+ request_uri.query = sign_query(build_escaped_query(options.merge(@merge_opts)))
147
+
148
+ res = Net::HTTP.get_response(request_uri)
149
+ hash = JSON.parse(res.body)
150
+ if res.is_a?(Net::HTTPSuccess)
151
+ #
152
+ else
153
+ case res.code
154
+ when '404'
155
+ raise CommandError.new(hash)
156
+ when '403'
157
+ raise AuthenticationError.new(hash)
158
+ when '500'
159
+ raise ServerError.new(hash)
160
+ else
161
+ fail "Unknown HTTP Error Code: #{res.code}: #{res.message}"
162
+ end
116
163
  end
117
164
 
118
- def authentication(uri, query)
119
- key = @public_key
120
- req = query + "&" + CGI.escape('timestamp') + "=" + CGI.escape(Time.now.utc.strftime("%Y%m%dT%H%M%SZ"))
121
- hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, key, req)
122
- sign = uri.to_s + req.to_s + "&signature=" + Base64.encode64(hash).gsub(/\+/, "").gsub(/\n/, "").to_s
123
- sign
165
+ if @common_opts[:json_print]
166
+ require 'pp'
167
+ puts "Response for: #{request_uri.to_s}"
168
+ pp hash
124
169
  end
170
+
171
+ hash
125
172
  end
173
+
174
+ private
175
+ def sign_query(query_str)
176
+ require 'openssl'
177
+ require 'base64'
178
+
179
+ hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, @common_opts[:public_key], query_str)
180
+ (query_str + "&signature=" + CGI::escape(Base64.encode64(hash).gsub(/\+/, "").gsub(/\n/, "").to_s))
181
+ end
182
+
183
+
184
+ def build_escaped_query(hash)
185
+ hash.map { |k,v|
186
+ CGI::escape(k.to_s) + '=' + CGI::escape(v.to_s)
187
+ }.join('&')
188
+ end
189
+
126
190
  end
127
191
 
192
+
128
193
  module Cli
129
194
  module Subcommand
130
195
  class CommandArgumentError < StandardError; end
@@ -139,6 +204,14 @@ module Wakame
139
204
  def command_name=(name)
140
205
  @command_name=name
141
206
  end
207
+
208
+ def summary
209
+ @summary
210
+ end
211
+
212
+ def summary=(summary)
213
+ @summary=summary
214
+ end
142
215
  end
143
216
  }
144
217
  end
@@ -146,26 +219,21 @@ module Wakame
146
219
  def parse(args)
147
220
  end
148
221
 
149
- def run(options)
222
+ def run(requester)
150
223
  end
151
224
 
152
- def print_result(res)
225
+ def print_result()
153
226
  end
154
227
 
155
- def create_parser(args,&blk)
156
- parser = OptionParser.new(&blk)
228
+
229
+ def create_parser(args, &blk)
230
+ parser = OptionParser.new { |opts|
231
+ blk.call(opts) if blk
232
+ }
157
233
  parser.order!(args)
158
234
  parser
159
235
  end
160
236
 
161
- def uri(options)
162
- uri = options
163
- res = Net::HTTP.get(URI.parse("#{uri}"))
164
- return res
165
- end
166
-
167
- def summary
168
- end
169
237
  end
170
238
  end
171
239
  end
@@ -173,139 +241,177 @@ end
173
241
  class Wakame::Cli::Subcommand::LaunchCluster
174
242
  include Wakame::Cli::Subcommand
175
243
 
176
- #command_name = 'launch_cluster'
244
+ command_name = 'launch_cluster'
245
+ summary = "Start up the cluster"
246
+
177
247
  def parse(args)
178
- blk = Proc.new {|opts|
179
- opts.banner = "Usage: launch_cluster [options]"
248
+ create_parser(args) {|opts|
249
+ opts.banner = "Usage: launch_cluster"
180
250
  opts.separator ""
181
251
  opts.separator "options:"
182
252
  }
183
- cmd = create_parser(args, &blk)
184
- options = {}
185
- options
186
253
  end
187
254
 
188
- def run(options)
189
- res = uri(options)
190
- res
255
+ def run(requester)
256
+ requester.request()
191
257
  end
192
258
 
193
- def print_result(res)
194
- p res[0]["message"]
195
- end
196
259
  end
197
260
 
198
261
  class Wakame::Cli::Subcommand::ShutdownCluster
199
262
  include Wakame::Cli::Subcommand
200
263
 
264
+ summary = "Shutdown the cluster"
265
+
201
266
  def parse(args)
202
- blk = Proc.new {|opts|
267
+ create_parser(args) {|opts|
203
268
  opts.banner = "Usage: shutdown_cluster"
204
269
  opts.separator ""
205
270
  opts.separator "options:"
206
271
  }
207
- cmd = create_parser(args, &blk)
208
- options = {}
209
- options
210
272
  end
211
273
 
212
- def run(options)
213
- res = uri(options)
214
- res
215
- end
216
-
217
- def print_result(res)
218
- p res[0]["message"]
274
+ def run(requester)
275
+ requester.request()
219
276
  end
220
277
  end
221
278
 
222
279
  class Wakame::Cli::Subcommand::Status
223
280
  include Wakame::Cli::Subcommand
224
281
 
282
+ summary = "Show summary status across the cluster"
283
+
225
284
  STATUS_TMPL = <<__E__
226
- Cluster : <%= @service_cluster["name"].to_s %> (<%= @service_cluster["status"].to_s %>)
227
- <%- @service_cluster["properties"].each { |prop, v| -%>
228
- <%= v["type"].to_s %> : <current=<%= v["instance_count"] %> min=<%= v["min_instances"] %>, max=<%= v["max_instances"] %><%= v["require_agent"] ? "" : ", AgentLess" %>>
229
- <%- v["instances"].each { |id|
230
- svc_inst = @service_cluster["instances"][id]
231
- -%>
232
- <%= svc_inst["instance_id"] %> (<%= trans_svc_status(svc_inst["status"]) %>)
285
+ <%- if cluster -%>
286
+ Cluster : <%= cluster["name"].to_s %> (<%= cluster_status_msg(cluster["status"]) %>)
287
+ <%- cluster["resources"].keys.each { |res_id|
288
+ resource = body["resources"][res_id]
289
+ -%>
290
+ <%= resource["class_type"] %> : <current=<%= resource["instance_count"] %> min=<%= resource["min_instances"] %>, max=<%= resource["max_instances"] %><%= resource["require_agent"] ? "" : ", AgentLess" %>>
291
+ <%- resource["services_ref"].each { |svc_inst| -%>
292
+ <%= svc_inst["id"] %> (<%= svc_status_msg(svc_inst["status"]) %>)
233
293
  <%- } -%>
234
294
  <%- } -%>
235
- <%- if @service_cluster["instances"].size > 0 -%>
295
+ <%- if cluster["services"].size > 0 -%>
236
296
 
237
- Instances :
238
- <%- @service_cluster["instances"].each { |k, v| -%>
239
- <%= v["instance_id"] %> : <%= v["property"] %> (<%= trans_svc_status(v["status"]) %>)
240
- <%- if v["agent_id"] -%>
241
- On VM instance: <%= v["agent_id"]%>
297
+ Instances (<%= cluster["services"].size %>):
298
+ <%- cluster["services"].keys.each { |svc_id|
299
+ svc = body["services"][svc_id]
300
+ -%>
301
+ <%= svc_id %> : <%= svc["resource_ref"]["class_type"] %> (<%= svc_status_msg(svc["status"]) %>)
302
+ <%- if svc["agent_ref"] -%>
303
+ On VM: <%= svc["agent_ref"]["id"] %>
242
304
  <%- end -%>
243
305
  <%- } -%>
244
306
  <%- end -%>
245
- <%- if @agent_monitor["registered"].size > 0 -%>
307
+ <%- if cluster["cloud_hosts"].size > 0 -%>
246
308
 
247
- Agents :
248
- <%- @agent_monitor["registered"].each { |a| -%>
249
- <%= a["agent_id"] %> : <%= a["attr"]["local_ipv4"] %>, <%= a["attr"]["public_ipv4"] %> load=<%= a["attr"]["uptime"] %>, <%= (Time.now - Time.parse(a["last_ping_at"])).to_i %> sec(s), placement=<%= a["attr"]["availability_zone"] %><%= a["root_path"] %> (<%= a["status"] %>)
250
- <%- if !a["services"].nil? && a["services"].size > 0 && !@service_cluster["instances"].empty? -%>
251
- Services (<%= a["services"].size %>): <%= a["services"].collect{|id| @service_cluster["instances"][id]["property"] unless @service_cluster["instances"][id].nil? }.join(', ') %>
309
+ Cloud Host (<%= cluster["cloud_hosts"].size %>):
310
+ <%- cluster["cloud_hosts"].keys.each { |host_id|
311
+ cloud_host = body["cloud_hosts"][host_id]
312
+ -%>
313
+ <%= host_id %> : <% if cloud_host["agent_id"] %>bind to <%= cloud_host["agent_id"] %><% end %>
314
+ <%- } -%>
315
+ <%- end -%>
316
+ <%- else # if cluster -%>
317
+ Cluster:
318
+ No cluster data is loaded in master. (Run import_cluster_config first)
319
+ <%- end # if cluster -%>
320
+ <%- if agent_pool && agent_pool["group_active"].size > 0 -%>
321
+
322
+ Agents (<%= agent_pool["group_active"].size %>):
323
+ <%- agent_pool["group_active"].keys.each { |agent_id|
324
+ a = body["agents"][agent_id]
325
+ -%>
326
+ <%= a["id"] %> : <%= a["vm_attr"]["local_ipv4"] %>, <%= a["vm_attr"]["public_ipv4"] %>, <%= (Time.now - Time.parse(a["last_ping_at"])).to_i %> sec(s), placement=<%= a["vm_attr"]["availability_zone"] %> (<%= svc_status_msg(a["status"]) %>)
327
+ <%- if a["reported_services"].size > 0 && !cluster["services"].empty? -%>
328
+ Services (<%= a["reported_services"].size %>): <%= a["reported_services"].keys.collect{ |svc_id| body["services"][svc_id]["resource_ref"]["class_type"] }.join(', ') %>
252
329
  <%- end -%>
253
330
  <%- } -%>
331
+ <%- else -%>
332
+
333
+ Agents (0):
334
+ None of agents are observed.
254
335
  <%- end -%>
255
336
  __E__
256
337
 
257
338
  SVC_STATUS_MSG={
339
+ Wakame::Service::STATUS_TERMINATE=>'Terminated',
340
+ Wakame::Service::STATUS_INIT=>'Initialized',
258
341
  Wakame::Service::STATUS_OFFLINE=>'Offline',
259
- Wakame::Service::STATUS_ONLINE=>'ONLINE',
342
+ Wakame::Service::STATUS_ONLINE=>'Online',
260
343
  Wakame::Service::STATUS_UNKNOWN=>'Unknown',
261
344
  Wakame::Service::STATUS_FAIL=>'Fail',
262
345
  Wakame::Service::STATUS_STARTING=>'Starting...',
263
346
  Wakame::Service::STATUS_STOPPING=>'Stopping...',
264
347
  Wakame::Service::STATUS_RELOADING=>'Reloading...',
265
348
  Wakame::Service::STATUS_MIGRATING=>'Migrating...',
349
+ Wakame::Service::STATUS_ENTERING=>'Entering...',
350
+ Wakame::Service::STATUS_QUITTING=>'Quitting...'
351
+ }
352
+
353
+ CLUSTER_STATUS_MSG={
354
+ Wakame::Service::ServiceCluster::STATUS_OFFLINE=>'Offline',
355
+ Wakame::Service::ServiceCluster::STATUS_ONLINE=>'Online',
356
+ Wakame::Service::ServiceCluster::STATUS_PARTIAL_ONLINE=>'Partial Online'
266
357
  }
267
358
 
268
359
  def parse(args)
269
- options = {}
270
- blk = Proc.new {|opts|
271
- opts.banner = "Usage: status [options]"
272
- opts.separator ""
273
- opts.separator "options:"
274
- opts.on("--dump"){|j| options[:json_print] = "yes" }
360
+ @params = {}
361
+ create_parser(args){|opts|
362
+ opts.banner = "Usage: status"
363
+ #opts.separator ""
364
+ #opts.separator "options:"
275
365
  }
276
- cmd = create_parser(args, &blk)
277
- options
278
366
  end
279
367
 
280
- def run(options)
281
- res = uri(options)
282
- res
368
+ def run(requester)
369
+ @res = requester.request(@params)
283
370
  end
284
371
 
285
- def print_result(res)
372
+ def print_result()
286
373
  require 'time'
287
- if res[1]["data"].nil?
288
- p res[0]["message"]
289
- else
290
- @service_cluster = res[1]["data"]["service_cluster"]
291
- @agent_monitor = res[1]["data"]["agent_monitor"]
292
- puts ERB.new(STATUS_TMPL, nil, '-').result(binding)
293
- end
374
+ body = @res[1]["data"]
375
+ map_ref_data(body)
376
+
377
+ cluster = body["cluster"]
378
+ agent_pool = body["agent_pool"]
379
+ puts ERB.new(STATUS_TMPL, nil, '-').result(binding)
294
380
  end
295
381
 
296
382
  private
297
- def trans_svc_status(stat)
383
+ def svc_status_msg(stat)
298
384
  SVC_STATUS_MSG[stat]
299
385
  end
386
+
387
+ def cluster_status_msg(stat)
388
+ CLUSTER_STATUS_MSG[stat]
389
+ end
390
+
391
+ def map_ref_data(body)
392
+ # Create reference for ServiceInstance to assciated object.(1:1)
393
+ body["services"].each { |k,v|
394
+ v["resource_ref"] = body["resources"][v["resource_id"]]
395
+ v["cloud_host_ref"] = body["cloud_hosts"][v["host_id"]]
396
+ if v["cloud_host_ref"]
397
+ v["agent_ref"] = body["agents"][v["cloud_host_ref"]["agent_id"]]
398
+ end
399
+ }
400
+
401
+ # Create reference for Resource object to ServiceInstance array. (1:N)
402
+ body["resources"].each { |res_id,v|
403
+ v["services_ref"] = body["services"].values.find_all{|v| v["resource_id"] == res_id }.map{|v| v}
404
+ }
405
+ end
300
406
  end
301
407
 
302
408
  class Wakame::Cli::Subcommand::ActionStatus
303
409
  include Wakame::Cli::Subcommand
304
410
 
305
411
  ACTION_STATUS_TMPL= <<__E__
306
- Running Actions : <%= @status.size %> action(s)
307
- <%- if @status.size > 0 -%>
308
- <%- @status.each { |id, j| -%>
412
+ Running Actions : <%= status.size %> action(s)
413
+ <%- if status.size > 0 -%>
414
+ <%- status.each { |id, j| -%>
309
415
  JOB <%= id %> :
310
416
  start : <%= j["created_at"] %>
311
417
  <%= tree_subactions(j["root_action"]) %>
@@ -314,27 +420,23 @@ JOB <%= id %> :
314
420
  __E__
315
421
 
316
422
  def parse(args)
317
- options = {}
318
- blk = Proc.new {|opts|
423
+ @params = {}
424
+ cmd = create_parser(args){|opts|
319
425
  opts.banner = "Usage: action_status"
320
- opts.separator ""
321
- opts.separator "options:"
322
- opts.on("--dump"){|j| options[:json_print] = "yes" }
426
+ #opts.separator ""
427
+ #opts.separator "options:"
323
428
  }
324
- cmd = create_parser(args, &blk)
325
- options
326
429
  end
327
430
 
328
- def run(options)
329
- res = uri(options)
330
- res
431
+ def run(requester)
432
+ @res = requester.request()
331
433
  end
332
434
 
333
- def print_result(res)
334
- if res[1]["data"].nil?
335
- p res[0]["message"]
435
+ def print_result
436
+ if @res[1]["data"].nil?
437
+ abort( @res[0]["message"] )
336
438
  else
337
- @status = res[1]['data']
439
+ status = @res[1]['data']
338
440
  puts ERB.new(ACTION_STATUS_TMPL, nil, '-').result(binding)
339
441
  end
340
442
  end
@@ -356,184 +458,206 @@ class Wakame::Cli::Subcommand::PropagateService
356
458
  include Wakame::Cli::Subcommand
357
459
 
358
460
  def parse(args)
359
- params = {}
360
- blk = Proc.new {|opts|
361
- opts.banner = "Usage: propagate_service"
362
- opts.separator ""
363
- opts.separator "options:"
364
- opts.on("-s SERVICE_NAME", "--service SERVICE_NAME"){|str| params[:service] = str}
365
- opts.on("-n NUMBER", "--number NUMBER"){|i| params["num"] = i}
461
+ @params = {}
462
+ create_parser(args) {|opts|
463
+ opts.banner = 'Usage: propagate_service [options] "Service ID"'
464
+ opts.separator('Options:')
465
+ opts.on('-h CLOUD_HOST_ID', '--host CLOUD_HOST_ID', String, "Cloud Host ID to be used as template."){ |i| @params["cloud_host_id"] = i }
466
+ opts.on('-n NUMBER', '--number NUMBER', Integer, "Number (>0) to propagate the specified service."){ |i| @params["number"] = i.to_i }
366
467
  }
367
- cmd = create_parser(args, &blk)
368
- options = {}
369
- options[:query] = "&" + params.collect{|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v)}"}.join("&")
370
- options
468
+ raise "Unknown Service ID: #{args}" unless args.size > 0
469
+ @params[:service_id] = args.shift
371
470
  end
372
471
 
373
- def run(options)
374
- res = uri(options)
375
- res
472
+ def run(requester)
473
+ requester.request(@params)
376
474
  end
377
475
 
378
- def print_result(res)
379
- p res[0]["message"]
476
+ end
477
+
478
+ class Wakame::Cli::Subcommand::PropagateResource
479
+ include Wakame::Cli::Subcommand
480
+
481
+ def parse(args)
482
+ @params = {}
483
+ create_parser(args) {|opts|
484
+ opts.banner = 'Usage: propagate_resource [options] "Resource Name" "Cloud Host ID"'
485
+ opts.separator(" Resource Name: ....")
486
+ opts.separator(" Cloud Host ID: ....")
487
+ opts.separator(" ")
488
+ opts.separator(" Options:")
489
+ opts.on("-n NUMBER", "--number NUMBER", Integer, "Number (>0) to propagate the specified resource."){|i| @params["number"] = i}
490
+ }
491
+ raise "Unknown Resource Name: #{args}" unless args.size > 0
492
+ @params["resource"] = args.shift
493
+
494
+ raise "Unknown Cloud Host ID: #{args}" unless args.size > 0
495
+ @params["cloud_host_id"] = args.shift
496
+ end
497
+
498
+ def run(requester)
499
+ requester.request(@params)
380
500
  end
501
+
381
502
  end
382
503
 
383
504
  class Wakame::Cli::Subcommand::StopService
384
505
  include Wakame::Cli::Subcommand
385
506
 
386
507
  def parse(args)
387
- params = {}
388
- blk = Proc.new {|opts|
508
+ @params = {}
509
+ create_parser(args) {|opts|
389
510
  opts.banner = "Usage: stop_service [options] \"Service ID\""
390
511
  opts.separator ""
391
512
  opts.separator "options:"
392
- opts.on("-i INSTANCE_ID", "--instance INSTANCE_ID"){|i| params[:service_id] = i}
393
- opts.on("-s SERVICE_NAME", "--service SERVICE_NAME"){|str| params[:service_name] = str}
394
- opts.on("-a AGENT_ID", "--agent AGENT_ID"){|i| params[:agent_id] = i}
513
+ opts.on("-i INSTANCE_ID", "--instance INSTANCE_ID"){|i| @params[:service_id] = i}
514
+ opts.on("-s SERVICE_NAME", "--service SERVICE_NAME"){|str| @params[:service_name] = str}
515
+ opts.on("-a AGENT_ID", "--agent AGENT_ID"){|i| @params[:agent_id] = i}
395
516
  }
396
- cmd = create_parser(args, &blk)
397
- options = {}
398
- options[:query] = "&" + params.collect{|k,v| CGI.escape(k.to_s) + "=" + CGI.escape(v)}.join("&")
399
- options
517
+ @params
400
518
  end
401
519
 
402
- def run(options)
403
- res = uri(options)
404
- res
520
+ def run(requester)
521
+ requester.request(@params)
405
522
  end
406
523
 
407
- def print_result(res)
408
- p res[0]["message"]
409
- end
410
524
  end
411
525
 
412
526
  class Wakame::Cli::Subcommand::MigrateService
413
527
  include Wakame::Cli::Subcommand
528
+
414
529
  def parse(args)
415
- params = {}
416
- blk = Proc.new {|opts|
530
+ @params = {}
531
+ cmd = create_parser(args){|opts|
417
532
  opts.banner = "Usage: migrate_service [options] \"Service ID\""
418
533
  opts.separator ""
419
534
  opts.separator "options:"
420
- opts.on("-a Agent ID", "--agent Agent ID"){ |i| params[:agent_id] = i}
535
+ opts.on("-a Agent ID", "--agent Agent ID"){ |i| @params[:agent_id] = i}
421
536
  }
422
- cmd = create_parser(args, &blk)
423
537
  service_id = args.shift || abort("[ERROR]: Service ID was not given")
424
- params[:service_id] = service_id
425
- options = {}
426
- options[:query] = "&" + params.collect{|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v)}"}.join("&")
427
- options
538
+ @params[:service_id] = service_id
428
539
  end
429
540
 
430
- def run(options)
431
- res = uri(options)
432
- res
541
+ def run(requester)
542
+ requester.request(@params)
433
543
  end
434
544
 
435
- def print_result(res)
436
- p res[0]["message"]
437
- end
438
545
  end
439
546
 
440
547
  class Wakame::Cli::Subcommand::ShutdownVm
441
548
  include Wakame::Cli::Subcommand
442
549
 
443
550
  def parse(args)
444
- params = {}
445
- blk = Proc.new {|opts|
551
+ @params = {}
552
+ cmd = create_parser(args) {|opts|
446
553
  opts.banner = "Usage: shutdown_vm [options] \"Agent ID\""
447
554
  opts.separator ""
448
555
  opts.separator "options:"
449
- opts.on("-f", "--force"){|str| params[:force] = "yes"}
556
+ opts.on("-f", "--force"){|str| @params[:force] = "yes"}
450
557
  }
451
- cmd = create_parser(args, &blk)
452
558
  agent_id = args.shift || abort("[ERROR]: Agent ID was not given")
453
- params[:agent_id] = agent_id
454
- options = {}
455
- options[:query] = "&" + params.collect{|k,v| CGI.escape(k.to_s) + "=" + CGI.escape(v)}.join("&")
456
- options
559
+ @params[:agent_id] = agent_id
457
560
  end
458
561
 
459
- def run(options)
460
- res = uri(options)
461
- res
562
+ def run(requester)
563
+ requester.request(@params)
462
564
  end
463
565
 
464
- def print_result(res)
465
- p res[0]["message"]
466
- end
467
566
  end
468
567
 
469
568
  class Wakame::Cli::Subcommand::LaunchVm
470
569
  include Wakame::Cli::Subcommand
471
570
 
472
571
  def parse(args)
473
- blk = Proc.new {|opts|
572
+ @params={}
573
+ cmd = create_parser(args) {|opts|
474
574
  opts.banner = "Usage: launch_vm"
475
575
  opts.separator ""
476
576
  opts.separator "options:"
477
577
  }
478
- cmd = create_parser(args, &blk)
479
- options = {}
480
- options
481
578
  end
482
579
 
483
- def run(options)
484
- res = uri(options)
485
- res
580
+ def run(requester)
581
+ requester.request(@params)
486
582
  end
487
583
 
488
- def print_result(res)
489
- p res[0]["message"]
490
- end
491
584
  end
492
585
 
493
586
  class Wakame::Cli::Subcommand::ReloadService
494
587
  include Wakame::Cli::Subcommand
495
588
 
496
589
  def parse(args)
497
- params = {}
498
- blk = Proc.new {|opts|
499
- opts.banner = "Usage: ReloadService [options] \"Service NAME\""
590
+ @params = {}
591
+ cmd = create_parser(args) {|opts|
592
+ opts.banner = "Usage: ReloadService [options] \"Service ID\""
500
593
  opts.separator ""
501
594
  opts.separator "options:"
502
595
  }
503
- cmd = create_parser(args, &blk)
504
- service_name = args.shift || abort("[ERROR]: Service NAME was not given")
505
- params[:service_name] = service_name
506
- options = {}
507
- options[:query] = "&" + params.collect{|k,v| CGI.escape(k.to_s) + "=" + CGI.escape(v)}.join("&")
508
- options
596
+ service_id = args.shift || abort("[ERROR]: Service ID was not given")
597
+ @params[:service_id] = service_id
509
598
  end
510
599
 
511
- def run(options)
512
- res = uri(options)
513
- res
600
+ def run(requester)
601
+ requester.request(@params)
514
602
  end
515
603
 
516
- def print_result(res)
517
- p res[0]["message"]
604
+ end
605
+
606
+ class Wakame::Cli::Subcommand::StartService
607
+ include Wakame::Cli::Subcommand
608
+
609
+ def parse(args)
610
+ @params = {}
611
+ cmd = create_parser(args) { |opts|
612
+ opts.banner = "Usage: start_service [options] \"Service ID\""
613
+ opts.separator ""
614
+ opts.separator "options:"
615
+ }
616
+ service_id = args.shift || abort("[ERROR]: Service ID was not given")
617
+ @params[:service_id] = service_id
518
618
  end
619
+
620
+ def run(requester)
621
+ requester.request(@params)
622
+ end
623
+
624
+ end
625
+
626
+ class Wakame::Cli::Subcommand::ImportClusterConfig
627
+ include Wakame::Cli::Subcommand
628
+
629
+ def parse(args)
630
+ @params = {}
631
+ cmd = create_parser(args) { |opts|
632
+ opts.banner = "Usage: import_cluster_config"
633
+ opts.separator ""
634
+ opts.separator "options:"
635
+ }
636
+ @params
637
+ end
638
+
639
+ def run(requester)
640
+ requester.request(@params)
641
+ end
642
+
519
643
  end
520
644
 
521
645
  class Wakame::Cli::Subcommand::AgentStatus
522
646
  include Wakame::Cli::Subcommand
523
647
 
524
648
  STATUS_TMPL = <<__E__
525
- Agent :<%= @agent["agent_id"]%> load=<%= @agent["attr"]["uptime"]%>, <%= (Time.now - Time.parse(@agent["last_ping_at"])).to_i%> sec(s), placement=<%= @agent["attr"]["availability_zone"]%><%= @agent["root_path"] %> (<%= trans_svc_status(@agent["status"]) %>)
526
- Instance ID : <%= @agent["attr"]["instance_id"]%>
527
- AMI ID : <%= @agent["attr"]["ami_id"]%>
528
- Public DNS Name : <%= @agent["attr"]["public_hostname"]%>
529
- Private DNS Name : <%= @agent["attr"]["local_hostname"]%>
530
- Instance Type : <%= @agent["attr"]["instance_type"]%>
531
- Availability Zone : <%= @agent["attr"]["availability_zone"]%>
532
-
533
- <%- if !@agent["services"].nil? && @agent["services"].size > 0 -%>
534
- Services (<%= @agent["services"].size%>):
535
- <%- @agent["services"].each {|id| -%>
536
- <%= @service_cluster["instances"][id]["instance_id"]%> : <%= @service_cluster["instances"][id]["property"]%> (<%= trans_svc_status(@service_cluster["instances"][id]["status"])%>)
649
+ Agent :<%= agent["agent_id"]%> load=<%= agent["attr"]["uptime"]%>, <%= (Time.now - Time.parse(agent["last_ping_at"])).to_i%> sec(s), placement=<%= agent["attr"]["availability_zone"]%><%= agent["root_path"] %> (<%= trans_svc_status(agent["status"]) %>)
650
+ Instance ID : <%= agent["attr"]["instance_id"]%>
651
+ AMI ID : <%= agent["attr"]["ami_id"]%>
652
+ Public DNS Name : <%= agent["attr"]["public_hostname"]%>
653
+ Private DNS Name : <%= agent["attr"]["local_hostname"]%>
654
+ Instance Type : <%= agent["attr"]["instance_type"]%>
655
+ Availability Zone : <%= agent["attr"]["availability_zone"]%>
656
+
657
+ <%- if !agent["services"].nil? && agent["services"].size > 0 -%>
658
+ Services (<%= agent["services"].size%>):
659
+ <%- agent["services"].each {|id| -%>
660
+ <%= service_cluster["instances"][id]["instance_id"]%> : <%= service_cluster["instances"][id]["property"]%> (<%= trans_svc_status(service_cluster["instances"][id]["status"])%>)
537
661
  <%- } -%>
538
662
  <%- end -%>
539
663
  __E__
@@ -550,29 +674,24 @@ __E__
550
674
  }
551
675
 
552
676
  def parse(args)
553
- params = {}
554
- blk = Proc.new {|opts|
677
+ @params = {}
678
+ blk = Proc.new
679
+ cmd = create_parser(args) {|opts|
555
680
  opts.banner = "Usage: AgentStatus [options] \"Agent ID\""
556
681
  opts.separator ""
557
682
  opts.separator "options:"
558
683
  }
559
- cmd = create_parser(args, &blk)
560
- agent_id = args.shift || abort("[ERROR]: Agent ID was not given")
561
- params[:agent_id] = agent_id
562
- options = {}
563
- options[:query] = "&" + params.collect{|k,v| CGI.escape(k.to_s) + "=" + CGI.escape(v)}.join("&")
564
- options
684
+ @params[:agent_id] = args.shift || abort("[ERROR]: Agent ID was not given")
565
685
  end
566
686
 
567
- def run(options)
568
- res = uri(options)
569
- res
687
+ def run(requester)
688
+ @res = requester.request(@params)
570
689
  end
571
690
 
572
691
  def print_result(res)
573
692
  require 'time'
574
- @agent = res[1]["data"]["agent_status"]
575
- @service_cluster = res[1]["data"]["service_cluster"]
693
+ agent = @res[1]["data"]["agent_status"]
694
+ service_cluster = res[1]["data"]["service_cluster"]
576
695
  puts ERB.new(STATUS_TMPL, nil, '-').result(binding)
577
696
  end
578
697
 
@@ -580,4 +699,4 @@ __E__
580
699
  def trans_svc_status(stat)
581
700
  SVC_STATUS_MSG[stat]
582
701
  end
583
- end
702
+ end