flare-tools 0.1.4 → 0.4.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/Flare-tools.txt +0 -0
- data/History.txt +114 -2
- data/LICENSE +21 -0
- data/Manifest.txt +65 -8
- data/README.txt +356 -0
- data/Rakefile +90 -25
- data/Tutorial.txt +370 -0
- data/bin/flare-admin +6 -0
- data/bin/flare-argv0 +6 -0
- data/bin/flare-deploy +6 -0
- data/bin/flare-keychecker +6 -0
- data/bin/flare-part +6 -0
- data/bin/flare-ping +6 -0
- data/bin/flare-stats +4 -10
- data/bin/flare-zkadmin +6 -0
- data/lib/flare/net/connection.rb +98 -0
- data/lib/flare/test/cluster.rb +140 -0
- data/lib/flare/test/daemon.rb +144 -0
- data/lib/flare/test/node.rb +62 -0
- data/lib/flare/tools.rb +18 -16
- data/lib/flare/tools/cli.rb +32 -0
- data/lib/flare/tools/cli/activate.rb +106 -0
- data/lib/flare/tools/cli/balance.rb +83 -0
- data/lib/flare/tools/cli/cli_util.rb +77 -0
- data/lib/flare/tools/cli/deploy.rb +170 -0
- data/lib/flare/tools/cli/down.rb +85 -0
- data/lib/flare/tools/cli/dump.rb +219 -0
- data/lib/flare/tools/cli/dumpkey.rb +117 -0
- data/lib/flare/tools/cli/flare_admin.rb +81 -0
- data/lib/flare/tools/cli/flare_argv0.rb +60 -0
- data/lib/flare/tools/cli/flare_keychecker.rb +106 -0
- data/lib/flare/tools/cli/flare_zkadmin.rb +226 -0
- data/lib/flare/tools/cli/index.rb +54 -0
- data/lib/flare/tools/cli/list.rb +93 -0
- data/lib/flare/tools/cli/master.rb +143 -0
- data/lib/flare/tools/cli/part.rb +100 -0
- data/lib/flare/tools/cli/ping.rb +81 -0
- data/lib/flare/tools/cli/reconstruct.rb +164 -0
- data/lib/flare/tools/cli/remove.rb +119 -0
- data/lib/flare/tools/cli/restore.rb +180 -0
- data/lib/flare/tools/cli/slave.rb +125 -0
- data/lib/flare/tools/cli/stats.rb +229 -122
- data/lib/flare/tools/cli/sub_command.rb +73 -0
- data/lib/flare/tools/cli/summary.rb +97 -0
- data/lib/flare/tools/cli/threads.rb +78 -0
- data/lib/flare/tools/cli/verify.rb +202 -0
- data/lib/flare/tools/client.rb +267 -0
- data/lib/flare/tools/cluster.rb +319 -0
- data/lib/flare/tools/common.rb +196 -0
- data/lib/flare/tools/index_server.rb +51 -0
- data/lib/flare/tools/node.rb +162 -0
- data/lib/flare/tools/stats.rb +75 -0
- data/lib/flare/tools/zk_util.rb +28 -0
- data/lib/flare/util.rb +34 -0
- data/lib/flare/util/bwlimit.rb +132 -0
- data/lib/flare/util/command_line.rb +79 -0
- data/lib/flare/util/conf.rb +71 -0
- data/lib/flare/util/constant.rb +25 -0
- data/lib/flare/util/conversion.rb +26 -0
- data/lib/flare/util/default_logger.rb +52 -0
- data/lib/flare/util/exception.rb +19 -0
- data/lib/flare/util/filesystem.rb +30 -0
- data/lib/flare/util/flared_conf.rb +33 -0
- data/lib/flare/util/flarei_conf.rb +32 -0
- data/lib/flare/util/hash_function.rb +32 -0
- data/lib/flare/util/interruption.rb +70 -0
- data/lib/flare/util/key_resolver.rb +67 -0
- data/lib/flare/util/log4r_logger.rb +79 -0
- data/lib/flare/util/logger.rb +40 -0
- data/lib/flare/util/logging.rb +84 -0
- data/lib/flare/util/result.rb +53 -0
- data/test/test/experimental/cache_test.rb +113 -0
- data/test/test/experimental/key_distribution_test.rb +38 -0
- data/test/test/experimental/keychecker_test.rb +60 -0
- data/test/test/experimental/list_test.rb +108 -0
- data/test/test/extra/replication_test.rb +184 -0
- data/test/test/integration/cli_test.rb +348 -0
- data/test/test/integration/dump_expired_test.rb +103 -0
- data/test/test/integration/dump_test.rb +128 -0
- data/test/test/integration/index_server_test.rb +35 -0
- data/test/test/integration/node_test.rb +78 -0
- data/test/test/integration/partition_test.rb +235 -0
- data/test/test/integration/proxy_test.rb +54 -0
- data/test/test/integration/stats_test.rb +79 -0
- data/test/test/system/flare_admin_test.rb +191 -0
- data/test/test/unit/bwlimit_test.rb +52 -0
- data/test/test/unit/cluster_test.rb +96 -0
- data/test/test/unit/daemon_test.rb +30 -0
- data/test/test/unit/logger_test.rb +46 -0
- data/test/test/unit/tools_test.rb +25 -0
- data/test/test/unit/util_test.rb +70 -0
- metadata +239 -84
- data/README.rdoc +0 -83
- data/bin/flare-partition-setting +0 -12
- data/lib/flare/tools/cli/partition_setting.rb +0 -86
- data/lib/flare/tools/core.rb +0 -189
- data/lib/flare/tools/logger.rb +0 -31
- data/test/test_flare-tools.rb +0 -11
- data/test/test_helper.rb +0 -3
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'flare/tools/node'
|
8
|
+
|
9
|
+
#
|
10
|
+
module Flare
|
11
|
+
module Test
|
12
|
+
|
13
|
+
# == Description
|
14
|
+
#
|
15
|
+
class Node
|
16
|
+
def initialize(hostname_port, pid)
|
17
|
+
@hostname_port = hostname_port
|
18
|
+
@hostname, @port = hostname_port.split(':')
|
19
|
+
@pid = pid
|
20
|
+
@alive = true
|
21
|
+
end
|
22
|
+
|
23
|
+
def open(&block)
|
24
|
+
return nil unless @alive
|
25
|
+
node = Flare::Tools::Node.open(@hostname, @port)
|
26
|
+
return node if block.nil?
|
27
|
+
ret = nil
|
28
|
+
begin
|
29
|
+
ret = block.call(node)
|
30
|
+
rescue => e
|
31
|
+
node.close
|
32
|
+
raise e
|
33
|
+
end
|
34
|
+
ret
|
35
|
+
end
|
36
|
+
|
37
|
+
def stop
|
38
|
+
Process.kill :STOP, @pid
|
39
|
+
end
|
40
|
+
|
41
|
+
def cont
|
42
|
+
Process.kill :CONT, @pid
|
43
|
+
end
|
44
|
+
|
45
|
+
def terminate
|
46
|
+
puts "killing... #{@pid}"
|
47
|
+
begin
|
48
|
+
timeout(10) do
|
49
|
+
Process.kill :TERM, @pid
|
50
|
+
Process.waitpid @pid
|
51
|
+
end
|
52
|
+
rescue TimeoutError => e
|
53
|
+
Process.kill :KILL, @pid
|
54
|
+
Process.waitpid @pid
|
55
|
+
end
|
56
|
+
@alive = false
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_reader :hostname, :port, :hostname_port
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/flare/tools.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
# -*- coding: utf-8; -*-
|
2
|
-
#
|
3
|
-
# Copyright:: Copyright (
|
4
|
-
# License::
|
5
|
-
#
|
6
|
-
# $--- flare-tools - [ by Ruby ] $
|
7
|
-
# vim: foldmethod=marker tabstop=2 shiftwidth=2
|
8
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
9
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
10
5
|
|
11
|
-
|
12
|
-
|
13
|
-
require 'timeout'
|
14
|
-
require 'resolv'
|
15
|
-
require 'tools/core'
|
16
|
-
require 'tools/logger'
|
6
|
+
#
|
7
|
+
module Flare
|
17
8
|
|
18
|
-
module
|
19
|
-
|
9
|
+
# flare-tools module.
|
10
|
+
module Tools
|
11
|
+
# the version number of flare-tools
|
12
|
+
VERSION = '0.4.5.1'
|
13
|
+
TITLE = "Flare-tools version #{VERSION} Copyright (C) GREE, Inc. 2011"
|
14
|
+
autoload :Common, 'flare/tools/common'
|
15
|
+
autoload :Cluster, 'flare/tools/cluster'
|
16
|
+
autoload :Stats, 'flare/tools/stats'
|
17
|
+
autoload :Node, 'flare/tools/node'
|
18
|
+
autoload :IndexServer, 'flare/tools/index_server'
|
19
|
+
autoload :Cli, 'flare/tools/cli'
|
20
|
+
autoload :ZkUtil, 'flare/tools/zk_util'
|
21
|
+
end
|
20
22
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
#
|
7
|
+
module Flare
|
8
|
+
module Tools
|
9
|
+
module Cli
|
10
|
+
autoload :List, 'flare/tools/cli/list'
|
11
|
+
autoload :Stats, 'flare/tools/cli/stats'
|
12
|
+
autoload :Index, 'flare/tools/cli/index'
|
13
|
+
autoload :Balance, 'flare/tools/cli/balance'
|
14
|
+
autoload :Down, 'flare/tools/cli/down'
|
15
|
+
autoload :Slave, 'flare/tools/cli/slave'
|
16
|
+
autoload :Reconstruct, 'flare/tools/cli/reconstruct'
|
17
|
+
autoload :Master, 'flare/tools/cli/master'
|
18
|
+
autoload :Deploy, 'flare/tools/cli/deploy'
|
19
|
+
autoload :Threads, 'flare/tools/cli/threads'
|
20
|
+
autoload :Ping, 'flare/tools/cli/ping'
|
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
|
+
autoload :Restore, 'flare/tools/cli/restore'
|
27
|
+
autoload :Summary, 'flare/tools/cli/summary'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/tools/stats'
|
7
|
+
require 'flare/tools/node'
|
8
|
+
require 'flare/tools/index_server'
|
9
|
+
require 'flare/tools/common'
|
10
|
+
require 'flare/tools/cluster'
|
11
|
+
require 'flare/util/conversion'
|
12
|
+
require 'flare/util/constant'
|
13
|
+
require 'flare/tools/cli/sub_command'
|
14
|
+
|
15
|
+
module Flare
|
16
|
+
module Tools
|
17
|
+
module Cli
|
18
|
+
|
19
|
+
class Activate < SubCommand
|
20
|
+
include Flare::Util::Conversion
|
21
|
+
include Flare::Util::Constant
|
22
|
+
include Flare::Util::Logging
|
23
|
+
include Flare::Tools::Common
|
24
|
+
|
25
|
+
myname :activate
|
26
|
+
desc "activate "
|
27
|
+
usage "activate [hostname:port] ..."
|
28
|
+
|
29
|
+
def setup(opt)
|
30
|
+
opt.on('--force', "commit changes without confirmation") {@force = true}
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
super
|
35
|
+
@force = false
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute(config, *args)
|
39
|
+
return S_NG if args.size < 1
|
40
|
+
|
41
|
+
hosts = args.map {|x| x.split(':')}
|
42
|
+
hosts.each do |x|
|
43
|
+
if x.size != 2
|
44
|
+
puts "invalid argument '#{x.join(':')}'."
|
45
|
+
return S_NG
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], config[:timeout]) do |s|
|
50
|
+
cluster = Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
|
51
|
+
nodes = s.stats_nodes.sort_by{|key, val| [val['partition'], val['role'], key]}
|
52
|
+
|
53
|
+
hosts.each do |hostname,port|
|
54
|
+
nodekey = nodekey_of hostname, port
|
55
|
+
ipaddr = address_of_hostname(hostname)
|
56
|
+
|
57
|
+
unless cluster.has_nodekey? nodekey
|
58
|
+
error "invalid 'hostname:port' pair: #{nodekey}"
|
59
|
+
return S_NG
|
60
|
+
end
|
61
|
+
|
62
|
+
node = cluster.node_stat(nodekey)
|
63
|
+
|
64
|
+
exec = @force
|
65
|
+
if exec
|
66
|
+
elsif node['state'] == 'active'
|
67
|
+
warn "#{ipaddr}:#{port} is already active."
|
68
|
+
else
|
69
|
+
STDERR.print "turning node up (node=#{ipaddr}:#{port}, state=#{node['state']} -> activate) (y/n): "
|
70
|
+
exec = interruptible {
|
71
|
+
(gets.chomp.upcase == "Y")
|
72
|
+
}
|
73
|
+
end
|
74
|
+
if exec && !config[:dry_run]
|
75
|
+
if @force
|
76
|
+
begin
|
77
|
+
s.set_state(hostname, port, 'active')
|
78
|
+
rescue Timeout::Error => e
|
79
|
+
error "failed to activate #{nodekey} (timeout)"
|
80
|
+
raise e
|
81
|
+
end
|
82
|
+
else
|
83
|
+
resp = false
|
84
|
+
until resp
|
85
|
+
resp = s.set_state(hostname, port, 'active')
|
86
|
+
unless resp
|
87
|
+
STDERR.print "turning node up (node=#{ipaddr}:#{port}, state=#{node['state']} -> activate) (y/n): "
|
88
|
+
exec = interruptible {
|
89
|
+
(gets.chomp.upcase == "Y")
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
STDOUT.puts string_of_nodelist(s.stats_nodes, hosts.map {|x| "#{x[0]}:#{x[1]}"})
|
98
|
+
end
|
99
|
+
|
100
|
+
S_OK
|
101
|
+
end # execute()
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/tools/stats'
|
7
|
+
require 'flare/tools/index_server'
|
8
|
+
require 'flare/tools/common'
|
9
|
+
require 'flare/util/conversion'
|
10
|
+
require 'flare/util/constant'
|
11
|
+
require 'flare/tools/cli/sub_command'
|
12
|
+
|
13
|
+
module Flare
|
14
|
+
module Tools
|
15
|
+
module Cli
|
16
|
+
class Balance < SubCommand
|
17
|
+
include Flare::Util::Conversion
|
18
|
+
include Flare::Util::Constant
|
19
|
+
include Flare::Tools::Common
|
20
|
+
|
21
|
+
myname :balance
|
22
|
+
desc "set the balance values of nodes."
|
23
|
+
usage "balance [hostname:port:balance] ..."
|
24
|
+
|
25
|
+
def setup(opt)
|
26
|
+
opt.on('--force', "commit changes without confirmation") {@force = true}
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
@force = false
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute(config, *args)
|
34
|
+
return S_NG if args.empty?
|
35
|
+
|
36
|
+
hosts = args.map {|x| x.to_s.split(':')}
|
37
|
+
hosts.each do |x|
|
38
|
+
if x.size != 3
|
39
|
+
puts "invalid argument '#{x.join(':')}'."
|
40
|
+
return S_NG
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], config[:timeout]) do |s|
|
45
|
+
cluster = Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
|
46
|
+
|
47
|
+
hosts.each do |hostname,port,balance|
|
48
|
+
balance = balance.to_i
|
49
|
+
nodekey = nodekey_of hostname, port
|
50
|
+
ipaddr = address_of_hostname(hostname)
|
51
|
+
|
52
|
+
unless cluster.has_nodekey? nodekey
|
53
|
+
error "unknown host: #{nodekey}"
|
54
|
+
return S_NG
|
55
|
+
end
|
56
|
+
|
57
|
+
node = cluster.node_stat(nodekey)
|
58
|
+
|
59
|
+
exec = false
|
60
|
+
if @force
|
61
|
+
exec = true
|
62
|
+
elsif node['balance'].to_i == balance
|
63
|
+
STDERR.puts "no need to change the balance of #{ipaddr}:#{port}."
|
64
|
+
else
|
65
|
+
interruptible do
|
66
|
+
STDERR.print "updating node balance (node=#{ipaddr}:#{port}, balance=#{node['balance']} -> #{balance}) (y/n): "
|
67
|
+
exec = true if gets.chomp.upcase == "Y"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
if exec
|
71
|
+
s.set_role(hostname, port.to_i, node['role'], balance, node['partition']) unless config[:dry_run]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
STDOUT.puts string_of_nodelist(s.stats_nodes, hosts.map {|x| "#{x[0]}:#{x[1]}"})
|
75
|
+
end
|
76
|
+
|
77
|
+
return S_OK
|
78
|
+
end # execute()
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/tools/index_server'
|
7
|
+
|
8
|
+
module Flare
|
9
|
+
module Tools
|
10
|
+
module Cli
|
11
|
+
module CliUtil
|
12
|
+
FLARE_INDEX_SERVERS = "FLARE_INDEX_SERVERS"
|
13
|
+
FLARE_INDEX_SERVER = "FLARE_INDEX_SERVER"
|
14
|
+
|
15
|
+
def get_index_server_from_cluster(name, envname = FLARE_INDEX_SERVERS)
|
16
|
+
return nil if name.nil?
|
17
|
+
if ENV.has_key? envname
|
18
|
+
clusters = ENV[envname].split(';').map{|s| s.split(':')}
|
19
|
+
clusters.each do |cluster_name,index_name,index_port|
|
20
|
+
return [index_name, index_port] if cluster_name == name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_index_server_from_nodekeys(dnodekeys, envname = FLARE_INDEX_SERVERS)
|
27
|
+
nodekeys = []
|
28
|
+
return nil if dnodekeys.empty?
|
29
|
+
dnodekeys.each do |n|
|
30
|
+
l = n.split(':')
|
31
|
+
return nil if l.size < 2
|
32
|
+
nodekeys << "#{l[0]}:#{l[1]}"
|
33
|
+
end
|
34
|
+
if ENV.has_key? envname
|
35
|
+
clusters = ENV[envname].split(';').map{|s| s.split(':')}
|
36
|
+
clusters.each do |cluster_name,index_name,index_port|
|
37
|
+
ret = Flare::Tools::IndexServer.open(index_name, index_port.to_i) do |s|
|
38
|
+
cluster_nodekeys = s.stats_nodes.map {|x| x[0]}
|
39
|
+
included = true
|
40
|
+
nodekeys.each do |nodekey|
|
41
|
+
included = false unless cluster_nodekeys.include? nodekey
|
42
|
+
end
|
43
|
+
if included
|
44
|
+
[index_name, index_port]
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return ret unless ret.nil?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
rescue => e
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_index_server_name_and_port(index_server_hostname, index_server_port, envname = FLARE_INDEX_SERVER)
|
58
|
+
env_ihostname = nil
|
59
|
+
env_iport = nil
|
60
|
+
if ENV.has_key? envname
|
61
|
+
env_ihostname, env_iport = ENV[envname].split(':')
|
62
|
+
end
|
63
|
+
ihostname, iport = index_server_hostname.split(':') unless index_server_hostname.nil?
|
64
|
+
ihostname = ihostname || env_ihostname || DefaultIndexServerName
|
65
|
+
if iport && index_server_port
|
66
|
+
raise "--index-server-port option isn't allowed."
|
67
|
+
else
|
68
|
+
iport = index_server_port || env_iport || DefaultIndexServerPort if iport.nil?
|
69
|
+
end
|
70
|
+
[ihostname, iport]
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/util'
|
7
|
+
require 'flare/tools/index_server'
|
8
|
+
require 'flare/tools/cli/sub_command'
|
9
|
+
|
10
|
+
#
|
11
|
+
module Flare
|
12
|
+
module Tools
|
13
|
+
module Cli
|
14
|
+
|
15
|
+
# == Description
|
16
|
+
#
|
17
|
+
class Deploy < SubCommand
|
18
|
+
include Flare::Util::Conversion
|
19
|
+
include Flare::Util::FileSystem
|
20
|
+
|
21
|
+
myname :deploy
|
22
|
+
desc "deploy for Debian-based system."
|
23
|
+
usage "deploy [hostname:port:balance:partition] ..."
|
24
|
+
|
25
|
+
def setup(opt)
|
26
|
+
opt.on('--deploy-index', "deploy the index server") {@deploy_index = true}
|
27
|
+
opt.on('--delete', "delete existing contents before deploying") {@delete = true}
|
28
|
+
opt.on('--flarei=PATH', "a path for flarei executable") {|v| @flarei = v}
|
29
|
+
opt.on('--flared=PATH', "a path for flared executable") {|v| @flared = v}
|
30
|
+
opt.separator('flarei/flared options:')
|
31
|
+
opt.on('--back-log=BACKLOG', "back log parameter for listen()" ) {|v| @iconf["back-log"] = v}
|
32
|
+
opt.on('--thread-pool-size=SIZE', "thread pool size" ) {|v| @iconf["thread_pool_size"] = @dconf["thread_pool_size"] = v}
|
33
|
+
opt.on('--daemonize=BOOL', "daemonize" ) {|v| @iconf["daemonize"] = @dconf["daemonize"] = v}
|
34
|
+
opt.on('--data-dir=PATH', "data directory" ) {|v| @iconf["data-dir"] = @dconf["data-dir"] = v}
|
35
|
+
opt.on('--log-facility=NAME', "log facility" ) {|v| @iconf["log-facility"] = @dconf["log-facility"] = v}
|
36
|
+
opt.on('--max-connection=SIZE', "max connection" ) {|v| @iconf["max-connection"] = @dconf["max-connection"] = v}
|
37
|
+
opt.on('--net-read-timeout=MILLISECOND', "read timeout for server connections") {|v| @iconf["net-read-timeout"] = @dconf["net-read-timeout"] = v}
|
38
|
+
opt.on('--stack-size=KB', "stack size" ) {|v| @iconf["stack-size"] = @dconf["stack-size"] = v}
|
39
|
+
opt.separator('flarei options:')
|
40
|
+
opt.on('--monitor-threshold=COUNT', "monitor threshold" ) {|v| @iconf["monitor-threshold"] = v}
|
41
|
+
opt.on('--monitor-interval=SECOND', "monitor interval" ) {|v| @iconf["monitor-interval"] = v}
|
42
|
+
opt.on('--monitor-read-timeout=MILLISECOND', "monitor read timeout in millisecond") {|v| @iconf["monitor-read-timeout"] = v}
|
43
|
+
opt.on('--partition-type=NAME', "partition type(modular)" ) {|v| @iconf["partition-type"] = v}
|
44
|
+
opt.on('--key-hash-algorithm=NAME' "hash algorithm for key distribution") {|v| @iconf["key-hash-algorithm"] = v}
|
45
|
+
opt.separator('flared options:')
|
46
|
+
opt.on('--proxy-concurrency=SIZE', "proxy concurrency" ) {|v| @dconf["proxy-concurrency"] = v}
|
47
|
+
opt.on('--mutex-slot=SIZE', "mutex slot size" ) {|v| @dconf["mutex-slot"]= v}
|
48
|
+
opt.on('--reconstruction-interval=MICROSEC', "reconstruction interval" ) {|v| @dconf["reconstruction-interval"] = v}
|
49
|
+
opt.on('--reconstruction-bwlimit=BYTES', "reconstruction bandwitdh limit" ) {|v| @dconf["reconstruction-bwlimit"] = v}
|
50
|
+
opt.on('--storage-ap=SIZE', "alignment power" ) {|v| @dconf["storage-ap"] = v}
|
51
|
+
opt.on('--storage-bucket-size=SIZE', "storage bucket size" ) {|v| @dconf["storage-bucket-size"] = v}
|
52
|
+
opt.on('--storage-cache-size=SIZE', "storage cache size" ) {|v| @dconf["storage-cache-size"] = v}
|
53
|
+
opt.on('--storage-compress=NAME', "storage compress type(deflate|bz2|tcbs)") {|v| @dconf["storage-compress"] = v}
|
54
|
+
opt.on('--storage-large', "strage large" ) {@dconf["storage-large"] = true}
|
55
|
+
opt.on('--storage-type=NAME', "storage type" ) {|v| @dconf["storage-type"] = v}
|
56
|
+
opt.on('--proxy-prior-netmask=SIZE', "proxy priority mask (ex. 24 for 255.255.255.0)") {|v| @dconf["proxy-prior-netmask"] = v}
|
57
|
+
opt.on('--max-total-thread-queue=SIZE', "max total thread queue" ) {|v| @dconf["max-total-thread-queue"] = v}
|
58
|
+
opt.on('--index-servers=NAME', "index servers" ) {|v| @dconf["index-servers"] = v}
|
59
|
+
opt.on('--noreply-window-limit=SIZE', "noreply window limit (experimental)") {|v| @dconf["noreply-window-limit"] = v}
|
60
|
+
opt.on('--mysql-replication', "MySQL replication (experimental)" ) {@dconf["mysql-replication"] = true}
|
61
|
+
opt.on('--mysql-replication-port=PORT', "MySQL replication port (experimental)") {|v| @dconf["mysql-replication-port"] = v}
|
62
|
+
opt.on('--mysql-replication-id=ID', "MySQL replication ID (experimental)") {|v| @dconf["mysql-replication-id"] = v}
|
63
|
+
opt.on('--mysql-replication-db=NAME', "MySQL replication DB (experimental)") {|v| @dconf["mysql-replication-db"] = v}
|
64
|
+
opt.on('--mysql-replication-table=NAME', "MySQL replication table (experimental)") {|v| @dconf["mysql-replication-table"] = v}
|
65
|
+
opt.on('--proxy-cache-size=SIZE', "proxy cache entry size (experimental)") {|v| @dconf["proxy-cache-size"] = v}
|
66
|
+
opt.on('--proxy-cache-expire=SECOND', "cache life-time in second (experimental)") {|v| @dconf["proxy-cache-expire"] = v}
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize
|
71
|
+
@deploy_index = false
|
72
|
+
@delete = false
|
73
|
+
@flarei = "/usr/local/bin/flarei"
|
74
|
+
@flared = "/usr/local/bin/flared"
|
75
|
+
@iconf = {}
|
76
|
+
@dconf = {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def output_scripts(basedir, datadir, name, exec)
|
80
|
+
starting = "/sbin/start-stop-daemon --start --quiet --pidfile #{datadir}/#{name}.pid --exec #{exec}"
|
81
|
+
starting += " -- -f #{basedir}/#{name}.conf --daemonize"
|
82
|
+
stopping = "/sbin/start-stop-daemon --stop --retry=TERM/30/KILL/5 --quiet --pidfile #{datadir}/#{name}.pid --exec #{exec}"
|
83
|
+
|
84
|
+
start = basedir+"/start.sh"
|
85
|
+
open(start, "w") do |f|
|
86
|
+
f.puts "#!/bin/sh"
|
87
|
+
f.puts starting
|
88
|
+
end
|
89
|
+
File.chmod(0744, start)
|
90
|
+
|
91
|
+
stop = basedir+"/stop.sh"
|
92
|
+
open(stop, "w") do |f|
|
93
|
+
f.puts "#!/bin/sh"
|
94
|
+
f.puts stopping
|
95
|
+
end
|
96
|
+
File.chmod(0744, stop)
|
97
|
+
|
98
|
+
restart = basedir+"/restart.sh"
|
99
|
+
open(restart, "w") do |f|
|
100
|
+
f.puts "#!/bin/sh"
|
101
|
+
f.puts stopping
|
102
|
+
f.puts "sleep 5"
|
103
|
+
f.puts starting
|
104
|
+
end
|
105
|
+
File.chmod(0744, restart)
|
106
|
+
end
|
107
|
+
|
108
|
+
def execute(config, *args)
|
109
|
+
if @deploy_index
|
110
|
+
hostname = config[:index_server_hostname]
|
111
|
+
port = config[:index_server_port]
|
112
|
+
hostname_port = "#{hostname}:#{port}"
|
113
|
+
basedir = Dir.pwd+"/"+hostname_port
|
114
|
+
datadir = basedir+"/data"
|
115
|
+
|
116
|
+
delete_all(basedir) if @delete && FileTest.exist?(basedir)
|
117
|
+
if FileTest.exist?(basedir)
|
118
|
+
warn "directory already exists: #{basedir}"
|
119
|
+
else
|
120
|
+
Dir.mkdir(basedir)
|
121
|
+
end
|
122
|
+
|
123
|
+
conf = Flare::Util::FlareiConf.new({
|
124
|
+
'server-name' => hostname,
|
125
|
+
'server-port' => port,
|
126
|
+
'data-dir' => datadir,
|
127
|
+
}.merge(@iconf))
|
128
|
+
open(basedir+"/flarei.conf", "w") {|f| f.puts conf}
|
129
|
+
Dir.mkdir(datadir) unless FileTest.exist?(datadir)
|
130
|
+
output_scripts(basedir, datadir, "flarei", @flarei)
|
131
|
+
end
|
132
|
+
|
133
|
+
args.each do |host|
|
134
|
+
hostname, port, balance, partition = host.split(':', 4)
|
135
|
+
hostname_port = "#{hostname}:#{port}"
|
136
|
+
basedir = Dir.pwd+"/"+hostname_port
|
137
|
+
datadir = basedir+"/data"
|
138
|
+
|
139
|
+
info "generateing ... #{hostname_port}"
|
140
|
+
delete_all(basedir) if @delete && FileTest.exist?(basedir)
|
141
|
+
if FileTest.exist?(basedir)
|
142
|
+
warn "directory already exists: #{basedir}"
|
143
|
+
else
|
144
|
+
Dir.mkdir(basedir)
|
145
|
+
end
|
146
|
+
|
147
|
+
if @dconf.has_key?("index-servers")
|
148
|
+
@dconf['index-server-name'] = nil
|
149
|
+
@dconf['index-server-port'] = nil
|
150
|
+
end
|
151
|
+
|
152
|
+
conf = Flare::Util::FlaredConf.new({
|
153
|
+
'index-server-name' => config[:index_server_hostname],
|
154
|
+
'index-server-port' => config[:index_server_port],
|
155
|
+
'server-name' => hostname,
|
156
|
+
'server-port' => port,
|
157
|
+
'data-dir' => datadir,
|
158
|
+
}.merge(@dconf))
|
159
|
+
open(basedir+"/flared.conf", "w") {|f| f.puts conf}
|
160
|
+
Dir.mkdir(datadir) unless FileTest.exist?(datadir)
|
161
|
+
output_scripts(basedir, datadir, "flared", @flared)
|
162
|
+
end
|
163
|
+
|
164
|
+
return 0
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|