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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -8
  3. data/README.md +92 -27
  4. data/Rakefile +1 -6
  5. data/VERSION +1 -1
  6. data/lib/rubyipmi.rb +69 -30
  7. data/lib/rubyipmi/commands/basecommand.rb +16 -18
  8. data/lib/rubyipmi/freeipmi/commands/basecommand.rb +2 -4
  9. data/lib/rubyipmi/freeipmi/commands/bmc.rb +7 -0
  10. data/lib/rubyipmi/freeipmi/commands/bmcconfig.rb +10 -0
  11. data/lib/rubyipmi/freeipmi/commands/bmcdevice.rb +1 -0
  12. data/lib/rubyipmi/freeipmi/commands/bmcinfo.rb +0 -3
  13. data/lib/rubyipmi/freeipmi/commands/chassis.rb +1 -0
  14. data/lib/rubyipmi/freeipmi/commands/chassisconfig.rb +0 -2
  15. data/lib/rubyipmi/freeipmi/commands/fru.rb +0 -1
  16. data/lib/rubyipmi/freeipmi/commands/lan.rb +22 -23
  17. data/lib/rubyipmi/freeipmi/commands/sensors.rb +8 -7
  18. data/lib/rubyipmi/freeipmi/connection.rb +14 -19
  19. data/lib/rubyipmi/freeipmi/errorcodes.rb +0 -1
  20. data/lib/rubyipmi/ipmitool/commands/basecommand.rb +0 -3
  21. data/lib/rubyipmi/ipmitool/commands/bmc.rb +8 -0
  22. data/lib/rubyipmi/ipmitool/commands/chassis.rb +1 -0
  23. data/lib/rubyipmi/ipmitool/commands/fru.rb +0 -7
  24. data/lib/rubyipmi/ipmitool/connection.rb +12 -13
  25. data/lib/rubyipmi/ipmitool/errorcodes.rb +2 -1
  26. data/rubyipmi.gemspec +21 -14
  27. data/spec/integration/bmc_spec.rb +9 -10
  28. data/spec/integration/chassis_config_spec.rb +6 -8
  29. data/spec/integration/chassis_spec.rb +3 -3
  30. data/spec/integration/connection_spec.rb +16 -15
  31. data/spec/integration/fru_spec.rb +6 -7
  32. data/spec/integration/lan_spec.rb +21 -34
  33. data/spec/integration/power_spec.rb +5 -5
  34. data/spec/integration/rubyipmi_spec.rb +63 -9
  35. data/spec/integration/sensor_spec.rb +7 -8
  36. data/spec/spec_helper.rb +10 -7
  37. data/spec/unit/freeipmi/bmc-info_spec.rb +5 -6
  38. data/spec/unit/freeipmi/bmc_spec.rb +8 -9
  39. data/spec/unit/freeipmi/connection_spec.rb +41 -23
  40. data/spec/unit/freeipmi/errorcodes_spec.rb +4 -10
  41. data/spec/unit/freeipmi/fru_spec.rb +15 -16
  42. data/spec/unit/freeipmi/sensors_spec.rb +17 -15
  43. data/spec/unit/ipmitool/bmc_spec.rb +11 -12
  44. data/spec/unit/ipmitool/connection_spec.rb +43 -21
  45. data/spec/unit/ipmitool/errorcodes_spec.rb +5 -4
  46. data/spec/unit/ipmitool/fru_spec.rb +15 -15
  47. data/spec/unit/ipmitool/lan_spec.rb +16 -15
  48. data/spec/unit/ipmitool/sensors_spec.rb +16 -15
  49. data/spec/unit/rubyipmi_spec.rb +6 -6
  50. metadata +64 -24
  51. 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
- return location
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(debug=false)
51
+ def runcmd
46
52
  @success = false
47
- @success = run(debug)
48
- if ENV['rubyipmi_debug'] == 'true'
49
- puts @lastcall.inspect unless @lastcall.nil?
50
- end
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(debug=false)
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 debug
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
@@ -10,6 +10,13 @@ module Rubyipmi::Freeipmi
10
10
  @bmcinfo = {}
11
11
  end
12
12
 
13
+ def version
14
+ @options['version'] = false
15
+ value = runcmd
16
+ @options.delete_notify('version')
17
+ @result.slice(/\d\.\d.\d/)
18
+ end
19
+
13
20
  def info
14
21
  if @bmcinfo.length > 0
15
22
  @bmcinfo
@@ -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")
@@ -20,6 +20,7 @@ module Rubyipmi::Freeipmi
20
20
  key = "#{type}-reset"
21
21
  command(key)
22
22
  else
23
+ logger.error("reset type: #{type} is not a valid choice, use warm or cold") if logger
23
24
  raise "reset type: #{type} is not a valid choice, use warm or cold"
24
25
  end
25
26
  end
@@ -7,7 +7,6 @@ module Rubyipmi::Freeipmi
7
7
 
8
8
  end
9
9
 
10
-
11
10
  def guid
12
11
  options["get-device-guid"] = false
13
12
  status = runcmd
@@ -48,8 +47,6 @@ module Rubyipmi::Freeipmi
48
47
  return bmcinfo
49
48
  end
50
49
  end
51
-
52
-
53
50
  end
54
51
  end
55
52
 
@@ -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
@@ -62,8 +62,6 @@ module Rubyipmi::Freeipmi
62
62
  return value
63
63
  end
64
64
 
65
-
66
-
67
65
  # shortcut to set boot device to pxe
68
66
  def bootpxe(persistent=true)
69
67
  bootdevice("PXE",persistent)
@@ -21,7 +21,6 @@ module Rubyipmi::Freeipmi
21
21
  end
22
22
  end
23
23
 
24
-
25
24
  def manufacturer
26
25
  get_from_list('board_manufacturer')
27
26
  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
- else
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
- # def snmp
50
- #
51
- # end
48
+ # def snmp
49
+ #
50
+ # end
52
51
 
53
- # def vlanid
54
- #
55
- # end
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
- # def snmp=(community)
58
- #
59
- # end
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
- @config.setsection("Lan_Conf", "IP_Address", address) if validaddr?(address)
74
+ @config.setsection("Lan_Conf", "IP_Address", address) if validaddr?(address)
73
75
  end
74
76
 
75
77
  def netmask=(netmask)
76
- @config.setsection("Lan_Conf", "Subnet_Mask", netmask) if validaddr?(netmask)
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
- # def vlanid=(vlan)
84
- #
85
- # end
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
- return @info
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
- return @result
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['provider'] = provider
65
- if @fru
66
- data['frus'] = @fru.getfrus
67
- end
68
- if @sensors
69
- data['sensors'] = @sensors.getsensors
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
@@ -5,7 +5,6 @@ module Rubyipmi::Freeipmi
5
5
  @@codes = {
6
6
  "authentication type unavailable for attempted privilege level" => {"driver-type" => "LAN_2_0"},
7
7
  "authentication type unavailable for attempted privilege level\n" => {"driver-type" => "LAN_2_0"},
8
-
9
8
  }
10
9
 
11
10
  def self.length
@@ -48,8 +48,5 @@ module Rubyipmi::Ipmitool
48
48
  end
49
49
  end
50
50
  end
51
-
52
51
  end
53
-
54
-
55
52
  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