Many bug fixes (mainly on the IPMI driver).

Change-Id: I05fa1fa8d34daa212c3cc51d5960e72eebfa82b7
This commit is contained in:
François Rossigneux 2013-02-19 18:32:36 +01:00
parent d0869dcf7d
commit a5ad06da44
5 changed files with 57 additions and 28 deletions

View File

@ -40,8 +40,8 @@ class Dummy(Driver):
def run(self):
"""Starts the driver thread."""
while not self.stop_request_pending():
measurements = {}
for probe_id in self.probe_ids:
measurements = {}
measurements['w'] = randrange(self.min_value, self.max_value)
measurements['v'] = 230.0
measurements['a'] = measurements['w'] / measurements['v']

View File

@ -20,8 +20,11 @@ import subprocess
import time
import uuid
from kwapi.openstack.common import log
from driver import Driver
LOG = log.getLogger(__name__)
class Ipmi(Driver):
"""Driver for IPMI cards."""
@ -40,11 +43,12 @@ class Ipmi(Driver):
def run(self):
"""Starts the driver thread."""
self.create_cache()
measurements = {}
while not self.stop_request_pending():
measurements = {}
measurements['w'] = self.get_watts()
self.send_measurements(self.probe_ids[0], measurements)
watts = self.get_watts()
if watts is not None:
measurements['w'] = watts
self.send_measurements(self.probe_ids[0], measurements)
time.sleep(1)
def get_cache_filename(self):
@ -54,6 +58,7 @@ class Ipmi(Driver):
def create_cache(self):
"""Creates the cache file."""
cache_file = self.get_cache_filename()
try:
os.makedirs(self.kwargs.get('cache_dir'))
except OSError as exception:
@ -64,28 +69,47 @@ class Ipmi(Driver):
command += '-H ' + self.kwargs.get('host') + ' '
command += '-U ' + self.kwargs.get('username', 'root') + ' '
command += '-P ' + self.kwargs.get('password') + ' '
command += 'sdr dump ' + self.get_cache_filename()
output, error = subprocess.Popen(command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
).communicate()
command += 'sdr dump ' + cache_file
child = subprocess.Popen(command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
output, error = child.communicate()
if child.returncode == 0:
return cache_file
else:
LOG.error('Failed to download cache from probe %s: %s'
% (self.probe_ids[0], error))
return None
def get_watts(self):
"""Returns the power consumption."""
cache_file = self.get_cache_filename()
# Try to create cache (not a problem if this fails)
if not os.path.exists(cache_file):
self.create_cache()
# Get power consumption
command = 'ipmitool '
command += '-S ' + cache_file + ' '
command += '-I ' + self.kwargs.get('interface') + ' '
command += '-H ' + self.kwargs.get('host') + ' '
command += '-U ' + self.kwargs.get('username', 'root') + ' '
command += '-P ' + self.kwargs.get('password') + ' '
command += 'sensor reading "System Level" | cut -f2 -d"|"'
output, error = subprocess.Popen(command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
).communicate()
return int(output)
command += 'sensor reading "System Level"'
child = subprocess.Popen(command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
output, error = child.communicate()
if child.returncode == 0:
try:
return int(output.split('|')[1])
except ValueError:
LOG.error('Received data from probe %s are invalid: %s'
% (self.probe_ids[0], output))
else:
LOG.error('Failed to retrieve data from probe %s: %s'
% (self.probe_ids[0], error))
return None

View File

@ -34,33 +34,31 @@ class Wattsup(Driver):
"""
Driver.__init__(self, probe_ids, kwargs)
def run(self):
"""Starts the driver thread."""
# Configure serial port
self.serial = serial.Serial(
port=kwargs.get('device', '/dev/ttyUSB0'),
port=self.kwargs.get('device', '/dev/ttyUSB0'),
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=2,
)
# Clear memory
self.serial.write('#R,W,0;')
self.serial.read(256)
# Start external logging with interval = 1
self.serial.write('#L,W,3,E,1,1;')
self.serial.read(256)
def run(self):
"""Starts the driver thread."""
# Take measurements
measurements = {}
while not self.stop_request_pending():
try:
packet = self.get_packet()
except SerialException:
self.serial.close()
self.stop()
measurements = {}
measurements['w'] = self.extract_watts(packet)
self.send_measurements(self.probe_ids[0], measurements)

View File

@ -143,5 +143,8 @@ class Collector:
try:
self.add(measurements['probe_id'],
float(measurements['w']))
except (TypeError, ValueError):
LOG.error('Malformed power consumption data: %s'
% measurements['w'])
except KeyError:
LOG.error('Malformed message (missing required key)')

View File

@ -135,7 +135,7 @@ def update_rrd(probe, watts):
create_rrd_file(filename)
try:
rrdtool.update(filename, 'N:%s' % watts)
except rrdtool.error, e:
except rrdtool.error as e:
LOG.error('Error updating RRD: %s' % e)
@ -277,10 +277,14 @@ def listen():
try:
probe = measurements['probe_id'].encode('utf-8')
update_rrd(probe, float(measurements['w']))
except (TypeError, ValueError):
LOG.error('Malformed power consumption data: %s'
% measurements['w'])
except KeyError:
LOG.error('Malformed message (missing required key)')
else:
if not probe in probes:
probes.add(probe)
color_seq = itertools.cycle(colors)
for probe in sorted(probes):
probe_colors[probe] = color_seq.next()
except KeyError:
LOG.error('Malformed message (missing required key)')