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 time
|
||||||
import logging
|
import logging
|
||||||
import cryptobox.core.settings
|
import cryptobox.core.settings
|
||||||
|
import cryptobox.core.exceptions
|
||||||
|
|
||||||
OPTIONAL_PROGS = { "lvm": True }
|
OPTIONAL_PROGS = { "lvm": True }
|
||||||
"""remember which programs don't exist to avoid calling them in vain
|
"""remember which programs don't exist to avoid calling them in vain
|
||||||
|
@ -99,6 +100,10 @@ class Blockdevices:
|
||||||
|
|
||||||
|
|
||||||
class Blockdevice:
|
class Blockdevice:
|
||||||
|
"""don't instantiate this class directly!
|
||||||
|
|
||||||
|
use "_get_blockdevice" instead
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, dev,
|
def __init__(self, dev,
|
||||||
sysblock_dir=DEFAULT_SYSBLOCK_DIR,
|
sysblock_dir=DEFAULT_SYSBLOCK_DIR,
|
||||||
|
@ -115,6 +120,11 @@ class Blockdevice:
|
||||||
self.devdir = dev
|
self.devdir = dev
|
||||||
self.devnode_dir = devnode_dir
|
self.devnode_dir = devnode_dir
|
||||||
self.sysblock_dir = sysblock_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)
|
self.name = os.path.basename(self.devdir)
|
||||||
## "reset" below will fill these values
|
## "reset" below will fill these values
|
||||||
self.devnum = None
|
self.devnum = None
|
||||||
|
@ -358,6 +368,38 @@ class Blockdevice:
|
||||||
return result
|
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):
|
def __get_dev_related(self, subdir):
|
||||||
"""return the content of sub directories (e.g. 'holders' or 'slaves')
|
"""return the content of sub directories (e.g. 'holders' or 'slaves')
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -22,30 +22,65 @@
|
||||||
exceptions of the cryptobox package
|
exceptions of the cryptobox package
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
__revision__ = "$Id$"
|
__revision__ = "$Id$"
|
||||||
|
|
||||||
|
|
||||||
class CBError(Exception):
|
class CBError(Exception):
|
||||||
"""base class for exceptions of the cryptobox"""
|
"""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):
|
class CBConfigError(CBError):
|
||||||
"""any kind of error related to the configuration of a cryptobox"""
|
"""any kind of error related to the configuration of a cryptobox"""
|
||||||
pass
|
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):
|
class CBConfigUnavailableError(CBConfigError):
|
||||||
"""config file/input was not available at all"""
|
"""config file/input was not available at all"""
|
||||||
|
|
||||||
def __init__(self, source=None):
|
prefix = "failed to access the configuration of the cryptobox"
|
||||||
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"
|
|
||||||
|
|
||||||
|
|
||||||
class CBConfigUndefinedError(CBConfigError):
|
class CBConfigUndefinedError(CBConfigError):
|
||||||
|
@ -86,25 +121,6 @@ class CBConfigInvalidValueError(CBConfigError):
|
||||||
(self.section, self.name, self.value, self.reason)
|
(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):
|
class CBCreateError(CBContainerError):
|
||||||
"""Raised if a container could not be created (formatted).
|
"""Raised if a container could not be created (formatted).
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -230,7 +230,7 @@ class CryptoBox:
|
||||||
device.devnodes.insert(0, devnode)
|
device.devnodes.insert(0, devnode)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.log.debug("Skipping device without read and write" \
|
self.log.debug("Skipping device without read and write " \
|
||||||
+ "permissions: %s" % device.name)
|
+ "permissions: %s" % device.name)
|
||||||
self.log.debug("Skipping unusable device: %s" % device.name)
|
self.log.debug("Skipping unusable device: %s" % device.name)
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -317,9 +317,13 @@ class CryptoBoxSettings:
|
||||||
else:
|
else:
|
||||||
raise CBConfigUnavailableError(
|
raise CBConfigUnavailableError(
|
||||||
"failed to load the config file: %s" % config_file)
|
"failed to load the config file: %s" % config_file)
|
||||||
except IOError:
|
except IOError, err_msgg:
|
||||||
raise CBConfigUnavailableError(
|
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
|
return prefs
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue