flare-tools 0.4.5.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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