diskmon 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in diskmon.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Morion Black
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Diskmon
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'diskmon'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install diskmon
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/diskmon ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "diskmon"
4
+ require "optparse"
5
+
6
+ OptionParser.new do |opt|
7
+ opt.separator ""
8
+ opt.separator "Options:"
9
+ opt.separator "-------------"
10
+ opt.on('-a', '--agent', 'Agent mode') { Diskmon::Runner.agent }
11
+ opt.on('-s', '--server', 'Server mode') { Diskmon::Runner.server }
12
+ opt.separator ""
13
+ opt.on_tail('-h', '--help') { puts opt; exit }
14
+
15
+ opt.parse!
16
+ end
data/diskmon.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/diskmon/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Morion Black"]
6
+ gem.email = ["morion.estariol@gmail.com"]
7
+ gem.description = %q{Gem for collect statistic from disks}
8
+ gem.summary = %q{Gem for collect statistic from disks}
9
+ gem.homepage = ""
10
+
11
+ gem.files = ["Gemfile", "LICENSE", "README.md", "Rakefile", "bin/diskmon", "diskmon.gemspec", "lib/diskmon.rb", "lib/diskmon/client/collector.rb", "lib/diskmon/client/config.rb", "lib/diskmon/client/harddisk.rb", "lib/diskmon/client/raidcontroller.rb", "lib/diskmon/client/solarismapdev.rb", "lib/diskmon/client/zpoolstree.rb", "lib/diskmon/server/harddisk.rb", "lib/diskmon/server/harddiskreport.rb", "lib/diskmon/version.rb"]
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "diskmon"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Diskmon::VERSION
17
+ gem.add_runtime_dependency 'data_mapper'
18
+ gem.add_runtime_dependency 'sinatra'
19
+ gem.add_runtime_dependency 'thin'
20
+ end
data/lib/diskmon.rb ADDED
@@ -0,0 +1,73 @@
1
+ require "diskmon/version"
2
+ require "diskmon/client/config"
3
+ require "diskmon/client/raidcontroller"
4
+ require "diskmon/client/collector"
5
+
6
+ require 'sinatra'
7
+ require "thin"
8
+ require 'data_mapper'
9
+ require 'dm-validations'
10
+ require 'pp'
11
+ require "diskmon/server/harddiskreport"
12
+
13
+ module Diskmon
14
+
15
+ module Runner
16
+
17
+ CONFIG = "/usr/local/etc/diskmon.conf"
18
+
19
+ ################################################################################
20
+ # Agent mode
21
+ ################################################################################
22
+
23
+ def self.agent
24
+
25
+ cfg = Diskmon::Config.new(CONFIG)
26
+ p cfg if $DEBUG
27
+
28
+ raid_ctl = Diskmon::RaidController.new
29
+ raid_ctl.get_all_stats
30
+ m = raid_ctl.serialize
31
+
32
+ coll = Diskmon::Collector.new
33
+ send_result = coll.send_report(cfg.collector_url, cfg.collector_login, cfg.collector_password, m)
34
+ p send_result
35
+ end
36
+
37
+ ################################################################################
38
+ # Server mode
39
+ ################################################################################
40
+
41
+ def self.server
42
+ set :port, 7777
43
+
44
+ DataMapper::Logger.new($stdout, :debug)
45
+ DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/reports.db")
46
+
47
+ $DEBUG = true
48
+
49
+ DataMapper.finalize
50
+
51
+ Diskmon::HardDiskReport.auto_upgrade!
52
+
53
+ post '/report/new' do
54
+ data = request.body.read
55
+
56
+ Kernel.puts "// Report from #{request.env['REMOTE_ADDR']}" if $DEBUG
57
+
58
+ @m = Marshal.load(data)
59
+
60
+ @m.each do |disk|
61
+ report = Diskmon::HardDiskReport.create(disk.to_hash)
62
+ report.checksum = disk.checksum
63
+
64
+ report.print if $DEBUG
65
+
66
+ report.save
67
+ end
68
+
69
+ "OK"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,24 @@
1
+ require "net/http"
2
+
3
+ module Diskmon
4
+
5
+ class Collector
6
+
7
+ def send_report(url, login, password, dump)
8
+ c_uri = URI(url)
9
+
10
+ p c_uri if $DEBUG
11
+
12
+ c_req = Net::HTTP::Post.new(c_uri.path)
13
+ c_req.basic_auth(login, password)
14
+ c_req.body = dump
15
+ c_req.content_type = 'text/plain'
16
+
17
+ res = Net::HTTP.start(c_uri.host, c_uri.port) do |http|
18
+ http.request(c_req)
19
+ end
20
+
21
+ res.code
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ require "yaml"
2
+
3
+ module Diskmon
4
+
5
+ class Config
6
+
7
+ def initialize(filepath)
8
+ h = YAML.load_file(filepath)
9
+ @collector_url = h["collector_url"]
10
+ @collector_login = h["collector_login"]
11
+ @collector_password = h["collector_password"]
12
+ end
13
+
14
+ attr_reader :collector_url
15
+ attr_reader :collector_login
16
+ attr_reader :collector_password
17
+
18
+ end
19
+ end
@@ -0,0 +1,43 @@
1
+ module Diskmon
2
+
3
+ class HardDisk
4
+
5
+ # TODO: convert to bytes
6
+ # def size(size)
7
+ # @size =
8
+ # end
9
+
10
+ attr_accessor :dri
11
+ attr_accessor :ctl_id
12
+ attr_accessor :port
13
+ attr_accessor :status
14
+ attr_accessor :unit
15
+ attr_accessor :type # sata or sas
16
+ attr_accessor :vendor_model
17
+ attr_accessor :smart_status_raw # array of hex numbers
18
+ attr_accessor :smart_status
19
+ attr_accessor :size
20
+
21
+ attr_accessor :reallocs
22
+ attr_accessor :age_hours
23
+ attr_accessor :temperature
24
+ attr_accessor :serial
25
+ attr_accessor :spindle_speed # rpms
26
+
27
+ attr_accessor :error_events
28
+
29
+ attr_accessor :member_of_zpool
30
+ attr_accessor :read_errors
31
+ attr_accessor :write_errors
32
+ attr_accessor :checksum_errors
33
+
34
+ attr_accessor :zpool_health
35
+ attr_accessor :zpool_last_command
36
+ attr_accessor :zpool_total_space
37
+ attr_accessor :zpool_free_space
38
+
39
+ attr_accessor :system_device
40
+ attr_accessor :short_device
41
+
42
+ end
43
+ end
@@ -0,0 +1,229 @@
1
+ require "diskmon/client/solarismapdev"
2
+ require "diskmon/client/harddisk"
3
+ require "diskmon/client/zpoolstree"
4
+
5
+ module Diskmon
6
+
7
+ class RaidController
8
+
9
+ def initialize
10
+ @vendor = get_vendor
11
+ @disks = []
12
+ end
13
+
14
+ def get_vendor
15
+ v = `scanpci | grep -i raid`
16
+
17
+ case v.downcase
18
+ when /3ware/ then return :threeware
19
+ when /adaptec/ then return :adaptec
20
+ else
21
+ return nil
22
+ end
23
+ end
24
+
25
+ def get_ctl_ids
26
+
27
+ ctl_ids = []
28
+
29
+ case @vendor
30
+
31
+ when :threeware
32
+ IO.popen("tw_cli show | grep ^c") do |tw_cli_show_io|
33
+ tw_cli_show_io.each_line { |l| ctl_ids.push( l.split[0] ) }
34
+ end
35
+ when :adaptec
36
+ IO.popen("arcconf getversion | grep 'Controller #'") do |arcconf_getversion_io|
37
+ arcconf_getversion_io.each_line { |l| ctl_ids.push( l.split[1][1..-1] ) }
38
+ end
39
+
40
+ end
41
+
42
+ ctl_ids
43
+ end
44
+
45
+ def get_ctl_disks_info(ctl_id)
46
+ case @vendor
47
+ when :threeware
48
+
49
+ mapdev = Diskmon::SolarisMapDev.new
50
+
51
+ # disks overview
52
+ #
53
+ IO.popen("tw_cli /#{ctl_id} show drivestatus | grep ^p") do |tw_cli_drives_io|
54
+ tw_cli_drives_io.each_line do |l|
55
+ l_arr = l.split
56
+
57
+ d = Diskmon::HardDisk.new
58
+
59
+ d.ctl_id = ctl_id[1..-1] # strip 'c'
60
+ d.port = l_arr[0][1..-1] # strip 'p'
61
+ d.status = l_arr[1]
62
+ d.unit = l_arr[2][1..-1] # strip 'u'
63
+ d.size = l_arr[3..4]
64
+ d.type = l_arr[5]
65
+ d.vendor_model = l_arr[8]
66
+
67
+ d.dri = "disk://" + Diskmon::Server.get_id + "/" + d.ctl_id + "/" + d.port
68
+
69
+ # IO.popen("tw_cli /#{ctl_id}/#{d.port} show smart") do |tw_cli_show_smart_io|
70
+
71
+ # d.smart_status_raw = []
72
+
73
+ # tw_cli_show_smart_io.each_line do |l|
74
+ # s = l.split
75
+ # d.smart_status_raw.push(s) if l[0,1] =~ /[0-9]/ and not s.empty?
76
+ # end
77
+
78
+ # d.smart_status = parse_smart_status(d.smart_status_raw.flatten!)
79
+
80
+ # end # show smart
81
+
82
+ # full stats
83
+ #
84
+ IO.popen("tw_cli /c#{d.ctl_id}/p#{d.port} show all | grep '^/c#{d.ctl_id}/p#{d.port}'") do |tw_cli_show_all_io|
85
+
86
+ tw_cli_show_all_io.each_line do |l|
87
+
88
+ params_arr = l.split
89
+
90
+ case params_arr[1]
91
+ when "Reallocated" then d.reallocs = params_arr[4]
92
+ when "Power" then d.age_hours = params_arr[5]
93
+ when "Temperature" then d.temperature = params_arr[3]
94
+ when "Serial" then d.serial = params_arr[3]
95
+ when "Spindle" then d.spindle_speed = params_arr[4]
96
+ end
97
+ end
98
+
99
+ end # show all
100
+
101
+ d.system_device = "c#{d.ctl_id}t#{d.unit}d0"
102
+ d.short_device = mapdev.to_short(d.system_device)
103
+
104
+ yield d
105
+ end
106
+ end
107
+
108
+ when :adaptec
109
+ end
110
+ end
111
+
112
+ def get_all_stats
113
+
114
+ ctl_ids = get_ctl_ids
115
+
116
+ zp = Diskmon::ZpoolsTree.new
117
+
118
+ if not ctl_ids.empty?
119
+ ctl_ids.each do |ctl_id|
120
+ get_ctl_disks_info(ctl_id) do |d|
121
+
122
+ d.member_of_zpool = zp.which_pool(d.system_device)
123
+ d.read_errors = zp.read_errors(d.system_device)
124
+ d.write_errors = zp.write_errors(d.system_device)
125
+ d.checksum_errors = zp.checksum_errors(d.system_device)
126
+
127
+ d.zpool_health = zp.get_pool_param(d.member_of_zpool, "health")
128
+ d.zpool_last_command = zp.get_pool_param(d.member_of_zpool, "last_command")
129
+ d.zpool_total_space = zp.get_pool_param(d.member_of_zpool, "total_space")
130
+ d.zpool_free_space = zp.get_pool_param(d.member_of_zpool, "free_space")
131
+
132
+ @disks.push(d)
133
+ end
134
+ end
135
+ end
136
+
137
+ # TODO: /c3 show events
138
+
139
+ p @disks if $DEBUG
140
+
141
+ end
142
+
143
+ def parse_smart_status(smart_arr)
144
+
145
+ # TODO: dig smartmontools sources
146
+
147
+ smart_attributes = {
148
+ '00' => 'Zero_Field',
149
+ '01' => 'Raw_Read_Error_Rate',
150
+ '03' => 'Spin_Up_Time',
151
+ '04' => 'Start_Stop_Count',
152
+ '05' => 'Reallocated_Sector_Ct',
153
+ '07' => 'Seek_Error_Rate',
154
+ '09' => 'Power_On_Hours',
155
+ '0A' => 'Spin_Retry_Count',
156
+ '0B' => 'Calibration_Retry_Count',
157
+ '0C' => 'Power_Cycle_Count',
158
+ 'B8' => 'End-to-End_error',
159
+ 'BB' => 'Reported_Uncorrect',
160
+ 'BC' => 'Command_Timeout',
161
+ 'BD' => 'High Fly Writes',
162
+ 'BE' => 'Airflow Temperature',
163
+ 'C0' => 'Power-off_Retract_Count',
164
+ 'C1' => 'Load_Cycle_Count',
165
+ 'C2' => 'Temperature',
166
+ 'C3' => 'Hardware ECC Recovered',
167
+ 'C4' => 'Reallocation Event Count',
168
+ 'C5' => 'Current Pending Sector Count',
169
+ 'C6' => 'Uncorrectable Sector Count',
170
+ 'C7' => 'UltraDMA CRC Error Count',
171
+ 'C8' => 'Multi-Zone Error Rate',
172
+ }
173
+
174
+ smart_parsed = {}
175
+
176
+ i = 0 ; while i < 360 do
177
+
178
+ if smart_arr[i+2].to_i != 0
179
+
180
+ j = 0 ; while j < 12 do
181
+ if j == 0
182
+ smart_param = smart_attributes[smart_arr[i+j+2]]
183
+ smart_val = ''
184
+ end
185
+
186
+ if j > 4 and j < 11
187
+ smart_val << smart_arr[i+j+2]
188
+ end
189
+
190
+ j += 1
191
+ end # while j < 12
192
+
193
+ smart_parsed["#{smart_param}"] = smart_val.to_i(10)
194
+
195
+ end # if smart_arr
196
+
197
+ i += 12
198
+
199
+ end # while i
200
+
201
+ # p smart_parsed if $DEBUG
202
+
203
+ smart_parsed
204
+
205
+ end
206
+
207
+ def serialize
208
+ Marshal.dump(@disks)
209
+ end
210
+
211
+ private :get_vendor
212
+ private :get_ctl_ids
213
+ private :get_ctl_disks_info
214
+
215
+ end
216
+
217
+ ########## Server
218
+
219
+ module Server
220
+
221
+ # def get_id
222
+ # Socket.gethostname.downcase
223
+ # end
224
+
225
+ def self.get_id
226
+ `/usr/sbin/zlogin df-storage hostname`.chomp
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,31 @@
1
+ module Diskmon
2
+
3
+ class SolarisMapDev
4
+
5
+ def initialize
6
+
7
+ @full_dev_to_inst = {}
8
+
9
+ # "/pci@7a,0/pci8086,340c@5/pci9005,2b5@0/disk@52,0" 11 "sd"
10
+ IO.foreach("/etc/path_to_inst") do |l|
11
+ case l.strip
12
+ when /"sd"$/
13
+ full_dev = l.split[0].tr('"','')
14
+ idx = l.split[-2]
15
+ @full_dev_to_inst[full_dev] = "sd#{idx}"
16
+ end
17
+ end
18
+ end
19
+
20
+ def to_short(device)
21
+ begin
22
+ dev = File.readlink("/dev/rdsk/#{device}").gsub("../../devices", "").split(':')[0]
23
+ rescue Errno::ENOENT
24
+ dev = File.readlink("/dev/rdsk/#{device}s0").gsub("../../devices", "").split(':')[0]
25
+ end
26
+
27
+ @full_dev_to_inst[dev]
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,82 @@
1
+ module Diskmon
2
+
3
+ class ZpoolsTree
4
+ def initialize
5
+
6
+ @disks = {}
7
+ @pools = {}
8
+
9
+ IO.popen("/usr/sbin/zpool status") do |zpool_status_io|
10
+
11
+ pool_name = ''
12
+
13
+ zpool_status_io.each_line do |l|
14
+ case l
15
+
16
+ when /pool: /
17
+ pool_name = l.split[1]
18
+ @pools[pool_name] = {}
19
+ @pools[pool_name]["health"] = `/usr/sbin/zpool get health #{pool_name} | grep #{pool_name}`.split[2]
20
+ @pools[pool_name]["free_space"] = `/usr/sbin/zpool get free #{pool_name} | grep #{pool_name}`.split[2]
21
+ @pools[pool_name]["total_space"] = `/usr/sbin/zpool get allocated #{pool_name} | grep #{pool_name}`.split[2]
22
+
23
+ history_events = []
24
+
25
+ IO.popen("/usr/sbin/zpool history #{pool_name}") do |zpool_history_io|
26
+
27
+ zpool_history_io.each_line do |l|
28
+ case l
29
+ when /^[0-9]/ then history_events.push(l)
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ @pools[pool_name]["last_command"] = history_events[-1].chomp
36
+
37
+ when /c[0-9]t/
38
+ disk_name = l.split[0]
39
+
40
+ @disks[disk_name] = {}
41
+ @disks[disk_name]["zpool"] = pool_name
42
+
43
+ @disks[disk_name]["read_errors"] = l.split[2]
44
+ @disks[disk_name]["write_errors"] = l.split[3]
45
+ @disks[disk_name]["checksum_errors"] = l.split[4]
46
+
47
+ end
48
+
49
+ end
50
+ end
51
+
52
+ # p @disks if $DEBUG
53
+ # p @pools if $DEBUG
54
+
55
+ end
56
+
57
+ def which_pool(device)
58
+ @disks[device]["zpool"]
59
+ end
60
+
61
+ def read_errors(device)
62
+ @disks[device]["read_errors"]
63
+ end
64
+
65
+ def write_errors(device)
66
+ @disks[device]["write_errors"]
67
+ end
68
+
69
+ def checksum_errors(device)
70
+ @disks[device]["checksum_errors"]
71
+ end
72
+
73
+ # free_space
74
+ # total_space
75
+ # last_command
76
+ # health
77
+ def get_pool_param(pool, param)
78
+ @pools[pool][param]
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,19 @@
1
+ require 'digest'
2
+
3
+ module Diskmon
4
+
5
+ class HardDisk
6
+
7
+ # credit: http://stackoverflow.com/a/5031637
8
+ def to_hash
9
+ Hash[instance_variables.map { |var| [var[1..-1].to_sym, instance_variable_get(var)] }]
10
+ end
11
+
12
+ def checksum
13
+ as_str = ''
14
+ instance_variables.sort.map { |k| as_str << "#{k}=#{instance_variable_get(k)};" }
15
+ p as_str if $DEBUG
16
+ Digest::MD5.hexdigest(as_str)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,50 @@
1
+ require "data_mapper"
2
+
3
+ module Diskmon
4
+
5
+ class HardDiskReport
6
+ include DataMapper::Resource
7
+
8
+ property :dri , String
9
+ property :ctl_id , String
10
+ property :port , String
11
+ property :status , String
12
+ property :unit , String
13
+ property :type , String
14
+ property :vendor_model , String
15
+ property :smart_status_raw , String
16
+ property :smart_status , String
17
+ property :size , String
18
+ property :reallocs , String
19
+ property :age_hours , String
20
+ property :temperature , String
21
+ property :serial , String
22
+ property :spindle_speed , String
23
+ property :error_events , String
24
+ property :member_of_zpool , String
25
+ property :disk_space_used , String
26
+
27
+ property :error_events , String
28
+
29
+ property :member_of_zpool , String
30
+ property :read_errors , String
31
+ property :write_errors , String
32
+ property :checksum_errors , String
33
+
34
+ property :zpool_health , String
35
+ property :zpool_last_command , String
36
+ property :zpool_total_space , String
37
+ property :zpool_free_space , String
38
+
39
+ property :system_device , String
40
+ property :short_device , String
41
+
42
+ property :created_at , EpochTime
43
+ property :checksum , String, :key => true, :unique => true
44
+
45
+ def print
46
+ instance_variables.sort.map { |k| printf( "%-20s => %s\n", k, instance_variable_get(k) ) }
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module Diskmon
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: diskmon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Morion Black
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: data_mapper
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sinatra
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: thin
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Gem for collect statistic from disks
63
+ email:
64
+ - morion.estariol@gmail.com
65
+ executables:
66
+ - diskmon
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - Gemfile
71
+ - LICENSE
72
+ - README.md
73
+ - Rakefile
74
+ - bin/diskmon
75
+ - diskmon.gemspec
76
+ - lib/diskmon.rb
77
+ - lib/diskmon/client/collector.rb
78
+ - lib/diskmon/client/config.rb
79
+ - lib/diskmon/client/harddisk.rb
80
+ - lib/diskmon/client/raidcontroller.rb
81
+ - lib/diskmon/client/solarismapdev.rb
82
+ - lib/diskmon/client/zpoolstree.rb
83
+ - lib/diskmon/server/harddisk.rb
84
+ - lib/diskmon/server/harddiskreport.rb
85
+ - lib/diskmon/version.rb
86
+ homepage: ''
87
+ licenses: []
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 1.8.23
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Gem for collect statistic from disks
110
+ test_files: []