Many bug fixes (mainly on the IPMI driver).
Change-Id: I05fa1fa8d34daa212c3cc51d5960e72eebfa82b7
This commit is contained in:
parent
d0869dcf7d
commit
a5ad06da44
|
@ -40,8 +40,8 @@ class Dummy(Driver):
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Starts the driver thread."""
|
"""Starts the driver thread."""
|
||||||
while not self.stop_request_pending():
|
while not self.stop_request_pending():
|
||||||
|
measurements = {}
|
||||||
for probe_id in self.probe_ids:
|
for probe_id in self.probe_ids:
|
||||||
measurements = {}
|
|
||||||
measurements['w'] = randrange(self.min_value, self.max_value)
|
measurements['w'] = randrange(self.min_value, self.max_value)
|
||||||
measurements['v'] = 230.0
|
measurements['v'] = 230.0
|
||||||
measurements['a'] = measurements['w'] / measurements['v']
|
measurements['a'] = measurements['w'] / measurements['v']
|
||||||
|
|
|
@ -20,8 +20,11 @@ import subprocess
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from kwapi.openstack.common import log
|
||||||
from driver import Driver
|
from driver import Driver
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Ipmi(Driver):
|
class Ipmi(Driver):
|
||||||
"""Driver for IPMI cards."""
|
"""Driver for IPMI cards."""
|
||||||
|
@ -40,11 +43,12 @@ class Ipmi(Driver):
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Starts the driver thread."""
|
"""Starts the driver thread."""
|
||||||
self.create_cache()
|
measurements = {}
|
||||||
while not self.stop_request_pending():
|
while not self.stop_request_pending():
|
||||||
measurements = {}
|
watts = self.get_watts()
|
||||||
measurements['w'] = self.get_watts()
|
if watts is not None:
|
||||||
self.send_measurements(self.probe_ids[0], measurements)
|
measurements['w'] = watts
|
||||||
|
self.send_measurements(self.probe_ids[0], measurements)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def get_cache_filename(self):
|
def get_cache_filename(self):
|
||||||
|
@ -54,6 +58,7 @@ class Ipmi(Driver):
|
||||||
|
|
||||||
def create_cache(self):
|
def create_cache(self):
|
||||||
"""Creates the cache file."""
|
"""Creates the cache file."""
|
||||||
|
cache_file = self.get_cache_filename()
|
||||||
try:
|
try:
|
||||||
os.makedirs(self.kwargs.get('cache_dir'))
|
os.makedirs(self.kwargs.get('cache_dir'))
|
||||||
except OSError as exception:
|
except OSError as exception:
|
||||||
|
@ -64,28 +69,47 @@ class Ipmi(Driver):
|
||||||
command += '-H ' + self.kwargs.get('host') + ' '
|
command += '-H ' + self.kwargs.get('host') + ' '
|
||||||
command += '-U ' + self.kwargs.get('username', 'root') + ' '
|
command += '-U ' + self.kwargs.get('username', 'root') + ' '
|
||||||
command += '-P ' + self.kwargs.get('password') + ' '
|
command += '-P ' + self.kwargs.get('password') + ' '
|
||||||
command += 'sdr dump ' + self.get_cache_filename()
|
command += 'sdr dump ' + cache_file
|
||||||
output, error = subprocess.Popen(command,
|
child = subprocess.Popen(command,
|
||||||
shell=True,
|
shell=True,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.STDOUT
|
stderr=subprocess.PIPE
|
||||||
).communicate()
|
)
|
||||||
|
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):
|
def get_watts(self):
|
||||||
"""Returns the power consumption."""
|
"""Returns the power consumption."""
|
||||||
cache_file = self.get_cache_filename()
|
cache_file = self.get_cache_filename()
|
||||||
|
# Try to create cache (not a problem if this fails)
|
||||||
if not os.path.exists(cache_file):
|
if not os.path.exists(cache_file):
|
||||||
self.create_cache()
|
self.create_cache()
|
||||||
|
# Get power consumption
|
||||||
command = 'ipmitool '
|
command = 'ipmitool '
|
||||||
command += '-S ' + cache_file + ' '
|
command += '-S ' + cache_file + ' '
|
||||||
command += '-I ' + self.kwargs.get('interface') + ' '
|
command += '-I ' + self.kwargs.get('interface') + ' '
|
||||||
command += '-H ' + self.kwargs.get('host') + ' '
|
command += '-H ' + self.kwargs.get('host') + ' '
|
||||||
command += '-U ' + self.kwargs.get('username', 'root') + ' '
|
command += '-U ' + self.kwargs.get('username', 'root') + ' '
|
||||||
command += '-P ' + self.kwargs.get('password') + ' '
|
command += '-P ' + self.kwargs.get('password') + ' '
|
||||||
command += 'sensor reading "System Level" | cut -f2 -d"|"'
|
command += 'sensor reading "System Level"'
|
||||||
output, error = subprocess.Popen(command,
|
child = subprocess.Popen(command,
|
||||||
shell=True,
|
shell=True,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.STDOUT
|
stderr=subprocess.PIPE
|
||||||
).communicate()
|
)
|
||||||
return int(output)
|
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
|
||||||
|
|
|
@ -34,33 +34,31 @@ class Wattsup(Driver):
|
||||||
"""
|
"""
|
||||||
Driver.__init__(self, probe_ids, kwargs)
|
Driver.__init__(self, probe_ids, kwargs)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Starts the driver thread."""
|
||||||
# Configure serial port
|
# Configure serial port
|
||||||
self.serial = serial.Serial(
|
self.serial = serial.Serial(
|
||||||
port=kwargs.get('device', '/dev/ttyUSB0'),
|
port=self.kwargs.get('device', '/dev/ttyUSB0'),
|
||||||
baudrate=115200,
|
baudrate=115200,
|
||||||
parity=serial.PARITY_NONE,
|
parity=serial.PARITY_NONE,
|
||||||
stopbits=serial.STOPBITS_ONE,
|
stopbits=serial.STOPBITS_ONE,
|
||||||
bytesize=serial.EIGHTBITS,
|
bytesize=serial.EIGHTBITS,
|
||||||
timeout=2,
|
timeout=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Clear memory
|
# Clear memory
|
||||||
self.serial.write('#R,W,0;')
|
self.serial.write('#R,W,0;')
|
||||||
self.serial.read(256)
|
self.serial.read(256)
|
||||||
|
|
||||||
# Start external logging with interval = 1
|
# Start external logging with interval = 1
|
||||||
self.serial.write('#L,W,3,E,1,1;')
|
self.serial.write('#L,W,3,E,1,1;')
|
||||||
self.serial.read(256)
|
self.serial.read(256)
|
||||||
|
# Take measurements
|
||||||
def run(self):
|
measurements = {}
|
||||||
"""Starts the driver thread."""
|
|
||||||
while not self.stop_request_pending():
|
while not self.stop_request_pending():
|
||||||
try:
|
try:
|
||||||
packet = self.get_packet()
|
packet = self.get_packet()
|
||||||
except SerialException:
|
except SerialException:
|
||||||
self.serial.close()
|
self.serial.close()
|
||||||
self.stop()
|
self.stop()
|
||||||
measurements = {}
|
|
||||||
measurements['w'] = self.extract_watts(packet)
|
measurements['w'] = self.extract_watts(packet)
|
||||||
self.send_measurements(self.probe_ids[0], measurements)
|
self.send_measurements(self.probe_ids[0], measurements)
|
||||||
|
|
||||||
|
|
|
@ -143,5 +143,8 @@ class Collector:
|
||||||
try:
|
try:
|
||||||
self.add(measurements['probe_id'],
|
self.add(measurements['probe_id'],
|
||||||
float(measurements['w']))
|
float(measurements['w']))
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
LOG.error('Malformed power consumption data: %s'
|
||||||
|
% measurements['w'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
LOG.error('Malformed message (missing required key)')
|
LOG.error('Malformed message (missing required key)')
|
||||||
|
|
|
@ -135,7 +135,7 @@ def update_rrd(probe, watts):
|
||||||
create_rrd_file(filename)
|
create_rrd_file(filename)
|
||||||
try:
|
try:
|
||||||
rrdtool.update(filename, 'N:%s' % watts)
|
rrdtool.update(filename, 'N:%s' % watts)
|
||||||
except rrdtool.error, e:
|
except rrdtool.error as e:
|
||||||
LOG.error('Error updating RRD: %s' % e)
|
LOG.error('Error updating RRD: %s' % e)
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,10 +277,14 @@ def listen():
|
||||||
try:
|
try:
|
||||||
probe = measurements['probe_id'].encode('utf-8')
|
probe = measurements['probe_id'].encode('utf-8')
|
||||||
update_rrd(probe, float(measurements['w']))
|
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:
|
if not probe in probes:
|
||||||
probes.add(probe)
|
probes.add(probe)
|
||||||
color_seq = itertools.cycle(colors)
|
color_seq = itertools.cycle(colors)
|
||||||
for probe in sorted(probes):
|
for probe in sorted(probes):
|
||||||
probe_colors[probe] = color_seq.next()
|
probe_colors[probe] = color_seq.next()
|
||||||
except KeyError:
|
|
||||||
LOG.error('Malformed message (missing required key)')
|
|
||||||
|
|
Loading…
Reference in New Issue