add "is_parent_of" function to blockdevice module
improve pre-defined exceptions improve few failure behaviours
This commit is contained in:
parent
42a5e1bcc6
commit
eaf37a872a
4 changed files with 93 additions and 31 deletions
|
@ -33,6 +33,7 @@ import subprocess
|
|||
import time
|
||||
import logging
|
||||
import cryptobox.core.settings
|
||||
import cryptobox.core.exceptions
|
||||
|
||||
OPTIONAL_PROGS = { "lvm": True }
|
||||
"""remember which programs don't exist to avoid calling them in vain
|
||||
|
@ -99,6 +100,10 @@ class Blockdevices:
|
|||
|
||||
|
||||
class Blockdevice:
|
||||
"""don't instantiate this class directly!
|
||||
|
||||
use "_get_blockdevice" instead
|
||||
"""
|
||||
|
||||
def __init__(self, dev,
|
||||
sysblock_dir=DEFAULT_SYSBLOCK_DIR,
|
||||
|
@ -115,6 +120,11 @@ class Blockdevice:
|
|||
self.devdir = dev
|
||||
self.devnode_dir = devnode_dir
|
||||
self.sysblock_dir = sysblock_dir
|
||||
## check if the device is valid
|
||||
if not os.path.isdir(os.path.join(self.devnode_dir, dev)):
|
||||
raise cryptobox.core.exceptions.CBInternalError(
|
||||
"invalid blockdevice given: %s (%s)" % \
|
||||
(self.devdir, self.sysblock_dir))
|
||||
self.name = os.path.basename(self.devdir)
|
||||
## "reset" below will fill these values
|
||||
self.devnum = None
|
||||
|
@ -358,6 +368,38 @@ class Blockdevice:
|
|||
return result
|
||||
|
||||
|
||||
def is_parent_of(self, ask_child):
|
||||
"""check if the blockdevice or any of its children contains the given child
|
||||
|
||||
the result of "foo.is_parent_of(foo)" returns False
|
||||
|
||||
invalid (None) "ask_child" devices return False
|
||||
|
||||
@param ask_child: the blockdevice that is considered to be a possible child
|
||||
@type ask_child: BlockDevice
|
||||
@return: True if the child is (even recursively) part of the blockdevice, otherwise False
|
||||
@rtype: bool
|
||||
"""
|
||||
## return False for non existing device
|
||||
if ask_child is None:
|
||||
return False
|
||||
## throw exception for invalid call
|
||||
if not isinstance(ask_child, Blockdevice):
|
||||
raise cryptobox.core.exceptions.CBInternalError(\
|
||||
"invalid arguments for 'is_parent_of'")
|
||||
## recursively go through all the children
|
||||
for child_devname in self.children:
|
||||
child_dev = get_blockdevice(child_devname)
|
||||
## direct child?
|
||||
if child_dev == ask_child:
|
||||
return True
|
||||
## indirect child?
|
||||
if child_dev.is_parent_of(ask_child):
|
||||
return True
|
||||
## no matches found
|
||||
return False
|
||||
|
||||
|
||||
def __get_dev_related(self, subdir):
|
||||
"""return the content of sub directories (e.g. 'holders' or 'slaves')
|
||||
"""
|
||||
|
|
|
@ -22,30 +22,65 @@
|
|||
exceptions of the cryptobox package
|
||||
"""
|
||||
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
|
||||
class CBError(Exception):
|
||||
"""base class for exceptions of the cryptobox"""
|
||||
pass
|
||||
|
||||
prefix = "general cryptobox error"
|
||||
|
||||
def __init__(self, desc):
|
||||
self.desc = desc
|
||||
|
||||
def __str__(self):
|
||||
"""Return the error description.
|
||||
"""
|
||||
if self.desc:
|
||||
return "%s: %s" % (self.prefix, self.desc)
|
||||
else:
|
||||
return self.prefix
|
||||
|
||||
|
||||
|
||||
# main exception classes
|
||||
|
||||
class CBConfigError(CBError):
|
||||
"""any kind of error related to the configuration of a cryptobox"""
|
||||
pass
|
||||
|
||||
|
||||
class CBContainerError(CBError):
|
||||
"""Any error raised while manipulating a cryptobox container.
|
||||
"""
|
||||
|
||||
prefix = "cryptobox container error"
|
||||
|
||||
|
||||
class CBEnvironmentError(CBError):
|
||||
"""some part of the environment of the cryptobox is broken
|
||||
e.g. the wrong version of a required program
|
||||
"""
|
||||
|
||||
prefix = "cryptobox environment error"
|
||||
|
||||
|
||||
class CBInternalError(CBError):
|
||||
"""report any failing internal assertions
|
||||
|
||||
this is always a bug
|
||||
"""
|
||||
|
||||
prefix = "internal error detected"
|
||||
|
||||
|
||||
# specialized exceptions
|
||||
|
||||
class CBConfigUnavailableError(CBConfigError):
|
||||
"""config file/input was not available at all"""
|
||||
|
||||
def __init__(self, source=None):
|
||||
self.source = source
|
||||
|
||||
def __str__(self):
|
||||
if self.source:
|
||||
return "failed to access the configuration of the cryptobox: %s" % self.source
|
||||
else:
|
||||
return "failed to access the configuration of the cryptobox"
|
||||
prefix = "failed to access the configuration of the cryptobox"
|
||||
|
||||
|
||||
class CBConfigUndefinedError(CBConfigError):
|
||||
|
@ -86,25 +121,6 @@ class CBConfigInvalidValueError(CBConfigError):
|
|||
(self.section, self.name, self.value, self.reason)
|
||||
|
||||
|
||||
class CBEnvironmentError(CBError):
|
||||
"""some part of the environment of the cryptobox is broken
|
||||
e.g. the wrong version of a required program
|
||||
"""
|
||||
|
||||
def __init__(self, desc):
|
||||
self.desc = desc
|
||||
|
||||
def __str__(self):
|
||||
"""Return the error description.
|
||||
"""
|
||||
return "misconfiguration detected: %s" % self.desc
|
||||
|
||||
|
||||
class CBContainerError(CBError):
|
||||
"""Any error raised while manipulating a cryptobox container.
|
||||
"""
|
||||
|
||||
|
||||
class CBCreateError(CBContainerError):
|
||||
"""Raised if a container could not be created (formatted).
|
||||
"""
|
||||
|
|
|
@ -317,9 +317,13 @@ class CryptoBoxSettings:
|
|||
else:
|
||||
raise CBConfigUnavailableError(
|
||||
"failed to load the config file: %s" % config_file)
|
||||
except IOError:
|
||||
except IOError, err_msgg:
|
||||
raise CBConfigUnavailableError(
|
||||
"unable to open the config file: %s" % config_file)
|
||||
"unable to open the config file (%s): %s" % \
|
||||
(config_file, err_msg))
|
||||
except configobj.ConfigObjError, err_msg:
|
||||
raise CBConfigError("failed to load config file (%s): %s" % \
|
||||
(config_file, err_msg))
|
||||
return prefs
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue