flare-tools 0.4.5.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/.gitignore +24 -0
  2. data/.travis.yml +15 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +28 -0
  5. data/History.txt +5 -0
  6. data/Makefile +25 -0
  7. data/README.txt +2 -2
  8. data/Rakefile +36 -34
  9. data/flare-tools.gemspec +26 -0
  10. data/lib/flare/entity/server.rb +4 -0
  11. data/lib/flare/tools.rb +3 -3
  12. data/lib/flare/tools/cli.rb +1 -0
  13. data/lib/flare/tools/cli/activate.rb +19 -13
  14. data/lib/flare/tools/cli/balance.rb +15 -8
  15. data/lib/flare/tools/cli/deploy.rb +53 -49
  16. data/lib/flare/tools/cli/dispatch.rb +101 -0
  17. data/lib/flare/tools/cli/down.rb +19 -14
  18. data/lib/flare/tools/cli/dump.rb +19 -14
  19. data/lib/flare/tools/cli/dumpkey.rb +21 -16
  20. data/lib/flare/tools/cli/flare_admin.rb +16 -72
  21. data/lib/flare/tools/cli/flare_argv0.rb +7 -51
  22. data/lib/flare/tools/cli/index.rb +10 -7
  23. data/lib/flare/tools/cli/index_server_config.rb +94 -0
  24. data/lib/flare/tools/cli/list.rb +14 -12
  25. data/lib/flare/tools/cli/master.rb +18 -12
  26. data/lib/flare/tools/cli/option.rb +55 -0
  27. data/lib/flare/tools/cli/part.rb +13 -12
  28. data/lib/flare/tools/cli/ping.rb +11 -13
  29. data/lib/flare/tools/cli/reconstruct.rb +22 -15
  30. data/lib/flare/tools/cli/remove.rb +20 -17
  31. data/lib/flare/tools/cli/restore.rb +20 -20
  32. data/lib/flare/tools/cli/slave.rb +20 -14
  33. data/lib/flare/tools/cli/stats.rb +171 -118
  34. data/lib/flare/tools/cli/sub_command.rb +16 -5
  35. data/lib/flare/tools/cli/summary.rb +12 -10
  36. data/lib/flare/tools/cli/threads.rb +15 -9
  37. data/lib/flare/tools/cli/verify.rb +20 -18
  38. data/lib/flare/tools/cluster.rb +3 -2
  39. data/lib/flare/util/constant.rb +3 -0
  40. data/lib/flare/util/pretty_table.rb +8 -0
  41. data/lib/flare/util/pretty_table/column.rb +41 -0
  42. data/lib/flare/util/pretty_table/row.rb +29 -0
  43. data/lib/flare/util/pretty_table/table.rb +37 -0
  44. data/package/Rakefile +44 -0
  45. data/package/flare-tools/Makefile +23 -0
  46. data/package/flare-tools/debian/changelog +135 -0
  47. data/package/flare-tools/debian/compat +1 -0
  48. data/package/flare-tools/debian/control +20 -0
  49. data/package/flare-tools/debian/copyright +35 -0
  50. data/package/flare-tools/debian/dirs +2 -0
  51. data/{.gemtest → package/flare-tools/debian/docs} +0 -0
  52. data/package/flare-tools/debian/rules +125 -0
  53. data/test/{test/experimental → experimental}/cache_test.rb +0 -0
  54. data/test/{test/experimental → experimental}/key_distribution_test.rb +0 -0
  55. data/test/{test/experimental → experimental}/keychecker_test.rb +0 -0
  56. data/test/{test/experimental → experimental}/list_test.rb +0 -0
  57. data/test/{test/extra → extra}/replication_test.rb +0 -0
  58. data/test/{test/integration → integration}/cli_test.rb +9 -7
  59. data/test/{test/integration → integration}/dump_expired_test.rb +4 -3
  60. data/test/{test/integration → integration}/dump_test.rb +5 -5
  61. data/test/{test/integration → integration}/index_server_test.rb +1 -1
  62. data/test/{test/integration → integration}/node_test.rb +1 -1
  63. data/test/{test/integration → integration}/partition_test.rb +6 -5
  64. data/test/{test/integration → integration}/proxy_test.rb +4 -3
  65. data/test/{test/integration → integration}/stats_test.rb +1 -1
  66. data/test/integration/subcommands.rb +128 -0
  67. data/test/{test/system → system}/flare_admin_test.rb +7 -5
  68. data/test/{test/unit → unit}/bwlimit_test.rb +0 -0
  69. data/test/{test/unit → unit}/cluster_test.rb +1 -1
  70. data/test/{test/unit → unit}/daemon_test.rb +0 -0
  71. data/test/{test/unit → unit}/logger_test.rb +0 -0
  72. data/test/{test/unit → unit}/tools_test.rb +0 -0
  73. data/test/unit/util/pretty_table_test.rb +46 -0
  74. data/test/{test/unit → unit}/util_test.rb +7 -2
  75. metadata +88 -100
  76. data/PostInstall.txt +0 -7
  77. data/lib/flare/tools/cli/cli_util.rb +0 -77
  78. data/lib/flare/util/command_line.rb +0 -79
@@ -3,79 +3,23 @@
3
3
  # Copyright:: Copyright (C) GREE, Inc. 2011.
4
4
  # License:: MIT-style
5
5
 
6
- require 'optparse'
7
- require 'flare/util/logging'
8
- require 'flare/util/constant'
9
- require 'flare/tools'
10
- require 'flare/tools/cli'
11
- require 'flare/tools/cli/cli_util'
12
-
13
- require 'flare/util/command_line'
14
-
15
- Version = Flare::Tools::VERSION
16
- include Flare::Util::Logging
17
- include Flare::Util::Constant
18
- include Flare::Tools::Cli::CliUtil
19
- Cli = Flare::Tools::Cli
20
-
21
- index_server_hostname = nil
22
- index_server_port = nil
23
- timeout = DefaultTimeout
24
- dry_run = false
25
- cluster = nil
26
- scname = ''
27
- subc = nil
28
-
29
- scclasses = [Cli::List, Cli::Balance, Cli::Down, Cli::Slave, Cli::Reconstruct, Cli::Master, Cli::Threads, Cli::Ping, Cli::Remove, Cli::Index, Cli::Activate, Cli::Dump, Cli::Dumpkey, Cli::Verify, Cli::Stats, Cli::Restore, Cli::Summary]
30
- unsupported = [Cli::Deploy]
31
- scclasses.concat unsupported
32
-
33
- subcommands = Hash[*scclasses.map {|x| [x.to_sym, x]}.flatten]
34
-
35
- setup do |opt|
36
- opt.banner = "#{Flare::Tools::TITLE}\nUsage: flare-admin [subcommand] [options] [arguments]"
37
- opt.on("-n", '--dry-run', "dry run") {dry_run = true}
38
- opt.on("-i HOSTNAME", '--index-server=HOSTNAME', "index server hostname(default:#{DefaultIndexServerName})") {|v| index_server_hostname = v}
39
- opt.on("-p PORT", '--index-server-port=PORT', "index server port(default:#{DefaultIndexServerPort})") {|v| index_server_port = v.to_i}
40
- opt.on( '--log-file=LOGFILE', "output log to LOGFILE") {|v| Flare::Util::Logging.set_logger(v)}
41
- opt.on( '--cluster=NAME', "specify a cluster name") {|v| cluster = v}
42
- opt.on( '--timeout=SECOND', "specify timeout") {|v| timeout = v.to_i}
43
-
44
- preparsed = opt.order(ARGV)
45
- scname = preparsed.shift.to_sym if preparsed.size > 0
46
-
47
- if subcommands.include?(scname)
48
- subc = subcommands[scname].new
49
- opt.separator("#{scname} subcommand:")
50
- subc.setup(opt)
51
- else
52
- error "unknown subcommand '#{scname}'" unless scname == ''
53
- opt.separator("subcommands:")
54
- puts opt.help
55
- subcommands.each do |k,v|
56
- next if unsupported.include?(v)
57
- o = OptionParser.new
58
- o.banner = "[#{k.to_s}] "+v.desc
59
- o.separator(" Usage: flare-admin "+v.usage)
60
- v.new.setup(o)
61
- puts o.help
62
- end
63
- exit 1
6
+ require 'flare/tools/cli/dispatch'
7
+
8
+ module Flare; end
9
+ module Flare::Tools; end
10
+ module Flare::Tools::Cli; end
11
+ class Flare::Tools::Cli::FlareAdmin
12
+ def main
13
+ subcommand = ARGV[0]
14
+ argv = ARGV[1..-1]
15
+
16
+ # We should clear ARGV to use (Kernel#)gets.
17
+ # see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
18
+ ARGV.clear
19
+ exit Flare::Tools::Cli::Dispatch.new.main(subcommand, argv, true)
64
20
  end
65
21
  end
66
22
 
67
- status = execute do |args|
68
- command = args.shift
69
- ihostname, iport = get_index_server_from_nodekeys(args) ||
70
- get_index_server_name_and_port(index_server_hostname, index_server_port)
71
- ihostname, iport = get_index_server_from_cluster(cluster) unless cluster.nil?
72
- subc.execute({ :command => command,
73
- :index_server_hostname => ihostname,
74
- :index_server_port => iport,
75
- :dry_run => dry_run,
76
- :timeout => timeout,
77
- :cluster => cluster },
78
- *args) if subc
79
- end
80
23
 
81
- exit status
24
+ # execute!
25
+ Flare::Tools::Cli::FlareAdmin.new.main
@@ -3,58 +3,14 @@
3
3
  # Copyright:: Copyright (C) GREE, Inc. 2011.
4
4
  # License:: MIT-style
5
5
 
6
+ require 'flare/tools/cli/dispatch'
7
+
6
8
  cliname = File.basename($PROGRAM_NAME)
7
9
  cliname[/flare-/] = ""
10
+ argv = ARGV.dup
8
11
 
9
- require 'resolv'
10
- require 'flare/tools'
11
- require 'flare/tools/cli/cli_util'
12
- require 'flare/util/logging'
13
- begin
14
- require "flare/tools/cli/#{cliname}"
15
- rescue LoadError
16
- exit 1
17
- end
18
- require 'flare/util/command_line.rb'
19
- require 'flare/util/conversion.rb'
20
-
21
- include Flare::Util::Logging
22
- include Flare::Util::Constant
23
- include Flare::Tools::Cli::CliUtil
24
-
25
- index_server_hostname = nil
26
- index_server_port = nil
27
- timeout = DefaultTimeout
28
- dry_run = false
29
- cluster = nil
30
-
31
- if ENV.has_key? "FLARE_INDEX_SERVER"
32
- h, p = ENV["FLARE_INDEX_SERVER"].split(':')
33
- index_server_hostname = h unless h.nil?
34
- index_server_port = p unless p.nil?
35
- end
36
-
37
- subc = eval "Flare::Tools::Cli::#{cliname.capitalize}.new"
38
-
39
- setup do |opt|
40
- opt.banner = "#{Flare::Tools::TITLE}\nUsage: flare-#{cliname} [options]"
41
- opt.on('-n', '--dry-run', "dry run") {dry_run = true}
42
- opt.on('-i HOSTNAME', '--index-server=HOSTNAME', "index server hostname(default:#{DefaultIndexServerName})") {|v| index_server_hostname = v}
43
- opt.on('-p PORT', '--index-server-port=PORT', "index server port(default:#{DefaultIndexServerPort})") {|v| index_server_port = v.to_i}
44
- opt.on( '--log-file=LOGFILE', "output log to LOGFILE") {|v| Flare::Util::Logging.set_logger(v)}
45
- opt.on( '--cluster=NAME', "specify a cluster name") {|v| cluster = v}
46
-
47
- subc.setup(opt)
48
- end
12
+ # We should clear ARGV to use (Kernel#)gets.
13
+ # see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
14
+ ARGV.clear
49
15
 
50
- execute do |args|
51
- ihostname, iport = get_index_server_from_nodekeys(args) ||
52
- get_index_server_name_and_port(index_server_hostname, index_server_port)
53
- ihostname, iport = get_index_server_from_cluster(cluster) unless cluster.nil?
54
- subc.execute({ :command => File.basename($PROGRAM_NAME),
55
- :index_server_hostname => ihostname,
56
- :index_server_port => iport,
57
- :dry_run => dry_run,
58
- :timeout => timeout },
59
- *args)
60
- end
16
+ Flare::Tools::Cli::Dispatch.new.main(cliname, argv, false)
@@ -8,30 +8,33 @@ require 'flare/tools/common'
8
8
  require 'flare/tools/cluster'
9
9
  require 'flare/tools/cli/sub_command'
10
10
  require 'flare/util/conversion'
11
+ require 'flare/tools/cli/index_server_config'
11
12
 
12
13
  module Flare
13
14
  module Tools
14
15
  module Cli
15
16
  class Index < SubCommand
16
17
  include Flare::Util::Conversion
17
-
18
+ include Flare::Tools::Cli::IndexServerConfig
19
+
18
20
  myname :index
19
21
  desc "print the index XML document from a cluster information."
20
22
  usage "index"
21
23
 
22
- def setup(opt)
23
- opt.on('--indexdb=URI', "index database" ) {|v| @indexdb = v}
24
- opt.on('--output=FILE', "output index to a file") {|v| @output = v}
24
+ def setup
25
+ super
26
+ set_option_index_server
27
+ @optp.on('--output=FILE', "output index to a file") {|v| @output = v}
25
28
  end
26
29
 
27
30
  def initialize
28
31
  super
29
32
  @output = nil
30
- @indexdb = nil
31
33
  end
32
34
 
33
- def execute(config, *args)
34
- cluster = Flare::Tools::Stats.open(config[:index_server_hostname], config[:index_server_port], config[:timeout]) do |s|
35
+ def execute(config, args)
36
+ parse_index_server(config, args)
37
+ cluster = Flare::Tools::Stats.open(config[:index_server_hostname], config[:index_server_port], @timeout) do |s|
35
38
  nodes = s.stats_nodes.sort_by{|key, val| [val['partition'], val['role'], key]}
36
39
  Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
37
40
  end
@@ -0,0 +1,94 @@
1
+ require 'flare/tools/index_server'
2
+ require 'flare/entity/server'
3
+ require 'flare/util/logging'
4
+
5
+ module Flare; end
6
+ module Flare::Tools; end
7
+ module Flare::Tools::Cli; end
8
+ module Flare::Tools::Cli::IndexServerConfig
9
+ include Flare::Util::Constant
10
+ include Flare::Util::Logging
11
+ FLARE_INDEX_SERVERS = "FLARE_INDEX_SERVERS"
12
+ FLARE_INDEX_SERVER = "FLARE_INDEX_SERVER"
13
+ Entity = Flare::Entity
14
+
15
+ private
16
+
17
+ def parse_index_server(config, rest)
18
+ if @cluster
19
+ @index_server_entity = get_index_server_from_cluster(@cluster)
20
+ else
21
+ @index_server_entity =
22
+ get_index_server_from_nodekeys(rest) ||
23
+ get_index_server_name_and_port(Entity::Server.new(@index_server_host, @index_server_port))
24
+ end
25
+
26
+ return unless @index_server_entity
27
+
28
+ config[:index_server_hostname] = @index_server_entity.host
29
+ config[:index_server_port] = @index_server_entity.port
30
+ end
31
+
32
+ # @return [Flare::Entity::Server | nil]
33
+ def get_index_server_from_cluster(name, envname = FLARE_INDEX_SERVERS)
34
+ return nil if name.nil?
35
+ if ENV.has_key? envname
36
+ clusters = ENV[envname].split(';').map{|s| s.split(':')}
37
+ clusters.each do |cluster_name,index_name,index_port|
38
+ return Entity::Server.new(index_name, index_port) if cluster_name == name
39
+ end
40
+ end
41
+ return nil
42
+ end
43
+
44
+ # @return [Flare::Entity::Server | nil]
45
+ def get_index_server_from_nodekeys(dnodekeys, envname = FLARE_INDEX_SERVERS)
46
+ nodekeys = []
47
+ return nil if dnodekeys.empty?
48
+ dnodekeys.each do |n|
49
+ l = n.split(':')
50
+ return nil if l.size < 2
51
+ nodekeys << "#{l[0]}:#{l[1]}"
52
+ end
53
+ if ENV.has_key? envname
54
+ clusters = ENV[envname].split(';').map{|s| s.split(':')}
55
+ clusters.each do |cluster_name,index_name,index_port|
56
+ ret = Flare::Tools::IndexServer.open(index_name, index_port.to_i) do |s|
57
+ cluster_nodekeys = s.stats_nodes.map {|x| x[0]}
58
+ included = true
59
+ nodekeys.each do |nodekey|
60
+ included = false unless cluster_nodekeys.include? nodekey
61
+ end
62
+ if included
63
+ Entity::Server.new(index_name, index_port)
64
+ else
65
+ nil
66
+ end
67
+ end
68
+ return ret unless ret.nil?
69
+ end
70
+ end
71
+ nil
72
+ rescue => e
73
+ debug(e.message)
74
+ nil
75
+ end
76
+
77
+ # @param [Flare::Entity::Server] index_server
78
+ # @return [Flare::Entity::Server]
79
+ def get_index_server_name_and_port(index_server, envname = FLARE_INDEX_SERVER)
80
+ env_ihostname = nil
81
+ env_iport = nil
82
+ if ENV.has_key? envname
83
+ env_ihostname, env_iport = ENV[envname].split(':')
84
+ end
85
+ ihostname, iport = index_server.host.split(':') unless index_server.host.nil?
86
+ ihostname = ihostname || env_ihostname || DefaultIndexServerName
87
+ if iport && index_server.port
88
+ raise "--index-server-port option isn't allowed."
89
+ else
90
+ iport = index_server.port || env_iport || DefaultIndexServerPort if iport.nil?
91
+ end
92
+ Entity::Server.new(ihostname, iport)
93
+ end
94
+ end
@@ -8,17 +8,16 @@ require 'flare/tools/cluster'
8
8
  require 'flare/tools/common'
9
9
  require 'flare/util/conversion'
10
10
  require 'flare/tools/cli/sub_command'
11
+ require 'flare/tools/cli/index_server_config'
11
12
 
12
- #
13
13
  module Flare
14
14
  module Tools
15
15
  module Cli
16
16
 
17
- # == Description
18
- #
19
17
  class List < SubCommand
20
18
  include Flare::Util::Conversion
21
19
  include Flare::Tools::Common
20
+ include Flare::Tools::Cli::IndexServerConfig
22
21
 
23
22
  myname :list
24
23
  desc "show the list of nodes in a flare cluster."
@@ -29,9 +28,11 @@ module Flare
29
28
  ['%6s', 'role'],
30
29
  ['%6s', 'state'],
31
30
  ['%7s', 'balance'] ]
32
-
33
- def setup(opt)
34
- opt.on('--numeric-hosts', "show numerical host addresses") {@numeric_hosts = true}
31
+
32
+ def setup
33
+ super
34
+ set_option_index_server
35
+ @optp.on('--numeric-hosts', "show numerical host addresses") {@numeric_hosts = true}
35
36
  end
36
37
 
37
38
  def initialize
@@ -50,7 +51,7 @@ module Flare
50
51
  @cout.puts @format % args
51
52
  nil
52
53
  end
53
-
54
+
54
55
  def get_address_or_remain hostname
55
56
  begin
56
57
  Resolv.getaddress(hostname)
@@ -59,14 +60,15 @@ module Flare
59
60
  end
60
61
  end
61
62
 
62
- def execute(config, *args)
63
+ def execute(config, args)
64
+ parse_index_server(config, args)
63
65
  if args.size > 0
64
66
  error "invalid arguments: "+args.join(' ')
65
67
  return S_NG
66
68
  end
67
-
69
+
68
70
  cluster = Flare::Tools::IndexServer.open(config[:index_server_hostname],
69
- config[:index_server_port], config[:timeout]) do |s|
71
+ config[:index_server_port], @timeout) do |s|
70
72
  Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
71
73
  end
72
74
 
@@ -74,7 +76,7 @@ module Flare
74
76
  error "Invalid index server."
75
77
  return S_NG
76
78
  end
77
-
79
+
78
80
  print_header
79
81
  cluster.nodekeys.each do |nodekey|
80
82
  data = cluster.node_stat(nodekey)
@@ -86,7 +88,7 @@ module Flare
86
88
 
87
89
  S_OK
88
90
  end
89
-
91
+
90
92
  end
91
93
  end
92
94
  end
@@ -10,6 +10,7 @@ require 'flare/tools/cluster'
10
10
  require 'flare/util/conversion'
11
11
  require 'flare/util/constant'
12
12
  require 'flare/tools/cli/sub_command'
13
+ require 'flare/tools/cli/index_server_config'
13
14
 
14
15
  module Flare
15
16
  module Tools
@@ -18,24 +19,30 @@ module Flare
18
19
  include Flare::Util::Conversion
19
20
  include Flare::Util::Constant
20
21
  include Flare::Tools::Common
22
+ include Flare::Tools::Cli::IndexServerConfig
21
23
 
22
24
  myname :master
23
25
  desc "construct a partition with a proxy node for master role."
24
26
  usage "master [hostname:port:balance:partition] ..."
25
27
 
26
- def setup(opt)
27
- opt.on('--force', "commit changes without confirmation" ) {@force = true}
28
- opt.on('--retry=COUNT', "specify retry count (default:#{@retry})" ) {|v| @retry = v.to_i}
29
- opt.on('--activate', "change node's state from ready to active") {@activate = true}
28
+ def setup
29
+ super
30
+ set_option_index_server
31
+ set_option_dry_run
32
+ set_option_force
33
+ @optp.on('--retry=COUNT', "specify retry count (default:#{@retry})" ) {|v| @retry = v.to_i}
34
+ @optp.on('--activate', "change node's state from ready to active") {@activate = true}
30
35
  end
31
36
 
32
37
  def initialize
38
+ super
33
39
  @force = false
34
40
  @retry = 10
35
41
  @activate = false
36
42
  end
37
-
38
- def execute(config, *args)
43
+
44
+ def execute(config, args)
45
+ parse_index_server(config, args)
39
46
  status = S_OK
40
47
 
41
48
  return S_NG if args.empty?
@@ -55,15 +62,15 @@ module Flare
55
62
  end
56
63
  end
57
64
  hosts = hosts.sort_by{|hostname,port,balance,partition| [partition]}
58
-
59
- Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], config[:timeout]) do |s|
65
+
66
+ Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], @timeout) do |s|
60
67
  cluster = Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
61
68
 
62
69
  hosts.each do |hostname,port,balance,partition|
63
70
  role = 'master'
64
71
  nodekey = nodekey_of hostname, port
65
72
  ipaddr = address_of_hostname(hostname)
66
-
73
+
67
74
  unless cluster.has_nodekey? nodekey
68
75
  error "unknown host: #{nodekey}"
69
76
  # return S_NG
@@ -86,7 +93,7 @@ module Flare
86
93
  STDERR.print "making the node master (node=#{ipaddr}:#{port}, role=#{node['role']} -> #{role}) (y/n): "
87
94
  exec = interruptible {(gets.chomp.upcase == "Y")}
88
95
  end
89
- if exec && !config[:dry_run]
96
+ if exec && !@dry_run
90
97
  nretry = 0
91
98
  resp = false
92
99
  while resp == false && nretry < @retry
@@ -101,7 +108,7 @@ module Flare
101
108
  end
102
109
  end
103
110
  if resp
104
- state = wait_for_master_construction(s, nodekey, config[:timeout])
111
+ state = wait_for_master_construction(s, nodekey, @timeout)
105
112
  if state == 'ready' && @activate
106
113
  unless @force
107
114
  node = s.stats_nodes[nodekey]
@@ -136,7 +143,6 @@ module Flare
136
143
 
137
144
  status
138
145
  end # execute()
139
-
140
146
  end
141
147
  end
142
148
  end