flare-tools 0.0.1

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.
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