rubyipmi 0.8.1 → 0.9.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 +4 -4
- data/Gemfile +5 -8
- data/README.md +92 -27
- data/Rakefile +1 -6
- data/VERSION +1 -1
- data/lib/rubyipmi.rb +69 -30
- data/lib/rubyipmi/commands/basecommand.rb +16 -18
- data/lib/rubyipmi/freeipmi/commands/basecommand.rb +2 -4
- data/lib/rubyipmi/freeipmi/commands/bmc.rb +7 -0
- data/lib/rubyipmi/freeipmi/commands/bmcconfig.rb +10 -0
- data/lib/rubyipmi/freeipmi/commands/bmcdevice.rb +1 -0
- data/lib/rubyipmi/freeipmi/commands/bmcinfo.rb +0 -3
- data/lib/rubyipmi/freeipmi/commands/chassis.rb +1 -0
- data/lib/rubyipmi/freeipmi/commands/chassisconfig.rb +0 -2
- data/lib/rubyipmi/freeipmi/commands/fru.rb +0 -1
- data/lib/rubyipmi/freeipmi/commands/lan.rb +22 -23
- data/lib/rubyipmi/freeipmi/commands/sensors.rb +8 -7
- data/lib/rubyipmi/freeipmi/connection.rb +14 -19
- data/lib/rubyipmi/freeipmi/errorcodes.rb +0 -1
- data/lib/rubyipmi/ipmitool/commands/basecommand.rb +0 -3
- data/lib/rubyipmi/ipmitool/commands/bmc.rb +8 -0
- data/lib/rubyipmi/ipmitool/commands/chassis.rb +1 -0
- data/lib/rubyipmi/ipmitool/commands/fru.rb +0 -7
- data/lib/rubyipmi/ipmitool/connection.rb +12 -13
- data/lib/rubyipmi/ipmitool/errorcodes.rb +2 -1
- data/rubyipmi.gemspec +21 -14
- data/spec/integration/bmc_spec.rb +9 -10
- data/spec/integration/chassis_config_spec.rb +6 -8
- data/spec/integration/chassis_spec.rb +3 -3
- data/spec/integration/connection_spec.rb +16 -15
- data/spec/integration/fru_spec.rb +6 -7
- data/spec/integration/lan_spec.rb +21 -34
- data/spec/integration/power_spec.rb +5 -5
- data/spec/integration/rubyipmi_spec.rb +63 -9
- data/spec/integration/sensor_spec.rb +7 -8
- data/spec/spec_helper.rb +10 -7
- data/spec/unit/freeipmi/bmc-info_spec.rb +5 -6
- data/spec/unit/freeipmi/bmc_spec.rb +8 -9
- data/spec/unit/freeipmi/connection_spec.rb +41 -23
- data/spec/unit/freeipmi/errorcodes_spec.rb +4 -10
- data/spec/unit/freeipmi/fru_spec.rb +15 -16
- data/spec/unit/freeipmi/sensors_spec.rb +17 -15
- data/spec/unit/ipmitool/bmc_spec.rb +11 -12
- data/spec/unit/ipmitool/connection_spec.rb +43 -21
- data/spec/unit/ipmitool/errorcodes_spec.rb +5 -4
- data/spec/unit/ipmitool/fru_spec.rb +15 -15
- data/spec/unit/ipmitool/lan_spec.rb +16 -15
- data/spec/unit/ipmitool/sensors_spec.rb +16 -15
- data/spec/unit/rubyipmi_spec.rb +6 -6
- metadata +64 -24
- data/README.rdoc +0 -18
@@ -1,5 +1,6 @@
|
|
1
1
|
require "observer"
|
2
2
|
require 'tempfile'
|
3
|
+
require 'rubyipmi'
|
3
4
|
|
4
5
|
module Rubyipmi
|
5
6
|
|
@@ -9,6 +10,10 @@ module Rubyipmi
|
|
9
10
|
attr_accessor :options, :passfile
|
10
11
|
attr_reader :lastcall, :result
|
11
12
|
|
13
|
+
def logger
|
14
|
+
Rubyipmi.logger
|
15
|
+
end
|
16
|
+
|
12
17
|
def makecommand
|
13
18
|
# override in subclass
|
14
19
|
end
|
@@ -35,23 +40,23 @@ module Rubyipmi
|
|
35
40
|
def locate_command(commandname)
|
36
41
|
location = `which #{commandname}`.strip
|
37
42
|
if not $?.success?
|
43
|
+
logger.error("#{commandname} command not found, is #{commandname} installed?") if logger
|
38
44
|
raise "#{commandname} command not found, is #{commandname} installed?"
|
39
45
|
end
|
40
|
-
|
46
|
+
location
|
41
47
|
end
|
42
48
|
|
43
49
|
# Use this function to run the command line tool, it will inherently use the options hash for all options
|
44
50
|
# That need to be specified on the command line
|
45
|
-
def runcmd
|
51
|
+
def runcmd
|
46
52
|
@success = false
|
47
|
-
@success = run
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
return @success
|
53
|
+
@success = run
|
54
|
+
logger.debug(@lastcall.inspect) unless @lastcall.nil? if logger
|
55
|
+
logger.debug(@result) unless @result.nil? if logger
|
56
|
+
@success
|
52
57
|
end
|
53
58
|
|
54
|
-
def run
|
59
|
+
def run
|
55
60
|
# we search for the command everytime just in case its removed during execution
|
56
61
|
# we also don't want to add this to the initialize since mocking is difficult and we don't want to
|
57
62
|
# throw errors upon object creation
|
@@ -60,11 +65,7 @@ module Rubyipmi
|
|
60
65
|
@cmd = locate_command(@cmdname)
|
61
66
|
setpass
|
62
67
|
@result = nil
|
63
|
-
if
|
64
|
-
# Log error
|
65
|
-
return makecommand
|
66
|
-
end
|
67
|
-
|
68
|
+
logger.debug(makecommand) if logger
|
68
69
|
begin
|
69
70
|
command = makecommand
|
70
71
|
@lastcall = "#{command}"
|
@@ -78,14 +79,13 @@ module Rubyipmi
|
|
78
79
|
retrycount = retrycount.next
|
79
80
|
retry
|
80
81
|
else
|
82
|
+
logger.error("Exhausted all auto fixes, cannot determine what the problem is") if logger
|
81
83
|
raise "Exhausted all auto fixes, cannot determine what the problem is"
|
82
84
|
end
|
83
85
|
ensure
|
84
86
|
removepass
|
85
87
|
return process_status
|
86
|
-
|
87
88
|
end
|
88
|
-
|
89
89
|
end
|
90
90
|
|
91
91
|
# The findfix method acts like a recursive method and applies fixes defined in the errorcodes
|
@@ -98,8 +98,8 @@ module Rubyipmi
|
|
98
98
|
begin
|
99
99
|
fix = ErrorCodes.search(result)
|
100
100
|
@options.merge_notify!(fix)
|
101
|
-
|
102
101
|
rescue
|
102
|
+
Rubyipmi.logger.debug("Could not find fix for error code: \n#{result}") if logger
|
103
103
|
raise "Could not find fix for error code: \n#{result}"
|
104
104
|
end
|
105
105
|
end
|
@@ -118,7 +118,5 @@ module Rubyipmi
|
|
118
118
|
return true
|
119
119
|
end
|
120
120
|
end
|
121
|
-
|
122
|
-
|
123
121
|
end
|
124
122
|
end
|
@@ -10,7 +10,6 @@ module Rubyipmi::Freeipmi
|
|
10
10
|
@passfile.write "username #{@options["username"]}\n"
|
11
11
|
@passfile.write "password #{@options["password"]}\n"
|
12
12
|
@passfile.close
|
13
|
-
|
14
13
|
end
|
15
14
|
|
16
15
|
def max_retry_count
|
@@ -33,6 +32,7 @@ module Rubyipmi::Freeipmi
|
|
33
32
|
end
|
34
33
|
|
35
34
|
# This method will check if the results are really valid as the exit code can be misleading and incorrect
|
35
|
+
# this is required because freeipmi in older version always returned 0 even if an error occured
|
36
36
|
def validate_status(exitstatus)
|
37
37
|
case @cmdname
|
38
38
|
when "ipmipower"
|
@@ -42,7 +42,7 @@ module Rubyipmi::Freeipmi
|
|
42
42
|
raise "Error occurred"
|
43
43
|
end
|
44
44
|
when "bmc-config"
|
45
|
-
if @result.length > 100
|
45
|
+
if @result.length > 100 and exitstatus.success?
|
46
46
|
return true
|
47
47
|
else
|
48
48
|
raise "Error occurred"
|
@@ -53,7 +53,6 @@ module Rubyipmi::Freeipmi
|
|
53
53
|
else
|
54
54
|
raise "Error occurred"
|
55
55
|
end
|
56
|
-
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
@@ -66,7 +65,6 @@ module Rubyipmi::Freeipmi
|
|
66
65
|
begin
|
67
66
|
fix = ErrorCodes.search(result)
|
68
67
|
@options.merge_notify!(fix)
|
69
|
-
|
70
68
|
rescue
|
71
69
|
raise "Could not find fix for error code: \n#{result}"
|
72
70
|
end
|
@@ -8,6 +8,14 @@ module Rubyipmi::Freeipmi
|
|
8
8
|
|
9
9
|
end
|
10
10
|
|
11
|
+
def verbose(on=false)
|
12
|
+
if on
|
13
|
+
@options['verbose'] = false
|
14
|
+
else
|
15
|
+
@options.delete_notify('verbose')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
11
19
|
def section(section)
|
12
20
|
@options["checkout"] = false
|
13
21
|
@options["section"] = section
|
@@ -33,6 +41,8 @@ module Rubyipmi::Freeipmi
|
|
33
41
|
|
34
42
|
# returns the entire bmc-config configuration, can take a while to execute
|
35
43
|
def configuration
|
44
|
+
require 'pry'
|
45
|
+
binding.pry
|
36
46
|
@options["checkout"] = false
|
37
47
|
value = runcmd
|
38
48
|
@options.delete_notify("checkout")
|
@@ -43,6 +43,7 @@ module Rubyipmi::Freeipmi
|
|
43
43
|
end
|
44
44
|
|
45
45
|
else
|
46
|
+
logger.error("Device with name: #{device} is not a valid boot device for host #{options["hostname"]}") if logger
|
46
47
|
raise "Device with name: #{device} is not a valid boot device for host #{options["hostname"]}"
|
47
48
|
end
|
48
49
|
end
|
@@ -8,18 +8,17 @@ module Rubyipmi::Freeipmi
|
|
8
8
|
|
9
9
|
def initialize(opts)
|
10
10
|
@config = Rubyipmi::Freeipmi::BmcConfig.new(opts)
|
11
|
-
|
12
11
|
@info = {}
|
13
12
|
@channel = 2
|
14
13
|
end
|
15
14
|
|
16
|
-
|
17
15
|
def info
|
18
16
|
if @info.length < 1
|
17
|
+
@config.verbose(true)
|
19
18
|
parse(@config.section("Lan_Conf"))
|
20
|
-
|
21
|
-
@info
|
19
|
+
@config.verbose(false)
|
22
20
|
end
|
21
|
+
@info
|
23
22
|
end
|
24
23
|
|
25
24
|
def dhcp?
|
@@ -46,17 +45,20 @@ module Rubyipmi::Freeipmi
|
|
46
45
|
info.fetch("default_gateway_ip_address", nil)
|
47
46
|
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
# def snmp
|
49
|
+
#
|
50
|
+
# end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
def vlanid
|
53
|
+
info.fetch("vlan_id", nil)
|
54
|
+
# some other vlan configuration that might also be useful
|
55
|
+
# "vlan_id_enable"
|
56
|
+
# "vlan_priority"
|
57
|
+
end
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
-
|
59
|
+
# def snmp=(community)
|
60
|
+
#
|
61
|
+
# end
|
60
62
|
|
61
63
|
# validates that the address, returns true/false
|
62
64
|
def validaddr?(source)
|
@@ -69,20 +71,20 @@ module Rubyipmi::Freeipmi
|
|
69
71
|
end
|
70
72
|
|
71
73
|
def ip=(address)
|
72
|
-
|
74
|
+
@config.setsection("Lan_Conf", "IP_Address", address) if validaddr?(address)
|
73
75
|
end
|
74
76
|
|
75
77
|
def netmask=(netmask)
|
76
|
-
|
78
|
+
@config.setsection("Lan_Conf", "Subnet_Mask", netmask) if validaddr?(netmask)
|
77
79
|
end
|
78
80
|
|
79
81
|
def gateway=(address)
|
80
82
|
@config.setsection("Lan_Conf", "Default_Gateway_IP_Address", address) if validaddr?(address)
|
81
83
|
end
|
82
84
|
|
83
|
-
|
84
|
-
|
85
|
-
|
85
|
+
# def vlanid=(vlan)
|
86
|
+
#
|
87
|
+
# end
|
86
88
|
|
87
89
|
def parse(landata)
|
88
90
|
if ! landata.nil? and ! landata.empty?
|
@@ -95,12 +97,9 @@ module Rubyipmi::Freeipmi
|
|
95
97
|
key = item.first.strip.downcase
|
96
98
|
value = item.last.strip
|
97
99
|
@info[key] = value
|
98
|
-
|
99
100
|
end
|
100
101
|
end
|
101
|
-
|
102
|
+
@info
|
102
103
|
end
|
103
104
|
end
|
104
|
-
end
|
105
|
-
|
106
|
-
|
105
|
+
end
|
@@ -4,9 +4,6 @@ module Rubyipmi::Freeipmi
|
|
4
4
|
|
5
5
|
def initialize(opts = ObservableHash.new)
|
6
6
|
super("ipmi-sensors", opts)
|
7
|
-
@options["no-header-output"] = false
|
8
|
-
@options["output-sensor-state"] = false
|
9
|
-
@options["entity-sensor-names"] = false
|
10
7
|
end
|
11
8
|
|
12
9
|
def refresh
|
@@ -51,8 +48,14 @@ module Rubyipmi::Freeipmi
|
|
51
48
|
end
|
52
49
|
|
53
50
|
def getsensors
|
51
|
+
@options["no-header-output"] = false
|
52
|
+
@options["output-sensor-state"] = false
|
53
|
+
@options["entity-sensor-names"] = false
|
54
54
|
value = runcmd
|
55
|
-
|
55
|
+
@options.delete_notify('no-header-output')
|
56
|
+
@options.delete_notify('output-sensor-state')
|
57
|
+
@options.delete_notify('entity-sensor-names')
|
58
|
+
@result
|
56
59
|
end
|
57
60
|
|
58
61
|
private
|
@@ -106,6 +109,4 @@ module Rubyipmi::Freeipmi
|
|
106
109
|
end
|
107
110
|
end
|
108
111
|
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
+
end
|
@@ -8,14 +8,10 @@ Dir[File.dirname(__FILE__) + '/commands/*.rb'].each do |file|
|
|
8
8
|
end
|
9
9
|
module Rubyipmi
|
10
10
|
module Freeipmi
|
11
|
-
|
12
11
|
class Connection
|
13
|
-
|
14
|
-
attr_accessor :options, :debug
|
15
|
-
|
12
|
+
attr_accessor :options
|
16
13
|
|
17
14
|
def initialize(user, pass, host, opts)
|
18
|
-
@debug = opts[:debug]
|
19
15
|
@options = Rubyipmi::ObservableHash.new
|
20
16
|
raise("Must provide a host to connect to") unless host
|
21
17
|
@options["hostname"] = host
|
@@ -27,10 +23,15 @@ module Rubyipmi
|
|
27
23
|
@options["privilege-level"] = opts[:privilege] # privilege type
|
28
24
|
end
|
29
25
|
# Note: rubyipmi should auto detect which driver to use so its unnecessary to specify the driver unless
|
30
|
-
# the user really wants to
|
26
|
+
# the user really wants to
|
31
27
|
@options['driver-type'] = drivers_map[opts[:driver]] unless drivers_map[opts[:driver]].nil?
|
32
28
|
end
|
33
29
|
|
30
|
+
# test the connection to ensure we can at least make a single call
|
31
|
+
def connection_works?
|
32
|
+
status = ! (bmc.info.nil? || bmc.info.empty? )
|
33
|
+
end
|
34
|
+
|
34
35
|
def drivers_map
|
35
36
|
{
|
36
37
|
'lan15' => 'LAN',
|
@@ -61,19 +62,13 @@ module Rubyipmi
|
|
61
62
|
|
62
63
|
def get_diag
|
63
64
|
data = {}
|
64
|
-
data[
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
71
|
-
if @bmc
|
72
|
-
data['bmc_info'] = @bmc.info
|
73
|
-
end
|
65
|
+
data[:provider] = provider
|
66
|
+
data[:frus] = fru.getfrus
|
67
|
+
data[:sensors] = sensors.getsensors
|
68
|
+
data[:bmc_info] = bmc.info
|
69
|
+
data[:version] = bmc.version
|
70
|
+
data
|
74
71
|
end
|
75
|
-
|
76
72
|
end
|
77
73
|
end
|
78
|
-
end
|
79
|
-
|
74
|
+
end
|
@@ -21,6 +21,13 @@ module Rubyipmi::Ipmitool
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def version
|
25
|
+
@options['V'] = nil
|
26
|
+
value = runcmd
|
27
|
+
@options.delete_notify('V')
|
28
|
+
@result.slice(/\d\.\d.\d/)
|
29
|
+
end
|
30
|
+
|
24
31
|
# reset the bmc device, useful for troubleshooting
|
25
32
|
def reset(type='cold')
|
26
33
|
if ['cold', 'warm'].include?(type)
|
@@ -29,6 +36,7 @@ module Rubyipmi::Ipmitool
|
|
29
36
|
@options.delete_notify("cmdargs")
|
30
37
|
return value
|
31
38
|
else
|
39
|
+
logger.error("reset type: #{type} is not a valid choice, use warm or cold") if logger
|
32
40
|
raise "reset type: #{type} is not a valid choice, use warm or cold"
|
33
41
|
end
|
34
42
|
|