mirror of
https://opendev.org/x/pyghmi
synced 2025-01-28 20:07:42 +00:00
Use distinct exceptions for many cases
Caller is likely going to want to catch certain conditions. For those, use more specific exception classes. Exceptions indicating either TODO or usage errors are being left as 'Exception' for the time being. Change-Id: I4d68a2dbc394b534d54586b9f770160c1409f720
This commit is contained in:
parent
ccac817f2b
commit
ffe493df0f
30
pyghmi/exceptions.py
Normal file
30
pyghmi/exceptions.py
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 IBM Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Exceptions that Pyghmi can throw
|
||||
|
||||
|
||||
class PyghmiException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class IpmiException(PyghmiException):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidParameterValue(PyghmiException):
|
||||
pass
|
@ -15,6 +15,8 @@
|
||||
# limitations under the License.
|
||||
# This represents the low layer message framing portion of IPMI
|
||||
|
||||
import pyghmi.exceptions as exc
|
||||
|
||||
from pyghmi.ipmi.private import session
|
||||
|
||||
|
||||
@ -160,11 +162,12 @@ class Command(object):
|
||||
:returns: dict -- A dict describing the response retrieved
|
||||
"""
|
||||
if powerstate not in power_states:
|
||||
raise Exception("Unknown power state %s requested" % powerstate)
|
||||
raise exc.InvalidParameterValue(
|
||||
"Unknown power state %s requested" % powerstate)
|
||||
self.newpowerstate = powerstate
|
||||
response = self.ipmi_session.raw_command(netfn=0, command=1)
|
||||
if 'error' in response:
|
||||
raise Exception(response['error'])
|
||||
raise exc.IpmiException(response['error'])
|
||||
self.powerstate = 'on' if (response['data'][0] & 1) else 'off'
|
||||
if self.powerstate == self.newpowerstate:
|
||||
return {'powerstate': self.powerstate}
|
||||
@ -173,7 +176,7 @@ class Command(object):
|
||||
response = self.ipmi_session.raw_command(
|
||||
netfn=0, command=2, data=[power_states[self.newpowerstate]])
|
||||
if 'error' in response:
|
||||
raise Exception(response['error'])
|
||||
raise exc.IpmiException(response['error'])
|
||||
self.lastresponse = {'pendingpowerstate': self.newpowerstate}
|
||||
waitattempts = 300
|
||||
if not isinstance(wait, bool):
|
||||
@ -193,7 +196,8 @@ class Command(object):
|
||||
currpowerstate = 'on' if (response['data'][0] & 1) else 'off'
|
||||
waitattempts -= 1
|
||||
if currpowerstate != self.waitpowerstate:
|
||||
raise Exception("System did not accomplish power state change")
|
||||
raise exc.IpmiException(
|
||||
"System did not accomplish power state change")
|
||||
return {'powerstate': currpowerstate}
|
||||
else:
|
||||
return self.lastresponse
|
||||
@ -281,8 +285,7 @@ class Command(object):
|
||||
"""
|
||||
response = self.ipmi_session.raw_command(netfn=0, command=1)
|
||||
if 'error' in response:
|
||||
raise Exception(response['error'])
|
||||
return
|
||||
raise exc.IpmiException(response['error'])
|
||||
assert(response['command'] == 1 and response['netfn'] == 1)
|
||||
self.powerstate = 'on' if (response['data'][0] & 1) else 'off'
|
||||
return {'powerstate': self.powerstate}
|
||||
|
@ -41,7 +41,7 @@ class Console(object):
|
||||
|
||||
#TODO(jbjohnso): still need an exit and a data callin function
|
||||
def __init__(self, bmc, userid, password,
|
||||
iohandler=None, port=623,
|
||||
iohandler, port=623,
|
||||
force=False, kg=None):
|
||||
if type(iohandler) == tuple: # two file handles
|
||||
self.console_in = iohandler[0]
|
||||
@ -53,8 +53,6 @@ class Console(object):
|
||||
self.console_out = None
|
||||
self.console_in = None
|
||||
self.out_handler = iohandler
|
||||
else:
|
||||
raise(Exception('No IO handler provided'))
|
||||
if self.console_in is not None:
|
||||
fcntl.fcntl(self.console_in.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
self.remseq = 0
|
||||
@ -136,7 +134,8 @@ class Console(object):
|
||||
#data[6:7] is the promise of how small packets are going to be, but we
|
||||
#don't have any reason to worry about it
|
||||
if (data[8] + (data[9] << 8)) != 623:
|
||||
raise Exception("TODO(jbjohnso): support atypical SOL port number")
|
||||
#TODO(jbjohnso): support atypical SOL port number
|
||||
raise NotImplementedError("Non-standard SOL Port Number")
|
||||
#ignore data[10:11] for now, the vlan detail, shouldn't matter to this
|
||||
#code anyway...
|
||||
self.ipmi_session.sol_handler = self._got_sol_payload
|
||||
|
@ -29,6 +29,7 @@ from Crypto.Cipher import AES
|
||||
from Crypto.Hash import HMAC
|
||||
from Crypto.Hash import SHA
|
||||
|
||||
import pyghmi.exceptions as exc
|
||||
from pyghmi.ipmi.private import constants
|
||||
|
||||
|
||||
@ -184,7 +185,7 @@ class Session:
|
||||
a client-provided callback.
|
||||
"""
|
||||
if 'error' in response:
|
||||
raise Exception(response['error'])
|
||||
raise exc.IpmiException(response['error'])
|
||||
|
||||
def __init__(self,
|
||||
bmc,
|
||||
@ -370,9 +371,11 @@ class Session:
|
||||
if (self.ipmiversion == 2.0):
|
||||
message.append(payload_type)
|
||||
if (baretype == 2):
|
||||
raise Exception("TODO(jbjohnso): OEM Payloads")
|
||||
#TODO(jbjohnso): OEM payload types
|
||||
raise NotImplementedError("OEM Payloads")
|
||||
elif baretype not in constants.payload_types.values():
|
||||
raise Exception("Unrecognized payload type %d" % baretype)
|
||||
raise NotImplementedError(
|
||||
"Unrecognized payload type %d" % baretype)
|
||||
message += struct.unpack("!4B", struct.pack("<I", self.sessionid))
|
||||
message += struct.unpack("!4B", struct.pack("<I", self.sequencenumber))
|
||||
if (self.ipmiversion == 1.5):
|
||||
@ -448,7 +451,7 @@ class Session:
|
||||
password = self.password
|
||||
padneeded = 16 - len(password)
|
||||
if padneeded < 0:
|
||||
raise Exception("Password is too long for ipmi 1.5")
|
||||
raise exc.IpmiException("Password is too long for ipmi 1.5")
|
||||
password += '\x00' * padneeded
|
||||
passdata = struct.unpack("16B", password)
|
||||
if checkremotecode:
|
||||
@ -547,7 +550,8 @@ class Session:
|
||||
def _get_session_challenge(self):
|
||||
reqdata = [2]
|
||||
if len(self.userid) > 16:
|
||||
raise Exception("Username too long for IPMI, must not exceed 16")
|
||||
raise exc.IpmiException(
|
||||
"Username too long for IPMI, must not exceed 16")
|
||||
padneeded = 16 - len(self.userid)
|
||||
userid = self.userid + ('\x00' * padneeded)
|
||||
reqdata += struct.unpack("!16B", userid)
|
||||
@ -1080,16 +1084,21 @@ class Session:
|
||||
Session.socket.sendto(self.netpacket, self.sockaddr)
|
||||
else: # he have not yet picked a working sockaddr for this connection,
|
||||
# try all the candidates that getaddrinfo provides
|
||||
for res in socket.getaddrinfo(self.bmc,
|
||||
self.port,
|
||||
0,
|
||||
socket.SOCK_DGRAM):
|
||||
sockaddr = res[4]
|
||||
if (res[0] == socket.AF_INET): # convert the sockaddr AF_INET6
|
||||
newhost = '::ffff:' + sockaddr[0]
|
||||
sockaddr = (newhost, sockaddr[1], 0, 0)
|
||||
Session.bmc_handlers[sockaddr] = self
|
||||
Session.socket.sendto(self.netpacket, sockaddr)
|
||||
try:
|
||||
for res in socket.getaddrinfo(self.bmc,
|
||||
self.port,
|
||||
0,
|
||||
socket.SOCK_DGRAM):
|
||||
sockaddr = res[4]
|
||||
if (res[0] == socket.AF_INET): # convert the sockaddr
|
||||
# to AF_INET6
|
||||
newhost = '::ffff:' + sockaddr[0]
|
||||
sockaddr = (newhost, sockaddr[1], 0, 0)
|
||||
Session.bmc_handlers[sockaddr] = self
|
||||
Session.socket.sendto(self.netpacket, sockaddr)
|
||||
except socket.gaierror:
|
||||
raise exc.IpmiException(
|
||||
"Unable to transmit to specified address")
|
||||
|
||||
def logout(self, callback=None, callback_args=None):
|
||||
if not self.logged:
|
||||
|
Loading…
x
Reference in New Issue
Block a user