rubyipmi 0.6.0 → 0.7.0
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.
- checksums.yaml +15 -0
- data/Gemfile +5 -3
- data/README.md +24 -14
- data/Rakefile +82 -4
- data/VERSION +1 -1
- data/lib/rubyipmi.rb +36 -14
- data/lib/rubyipmi/commands/basecommand.rb +57 -119
- data/lib/rubyipmi/freeipmi/commands/basecommand.rb +29 -25
- data/lib/rubyipmi/freeipmi/commands/bmc.rb +3 -3
- data/lib/rubyipmi/freeipmi/commands/bmcconfig.rb +6 -6
- data/lib/rubyipmi/freeipmi/commands/bmcinfo.rb +3 -23
- data/lib/rubyipmi/freeipmi/commands/fru.rb +117 -23
- data/lib/rubyipmi/freeipmi/commands/lan.rb +32 -37
- data/lib/rubyipmi/freeipmi/commands/power.rb +1 -1
- data/lib/rubyipmi/freeipmi/commands/sensors.rb +53 -50
- data/lib/rubyipmi/freeipmi/connection.rb +16 -2
- data/lib/rubyipmi/freeipmi/errorcodes.rb +25 -2
- data/lib/rubyipmi/ipmitool/commands/basecommand.rb +20 -37
- data/lib/rubyipmi/ipmitool/commands/bmc.rb +1 -24
- data/lib/rubyipmi/ipmitool/commands/chassis.rb +1 -0
- data/lib/rubyipmi/ipmitool/commands/fru.rb +112 -30
- data/lib/rubyipmi/ipmitool/commands/lan.rb +55 -77
- data/lib/rubyipmi/ipmitool/commands/power.rb +10 -4
- data/lib/rubyipmi/ipmitool/commands/sensors.rb +53 -80
- data/lib/rubyipmi/ipmitool/connection.rb +19 -3
- data/lib/rubyipmi/ipmitool/errorcodes.rb +51 -3
- data/rubyipmi.gemspec +73 -33
- data/spec/Vagrantfile +45 -0
- data/spec/fixtures/freeipmi/bmc_config.txt +317 -0
- data/spec/fixtures/freeipmi/bmc_config_lan_conf.txt +19 -0
- data/spec/fixtures/freeipmi/bmc_info.txt +32 -0
- data/spec/fixtures/freeipmi/errors.txt +3 -0
- data/spec/fixtures/freeipmi/fru.txt +13 -0
- data/spec/fixtures/freeipmi/sensors.txt +29 -0
- data/spec/fixtures/ipmitool/bmc_info.txt +20 -0
- data/spec/fixtures/ipmitool/errors.txt +10 -0
- data/spec/fixtures/ipmitool/fru.txt +96 -0
- data/spec/fixtures/ipmitool/lan.txt +17 -0
- data/spec/fixtures/ipmitool/sensors.txt +105 -0
- data/spec/integration/bmc_spec.rb +49 -0
- data/spec/{chassis_config_spec.rb → integration/chassis_config_spec.rb} +6 -6
- data/spec/integration/chassis_spec.rb +26 -0
- data/spec/integration/connection_spec.rb +35 -0
- data/spec/{fru_spec.rb → integration/fru_spec.rb} +11 -10
- data/spec/{lan_spec.rb → integration/lan_spec.rb} +9 -7
- data/spec/integration/power_spec.rb +40 -0
- data/spec/{rubyipmi_spec.rb → integration/rubyipmi_spec.rb} +7 -10
- data/spec/{sensor_spec.rb → integration/sensor_spec.rb} +5 -20
- data/spec/manifests/default.pp +50 -0
- data/spec/puppetmodules/archive/LICENSE-2.0.txt +202 -0
- data/spec/puppetmodules/archive/Modulefile +8 -0
- data/spec/puppetmodules/archive/README.md +40 -0
- data/spec/puppetmodules/archive/manifests/download.pp +157 -0
- data/spec/puppetmodules/archive/manifests/extract.pp +81 -0
- data/spec/puppetmodules/archive/manifests/init.pp +70 -0
- data/spec/puppetmodules/archive/manifests/tar-gz.pp +7 -0
- data/spec/puppetmodules/archive/manifests/zip.pp +7 -0
- data/spec/puppetmodules/archive/metadata.json +26 -0
- data/spec/spec_helper.rb +35 -3
- data/spec/unit/freeipmi/bmc-info_spec.rb +42 -0
- data/spec/unit/freeipmi/bmc_spec.rb +44 -0
- data/spec/unit/freeipmi/connection_spec.rb +56 -0
- data/spec/unit/freeipmi/errorcodes_spec.rb +34 -0
- data/spec/unit/freeipmi/fru_spec.rb +77 -0
- data/spec/unit/freeipmi/lan_spec.rb +0 -0
- data/spec/unit/freeipmi/sensors_spec.rb +83 -0
- data/spec/unit/ipmitool/bmc_spec.rb +78 -0
- data/spec/unit/ipmitool/connection_spec.rb +58 -0
- data/spec/unit/ipmitool/errorcodes_spec.rb +34 -0
- data/spec/unit/ipmitool/fru_spec.rb +77 -0
- data/spec/unit/ipmitool/lan_spec.rb +93 -0
- data/spec/unit/ipmitool/sensors_spec.rb +95 -0
- data/spec/unit/rubyipmi_spec.rb +31 -0
- data/spec/vagrant +27 -0
- data/spec/vagrant.pub +1 -0
- metadata +157 -106
- data/.document +0 -5
- data/.rspec +0 -1
- data/Gemfile.lock +0 -33
- data/spec/bmc_spec.rb +0 -46
- data/spec/chassis_spec.rb +0 -26
- data/spec/connection_spec.rb +0 -31
- data/spec/power_spec.rb +0 -42
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rubyipmi/freeipmi/errorcodes'
|
2
|
+
|
1
3
|
module Rubyipmi::Freeipmi
|
2
4
|
|
3
5
|
class BaseCommand < Rubyipmi::BaseCommand
|
@@ -5,27 +7,29 @@ module Rubyipmi::Freeipmi
|
|
5
7
|
def setpass
|
6
8
|
super
|
7
9
|
@options["config-file"] = @passfile.path
|
8
|
-
@passfile.
|
9
|
-
@passfile.
|
10
|
-
|
10
|
+
@passfile.write "username #{@options["username"]}\n"
|
11
|
+
@passfile.write "password #{@options["password"]}\n"
|
11
12
|
@passfile.close
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def max_retry_count
|
17
|
+
@max_retry_count ||= Rubyipmi::Freeipmi::ErrorCodes.length
|
12
18
|
end
|
13
19
|
|
14
20
|
def makecommand
|
15
21
|
# need to format the options to freeipmi format
|
16
22
|
args = @options.collect { |k, v|
|
23
|
+
# must remove from command line as its handled via conf file
|
24
|
+
next if k == 'password'
|
25
|
+
next if k == 'username'
|
17
26
|
if not v
|
18
27
|
"--#{k}"
|
19
28
|
else
|
20
29
|
"--#{k}=#{v}"
|
21
30
|
end
|
22
31
|
}.join(" ")
|
23
|
-
#
|
24
|
-
args.delete("--password")
|
25
|
-
args.delete("--username")
|
26
|
-
|
27
|
-
|
28
|
-
return "#{cmd} #{args}"
|
32
|
+
return "#{cmd} #{args.rstrip}"
|
29
33
|
end
|
30
34
|
|
31
35
|
# This method will check if the results are really valid as the exit code can be misleading and incorrect
|
@@ -35,39 +39,39 @@ module Rubyipmi::Freeipmi
|
|
35
39
|
# until ipmipower returns the correct exit status this is a hack
|
36
40
|
# essentially any result greater than 23 characters is an error
|
37
41
|
if @result.length > 23
|
38
|
-
|
42
|
+
raise "Error occurred"
|
39
43
|
end
|
40
44
|
when "bmc-config"
|
41
45
|
if @result.length > 100
|
42
46
|
return true
|
47
|
+
else
|
48
|
+
raise "Error occurred"
|
49
|
+
end
|
50
|
+
else
|
51
|
+
if exitstatus.success?
|
52
|
+
return true
|
53
|
+
else
|
54
|
+
raise "Error occurred"
|
43
55
|
end
|
44
|
-
end
|
45
|
-
return exitstatus.success?
|
46
56
|
|
57
|
+
end
|
47
58
|
end
|
48
59
|
|
49
60
|
# The findfix method acts like a recursive method and applies fixes defined in the errorcodes
|
50
61
|
# If a fix is found it is applied to the options hash, and then the last run command is retried
|
51
62
|
# until all the fixes are exhausted or a error not defined in the errorcodes is found
|
52
|
-
def
|
63
|
+
def find_fix(result)
|
53
64
|
if result
|
54
65
|
# The errorcode code hash contains the fix
|
55
|
-
|
56
|
-
|
57
|
-
raise "#{result}"
|
58
|
-
else
|
66
|
+
begin
|
67
|
+
fix = ErrorCodes.search(result)
|
59
68
|
@options.merge_notify!(fix)
|
60
|
-
# retry the last called method
|
61
|
-
# its quicker to explicitly call these commands than calling a command block
|
62
|
-
if runmethod == "runcmd"
|
63
|
-
runcmd(debug)
|
64
|
-
else
|
65
|
-
runcmd_without_opts(args, debug)
|
66
|
-
end
|
67
69
|
|
70
|
+
rescue
|
71
|
+
raise "Could not find fix for error code: \n#{result}"
|
68
72
|
end
|
69
|
-
|
70
73
|
end
|
71
74
|
end
|
75
|
+
|
72
76
|
end
|
73
77
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Rubyipmi::Freeipmi
|
2
2
|
|
3
|
-
class Bmc
|
3
|
+
class Bmc < Rubyipmi::Freeipmi::BaseCommand
|
4
4
|
|
5
|
-
attr_accessor :options
|
5
|
+
#attr_accessor :options
|
6
6
|
attr_accessor :config
|
7
7
|
|
8
8
|
def initialize(opts = ObservableHash.new)
|
9
|
-
|
9
|
+
super("bmc-device", opts)
|
10
10
|
@bmcinfo = {}
|
11
11
|
end
|
12
12
|
|
@@ -9,12 +9,12 @@ module Rubyipmi::Freeipmi
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def section(section)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
@options["checkout"] = false
|
13
|
+
@options["section"] = section
|
14
|
+
value = runcmd
|
15
|
+
@options.delete_notify("checkout")
|
16
|
+
@options.delete_notify("section")
|
17
|
+
return @result
|
18
18
|
end
|
19
19
|
|
20
20
|
def setsection(section, key, value)
|
@@ -9,9 +9,9 @@ module Rubyipmi::Freeipmi
|
|
9
9
|
|
10
10
|
|
11
11
|
def guid
|
12
|
-
|
12
|
+
options["get-device-guid"] = false
|
13
13
|
status = runcmd
|
14
|
-
|
14
|
+
options.delete_notify("get-device-guid")
|
15
15
|
if not status
|
16
16
|
raise @result
|
17
17
|
else
|
@@ -19,27 +19,7 @@ module Rubyipmi::Freeipmi
|
|
19
19
|
end
|
20
20
|
|
21
21
|
end
|
22
|
-
|
23
|
-
# Device ID: 17
|
24
|
-
# Device Revision: 1
|
25
|
-
# [SDR Support]
|
26
|
-
# Firmware Revision: 2.09
|
27
|
-
# [Device Available (normal operation)]
|
28
|
-
# IPMI Version: 2.0
|
29
|
-
# Additional Device Support:
|
30
|
-
# [Sensor Device]
|
31
|
-
# [SDR Repository Device]
|
32
|
-
# [SEL Device]
|
33
|
-
# [FRU Inventory Device]
|
34
|
-
# Manufacturer ID: 11
|
35
|
-
# Product ID: 8192
|
36
|
-
# Channel Information:
|
37
|
-
# Channel No: 2
|
38
|
-
# Medium Type: 802.3 LAN
|
39
|
-
# Protocol Type: IPMB-1.0
|
40
|
-
# Channel No: 7
|
41
|
-
# Medium Type: OEM
|
42
|
-
# Protocol Type: KCS
|
22
|
+
|
43
23
|
def retrieve
|
44
24
|
bmcinfo = {}
|
45
25
|
status = runcmd
|
@@ -2,48 +2,105 @@ module Rubyipmi::Freeipmi
|
|
2
2
|
|
3
3
|
class Fru < Rubyipmi::Freeipmi::BaseCommand
|
4
4
|
|
5
|
+
attr_accessor :list
|
6
|
+
|
7
|
+
DEFAULT_FRU = 'default_fru_device'
|
8
|
+
|
5
9
|
def initialize(opts = ObservableHash.new)
|
6
|
-
|
10
|
+
super("ipmi-fru", opts)
|
11
|
+
@list = {}
|
7
12
|
end
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
14
|
+
def get_from_list(key)
|
15
|
+
if list.has_key?(DEFAULT_FRU)
|
16
|
+
if list[DEFAULT_FRU].has_key?(key)
|
17
|
+
list[DEFAULT_FRU][key]
|
18
|
+
else
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def manufacturer
|
26
|
+
get_from_list('board_manufacturer')
|
27
|
+
end
|
28
|
+
|
29
|
+
def board_serial
|
30
|
+
get_from_list('board_serial_number')
|
12
31
|
end
|
13
32
|
|
14
33
|
def serial
|
15
|
-
|
34
|
+
get_from_list('board_serial_number')
|
16
35
|
end
|
17
36
|
|
18
|
-
def
|
19
|
-
|
37
|
+
def model
|
38
|
+
get_from_list('board_product_name')
|
39
|
+
end
|
40
|
+
|
41
|
+
# method to retrieve the raw fru data
|
42
|
+
def getfrus
|
43
|
+
command
|
44
|
+
return @result
|
20
45
|
end
|
21
46
|
|
22
|
-
def
|
23
|
-
list
|
47
|
+
def names
|
48
|
+
list.keys
|
49
|
+
end
|
50
|
+
|
51
|
+
# return the list of fru information in a hash
|
52
|
+
def list
|
53
|
+
if @list.count < 1
|
54
|
+
parse(getfrus)
|
55
|
+
end
|
56
|
+
@list
|
24
57
|
end
|
25
58
|
|
26
59
|
private
|
27
60
|
|
28
61
|
def method_missing(method, *args, &block)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
62
|
+
name = method.to_s
|
63
|
+
fru = list.fetch(name, nil)
|
64
|
+
# if the user wanted some data from the default fru, lets show the data for the fru. Otherwise
|
65
|
+
# we return the Fru with the given name
|
66
|
+
if fru.nil?
|
67
|
+
if list[DEFAULT_FRU].keys.include?(name)
|
68
|
+
return list[DEFAULT_FRU][name]
|
69
|
+
else
|
70
|
+
# maybe we should return nil instead? hmm...
|
71
|
+
raise NoMethodError
|
72
|
+
end
|
73
|
+
else
|
74
|
+
return fru
|
75
|
+
end
|
76
|
+
end
|
35
77
|
|
36
78
|
# parse the fru information
|
37
79
|
def parse(data)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
80
|
+
if ! data.nil? and ! data.empty?
|
81
|
+
parsed_data = []
|
82
|
+
data.lines.each do |line|
|
83
|
+
if line =~ /^FRU.*/
|
84
|
+
# this is the either the first line of of the fru or another fru
|
85
|
+
if parsed_data.count != 0
|
86
|
+
# we have reached a new fru device so lets record the previous fru
|
87
|
+
new_fru = FruData.new(parsed_data)
|
88
|
+
parsed_data = []
|
89
|
+
@list[new_fru[:name]] = new_fru
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
parsed_data << line
|
94
|
+
end
|
95
|
+
# process the last fru
|
96
|
+
if parsed_data.count != 0
|
97
|
+
# we have reached a new fru device so lets record the previous fru
|
98
|
+
new_fru = FruData.new(parsed_data)
|
99
|
+
parsed_data = []
|
100
|
+
@list[new_fru[:name]] = new_fru
|
101
|
+
end
|
45
102
|
end
|
46
|
-
return
|
103
|
+
return @list
|
47
104
|
end
|
48
105
|
|
49
106
|
# run the command and return result
|
@@ -56,4 +113,41 @@ module Rubyipmi::Freeipmi
|
|
56
113
|
|
57
114
|
end
|
58
115
|
|
116
|
+
class FruData < Hash
|
117
|
+
|
118
|
+
def name
|
119
|
+
self[:name]
|
120
|
+
end
|
121
|
+
|
122
|
+
def initialize(data)
|
123
|
+
parse(data)
|
124
|
+
end
|
125
|
+
|
126
|
+
# parse the fru information that should be an array of lines
|
127
|
+
def parse(data)
|
128
|
+
if ! data.nil?
|
129
|
+
data.each do |line|
|
130
|
+
key, value = line.split(':', 2)
|
131
|
+
if key =~ /^FRU.*/
|
132
|
+
if value =~ /([\w\s]*)\(.*\)/
|
133
|
+
self[:name] = $~[1].strip.gsub(/\ /, '_').downcase
|
134
|
+
end
|
135
|
+
else
|
136
|
+
key = key.strip.gsub(/\ /, '_').downcase.gsub(/fru_/, '')
|
137
|
+
if ! value.nil?
|
138
|
+
self[key] = value.strip
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def method_missing(method, *args, &block)
|
149
|
+
self.fetch(method.to_s, nil)
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
59
153
|
end
|
@@ -13,6 +13,7 @@ module Rubyipmi::Freeipmi
|
|
13
13
|
@channel = 2
|
14
14
|
end
|
15
15
|
|
16
|
+
|
16
17
|
def info
|
17
18
|
if @info.length < 1
|
18
19
|
parse(@config.section("Lan_Conf"))
|
@@ -22,45 +23,27 @@ module Rubyipmi::Freeipmi
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def dhcp?
|
25
|
-
|
26
|
-
parse(@config.section("Lan_Conf"))
|
27
|
-
end
|
28
|
-
@info["ip_address_source"].match(/dhcp/i) != nil
|
26
|
+
info.fetch("ip_address_source",nil).match(/dhcp/i) != nil
|
29
27
|
end
|
30
28
|
|
31
29
|
def static?
|
32
|
-
|
33
|
-
parse(@config.section("Lan_Conf"))
|
34
|
-
end
|
35
|
-
@info["ip_address_source"].match(/static/i) != nil
|
30
|
+
info.fetch("ip_address_source",nil).match(/static/i) != nil
|
36
31
|
end
|
37
32
|
|
38
33
|
def ip
|
39
|
-
|
40
|
-
parse(@config.section("Lan_Conf"))
|
41
|
-
end
|
42
|
-
@info["ip_address"]
|
34
|
+
info.fetch("ip_address", nil)
|
43
35
|
end
|
44
36
|
|
45
37
|
def mac
|
46
|
-
|
47
|
-
parse(@config.section("Lan_Conf"))
|
48
|
-
end
|
49
|
-
@info["mac_address"]
|
38
|
+
info.fetch("mac_address", nil)
|
50
39
|
end
|
51
40
|
|
52
41
|
def netmask
|
53
|
-
|
54
|
-
parse(@config.section("Lan_Conf"))
|
55
|
-
end
|
56
|
-
@info["subnet_mask"]
|
42
|
+
info.fetch("subnet_mask", nil)
|
57
43
|
end
|
58
44
|
|
59
45
|
def gateway
|
60
|
-
|
61
|
-
parse(@config.section("Lan_Conf"))
|
62
|
-
end
|
63
|
-
@info["default_gateway_ip_address"]
|
46
|
+
info.fetch("default_gateway_ip_address", nil)
|
64
47
|
end
|
65
48
|
|
66
49
|
# def snmp
|
@@ -75,16 +58,26 @@ module Rubyipmi::Freeipmi
|
|
75
58
|
#
|
76
59
|
# end
|
77
60
|
|
61
|
+
# validates that the address, returns true/false
|
62
|
+
def validaddr?(source)
|
63
|
+
valid = /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/.match("#{source}")
|
64
|
+
if valid.nil?
|
65
|
+
raise "#{source} is not a valid address"
|
66
|
+
else
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
78
71
|
def ip=(address)
|
79
|
-
|
72
|
+
@config.setsection("Lan_Conf", "IP_Address", address) if validaddr?(address)
|
80
73
|
end
|
81
74
|
|
82
75
|
def netmask=(netmask)
|
83
|
-
|
76
|
+
@config.setsection("Lan_Conf", "Subnet_Mask", netmask) if validaddr?(netmask)
|
84
77
|
end
|
85
78
|
|
86
79
|
def gateway=(address)
|
87
|
-
@config.setsection("Lan_Conf", "Default_Gateway_IP_Address", address)
|
80
|
+
@config.setsection("Lan_Conf", "Default_Gateway_IP_Address", address) if validaddr?(address)
|
88
81
|
end
|
89
82
|
|
90
83
|
# def vlanid=(vlan)
|
@@ -92,16 +85,18 @@ module Rubyipmi::Freeipmi
|
|
92
85
|
# end
|
93
86
|
|
94
87
|
def parse(landata)
|
95
|
-
landata.
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
88
|
+
if ! landata.nil? and ! landata.empty?
|
89
|
+
landata.lines.each do |line|
|
90
|
+
# clean up the data from spaces
|
91
|
+
next if line.match(/#+/)
|
92
|
+
next if line.match(/Section/i)
|
93
|
+
line.gsub!(/\t/, '')
|
94
|
+
item = line.split(/\s+/)
|
95
|
+
key = item.first.strip.downcase
|
96
|
+
value = item.last.strip
|
97
|
+
@info[key] = value
|
98
|
+
|
99
|
+
end
|
105
100
|
end
|
106
101
|
return @info
|
107
102
|
end
|