flare-tools 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2010-11-13
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,14 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ bin/flare-partition-setting
7
+ bin/flare-stats
8
+ lib/flare
9
+ lib/flare/tools
10
+ lib/flare/tools.rb
11
+ lib/flare/tools/cli
12
+ lib/flare/tools/cli/partition_setting.rb
13
+ lib/flare/tools/cli/stats.rb
14
+ lib/flare/tools/core.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on flare-tools, see http://flare-tools.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc ADDED
@@ -0,0 +1,83 @@
1
+ = flare-tools
2
+
3
+ * http://github.com/kgws/flare-tools
4
+
5
+ == DESCRIPTION:
6
+
7
+ Management Tools for Flare
8
+
9
+ == SYNOPSIS:
10
+
11
+ * flare-stats
12
+ $ flare-stats --index-server=flare1.example.com
13
+ hostname state role partition balance behind uptime hit version
14
+ flare1.example.com:12121 active master 0 1 0 12345 100 1.0.10
15
+ flare2.example.com:12121 active slave 0 1 0 12345 100 1.0.10
16
+ flare3.example.com:12121 active master 1 1 0 12345 100 1.0.10
17
+ flare4.example.com:12121 active slave 1 1 0 12345 100 1.0.10
18
+
19
+ * flare-partition-setting
20
+ $ flare-partition-setting --partition=2
21
+
22
+ == REQUIREMENTS:
23
+
24
+ * Flare >= 1.0.0
25
+
26
+ == INSTALL:
27
+
28
+ * Install Flare
29
+ {Flare}[http://labs.gree.jp/Top/OpenSource/Flare.html]
30
+
31
+ * Install flare-tools
32
+ # gem install flare-tools
33
+
34
+ == AUTHORS:
35
+
36
+ * kgws[http://d.hatena.ne.jp/kgws]
37
+
38
+ == USAGE:
39
+ * flare-stats-nodes
40
+ Usage: flare-stats [options]
41
+ -h, --help this message show
42
+ -d, --debug debug mode on
43
+ -w, --warn turn warnings on for this script
44
+ --index-server=[HOSTNAME] index server hostname(default:127.0.0.1)
45
+ --index-server-port=[PORT] index server port(default:12120)
46
+
47
+ * flare-partition-setting
48
+ Usage: flare-partition-setting [options]
49
+ -h, --help this message show
50
+ -d, --debug debug mode on
51
+ -w, --warn turn warnings on for this script
52
+ -n, --dry-run dry run
53
+ --index-server=[HOSTNAME] index server hostname(default:127.0.0.1)
54
+ --index-server-port=[PORT] index server port(default:11210)
55
+ --partition=partition partition
56
+
57
+ == LICENSE:
58
+
59
+ (The MIT License)
60
+
61
+ Copyright (c) 2010- kgws
62
+
63
+ Permission is hereby granted, free of charge, to any person obtaining
64
+ a copy of this software and associated documentation files (the
65
+ 'Software'), to deal in the Software without restriction, including
66
+ without limitation the rights to use, copy, modify, merge, publish,
67
+ distribute, sublicense, and/or sell copies of the Software, and to
68
+ permit persons to whom the Software is furnished to do so, subject to
69
+ the following conditions:
70
+
71
+ The above copyright notice and this permission notice shall be
72
+ included in all copies or substantial portions of the Software.
73
+
74
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
75
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
76
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
77
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
78
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
79
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
80
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
81
+
82
+ == THANKS:
83
+ * Masaki FUJIMOTO (Flare author)
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require 'lib/flare/tools'
6
+
7
+ Hoe.plugin :newgem
8
+ # Hoe.plugin :website
9
+ # Hoe.plugin :cucumberfeatures
10
+
11
+ $hoe = Hoe.spec 'flare-tools' do
12
+ self.version = FlareTools::VERSION
13
+ self.developer 'kgws', 'dev.kgws@gmail.com'
14
+ self.post_install_message = 'PostInstall.txt'
15
+ self.rubyforge_name = 'kgws'
16
+ self.url = 'http://github.com/kgws/flare-tools'
17
+ self.summary = "Management Tools for Flare"
18
+ self.description = "Flare is a collection of tools for management."
19
+ end
20
+
21
+ require 'newgem/tasks'
22
+ Dir['tasks/**/*.rake'].each { |t| load t }
23
+
24
+ task :default => [:spec, :features]
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env ruby
2
+ # -*- coding: utf-8; -*-
3
+ # Author:: kgws (http://d.hatena.ne.jp/kgws/)
4
+ # Copyright:: Copyright (c) 2010- kgws.
5
+ # License:: This program is licenced under the same licence as kgws.
6
+ #
7
+ # $--- flare-partition-setting - [ by Ruby ] $
8
+ # vim: foldmethod=marker tabstop=2 shiftwidth=2
9
+ $: << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
10
+ require 'flare/tools/cli/partition_setting'
11
+
12
+ FlareTools::PartitionSetting.new.execute
data/bin/flare-stats ADDED
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env ruby
2
+ # -*- coding: utf-8; -*-
3
+ # Author:: kgws (http://d.hatena.ne.jp/kgws/)
4
+ # Copyright:: Copyright (c) 2010- kgws.
5
+ # License:: This program is licenced under the same licence as kgws.
6
+ #
7
+ # $--- flare-partition-setting - [ by Ruby ] $
8
+ # vim: foldmethod=marker tabstop=2 shiftwidth=2
9
+ $: << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
10
+ require 'flare/tools/cli/stats'
11
+
12
+ FlareTools::Stats.new.execute
@@ -0,0 +1,18 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Author:: kgws (http://d.hatena.ne.jp/kgws/)
3
+ # Copyright:: Copyright (c) 2010- kgws.
4
+ # License:: This program is licenced under the same licence as kgws.
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__)))
10
+
11
+ require 'optparse'
12
+ require 'socket'
13
+ require 'timeout'
14
+ require 'tools/core'
15
+
16
+ module FlareTools
17
+ VERSION = '0.0.1'
18
+ end
@@ -0,0 +1,93 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Author:: kgws (http://d.hatena.ne.jp/kgws/)
3
+ # Copyright:: Copyright (c) 2010- kgws.
4
+ # License:: This program is licenced under the same licence as kgws.
5
+ #
6
+ # $--- flare-partition-setting - [ by Ruby ] $
7
+ # vim: foldmethod=marker tabstop=2 shiftwidth=2
8
+ require 'flare/tools'
9
+
10
+ module FlareTools
11
+ class PartitionSetting < Core
12
+ # {{{ constractor
13
+ def initialize()
14
+ super
15
+ @partition = 0
16
+ @run_flag = true
17
+ self.option_parse
18
+ end
19
+ # }}}
20
+ # {{{ opt_parse
21
+ def option_parse
22
+ super
23
+ @option.on("-n", '--dry-run', "dry run") {@run_flag = false}
24
+ @option.on( '--partition=partition', "partition") {|v| @partition = v.to_i}
25
+ begin
26
+ @option.parse!(ARGV)
27
+ rescue OptionParser::ParseError => err
28
+ puts err.message
29
+ puts @option.to_s
30
+ exit 1
31
+ end
32
+ self.param_check
33
+ end
34
+ # }}}
35
+ # {{{ pram_check
36
+ def param_check
37
+ flag = false
38
+ if @partition == 0
39
+ self.error "specifies the number of partitions"
40
+ flag = true
41
+ end
42
+ if flag
43
+ exit 1
44
+ end
45
+ end
46
+ # }}}
47
+ # {{{ execute
48
+ def execute
49
+ servers = self.get_stats_nodes.sort
50
+
51
+ # partition size check
52
+ unless servers.size % @partition == 0
53
+ self.error "Invalid partition setting. nodes_server=[#{servers.size}] partition=[#{@partition}]"
54
+ exit 1
55
+ end
56
+
57
+ server_group_num = servers.size / @partition
58
+ partition_num = 0
59
+ count = 0
60
+ balance = 1
61
+ servers.each do |server, stats|
62
+ count +=1
63
+ if count == 1
64
+ state = 'master'
65
+ else
66
+ state = 'slave'
67
+ end
68
+ self.debug "index_server=[#{@index_server_hostname}:#{@index_server_port}] server=[#{server}:#{stats['port']}] count=[#{count}] partition_num=[#{partition_num}] server_group
69
+ _num=[#{server_group_num}]"
70
+
71
+ # nodes group setting
72
+ unless self.set_node_role(server, stats['port'], state, balance, partition_num)
73
+ self.error "Can't set. server=[#{server}:#{stats['port']} state=[#{state}]] balance=[#{balance}] partition=[#{partition_num}]"
74
+ exit 1
75
+ end
76
+
77
+ # node state active
78
+ if state == 'master'
79
+ unless self.set_nodes_state(server, stats['port'], "active")
80
+ self.error "Unable to activate. server=[#{server}:#{stats['port']}]"
81
+ exit 1
82
+ end
83
+ end
84
+
85
+ if server_group_num == count
86
+ count = 0
87
+ partition_num += 1
88
+ end
89
+ end
90
+ end
91
+ # }}}
92
+ end
93
+ end
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Author:: kgws (http://d.hatena.ne.jp/kgws/)
3
+ # Copyright:: Copyright (c) 2010- kgws.
4
+ # License:: This program is licenced under the same licence as kgws.
5
+ #
6
+ # $--- flare-stats-nodes - [ by Ruby ] $
7
+ # vim: foldmethod=marker tabstop=2 shiftwidth=2
8
+ require 'flare/tools'
9
+
10
+ module FlareTools
11
+ class Stats < Core
12
+ # {{{ constractor
13
+ def initialize()
14
+ super
15
+ self.option_parse
16
+ end
17
+ # }}}
18
+ # {{{ opt_parse
19
+ def option_parse
20
+ super
21
+ begin
22
+ @option.parse!(ARGV)
23
+ rescue OptionParser::ParseError => err
24
+ puts err.message
25
+ puts @option.to_s
26
+ exit 1
27
+ end
28
+ end
29
+ # }}}
30
+ # {{{ execute
31
+ def execute
32
+ format = "%21s %6s %6s %9s %7s %6s %6s %3s %7s\n"
33
+ label = format % ["hostname", "state", "role", "partition", "balance", "behind", "uptime", "hit", "version"]
34
+ str = ""
35
+ nodes = self.get_stats_nodes
36
+ threads = self.get_stats_threads
37
+ nodes.each do |hostname_port,data|
38
+ hostname, port = hostname_port.split(":", 2)
39
+ stats = self.get_stats(hostname, data['port'])
40
+ threads[hostname_port]['behind'] = "-" unless threads[hostname_port].key?('behind')
41
+ str += format % [hostname, data['state'], data['role'], data['partition'], data['balance'], threads[hostname_port]['behind'], stats['uptime'], stats["get_hits"], stats["version"]]
42
+ end
43
+ puts label + str
44
+ end
45
+ # }}}
46
+ end
47
+ end
@@ -0,0 +1,149 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Author:: kgws (http://d.hatena.ne.jp/kgws/)
3
+ # Copyright:: Copyright (c) 2010- kgws.
4
+ # License:: This program is licenced under the same licence as kgws.
5
+ #
6
+ # $--- flare-stats-nodes - [ by Ruby ] $
7
+ # vim: foldmethod=marker tabstop=2 shiftwidth=2
8
+
9
+ module FlareTools
10
+ class Core
11
+ #{{{ Constructor
12
+ def initialize()
13
+ @index_server_hostname = '127.0.0.1'
14
+ @index_server_port = 12120
15
+ @run_flag = true
16
+ @timeout = 10
17
+ @option = OptionParser.new
18
+ end
19
+ # }}}
20
+ # {{{ option_parse
21
+ def option_parse
22
+ @option.on('-h', '--help', "this message show") {puts @option.help; exit 1}
23
+ @option.on('-d', '--debug', "debug mode on") {$DEBUG = true}
24
+ @option.on("-w", '--warn', "turn warnings on for this script") {$-w = true}
25
+ @option.on( '--index-server=[HOSTNAME]', "index server hostname(default:#{@index_server_hostname})") {|v| @index_server_hostname = v}
26
+ @option.on( '--index-server-port=[PORT]', "index server port(default:#{@index_server_port})") {|v| @index_server_port = v.to_i}
27
+ end
28
+ # }}}
29
+ # {{{ info
30
+ def info(msg)
31
+ puts "[INFO] #{msg}"
32
+ end
33
+ # }}}
34
+ # {{{ error
35
+ def error(msg)
36
+ puts "\033[31m[ERROR]\033[m #{msg}"
37
+ end
38
+ # }}}
39
+ # {{{ debug
40
+ def debug(msg)
41
+ puts "[DEBUG] #{msg}" if $DEBUG
42
+ end
43
+ # }}}
44
+ # {{{ command
45
+ def command(host, port, cmd, flag=false, t=10)
46
+ self.debug "Enter the command server. server=[#{host}:#{port}] command=[#{cmd.strip}]"
47
+ return true if @run_flag === false && flag === false
48
+ cmd += "\n" unless /\n$/ =~ cmd
49
+ str = ""
50
+ timeout(t) do
51
+ s = TCPSocket.open(host, port)
52
+ s.write cmd
53
+ while x = s.gets
54
+ if x == "OK\r\n" || x == "END\r\n"
55
+ break
56
+ elsif x == "ERROR\r\n"
57
+ self.error "Failed command. server=[#{host}:#{port}] command=[#{cmd.strip}]"
58
+ str = false
59
+ break
60
+ end
61
+ str += x
62
+ end
63
+ s.close
64
+ end
65
+ str
66
+ rescue Errno::ECONNREFUSED
67
+ self.error "Connection refused. server=[#{host}:#{port}] command=[#{cmd.strip}]"
68
+ exit 1
69
+ rescue TimeoutError
70
+ self.error "Connection timeout. server=[#{host}:#{port}] command=[#{cmd.strip}]"
71
+ exit 1
72
+ end
73
+ # }}}
74
+ # {{{ get_stats
75
+ def get_stats(hostname, port, t=10)
76
+ str = self.command(hostname, port, "stats", true, t)
77
+ self.stats_parse(str)
78
+ end
79
+ # }}}
80
+ # {{{ get_stats_nodes
81
+ def get_stats_nodes(t=10)
82
+ str = self.command(@index_server_hostname, @index_server_port, "stats nodes", true, t)
83
+ self.stats_nodes_parse(str)
84
+ end
85
+ # }}}
86
+ # {{{ get_stats_threads
87
+ def get_stats_threads(t=10)
88
+ str = self.command(@index_server_hostname, @index_server_port, "stats threads", true, t)
89
+ self.stats_threads_parse(str)
90
+ end
91
+ # }}}
92
+ # {{{ set_node_role
93
+ def set_node_role(host, port, state, balance, partition, t=10)
94
+ cmd = "node role %s %s %s %s %s\n" % [host, port, state, balance, partition]
95
+ self.command(@index_server_hostname, @index_server_port, cmd, false, t)
96
+ end
97
+ # }}}
98
+ # {{{ set_nodes_state
99
+ def set_nodes_state(host, port, state="active", t=10)
100
+ cmd = "node state %s %s %s\n" % [host, port, state]
101
+ self.command(@index_server_hostname, @index_server_port, cmd, false, t)
102
+ end
103
+ # }}}
104
+ # {{{ stats_parse
105
+ def stats_parse(str)
106
+ res = {}
107
+ str.gsub(/STAT /, '').split("\r\n").each do |x|
108
+ key, val = x.split(" ", 2)
109
+ res[key] = val
110
+ end
111
+ res
112
+ end
113
+ # }}}
114
+ # {{{ stats_nodes_parse
115
+ def stats_nodes_parse(str)
116
+ res = {}
117
+ str.gsub(/STAT /, '').split("\r\n").each do |x|
118
+ ip, port, stat = x.split(":", 3)
119
+ key, val = stat.split(" ")
120
+ res["#{ip}:#{port}"] = {} if res["#{ip}:#{port}"].nil?
121
+ res["#{ip}:#{port}"]['port'] = port
122
+ res["#{ip}:#{port}"][key] = val
123
+ end
124
+ res
125
+ end
126
+ # }}}
127
+ # {{{ stats_threads_parse
128
+ def stats_threads_parse(str)
129
+ threads = {}
130
+ res = {}
131
+ str.gsub(/STAT /, '').split("\r\n").each do |x|
132
+ thread_id, stat = x.split(":", 2)
133
+ key, val = stat.split(" ")
134
+ threads[thread_id] = {} if threads[thread_id].nil?
135
+ threads[thread_id][key] = val
136
+ end
137
+ threads.each do |thread_id, stat|
138
+ res[stat['peer']] = {} if res[stat['peer']].nil?
139
+ res[stat['peer']]['thread_id'] = thread_id
140
+ res[stat['peer']].merge!(stat)
141
+ end
142
+ res
143
+ end
144
+ # }}}
145
+ # {{{ execute
146
+ def execute ; end
147
+ # }}}
148
+ end
149
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestFlareTools < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/flare/tools'
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flare-tools
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - kgws
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-21 00:00:00 +09:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rubyforge
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 2
32
+ - 0
33
+ - 4
34
+ version: 2.0.4
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: hoe
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 19
46
+ segments:
47
+ - 2
48
+ - 6
49
+ - 2
50
+ version: 2.6.2
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: Flare is a collection of tools for management.
54
+ email:
55
+ - dev.kgws@gmail.com
56
+ executables:
57
+ - flare-partition-setting
58
+ - flare-stats
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - History.txt
63
+ - Manifest.txt
64
+ - PostInstall.txt
65
+ files:
66
+ - History.txt
67
+ - Manifest.txt
68
+ - PostInstall.txt
69
+ - README.rdoc
70
+ - Rakefile
71
+ - bin/flare-partition-setting
72
+ - bin/flare-stats
73
+ - lib/flare/tools.rb
74
+ - lib/flare/tools/cli/partition_setting.rb
75
+ - lib/flare/tools/cli/stats.rb
76
+ - lib/flare/tools/core.rb
77
+ - test/test_flare-tools.rb
78
+ - test/test_helper.rb
79
+ has_rdoc: true
80
+ homepage: http://github.com/kgws/flare-tools
81
+ licenses: []
82
+
83
+ post_install_message: PostInstall.txt
84
+ rdoc_options:
85
+ - --main
86
+ - README.rdoc
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ requirements: []
108
+
109
+ rubyforge_project: kgws
110
+ rubygems_version: 1.3.7
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Management Tools for Flare
114
+ test_files:
115
+ - test/test_flare-tools.rb
116
+ - test/test_helper.rb