Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 14 commits
  • 24 files changed
  • 0 commit comments
  • 1 contributor
View
73 parser/lib/uliska_parser.rb
@@ -12,29 +12,37 @@ module Uliska
class Parser
include Singleton
-
- # Read-in YAML inventory file produced by scanner. If file name
- # is not provided read from STDIN.
- def read yaml=STDIN
- @raw = @data = @errors = @commands = nil
- case yaml
- when String
- raise "Input file not defined" unless yaml
- raise "Input file does not exist" unless File.exist? yaml
- raise "Input file is not readable " unless File.readable? yaml
-
- data = YAML::load_file(yaml) rescue "Wrong format of YAML file"
- when IO
- data = YAML::load yaml
- end
+ # Load YAML data string and initialize instance variables.
+ def load yaml
+ data = YAML::load yaml
raise "Cannot load YAML data" unless data
+ @raw = @data = @errors = @commands = nil
@errors = data.delete('__ERRORS__')
@commands = data.delete('__COMMANDS__')
@raw = OpenStruct.new data
@data = { }
end
+
+ # Read-in YAML inventory file produced by scanner. If file name
+ # is not provided read from STDIN.
+ def read file=STDIN
+
+ yaml = case file
+ when String
+ raise "Input file not defined" unless file
+ raise "Input file does not exist" unless File.exist? file
+ raise "Input file is not readable " unless File.readable? file
+
+ File.read(file)
+ when IO
+ file.read
+ end
+
+ raise "Cannot read YAML data" unless yaml
+ load yaml
+ end
attr_accessor :data, :errors, :commands, :raw, :parsed
@@ -90,10 +98,11 @@ def self.colon_separated in_data, fields, delimiter=':'
end
return nil unless out
- out.delete_if { |x| x =~ /^\#/} # Delete comments - BSD group and passwd files have comments
+ out.delete_if { |x| x =~ /^\#/} # Delete comments - BSD group
+ # and passwd files have comments
out.map { |line|
- arr = line.split(delimiter)
+ arr = line.strip.split(delimiter, fields.count)
hsh={ }
fields.each do |a|
@@ -108,6 +117,36 @@ def self.space_separated file, fields
colon_separated file, fields, /\s+/
end
+ # Format similar to vmstat -s output,
+ # vmstat:
+ # - ' 4096 bytes per page'
+ # - ' 13573 pages managed'
+ # - ' 5553 pages free'
+ # Converted into Hash
+ # :vmstat=>
+ # {"bytes per page"=>4096,
+ # "pages managed"=>13573,
+ # "pages free"=>5553
+ # @param [String, Symbol or Array] data @see self.colon_separated
+ # @param [String or Regexp] delimiter @see self.colon_separated, defaults to spaces
+ #
+ # TODO: for now limiting hash to have only numeric values. How to make it more generic?
+ def self.value_label_pairs data, delimiter = /\s+/
+ colon_separated(data, [:value, :label], delimiter).inject({ }) { |res,hash|
+
+ if hash[:value].is_a?(Numeric)
+ if hash[:label] =~ /^K\s/ # For lines like: 384636 K total memory (Linux vmstat)
+ hash[:label].sub!(/^K\s+/,'')
+ hash[:value] *= 1024
+ end
+
+ res[hash[:label]] = hash[:value]
+ end
+
+ res
+ }
+ end
+
end
end
View
42 parser/lib/uliska_parser/darwin.rb
@@ -4,6 +4,7 @@
module Uliska
class Parser
+
parse :filesystems do
#
# Filesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on
@@ -21,5 +22,46 @@ class Parser
fss
end
+ # @method :vmstat Parse result of vmstat -s into Hash. Parse
+ # memory uses result of this, so it should go before +parse :memory+.
+ parse :vmstat do
+ raw.vmstat.find{ |x| x =~ /\(page size of (\d+) bytes\)/}
+ mem = {"page_size" => $1.to_num}
+
+ colon_separated(:vmstat, [:label, :value]).inject(mem) { |mem,hash|
+ mem[hash[:label]] = hash[:value].to_i
+ mem
+ }
+ mem
+ end
+
+
+ parse :memory do
+ {
+ :total => sysctl["hw.memsize"],
+ :free => data[:vmstat]["Pages free"] * data[:vmstat]["page_size"]
+ }
+ end
+
+ parse :swap do
+ # "vm.swapusage"=>
+ # "total = 2048.00M used = 1139.05M free = 908.95M (encrypted)"
+
+ swap = /total = ([\d\.]+\w) used = ([\d\.]+\w) free = ([\d\.]+\w)/.match(sysctl["vm.swapusage"]) { |m|
+ m.to_num
+ }
+
+ {
+ :total => swap[1],
+ :free => swap[2],
+ :used => swap[3],
+ :segments => space_separated(:swap, [:size, :device]).map{ |x|
+ x[:used] = x[:size] *= 1024; x
+ }
+
+
+ }
+ end
+
end
end
View
26 parser/lib/uliska_parser/extensions.rb
@@ -41,13 +41,23 @@ class Object
# Convert to one of integer, float etc depending on format. If it
# does not look like number, return self unmodified.
def to_num
- if self.class != String
- return self
- end
- case self
- when /^-?\s*\d+$/ then self.to_i
- when /^-?\s*\d+\.\d*$/ then self.to_f
- else self
- end
+
+ number = /^([-+]?\d+(\.\d+)?)(\s?[GMK])?$/
+
+ return self unless self.is_a? String
+ return self unless self =~ number
+
+ decimal, suffix = $2, $3
+
+ self.sub!(number,'\1')
+
+ coeff = case suffix
+ when /G/ then 1073741824
+ when /M/ then 1048576
+ when /K/ then 1024
+ end
+
+ (coeff || 1) * (decimal ? self.to_f : self.to_i)
+
end
end
View
21 parser/lib/uliska_parser/freebsd.rb
@@ -3,18 +3,33 @@
module Uliska
class Parser
+ # @method :vmstat Parse result of vmstat -s into Hash. Parse
+ # memory uses result of this, so it should go before +parse :memory+.
+ parse :vmstat do
+ value_label_pairs :vmstat
+ end
+
+ # See script for commands
+ # http://www.cyberciti.biz/files/scripts/freebsd-memory.pl.txt
+
+ parse :memory do
+ { :free => sysctl["vm.stats.vm.v_free_count"] * sysctl["hw.pagesize"],
+ :total => sysctl["hw.physmem"]
+ }
+ end
+
# Parse output of swapctl -l
parse :swap do
# Device: 1024-blocks Used:
# /dev/ad0s1b 34368 0
# /dev/md0 10240 0
- fields = space_separated :swap, %w{ device blocks used }
+ fields = space_separated :swap, %w{ device size used }
- block_size = (fields.shift[:blocks].gsub(/[^\d]/,'').to_i) /1024
+ block_size = (fields.shift[:size].gsub(/[^\d]/,'').to_i) /1024
{
:segments => fields,
- :total => (total = fields.sum_by(:blocks).to_i * block_size),
+ :total => (total = fields.sum_by(:size).to_i * block_size),
:free => (total - fields.sum_by(:used).to_i) * block_size
}
end
View
29 parser/lib/uliska_parser/generic.rb
@@ -66,14 +66,33 @@ def hostname
parse :sysctl do
break unless raw[:sysctl]
- raw[:sysctl].map { |line|
- key,val = line.split(/\s*=\s*/)
- next unless key && val;
- { key.strip => val.strip.to_num }
- }.compact
+ raw[:sysctl].inject({ }) { |res,line|
+ key,val = line.split(/\s*[=:]\s*/,2) # FreeBSD/Darwin use ':' as separator, Linux/OpenBSD '='
+ if key && val
+ case res[key.strip]
+ when Array
+ res[key.strip] << val.strip.to_num
+ when String, Fixnum
+ # Darwin has multiple entries with the same key,value
+ # Linux has multiple entries with the same key, different values.
+ res[key.strip] = [res[key.strip]] << val.strip.to_num unless val.strip.to_num == res[key.strip]
+ else
+ res[key.strip] = val.strip.to_num
+ end
+ end
+
+ res
+ }
+ end
+ class << self
+ # Helper method to gt to sysctl information easier
+ def sysctl
+ OpenStruct.new data[:sysctl]
+ end
end
+
# Chain load additional files
load_parsers kernel.name
load_parsers [kernel.name, kernel.major]
View
19 parser/lib/uliska_parser/linux.rb
@@ -8,9 +8,25 @@ class Parser
parse :distro
def self.distro; data[:distro] end
+ # @method :vmstat Parse result of vmstat -s into Hash.
+ parse :vmstat do
+ value_label_pairs :vmstat
+ end
+
+ # @method memory
+ # Parse output of free command.
+ parse :memory do
+ out = space_separated(
+ [raw.memory.find{ |x| x =~ /^Mem:/}],
+ %w{mem total used free shared buffers cached}
+ ).first
+ out.shift
+ out
+ end
+
# Parse output of swapon -s
parse :swap do
- fields = space_separated raw.swap[1..-1], %w{ filename type size used priority}
+ fields = space_separated raw.swap[1..-1], %w{device type size used priority}
{
:total => (total = fields.sum_by(:size).to_i),
@@ -43,7 +59,6 @@ def self.distro; data[:distro] end
filesystems
end
- parse :memory
end
end
View
23 parser/lib/uliska_parser/openbsd.rb
@@ -4,18 +4,35 @@
module Uliska
class Parser
+
+ # @method :vmstat Parse result of vmstat -s into Hash. Parse
+ # memory uses result of this, so it should go before +parse :memory+.
+ parse :vmstat do
+ value_label_pairs :vmstat
+ end
+
+
+ parse :memory do
+ page_size = data[:vmstat]["bytes per page"]
+ {
+ :page_size => page_size,
+ :total => data[:sysctl]["hw.physmem"].to_num,
+ :free => data[:vmstat]["pages free"] * page_size
+ }
+ end
+
# Parse output of swapctl -l
parse :swap do
# Device 512-blocks Used Avail Capacity Priority
# /dev/wd0b 166180 0 166180 0% 0
# /var/swapfile 20480 0 20480 0% 0
# Total 186660 0 186660 0%
- fields = space_separated :swap, %w{ device blocks used avail capacity priority}
+ fields = space_separated :swap, %w{ device size used avail capacity priority}
- block_size = fields.shift[:blocks].gsub(/[^\d]/,'').to_i
+ block_size = fields.shift[:size].gsub(/[^\d]/,'').to_i
fields.delete_if { |x| x[:device] == 'Total' }
- total = fields.sum_by(:blocks).to_i * block_size / 1024
+ total = fields.sum_by(:size).to_i * block_size / 1024
free = total - (fields.sum_by(:used).to_i * block_size / 1024)
{:segments => fields, :total => total, :free => free }
View
30 parser/lib/uliska_parser/sunos.rb
@@ -23,6 +23,28 @@ def self.inodes_parser
space_separated raw.inodes[-1..-1], %w{ filesystem iused ifree iuse mounted_on}
end
+ # @method :vmstat Parse result of vmstat -s into Hash. Parse
+ # memory uses result of this, so it should go before +parse :memory+.
+ parse :vmstat do
+ value_label_pairs :vmstat
+ end
+
+ parse :memory do
+ size = raw.prtconf.find { |x| x =~ /^Memory size:/}.split(':')[1]
+ number,units = size.split
+
+ {
+ :total => number.to_i * case
+ when units =~ /Mega/ then 1024*1024
+ when units =~ /Gig/ then 1024*1024*124
+ else 1
+ end,
+
+ :free => nil,
+ :segments => [
+ ]
+ }
+ end
# Parse output of swap -l
# @return [Hash] like
@@ -37,8 +59,12 @@ def self.inodes_parser
# :free=>"1572856",
# :type=>:partition},
parse :swap do
- fields = space_separated raw.swap[1..-1], %w{swapfile dev swaplo blocks free}
- fields.map { |x| x[:type] = x[:dev] == '-' ? :file : :partition}
+ fields = space_separated raw.swap[1..-1], %w{swapfile device swaplo size free}
+ fields.map { |x|
+ x[:type] = x[:dev] == '-' ? :file : :partition;
+ x[:used] = x[:size] - x[:free];
+ x
+ }
{
:total => fields.sum_by(:blocks).to_i / 2,
View
9 parser/spec/common.rb
@@ -5,8 +5,9 @@
DATA_ROOT = File.dirname(File.dirname(__FILE__)) + "/spec/data"
-require "filesystems"
-require "any_unix"
-require "any_linux"
-require "any_linux2"
+require "lib/filesystems"
+require "lib/any_unix"
+require "lib/unix_with_sysctl"
+require "lib/any_linux"
+require "lib/any_linux2"
View
1 parser/spec/darwin_spec.rb
@@ -3,5 +3,6 @@
describe "Darwin" do
before { $data_file = "darwin.yml" }
it_should_behave_like "any unix"
+ it_should_behave_like "unix with sysctl"
it_should_behave_like "any filesystem"
end
View
3 parser/spec/debian_spec.rb
@@ -2,10 +2,7 @@
describe "Debian Linux" do
before { $data_file = "deb.yml" }
- it_should_behave_like "any unix"
- it_should_behave_like "any filesystem"
it_should_behave_like "any linux"
-
it_should_behave_like "any linux v.2"
end
View
4 parser/spec/any_linux.rb → parser/spec/lib/any_linux.rb
@@ -15,6 +15,10 @@
end
+ it_should_behave_like "any unix"
+ it_should_behave_like "unix with sysctl"
+ it_should_behave_like "any filesystem"
+
it "should have distro name" do
data.distro.should be_a_kind_of String
View
0 parser/spec/any_linux2.rb → parser/spec/lib/any_linux2.rb
File renamed without changes.
View
56 parser/spec/any_unix.rb → parser/spec/lib/any_unix.rb
@@ -15,7 +15,6 @@
context "any UNIX" do
-
#
# hostname
#
@@ -122,45 +121,59 @@
context "memory and swap" do
- memory = swap = nil
+ memory = swap = vmstat = nil
before do
swap = OpenStruct.new data.swap
memory = OpenStruct.new data.memory
+ vmstat = OpenStruct.new data.vmstat
end
it "should have physical memory" do
- fail
+ memory.should_not be_empty
end
it "should have swap" do
swap.should_not be_empty
end
-
- context "physical memory" do
+ context "vmstat" do
+
+ it "should be Hash" do
+ data.vmstat.should be_a_kind_of Hash
+ end
+
+ it "values should be Numeric" do
+ data.vmstat.each do |k,v|
+ k.should be_a_kind_of String
+ v.should be_a_kind_of Integer
+ end
+ end
+
+ end
+
+ context "memory" do
it "should be numeric" do
- fail
+ memory[:total].should be_a_kind_of Integer
end
- it "should be non zero" do
- fail
+ it "total should > 0" do
+ memory[:total].should > 0
end
it "should have free memory" do
- fail
+ memory[:free].should be_a_kind_of Integer
end
it "free memory should be >= 0 " do
- fail
+ memory[:free].should >= 0
end
end # physical memory
-
context "swap" do
- it "should have required fields" do
+ it "should have fields :total, :free, :segments" do
data.swap.should be_a_kind_of Hash
data.swap.should have_key :total
data.swap.should have_key :free
@@ -182,7 +195,26 @@
it "free swap should be >= 0 " do
swap.free.should >= 0
end
+
+ context "swap segments" do
+
+ it "should be an Array" do
+ data.swap[:segments].should be_a_kind_of Array
+ end
+
+ it "every segment should be a Hash with keys :device, :size, :used" do
+ data.swap[:segments].each do |seg|
+ seg.should be_a_kind_of Hash
+ seg.should have_key :device
+ seg.should have_key :size
+ seg.should have_key :used
+ end
+ end
+
+
+ end
end # swap
end
+
end
View
0 parser/spec/filesystems.rb → parser/spec/lib/filesystems.rb
File renamed without changes.
View
24 parser/spec/lib/unix_with_sysctl.rb
@@ -0,0 +1,24 @@
+shared_examples_for "unix with sysctl" do
+
+ require 'ostruct'
+ require 'pp'
+
+ data = nil
+
+ before(:each) do
+
+ Uliska::Parser.instance.read("#{DATA_ROOT}/#{$data_file}")
+ Uliska::Parser.load_parsers
+ data = OpenStruct.new Uliska::Parser.data
+
+ end
+
+ context "sysctl" do
+
+ it "should exist and be a Hash" do
+ data.sysctl.should be_a_kind_of Hash
+ end
+
+ end
+
+end
View
52 parser/spec/object_spec.rb
@@ -3,20 +3,56 @@
describe String do
+ it "not string shoulde return self" do
+ nil.to_num.should == nil
+ [].to_num.should == []
+ { }.to_num.should == { }
+ end
+
+ it "string with G/M/K at the end should not be converted" do
+ "aaaG".to_num.should == "aaaG"
+ "aaaM".to_num.should == "aaaM"
+ "aaaK".to_num.should == "aaaK"
+ end
+
it "should convert int" do
- "123".to_num.should be_a_kind_of Fixnum
- "1243".to_num.should be 1243
+ "42".to_num.should == 42
end
- it "should convert neint" do
- "- 1233".to_num.should be_a_kind_of Fixnum
- "-1233".to_num.should be_a_kind_of Fixnum
- "- 1233".to_num.should be_a_kind_of Fixnum
+ it "should convert negative int" do
+ "- 1233".to_num.should be_a_kind_of String
+ "-1233".to_num.should be_a_kind_of Numeric
+ "- 1233".to_num.should be_a_kind_of String
"-1".to_num.should be -1
end
- it "should return self for not number" do
- "qwerwqerr".to_num.should be_a_kind_of String
+
+ it "should honor plus with number" do
+ "+42".to_num.should == 42
+ "+ 42".to_num.should == "+ 42"
+ "+0.1".to_num.should == 0.1
+ end
+
+ it "should return string for not number" do
+ "qwerwqerr".to_num.should == "qwerwqerr"
+ end
+
+ it "should convert 1K to 1024" do
+ "1K".to_num.should == 1024
+ "1 K".to_num.should == 1024
+ "0.1 K".to_num.should == 102.4
+ end
+
+ it "should convert number 1M to number" do
+ "1M".to_num.should == 1024*1024
+ "1 M".to_num.should == 1024*1024
+ "0.1 M".to_num.should == 0.1 * 1024*1024
+ end
+
+ it "should convert 1G to number" do
+ "1G".to_num.should == 1024*1024*1024
+ "1 G".to_num.should == 1024*1024*1024
+ "0.1G".to_num.should == 0.1 * 1024*1024*1024
end
end
View
100 parser/spec/uliska_parser_spec.rb
@@ -0,0 +1,100 @@
+$: << File.dirname(File.dirname(__FILE__)) + "/lib"
+require "uliska_parser.rb"
+require "uliska_parser/extensions"
+
+require "#{File.dirname(__FILE__)}/common"
+
+describe "uliska parser" do
+
+ before do
+ @p = Uliska::Parser
+ end
+
+ context "load data" do
+
+ it "should load YAML data" do
+ @p.instance.load %q{
+---
+a: b
+}
+ @p.raw[:a].should == "b"
+ end
+
+ it "should load YAML file" do
+ @p.instance.read "#{DATA_ROOT}/sample_yaml.yml"
+ @p.raw[:string].should == "test"
+ end
+
+ end
+
+ context "colon separated" do
+
+ before do
+ @p.instance.load <<-DATA
+/etc/passwd:
+ - nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
+ - root:*:0:0:System Administrator:/var/root:/bin/sh
+ - daemon:*:1:1:System Services:/var/root:/usr/bin/false
+DATA
+ end
+
+ it "has all fields" do
+ data = @p.colon_separated(['a:b:c:d'],%w{f1 f2 f3 f4}).first
+ [:f1, :f2, :f3, :f4].each do |key|
+ data.should have_key key
+ end
+ end
+
+ it "has not more then required fields" do
+ data = @p.colon_separated(['a:b:c:d'],%w{f1 f2 f3}).first
+ [:f1, :f2, :f3].each do |key|
+ data.should have_key key
+ end
+ data.should_not have_key :f4
+ end
+
+ it "allow override separator" do
+ data = @p.colon_separated(['a:b,c:d'],%w{f1 f2}, ',').first
+ data[:f1].should == 'a:b'
+ end
+
+
+ it "converts numbers to numeric" do
+
+ @p.colon_separated("/etc/passwd", %w{ user passwd uid gid gecos home shell}).each do |line|
+ line[:uid].should be_a_kind_of Numeric
+ line[:gid].should be_a_kind_of Numeric
+ end
+ end
+ end
+
+ context "value-key pairs" do
+
+ before do
+ @p.instance.load <<DATA
+vmstat:
+ - ' 384636 K total memory'
+ - ' 194936 K used memory'
+ - ' 85784 K inactive memory'
+ - ' 3172 non-nice user cpu ticks'
+ - ' 0 nice user cpu ticks'
+ - ' 5009 IO-wait cpu ticks'
+ - ' 968 IRQ cpu ticks'
+
+
+DATA
+ end
+
+ it "values should be numeric" do
+ @p.value_label_pairs(:vmstat).each do |key,value|
+ value.should be_a_kind_of Integer
+ end
+ end
+
+ it "values should properly convert values with K suffix" do
+ @p.value_label_pairs(:vmstat)["total memory"].should == 384636 * 1024
+ @p.value_label_pairs(:vmstat)["IRQ cpu ticks"].should == 968
+ end
+
+ end
+end
View
8 scanner/cfg/Darwin.cfg
@@ -5,3 +5,11 @@ df -i -k # inodes
# for i in `diskutil list | grep -v "^ "`; do echo $i; fdisk -d $i ; done # fdisk
# diskutil info / # root_disk
+#
+# Darwin version of vmstat has undesrcore, not all other UNIX's options.
+#
+vm_stat # vmstat
+#
+# For swapfle show only size in K's and filename
+ls -1sk /private/var/vm/swapfile* # swap
+
View
3 scanner/cfg/FreeBSD.cfg
@@ -3,4 +3,5 @@ cat /etc/rc.conf # hostconfig
# FreeBSD df prints FS type, space and inodes
#
df -T -k -i # df
-swapctl -l # swap
+swapctl -l # swap
+vmstat -s # vmstat
View
6 scanner/cfg/Linux.cfg
@@ -24,5 +24,7 @@ free # memory
cat /proc/meminfo # meminfo
#
# Sysctl
-#
-sysctl -a # sysctl
+# Grep out key permission denied erro
+#sysctl -a | grep -v 'permission denied' # sysctl
+sysctl -a # sysctl
+vmstat -s # vmstat
View
1 scanner/cfg/OpenBSD.cfg
@@ -5,3 +5,4 @@ cat /etc/rc.conf
#
df -k -i # df
swapctl -l # swap
+vmstat -s # vmstat
View
3 scanner/cfg/SunOS.cfg
@@ -4,6 +4,7 @@
cat /etc/vfstab
#
prtconf
+prtdiag
#
swap -l # swap
#
@@ -14,3 +15,5 @@ df -o i -F ufs # inodes
# Additional command for Solaris to get FS type information
#
df -n # fs_types
+#
+vmstat -s # vmstat
View
2 scanner/lib/Uliska.pm
@@ -190,7 +190,7 @@ sub run ($) {
scalar grep {/(operation\s+not\s+permitted|
command\s+not\s+found|
no\s+such\s+file\s+or\s+directory|
- permission\s+denied|
+ permission\s+denied$|
cat:\s+cannot\s+open
)/ix} @out or
scalar grep {/^usage: /} @out

No commit comments for this range

Something went wrong with that request. Please try again.