flare-tools 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|