flare-tools 0.6.0 → 0.7.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.
- checksums.yaml +7 -0
- data/.travis.yml +3 -3
- data/History.txt +8 -0
- data/README.txt +3 -6
- data/Tutorial.txt +16 -6
- data/bin/flare-argv0 +16 -1
- data/bin/flare-deploy +16 -1
- data/bin/flare-part +16 -1
- data/bin/flare-ping +16 -1
- data/bin/flare-stats +16 -1
- data/lib/flare/cli/ask_node_remove.rb +22 -0
- data/lib/flare/cli/parse_host_port_pairs.rb +29 -0
- data/lib/flare/entity/server.rb +4 -0
- data/lib/flare/operation/node_remove.rb +33 -0
- data/lib/flare/test/cluster.rb +6 -1
- data/lib/flare/test/daemon.rb +29 -13
- data/lib/flare/test/node.rb +1 -1
- data/lib/flare/tools.rb +1 -1
- data/lib/flare/tools/cli.rb +12 -13
- data/lib/flare/tools/cli/dispatch.rb +16 -11
- data/lib/flare/tools/cli/remove.rb +61 -99
- data/lib/flare/tools/cli/stats.rb +1 -1
- data/lib/flare/tools/stats.rb +6 -0
- data/test/integration/cli_test.rb +3 -4
- metadata +18 -28
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 51a516a3ee2ee78de4e03ac77194243273ef4b97
|
4
|
+
data.tar.gz: 8e3c8e3cfcb570b6207c784f43c25882b4fe8d42
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6d5145f2207134f8fdac4574db9fecb08d34accbd2532be32528bf90c029b816d722a9392840364e4fe5a18fe108d18ee453f145fd40413f34153015f77cf23e
|
7
|
+
data.tar.gz: f8cc80b90393f36481cb8668076fc2c49bf2ca11994f589971a5dbc04aa4cf055739196a5e92aec25e4e84fcf002b41da5f105837cf29ea3589998398bd68038
|
data/.travis.yml
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 1.9.3
|
4
3
|
- 1.8.7
|
4
|
+
- 1.9.3
|
5
5
|
- 2.0.0
|
6
|
-
- 2.1.
|
6
|
+
- 2.1.5
|
7
7
|
before_install:
|
8
8
|
- travis_retry sudo apt-get update
|
9
9
|
- travis_retry sudo apt-get install libtokyocabinet-dev
|
10
|
-
- travis_retry sudo apt-get install libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-thread-dev
|
10
|
+
- travis_retry sudo apt-get install libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-thread-dev libboost-system-dev
|
11
11
|
- travis_retry sudo apt-get install uuid-dev
|
12
12
|
- git clone https://github.com/gree/flare.git flare
|
13
13
|
- (cd flare && ./autogen.sh)
|
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 0.7.0 / 2014-12-12
|
2
|
+
* Major Enhancements
|
3
|
+
* Modify 'remove' subcommand behavior.
|
4
|
+
* Now flare-tools can remove a downed node.
|
5
|
+
* Minor Enhancements
|
6
|
+
* Fixed sometimes stats command abort.
|
7
|
+
* Fixed flare-deploy command degraded
|
8
|
+
|
1
9
|
=== 0.6.0 / 2014-11-07
|
2
10
|
* Minor Enhancements
|
3
11
|
* Modify default options to safely
|
data/README.txt
CHANGED
@@ -101,7 +101,7 @@ Please see the stats subcommand section of flare-admin for further detail.
|
|
101
101
|
-c, --count=[REPEATTIME] repeat count
|
102
102
|
--delimiter=[CHAR] delimiter
|
103
103
|
|
104
|
-
=== flare-
|
104
|
+
=== flare-admin
|
105
105
|
|
106
106
|
Flare-admin consists of a battery of subcommands used for maintaining a flare cluster.
|
107
107
|
You must specify the hostname and port number of the index node by telling them as options
|
@@ -305,12 +305,9 @@ subcommands:
|
|
305
305
|
--quiet use quiet mode
|
306
306
|
|
307
307
|
[remove] remove a node. (experimental)
|
308
|
-
Usage: flare-admin remove
|
308
|
+
Usage: flare-admin remove [hostname:port] ...
|
309
309
|
--force commit changes without confirmation
|
310
|
-
--
|
311
|
-
--retry=[COUNT] retry count(default:5)
|
312
|
-
--connection-threshold=[COUNT]
|
313
|
-
specify connection threashold (default:2)
|
310
|
+
--retry=COUNT retry count(default:0)
|
314
311
|
|
315
312
|
[dump] dump data from nodes. (experimental)
|
316
313
|
Usage: flare-admin dump [hostname:port] ...
|
data/Tutorial.txt
CHANGED
@@ -42,13 +42,23 @@ You can find debian packages at http://labs.gree.jp/Top/OpenSource/Flare/Downloa
|
|
42
42
|
|
43
43
|
== Installing flare-tools
|
44
44
|
|
45
|
-
|
46
|
-
code from the git repository and type "rake install_gem" in your shell.
|
45
|
+
=== Before install
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
flare-tools and dependent gem packages require the libraries shown below.
|
48
|
+
|
49
|
+
- libtokyocabinet
|
50
|
+
- libbz2
|
51
|
+
- zlib
|
52
|
+
|
53
|
+
You should install these libraries before installing flare-tools. For example, if you are using Debian / Ubuntu:
|
54
|
+
|
55
|
+
mynode1$ sudo apt-get install libtokyocabinet-dev libbz2-dev zlib1g-dev rubygems
|
56
|
+
|
57
|
+
=== Install
|
58
|
+
|
59
|
+
flare-tools is available on rubygems.
|
60
|
+
|
61
|
+
mynode1$ gem install flare-tools
|
52
62
|
|
53
63
|
== Setting up your index server.
|
54
64
|
|
data/bin/flare-argv0
CHANGED
@@ -3,4 +3,19 @@
|
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
|
5
5
|
|
6
|
-
require 'flare/tools/cli/
|
6
|
+
require 'flare/tools/cli/dispatch'
|
7
|
+
|
8
|
+
cliname = "deploy"
|
9
|
+
argv = ARGV.dup
|
10
|
+
|
11
|
+
# We should clear ARGV to use (Kernel#)gets.
|
12
|
+
# see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
|
13
|
+
ARGV.clear
|
14
|
+
|
15
|
+
class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
|
16
|
+
def initialize
|
17
|
+
super
|
18
|
+
@subcommands['deploy'] = Flare::Tools::Cli::Deploy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
|
data/bin/flare-deploy
CHANGED
@@ -3,4 +3,19 @@
|
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
|
5
5
|
|
6
|
-
require 'flare/tools/cli/
|
6
|
+
require 'flare/tools/cli/dispatch'
|
7
|
+
|
8
|
+
cliname = "deploy"
|
9
|
+
argv = ARGV.dup
|
10
|
+
|
11
|
+
# We should clear ARGV to use (Kernel#)gets.
|
12
|
+
# see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
|
13
|
+
ARGV.clear
|
14
|
+
|
15
|
+
class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
|
16
|
+
def initialize
|
17
|
+
super
|
18
|
+
@subcommands['deploy'] = Flare::Tools::Cli::Deploy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
|
data/bin/flare-part
CHANGED
@@ -3,4 +3,19 @@
|
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
|
5
5
|
|
6
|
-
require 'flare/tools/cli/
|
6
|
+
require 'flare/tools/cli/dispatch'
|
7
|
+
|
8
|
+
cliname = "deploy"
|
9
|
+
argv = ARGV.dup
|
10
|
+
|
11
|
+
# We should clear ARGV to use (Kernel#)gets.
|
12
|
+
# see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
|
13
|
+
ARGV.clear
|
14
|
+
|
15
|
+
class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
|
16
|
+
def initialize
|
17
|
+
super
|
18
|
+
@subcommands['deploy'] = Flare::Tools::Cli::Deploy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
|
data/bin/flare-ping
CHANGED
@@ -3,4 +3,19 @@
|
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
|
5
5
|
|
6
|
-
require 'flare/tools/cli/
|
6
|
+
require 'flare/tools/cli/dispatch'
|
7
|
+
|
8
|
+
cliname = "deploy"
|
9
|
+
argv = ARGV.dup
|
10
|
+
|
11
|
+
# We should clear ARGV to use (Kernel#)gets.
|
12
|
+
# see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
|
13
|
+
ARGV.clear
|
14
|
+
|
15
|
+
class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
|
16
|
+
def initialize
|
17
|
+
super
|
18
|
+
@subcommands['deploy'] = Flare::Tools::Cli::Deploy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
|
data/bin/flare-stats
CHANGED
@@ -3,4 +3,19 @@
|
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
|
5
5
|
|
6
|
-
require 'flare/tools/cli/
|
6
|
+
require 'flare/tools/cli/dispatch'
|
7
|
+
|
8
|
+
cliname = "deploy"
|
9
|
+
argv = ARGV.dup
|
10
|
+
|
11
|
+
# We should clear ARGV to use (Kernel#)gets.
|
12
|
+
# see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
|
13
|
+
ARGV.clear
|
14
|
+
|
15
|
+
class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
|
16
|
+
def initialize
|
17
|
+
super
|
18
|
+
@subcommands['deploy'] = Flare::Tools::Cli::Deploy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2014.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/util/interruption'
|
7
|
+
|
8
|
+
module Flare; end
|
9
|
+
module Flare::Cli; end
|
10
|
+
module Flare::Cli::AskNodeRemove
|
11
|
+
|
12
|
+
# @param [Flare::Entity::Server] server
|
13
|
+
# @param [Flare::Tools::Cluster::NodeStat] node_stat
|
14
|
+
# @return [Boolean] approved
|
15
|
+
def ask_node_remove(server, node_stat)
|
16
|
+
STDERR.print "remove the node from a cluster (node=#{server}, role=#{node_stat.role}, state=#{node_stat.state}) (y/n): "
|
17
|
+
interruptible {
|
18
|
+
STDIN.gets.chomp.upcase == "Y"
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2014.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/entity/server'
|
7
|
+
|
8
|
+
module Flare; end
|
9
|
+
module Flare::Cli; end
|
10
|
+
module Flare::Cli::ParseHostPortPairs
|
11
|
+
Entity = Flare::Entity
|
12
|
+
|
13
|
+
# @param [String] args
|
14
|
+
# @return [Array] server entities
|
15
|
+
# @return [nil]
|
16
|
+
def parse_host_port_pairs(args)
|
17
|
+
servers = args.map {|x| x.split(':')}
|
18
|
+
servers.each do |x|
|
19
|
+
if x.size != 2
|
20
|
+
error "invalid argument '#{x.join(':')}'. it must be hostname:port."
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
servers.map do |s|
|
25
|
+
Entity::Server.new(s[0], s[1])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/flare/entity/server.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2014.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
module Flare; end
|
7
|
+
module Flare::Operation; end
|
8
|
+
module Flare::Operation::NodeRemove
|
9
|
+
|
10
|
+
# @param [Flare::Tools::Cluster::NodeStat] node_stat
|
11
|
+
# @return [Boolean]
|
12
|
+
def node_can_remove_safely?(node_stat)
|
13
|
+
node_stat.proxy? && node_stat.down?
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [Flare::Tools::IndexServer] client index server client
|
17
|
+
# @param [Flare::Entity::Server] server
|
18
|
+
# @param [Integer] retry_count
|
19
|
+
# @param [Boolean] dry_run
|
20
|
+
# @return [Boolean] succeeded
|
21
|
+
def node_remove(client, server, retry_count, dry_run)
|
22
|
+
(retry_count + 1).times do
|
23
|
+
resp = false
|
24
|
+
info "removing #{server}."
|
25
|
+
resp = client.node_remove(server.host, server.port) unless dry_run
|
26
|
+
if resp
|
27
|
+
return true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/flare/test/cluster.rb
CHANGED
@@ -73,12 +73,17 @@ module Flare
|
|
73
73
|
node = @nodes[hostname_port] = Node.new(hostname_port, pid)
|
74
74
|
node
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
def shutdown
|
78
78
|
daemon = Daemon.instance
|
79
79
|
daemon.shutdown
|
80
80
|
end
|
81
81
|
|
82
|
+
def shutdown_node(node)
|
83
|
+
daemon = Daemon.instance
|
84
|
+
daemon.shutdown_flared(node.pid)
|
85
|
+
end
|
86
|
+
|
82
87
|
def nodes
|
83
88
|
@nodes.values
|
84
89
|
end
|
data/lib/flare/test/daemon.rb
CHANGED
@@ -36,19 +36,7 @@ module Flare
|
|
36
36
|
def shutdown
|
37
37
|
STDERR.print "killing..."
|
38
38
|
(@flared+@flarei).each do |pid|
|
39
|
-
|
40
|
-
begin
|
41
|
-
timeout(10) do
|
42
|
-
Process.kill :TERM, pid
|
43
|
-
Process.waitpid pid
|
44
|
-
end
|
45
|
-
rescue Errno::ESRCH
|
46
|
-
STDERR.print "?"
|
47
|
-
rescue TimeoutError => e
|
48
|
-
Process.kill :KILL, pid
|
49
|
-
Process.waitpid pid
|
50
|
-
STDERR.print "*"
|
51
|
-
end
|
39
|
+
kill_node_process(pid)
|
52
40
|
end
|
53
41
|
STDERR.print "\n"
|
54
42
|
Process.waitall
|
@@ -126,6 +114,16 @@ module Flare
|
|
126
114
|
pid
|
127
115
|
end
|
128
116
|
|
117
|
+
def shutdown_flared(target_pid)
|
118
|
+
STDERR.print "killing node..."
|
119
|
+
@flared.each_with_index do |pid, i|
|
120
|
+
next unless pid == target_pid
|
121
|
+
kill_node_process(pid)
|
122
|
+
end
|
123
|
+
STDERR.print "\n"
|
124
|
+
@flared.delete(target_pid)
|
125
|
+
end
|
126
|
+
|
129
127
|
def deleteall(delthem)
|
130
128
|
return unless FileTest.exist?(delthem)
|
131
129
|
if FileTest.directory?(delthem)
|
@@ -139,6 +137,24 @@ module Flare
|
|
139
137
|
end
|
140
138
|
end
|
141
139
|
|
140
|
+
private
|
141
|
+
|
142
|
+
def kill_node_process(pid)
|
143
|
+
STDERR.print " #{pid}"
|
144
|
+
begin
|
145
|
+
timeout(10) do
|
146
|
+
Process.kill :TERM, pid
|
147
|
+
Process.waitpid pid
|
148
|
+
end
|
149
|
+
rescue Errno::ESRCH
|
150
|
+
STDERR.print "?"
|
151
|
+
rescue TimeoutError => e
|
152
|
+
Process.kill :KILL, pid
|
153
|
+
Process.waitpid pid
|
154
|
+
STDERR.print "*"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
142
158
|
end
|
143
159
|
end
|
144
160
|
end
|
data/lib/flare/test/node.rb
CHANGED
data/lib/flare/tools.rb
CHANGED
@@ -9,7 +9,7 @@ module Flare
|
|
9
9
|
# flare-tools module.
|
10
10
|
module Tools
|
11
11
|
# the version number of flare-tools
|
12
|
-
VERSION = '0.
|
12
|
+
VERSION = '0.7.0'
|
13
13
|
TITLE = "Flare-tools version #{VERSION} Copyright (C) GREE, Inc. 2011-2014"
|
14
14
|
autoload :Common, 'flare/tools/common'
|
15
15
|
autoload :Cluster, 'flare/tools/cluster'
|
data/lib/flare/tools/cli.rb
CHANGED
@@ -3,29 +3,28 @@
|
|
3
3
|
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
4
|
# License:: MIT-style
|
5
5
|
|
6
|
-
#
|
7
6
|
module Flare
|
8
7
|
module Tools
|
9
8
|
module Cli
|
10
|
-
autoload :
|
11
|
-
autoload :Stats, 'flare/tools/cli/stats'
|
12
|
-
autoload :Index, 'flare/tools/cli/index'
|
9
|
+
autoload :Activate, 'flare/tools/cli/activate'
|
13
10
|
autoload :Balance, 'flare/tools/cli/balance'
|
11
|
+
autoload :Deploy, 'flare/tools/cli/deploy'
|
14
12
|
autoload :Down, 'flare/tools/cli/down'
|
15
|
-
autoload :
|
16
|
-
autoload :
|
13
|
+
autoload :Dump, 'flare/tools/cli/dump'
|
14
|
+
autoload :Dumpkey, 'flare/tools/cli/dumpkey'
|
15
|
+
autoload :Index, 'flare/tools/cli/index'
|
16
|
+
autoload :List, 'flare/tools/cli/list'
|
17
17
|
autoload :Master, 'flare/tools/cli/master'
|
18
|
-
autoload :
|
19
|
-
autoload :Threads, 'flare/tools/cli/threads'
|
18
|
+
autoload :Part, 'flare/tools/cli/part'
|
20
19
|
autoload :Ping, 'flare/tools/cli/ping'
|
20
|
+
autoload :Reconstruct, 'flare/tools/cli/reconstruct'
|
21
21
|
autoload :Remove, 'flare/tools/cli/remove'
|
22
|
-
autoload :Activate, 'flare/tools/cli/activate'
|
23
|
-
autoload :Dump, 'flare/tools/cli/dump'
|
24
|
-
autoload :Dumpkey, 'flare/tools/cli/dumpkey'
|
25
|
-
autoload :Verify, 'flare/tools/cli/verify'
|
26
22
|
autoload :Restore, 'flare/tools/cli/restore'
|
23
|
+
autoload :Slave, 'flare/tools/cli/slave'
|
24
|
+
autoload :Stats, 'flare/tools/cli/stats'
|
27
25
|
autoload :Summary, 'flare/tools/cli/summary'
|
28
|
-
autoload :
|
26
|
+
autoload :Threads, 'flare/tools/cli/threads'
|
27
|
+
autoload :Verify, 'flare/tools/cli/verify'
|
29
28
|
end
|
30
29
|
end
|
31
30
|
end
|
@@ -19,28 +19,29 @@ class Flare::Tools::Cli::Dispatch
|
|
19
19
|
|
20
20
|
def initialize
|
21
21
|
@subcommands = {
|
22
|
-
'
|
22
|
+
'activate' => Cli::Activate,
|
23
23
|
'balance' => Cli::Balance,
|
24
24
|
'down' => Cli::Down,
|
25
|
-
'
|
26
|
-
'
|
25
|
+
'dump' => Cli::Dump,
|
26
|
+
'dumpkey' => Cli::Dumpkey,
|
27
|
+
'index' => Cli::Index,
|
28
|
+
'list' => Cli::List,
|
27
29
|
'master' => Cli::Master,
|
28
|
-
'
|
30
|
+
'part' => Cli::Part,
|
29
31
|
'ping' => Cli::Ping,
|
32
|
+
'reconstruct' => Cli::Reconstruct,
|
30
33
|
'remove' => Cli::Remove,
|
31
|
-
'index' => Cli::Index,
|
32
|
-
'activate' => Cli::Activate,
|
33
|
-
'dump' => Cli::Dump,
|
34
|
-
'dumpkey' => Cli::Dumpkey,
|
35
|
-
'verify' => Cli::Verify,
|
36
|
-
'stats' => Cli::Stats,
|
37
34
|
'restore' => Cli::Restore,
|
35
|
+
'slave' => Cli::Slave,
|
36
|
+
'stats' => Cli::Stats,
|
38
37
|
'summary' => Cli::Summary,
|
39
|
-
'
|
38
|
+
'threads' => Cli::Threads,
|
39
|
+
'verify' => Cli::Verify,
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
43
|
def main(subcommand_name, argv, as_subcommand)
|
44
|
+
prepare
|
44
45
|
_main(subcommand_name, argv, as_subcommand)
|
45
46
|
rescue => e
|
46
47
|
level = 1
|
@@ -55,6 +56,10 @@ class Flare::Tools::Cli::Dispatch
|
|
55
56
|
|
56
57
|
private
|
57
58
|
|
59
|
+
def prepare
|
60
|
+
Thread.abort_on_exception = true
|
61
|
+
end
|
62
|
+
|
58
63
|
def _main(subcommand_name, argv, as_subcommand)
|
59
64
|
@subcommand_name = subcommand_name
|
60
65
|
|
@@ -1,122 +1,84 @@
|
|
1
1
|
# -*- coding: utf-8; -*-
|
2
|
-
# Authors::
|
3
|
-
# Copyright:: Copyright (C) GREE, Inc.
|
2
|
+
# Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2014.
|
4
4
|
# License:: MIT-style
|
5
5
|
|
6
|
-
require 'flare/tools/index_server'
|
7
|
-
require 'flare/util/conversion'
|
8
6
|
require 'flare/tools/common'
|
9
7
|
require 'flare/tools/cli/sub_command'
|
10
8
|
require 'flare/tools/cli/index_server_config'
|
9
|
+
require 'flare/cli/parse_host_port_pairs'
|
10
|
+
require 'flare/cli/ask_node_remove'
|
11
|
+
require 'flare/operation/node_remove'
|
11
12
|
|
12
|
-
module Flare
|
13
|
-
|
14
|
-
|
13
|
+
module Flare; end
|
14
|
+
module Flare::Tools; end
|
15
|
+
module Flare::Tools::Cli; end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
class Flare::Tools::Cli::Remove < Flare::Tools::Cli::SubCommand
|
18
|
+
include Flare::Tools::Common
|
19
|
+
include Flare::Tools::Cli::IndexServerConfig
|
20
|
+
include Flare::Cli::ParseHostPortPairs
|
21
|
+
include Flare::Cli::AskNodeRemove
|
22
|
+
include Flare::Operation::NodeRemove
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
myname :remove
|
25
|
+
desc "remove a downed node."
|
26
|
+
usage "remove [hostname:port] ..."
|
24
27
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@optp.on('--connection-threshold=[COUNT]', "specify connection threashold (default:#{@connection_threshold})") {|v| @connection_threshold = v.to_i}
|
33
|
-
end
|
28
|
+
def setup
|
29
|
+
super
|
30
|
+
set_option_index_server
|
31
|
+
set_option_dry_run
|
32
|
+
set_option_force
|
33
|
+
@optp.on('--retry=COUNT', "retry count(default:#{@retry})") {|v| @retry = v.to_i }
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@retry = 5
|
40
|
-
@connection_threshold = 2
|
41
|
-
end
|
36
|
+
def initialize
|
37
|
+
super
|
38
|
+
@retry = 0
|
39
|
+
end
|
42
40
|
|
43
|
-
|
44
|
-
|
41
|
+
def execute(config, args)
|
42
|
+
parse_index_server(config, args)
|
43
|
+
nodes = parse_host_port_pairs(args)
|
44
|
+
unless nodes
|
45
|
+
return S_NG
|
46
|
+
end
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
if x.size != 2
|
49
|
-
error "invalid argument '#{x.join(':')}'. it must be hostname:port."
|
50
|
-
return S_NG
|
51
|
-
end
|
52
|
-
end
|
48
|
+
Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], @timeout) do |s|
|
49
|
+
cluster = fetch_cluster(s)
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
nodes.each do |node|
|
52
|
+
node_stat = cluster.node_stat(node.nodekey)
|
56
53
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
return S_NG
|
62
|
-
end
|
63
|
-
end
|
54
|
+
unless node_stat
|
55
|
+
error "node not found in cluster. (node=#{node})"
|
56
|
+
next
|
57
|
+
end
|
64
58
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
cluster = Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
|
71
|
-
while nwait > 0
|
72
|
-
conn = node['curr_connections'].to_i
|
73
|
-
cluster = fetch_cluster(s)
|
74
|
-
role = cluster.node_stat("#{hostname}:#{port}")['role']
|
75
|
-
info "waiting until #{hostname}:#{port} (role=#{role}, connections=#{conn}) is inactive..."
|
76
|
-
if conn <= @connection_threshold && role == 'proxy'
|
77
|
-
exec = true
|
78
|
-
break
|
79
|
-
end
|
80
|
-
interruptible {sleep 1}
|
81
|
-
nwait -= 1
|
82
|
-
node = n.stats
|
83
|
-
end
|
84
|
-
unless @force
|
85
|
-
node_stat = cluster.node_stat("#{hostname}:#{port}")
|
86
|
-
role = node_stat['role']
|
87
|
-
state = node_stat['state']
|
88
|
-
STDERR.print "please shutdown the daemon and continue (node=#{hostname}:#{port}, role=#{role}, state=#{state}) (y/n): "
|
89
|
-
interruptible {
|
90
|
-
exec = false if gets.chomp.upcase != "Y"
|
91
|
-
}
|
92
|
-
end
|
93
|
-
end
|
59
|
+
# check status downed & proxy
|
60
|
+
unless node_can_remove_safely?(node_stat)
|
61
|
+
error "node should role=proxy and state=down. (node=#{node} role=#{node_stat.role} state=#{node_stat.state})"
|
62
|
+
return S_NG
|
63
|
+
end
|
94
64
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
resp = false
|
100
|
-
info "removing #{hostname}:#{port}."
|
101
|
-
resp = s.node_remove(hostname, port) unless @dry_run
|
102
|
-
if resp
|
103
|
-
suc = true
|
104
|
-
break
|
105
|
-
end
|
106
|
-
nretry -= 1
|
107
|
-
end
|
108
|
-
info "done." if suc
|
109
|
-
info "failed." unless suc
|
110
|
-
else
|
111
|
-
info "skipped."
|
112
|
-
end
|
113
|
-
end
|
114
|
-
puts string_of_nodelist(s.stats_nodes)
|
115
|
-
end
|
65
|
+
# ask really remove or not
|
66
|
+
unless @force || ask_node_remove(node, node_stat)
|
67
|
+
return S_NG
|
68
|
+
end
|
116
69
|
|
117
|
-
|
70
|
+
succeeded = node_remove(s, node, @retry, @dry_run)
|
71
|
+
unless succeeded
|
72
|
+
error "node remove failed. (node=#{node})"
|
73
|
+
return S_NG
|
118
74
|
end
|
119
75
|
end
|
76
|
+
|
77
|
+
# puts node list after nodes removed
|
78
|
+
puts ""
|
79
|
+
puts string_of_nodelist(s.stats_nodes)
|
80
|
+
|
81
|
+
return S_OK
|
120
82
|
end
|
121
83
|
end
|
122
84
|
end
|
data/lib/flare/tools/stats.rb
CHANGED
@@ -62,6 +62,12 @@ module Flare
|
|
62
62
|
threads
|
63
63
|
end
|
64
64
|
|
65
|
+
defcmd :stats_threads_queue, 'stats threads queue\r\n' do |resp|
|
66
|
+
m = /STAT total_thread_queue (\d+)/.match(resp)
|
67
|
+
return false unless m
|
68
|
+
m[1].to_i
|
69
|
+
end
|
70
|
+
|
65
71
|
defcmd :ping, 'ping\r\n' do |resp|
|
66
72
|
true if resp
|
67
73
|
end
|
@@ -239,8 +239,7 @@ class CliTest < Test::Unit::TestCase
|
|
239
239
|
master = targets.shift
|
240
240
|
args = targets.map{|n| "#{n.hostname}:#{n.port}"}
|
241
241
|
assert_equal(S_OK, down(*args))
|
242
|
-
|
243
|
-
# sleep 3
|
242
|
+
targets.map{|n| @flare_cluster.shutdown_node(n) }
|
244
243
|
assert_equal(S_OK, remove(*args))
|
245
244
|
assert_equal(false, @flare_cluster.exist?(args[0]))
|
246
245
|
assert_equal(false, @flare_cluster.exist?(args[1]))
|
@@ -251,8 +250,8 @@ class CliTest < Test::Unit::TestCase
|
|
251
250
|
@flare_cluster.prepare_data(@node_servers[0], "key", 1000)
|
252
251
|
targets = @node_servers.dup
|
253
252
|
master = targets.shift
|
254
|
-
args = targets.map{|n| "#{n.hostname}:#{n.port}"}
|
255
|
-
assert_equal(
|
253
|
+
args = targets.map{|n| "#{n.hostname}:#{n.port}"}
|
254
|
+
assert_equal(S_NG, remove(*args))
|
256
255
|
assert_equal(true, @flare_cluster.exist?(args[0]))
|
257
256
|
assert_equal(true, @flare_cluster.exist?(args[1]))
|
258
257
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flare-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.7.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- kikehara
|
@@ -10,70 +9,62 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date: 2014-
|
12
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: log4r
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
|
-
- -
|
18
|
+
- - '>='
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: 1.1.10
|
23
21
|
type: :runtime
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
|
-
- -
|
25
|
+
- - '>='
|
29
26
|
- !ruby/object:Gem::Version
|
30
27
|
version: 1.1.10
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
29
|
name: tokyocabinet
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
|
-
- -
|
32
|
+
- - '>='
|
37
33
|
- !ruby/object:Gem::Version
|
38
34
|
version: '1.29'
|
39
35
|
type: :runtime
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
|
-
- -
|
39
|
+
- - '>='
|
45
40
|
- !ruby/object:Gem::Version
|
46
41
|
version: '1.29'
|
47
42
|
- !ruby/object:Gem::Dependency
|
48
43
|
name: bundler
|
49
44
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
45
|
requirements:
|
52
|
-
- -
|
46
|
+
- - '>='
|
53
47
|
- !ruby/object:Gem::Version
|
54
48
|
version: '1.6'
|
55
49
|
type: :development
|
56
50
|
prerelease: false
|
57
51
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
52
|
requirements:
|
60
|
-
- -
|
53
|
+
- - '>='
|
61
54
|
- !ruby/object:Gem::Version
|
62
55
|
version: '1.6'
|
63
56
|
- !ruby/object:Gem::Dependency
|
64
57
|
name: rake
|
65
58
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
59
|
requirements:
|
68
|
-
- -
|
60
|
+
- - '>='
|
69
61
|
- !ruby/object:Gem::Version
|
70
62
|
version: '0'
|
71
63
|
type: :development
|
72
64
|
prerelease: false
|
73
65
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
66
|
requirements:
|
76
|
-
- -
|
67
|
+
- - '>='
|
77
68
|
- !ruby/object:Gem::Version
|
78
69
|
version: '0'
|
79
70
|
description: Flare-tools is a collection of tools for Flare distributed key-value
|
@@ -114,8 +105,11 @@ files:
|
|
114
105
|
- bin/flare-stats
|
115
106
|
- bin/flare-zkadmin
|
116
107
|
- flare-tools.gemspec
|
108
|
+
- lib/flare/cli/ask_node_remove.rb
|
109
|
+
- lib/flare/cli/parse_host_port_pairs.rb
|
117
110
|
- lib/flare/entity/server.rb
|
118
111
|
- lib/flare/net/connection.rb
|
112
|
+
- lib/flare/operation/node_remove.rb
|
119
113
|
- lib/flare/test/cluster.rb
|
120
114
|
- lib/flare/test/daemon.rb
|
121
115
|
- lib/flare/test/node.rb
|
@@ -210,30 +204,26 @@ files:
|
|
210
204
|
homepage: http://github.com/gree/flare-tools
|
211
205
|
licenses:
|
212
206
|
- MIT
|
207
|
+
metadata: {}
|
213
208
|
post_install_message:
|
214
209
|
rdoc_options: []
|
215
210
|
require_paths:
|
216
211
|
- lib
|
217
212
|
required_ruby_version: !ruby/object:Gem::Requirement
|
218
|
-
none: false
|
219
213
|
requirements:
|
220
|
-
- -
|
214
|
+
- - '>='
|
221
215
|
- !ruby/object:Gem::Version
|
222
216
|
version: '0'
|
223
|
-
segments:
|
224
|
-
- 0
|
225
|
-
hash: 4173589925550821460
|
226
217
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
|
-
none: false
|
228
218
|
requirements:
|
229
|
-
- -
|
219
|
+
- - '>='
|
230
220
|
- !ruby/object:Gem::Version
|
231
221
|
version: '0'
|
232
222
|
requirements: []
|
233
223
|
rubyforge_project:
|
234
|
-
rubygems_version:
|
224
|
+
rubygems_version: 2.4.4
|
235
225
|
signing_key:
|
236
|
-
specification_version:
|
226
|
+
specification_version: 4
|
237
227
|
summary: Management Tools for Flare
|
238
228
|
test_files:
|
239
229
|
- test/experimental/cache_test.rb
|