Module: Rubyipmi

Defined in:
lib/rubyipmi.rb,
lib/rubyipmi/version.rb,
lib/rubyipmi/observablehash.rb,
lib/rubyipmi/freeipmi/connection.rb,
lib/rubyipmi/ipmitool/connection.rb,
lib/rubyipmi/ipmitool/errorcodes.rb,
lib/rubyipmi/commands/basecommand.rb,
lib/rubyipmi/commands/mixins/power_mixin.rb,
lib/rubyipmi/commands/mixins/sensors_mixin.rb

Defined Under Namespace

Modules: Freeipmi, Ipmitool, PowerMixin, SensorsMixin Classes: BaseCommand, ObservableHash

Constant Summary collapse

PRIV_TYPES =
['CALLBACK', 'USER', 'OPERATOR', 'ADMINISTRATOR']
VERSION =
'0.11.1'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#log_levelObject

Returns the value of attribute log_level.



33
34
35
# File 'lib/rubyipmi.rb', line 33

def log_level
  @log_level
end

#loggerObject

Returns the value of attribute logger.



33
34
35
# File 'lib/rubyipmi.rb', line 33

def logger
  @logger
end

Class Method Details

.connect(user, pass, host, provider = 'any', opts = {:driver => 'lan20', :timeout => 'default'}) ⇒ Object

The connect method will create a connection object based the provider type passed in If provider is left blank the function will use the first available provider When the driver is set to auto, rubyipmi will try and figure out which driver to use by common error messages. We will most likely be using the lan20 driver, but in order to support a wide use case we default to auto.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/rubyipmi.rb', line 75

def self.connect(user, pass, host, provider = 'any', opts = {:driver => 'lan20', :timeout => 'default'})
  # use this variable to reduce cmd calls
  installed = false

  # if the user supplied nil, we want to fix this automatically
  opts = {:driver => 'lan20', :timeout => 'default'} if opts.nil?

  # convert all keys to symbols for opts, we can't assume the user will use symbols
  opts.keys.each do |key|
    opts[(key.to_sym rescue key) || key] = opts.delete(key)
  end

  # allow the user to specify an options hash instead of the provider
  # in the future I would stop using the provider and use the opts hash instead to get the provider
  # This allows us to be a little more flexible if the user is doesn't supply us what we need.
  if provider.kind_of?(Hash)
    opts = provider
    provider = opts[:provider] ||= 'any'
  end

  # Verify options just in case user passed in a incomplete hash
  opts[:driver] ||= 'lan20'
  opts[:timeout] ||= 'default'

  if opts[:privilege] && !supported_privilege_type?(opts[:privilege])
    logger.error("Invalid privilege type :#{opts[:privilege]}, must be one of: #{PRIV_TYPES.join("\n")}") if logger
    raise "Invalid privilege type :#{opts[:privilege]}, must be one of: #{PRIV_TYPES.join("\n")}"
  end

  # use the first available provider
  if provider == 'any'
    if is_provider_installed?("freeipmi")
      provider = "freeipmi"
      installed = true
    elsif is_provider_installed?("ipmitool")
      provider = "ipmitool"
      installed = true
    else
      logger.error("No IPMI provider is installed, please install freeipmi or ipmitool")
      raise "No IPMI provider is installed, please install freeipmi or ipmitool"
    end
  end

  # Support multiple drivers
  # Note: these are just generic names of drivers that need to be specified for each provider
  unless valid_drivers.include?(opts[:driver])
    logger.debug("You must specify a valid driver: #{valid_drivers.join(',')}") if logger
    raise "You must specify a valid driver: #{valid_drivers.join(',')}"
  end

  # If the provider is available create a connection object
  if installed || is_provider_installed?(provider)
    if provider == "freeipmi"
      Rubyipmi::Freeipmi::Connection.new(user, pass, host, opts)
    elsif provider == "ipmitool"
      Rubyipmi::Ipmitool::Connection.new(user, pass, host, opts)
    else
      logger.error("Incorrect provider given, must use one of #{valid_providers.join(', ')}") if logger
      raise "Incorrect provider given, must use one of #{valid_providers.join(', ')}"
    end
  else
    # Can't find the provider command line tool, maybe try other provider?
    logger.error("The IPMI provider: #{provider} is not installed") if logger
    raise "The IPMI provider: #{provider} is not installed"
  end
end

.get_diag(user, pass, host, opts = {:driver => 'lan20', :timeout => 'default'}) ⇒ Object

gets data from the bmc device and puts in a hash for diagnostics



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/rubyipmi.rb', line 187

def self.get_diag(user, pass, host, opts = {:driver => 'lan20', :timeout => 'default'})
  data = {}
  if Rubyipmi.is_provider_installed?('freeipmi')
    freeconn = Rubyipmi.connect(user, pass, host, 'freeipmi', opts)
    if freeconn
      puts "Retrieving freeipmi data"
      data[:freeipmi] = freeconn.get_diag
    end
  end
  if Rubyipmi.is_provider_installed?('ipmitool')
    ipmiconn = Rubyipmi.connect(user, pass, host, 'ipmitool', opts)
    if ipmiconn
      puts "Retrieving ipmitool data"
      data[:ipmitool] = ipmiconn.get_diag
    end
  end
  File.open('/tmp/rubyipmi_diag_data.txt', 'w') { |f| f.write(data) }
  puts "Created file /tmp/rubyipmi_diag_data.txt"
end

.is_provider_installed?(provider) ⇒ Boolean

Return true or false if the provider is available

Returns:

  • (Boolean)


155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rubyipmi.rb', line 155

def self.is_provider_installed?(provider)
  case provider
  when "freeipmi"
    cmdpath = locate_command('ipmipower')
  when "ipmitool"
    cmdpath = locate_command('ipmitool')
  else
    logger.error("Invalid BMC provider type #{provider}") if logger
    false
  end
  # return false if command was not found
  !cmdpath.nil?
end

.locate_command(commandname) ⇒ Object

method used to find the command which also makes it easier to mock with



148
149
150
151
152
# File 'lib/rubyipmi.rb', line 148

def self.locate_command(commandname)
  location = `which #{commandname}`.strip
  location = nil unless $?.success?
  location
end

.log_level=(level) ⇒ Object

sets the log level, this should be called first if logging to a file is desired if you wish to customize the logging options, set the logger yourself with logger= valid levels are of the type Logger::INFO, Logger::DEBUG, Logger::ERROR, …



44
45
46
# File 'lib/rubyipmi.rb', line 44

def self.log_level=(level)
  @log_level = level
end

.loggerObject

this is an read only method that only creates a real logger if the log_level is set if the log_level is not setup it creates a null logger which logs nothing



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rubyipmi.rb', line 50

def self.logger
  # by default the log will be set to info
  unless @logger
    if @log_level && @log_level >= 0
      @logger = Logger.new('/tmp/rubyipmi.log')
      @logger.progname = 'Rubyipmi'
      @logger.level = @log_level
    else
      @logger = NullLogger.new
    end
  end
  @logger
end

.logger=(log) ⇒ Object

set a logger instance yourself to customize where the logs should go you will need to set the log level yourself



37
38
39
# File 'lib/rubyipmi.rb', line 37

def self.logger=(log)
  @logger = log
end

.provider_installed?Boolean

returns true if any of the providers are installed

Returns:

  • (Boolean)


174
175
176
# File 'lib/rubyipmi.rb', line 174

def self.provider_installed?
  providers_installed.length > 0
end

.providersObject



169
170
171
# File 'lib/rubyipmi.rb', line 169

def self.providers
  ["freeipmi", "ipmitool"]
end

.providers_installedObject



178
179
180
181
182
183
184
# File 'lib/rubyipmi.rb', line 178

def self.providers_installed
  available = []
  providers.each do |prov|
    available << prov if is_provider_installed?(prov)
  end
  available
end

.supported_privilege_type?(type) ⇒ Boolean

returns boolean true if privilege type is valid

Returns:

  • (Boolean)


143
144
145
# File 'lib/rubyipmi.rb', line 143

def self.supported_privilege_type?(type)
  PRIV_TYPES.include?(type)
end

.valid_driversObject



64
65
66
# File 'lib/rubyipmi.rb', line 64

def self.valid_drivers
  ['auto', "lan15", "lan20", "open"]
end

.valid_providersObject



68
69
70
# File 'lib/rubyipmi.rb', line 68

def self.valid_providers
  ['auto', 'ipmitool', 'freeipmi']
end