[Kimchi-devel] [PATCH 5/8] refactor exception: Update all exceptions

Aline Manera alinefm at linux.vnet.ibm.com
Sun Feb 9 22:47:59 UTC 2014


From: Aline Manera <alinefm at br.ibm.com>

Update all Kimchi exceptions to translate backend messages.
Use message code to get the correct messages in i18n.py and raise a
message like: "<code>: <translated-message>"

Signed-off-by: Aline Manera <alinefm at br.ibm.com>
---
 plugins/sample/model.py                |   12 ++--
 src/kimchi/asynctask.py                |    4 +-
 src/kimchi/auth.py                     |    3 +-
 src/kimchi/disks.py                    |    5 +-
 src/kimchi/distroloader.py             |    5 +-
 src/kimchi/exception.py                |   14 ++--
 src/kimchi/iscsi.py                    |    6 +-
 src/kimchi/isoinfo.py                  |   17 +++--
 src/kimchi/mockmodel.py                |  113 +++++++++++++++++++-------------
 src/kimchi/model/config.py             |    2 +-
 src/kimchi/model/debugreports.py       |   18 ++---
 src/kimchi/model/host.py               |   10 +--
 src/kimchi/model/interfaces.py         |    4 +-
 src/kimchi/model/libvirtstoragepool.py |   14 ++--
 src/kimchi/model/networks.py           |   37 ++++++-----
 src/kimchi/model/storagepools.py       |   39 ++++++-----
 src/kimchi/model/storageservers.py     |    2 +-
 src/kimchi/model/storagevolumes.py     |   37 ++++++-----
 src/kimchi/model/templates.py          |   44 ++++++-------
 src/kimchi/model/utils.py              |    2 +-
 src/kimchi/model/vmifaces.py           |   15 ++---
 src/kimchi/model/vms.py                |   28 ++++----
 src/kimchi/objectstore.py              |    4 +-
 src/kimchi/template.py                 |    2 +-
 src/kimchi/utils.py                    |   12 ++--
 src/kimchi/vmtemplate.py               |    7 +-
 tests/test_exception.py                |    4 +-
 tests/test_rest.py                     |    4 +-
 tests/utils.py                         |    5 +-
 29 files changed, 255 insertions(+), 214 deletions(-)

diff --git a/plugins/sample/model.py b/plugins/sample/model.py
index 184864d..f7ca319 100644
--- a/plugins/sample/model.py
+++ b/plugins/sample/model.py
@@ -31,7 +31,7 @@ class CirclesModel(object):
     def create(self, params):
         name = params['name']
         if name in self._circles:
-            raise InvalidOperation("Circle %s already exists" % name)
+            raise InvalidOperation("SPCIRCLE0001E", {'name': name})
         self._circles[name] = Circle(params['radius'])
         return name
 
@@ -48,12 +48,12 @@ class CircleModel(object):
         try:
             circle = self._circles[name]
         except KeyError:
-            raise NotFoundError("Circle %s not found" % name)
+            raise NotFoundError("SPCIRC0002E", {'name': name})
         return {'radius': circle.radius}
 
     def update(self, name, params):
         if name not in self._circles:
-            raise NotFoundError("Circle %s not found" % name)
+            raise NotFoundError("SPCIRC0002E", {'name': name})
         self._circles[name].radius = params['radius']
         return name
 
@@ -71,7 +71,7 @@ class RectanglesModel(object):
     def create(self, params):
         name = params['name']
         if name in self._rectangles:
-            raise InvalidOperation("Rectangle %s already exists" % name)
+            raise InvalidOperation("SPRET0001E", {'name': name})
         self._rectangles[name] = Rectangle(params['length'], params['width'])
         return name
 
@@ -87,12 +87,12 @@ class RectangleModel(object):
         try:
             rectangle = self._rectangles[name]
         except KeyError:
-            raise NotFoundError("Rectangle %s not found" % name)
+            raise NotFoundError("SPRET0002E", {'name': name})
         return {'length': rectangle.length, 'width': rectangle.width}
 
     def update(self, name, params):
         if name not in self._rectangles:
-            raise NotFoundError("Rectangle %s not found" % name)
+            raise NotFoundError("SPRET0002E", {'name': name})
         try:
             self._rectangles[name].length = params['length']
         except KeyError:
diff --git a/src/kimchi/asynctask.py b/src/kimchi/asynctask.py
index 4ff76e4..f5cba50 100644
--- a/src/kimchi/asynctask.py
+++ b/src/kimchi/asynctask.py
@@ -31,8 +31,8 @@ from kimchi.exception import OperationFailed
 class AsyncTask(object):
     def __init__(self, id, target_uri, fn, objstore, opaque=None):
         if objstore is None:
-            raise OperationFailed("Datastore is not initiated in "
-                                  "the model object")
+            raise OperationFailed("KCHASYNC0001E")
+
         self.id = str(id)
         self.target_uri = target_uri
         self.fn = fn
diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index 242fdcf..1cae45d 100644
--- a/src/kimchi/auth.py
+++ b/src/kimchi/auth.py
@@ -68,7 +68,8 @@ def authenticate(username, password, service="passwd"):
     try:
         auth.authenticate()
     except PAM.error, (resp, code):
-        raise OperationFailed(resp, code)
+        msg_args = {'userid': username, 'code': code}
+        raise OperationFailed("KCHAUTH0001E", msg_args)
 
     return True
 
diff --git a/src/kimchi/disks.py b/src/kimchi/disks.py
index 941aaca..83d5cc6 100644
--- a/src/kimchi/disks.py
+++ b/src/kimchi/disks.py
@@ -44,7 +44,7 @@ def _get_lsblk_devs(keys, devs=[]):
         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     out, err = lsblk.communicate()
     if lsblk.returncode != 0:
-        raise OperationFailed('Error executing lsblk: %s' % err)
+        raise OperationFailed("KCHDISKS0001E", {'err': err})
 
     return _parse_lsblk_output(out, keys)
 
@@ -60,8 +60,7 @@ def _get_dev_major_min(name):
             maj_min = dev['maj:min']
             break
     else:
-        msg = "Failed to find major and minor number for %s" % name
-        raise OperationFailed(msg)
+        raise OperationFailed("KCHDISKS0002E", {'device': name})
 
     return maj_min
 
diff --git a/src/kimchi/distroloader.py b/src/kimchi/distroloader.py
index 98fd764..f0b0208 100644
--- a/src/kimchi/distroloader.py
+++ b/src/kimchi/distroloader.py
@@ -37,10 +37,11 @@ class DistroLoader(object):
         self.location = location or config.get_distros_store()
 
     def _get_json_info(self, fname):
+        msg_args = {'filename': fname}
         if not os.path.isfile(fname):
             msg = "DistroLoader: failed to find distro file: %s" % fname
             kimchi_log.error(msg)
-            raise NotFoundError(msg)
+            raise NotFoundError("KCHDL0001E", msg_args)
         try:
             with open(fname) as f:
                 data = json.load(f)
@@ -48,7 +49,7 @@ class DistroLoader(object):
         except ValueError:
             msg = "DistroLoader: failed to parse distro file: %s" % fname
             kimchi_log.error(msg)
-            raise OperationFailed(msg)
+            raise OperationFailed("KCHDL0002E", msg_args)
 
     def get(self):
         all_json_files = glob.glob("%s/%s" % (self.location, "*.json"))
diff --git a/src/kimchi/exception.py b/src/kimchi/exception.py
index 7fcce54..952e243 100644
--- a/src/kimchi/exception.py
+++ b/src/kimchi/exception.py
@@ -49,29 +49,29 @@ class KimchiException(Exception):
         Exception.__init__(self, pattern)
 
 
-class NotFoundError(Exception):
+class NotFoundError(KimchiException):
     pass
 
 
-class OperationFailed(Exception):
+class OperationFailed(KimchiException):
     pass
 
 
-class MissingParameter(Exception):
+class MissingParameter(KimchiException):
     pass
 
 
-class InvalidParameter(Exception):
+class InvalidParameter(KimchiException):
     pass
 
 
-class InvalidOperation(Exception):
+class InvalidOperation(KimchiException):
     pass
 
 
-class IsoFormatError(Exception):
+class IsoFormatError(KimchiException):
     pass
 
 
-class TimeoutExpired(Exception):
+class TimeoutExpired(KimchiException):
     pass
diff --git a/src/kimchi/iscsi.py b/src/kimchi/iscsi.py
index 35c0b8a..248188c 100644
--- a/src/kimchi/iscsi.py
+++ b/src/kimchi/iscsi.py
@@ -55,7 +55,8 @@ class TargetClient(object):
             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         out, err = iscsiadm.communicate()
         if iscsiadm.returncode != 0:
-            raise OperationFailed('Error executing iscsiadm: %s' % err)
+            msg_args = {'portal': self.portal, 'err': err}
+            raise OperationFailed("KCHISCSI0001E", msg_args)
         return out
 
     def _discover(self):
@@ -65,7 +66,8 @@ class TargetClient(object):
             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         out, err = iscsiadm.communicate()
         if iscsiadm.returncode != 0:
-            raise OperationFailed('Error executing iscsiadm: %s' % err)
+            msg_args = {'portal': self.portal, 'err': err}
+            raise OperationFailed("KCHISCSI0001E", msg_args)
         return out
 
     def _run_op(self, op):
diff --git a/src/kimchi/isoinfo.py b/src/kimchi/isoinfo.py
index a3cd4cd..5629391 100644
--- a/src/kimchi/isoinfo.py
+++ b/src/kimchi/isoinfo.py
@@ -149,11 +149,11 @@ class IsoImage(object):
         if check_url_path(self.path):
             return True
 
-        raise IsoFormatError('ISO %s does not exist' % self.path)
+        raise IsoFormatError("KCHISO0001E", {'filename': self.path})
 
     def probe(self):
         if not self.bootable:
-            raise IsoFormatError("ISO %s not bootable" % self.path)
+            raise IsoFormatError("KCHISO0002E", {'filename': self.path})
 
         matcher = Matcher(self.volume_id)
 
@@ -197,7 +197,8 @@ class IsoImage(object):
             if vd_type == 0:  # Found El-Torito Boot Record
                 break
         if not et_ident.startswith('EL TORITO SPECIFICATION'):
-            raise IsoFormatError("Invalid El Torito boot record")
+            raise IsoFormatError("KCHISO0003E",
+                                 {'filename': self.path})
 
         offset = IsoImage.SECTOR_SIZE * boot_cat
         size = IsoImage.EL_TORITO_VALIDATION_ENTRY.size + \
@@ -210,7 +211,8 @@ class IsoImage(object):
         (hdr_id, platform_id, pad0,
          ident, csum, key55, keyAA) = self._unpack(fmt, tmp_data)
         if key55 != 0x55 or keyAA != 0xaa:
-            raise IsoFormatError("Invalid El Torito validation entry")
+            raise IsoFormatError("KCHISO0004E",
+                                 {'filename': self.path})
 
         fmt = IsoImage.EL_TORITO_BOOT_ENTRY
         tmp_data = data[ptr:ptr+fmt.size]
@@ -221,7 +223,8 @@ class IsoImage(object):
         elif boot == 0:
             self.bootable = False
         else:
-            raise IsoFormatError("Invalid El Torito boot indicator")
+            raise IsoFormatError("KCHISO0005E",
+                                 {'filename': self.path})
 
     def _scan_primary_vol(self, data):
         """
@@ -232,9 +235,9 @@ class IsoImage(object):
         info = self._unpack(IsoImage.VOL_DESC, primary_vol_data)
         (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id) = info
         if vd_type != 1:
-            raise IsoFormatError("Unexpected volume type for primary volume")
+            raise IsoFormatError("KCHISO0006E", {'filename': self.path})
         if vd_ident != 'CD001' or vd_ver != 1:
-            raise IsoFormatError("Bad format while reading volume descriptor")
+            raise IsoFormatError("KCHISO0007E", {'filename': self.path})
         self.volume_id = vol_id
 
     def _get_iso_data(self, offset, size):
diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index 4e276eb..e5425b2 100644
--- a/src/kimchi/mockmodel.py
+++ b/src/kimchi/mockmodel.py
@@ -83,7 +83,8 @@ class MockModel(object):
 
         if 'name' in params:
             if state == 'running' or params['name'] in self.vms_get_list():
-                raise InvalidParameter("VM name existed or vm not shutoff.")
+                msg_args = {'name': dom.name, 'new_name': params['name']}
+                raise InvalidParameter("KCHVM0003E", msg_args)
             else:
                 del self._mock_vms[dom.name]
                 dom.name = params['name']
@@ -134,7 +135,7 @@ class MockModel(object):
         name = get_vm_name(params.get('name'), t_name,
                                       self._mock_vms.keys())
         if name in self._mock_vms:
-            raise InvalidOperation("VM already exists")
+            raise InvalidOperation("KCHVM0001E", {'name': name})
 
         vm_uuid = str(uuid.uuid4())
         vm_overrides = dict()
@@ -166,7 +167,8 @@ class MockModel(object):
     def vmscreenshot_lookup(self, name):
         vm = self._get_vm(name)
         if vm.info['state'] != 'running':
-            raise NotFoundError('No screenshot for stopped vm')
+            raise NotFoundError("KCHVM0004E", {'name': name})
+
         screenshot = self._mock_screenshots.setdefault(
             vm.uuid, MockVMScreenshot({'uuid': vm.uuid}))
         return screenshot.lookup()
@@ -185,18 +187,19 @@ class MockModel(object):
         try:
             del self._mock_templates[name]
         except KeyError:
-            raise NotFoundError()
+            raise NotFoundError("KCHTMPL0002E", {'name': name})
 
     def templates_create(self, params):
         name = params['name']
         if name in self._mock_templates:
-            raise InvalidOperation("Template already exists")
+            raise InvalidOperation("KCHTMPL0001E", {'name': name})
+
         for net_name in params.get(u'networks', []):
             try:
                 self._get_network(net_name)
             except NotFoundError:
-                raise InvalidParameter("Network '%s' specified by template "
-                                       "does not exist" % net_name)
+                msg_args = {'network': net_name, 'template': name}
+                raise InvalidParameter("KCHTMPL0003E", msg_args)
 
         t = MockVMTemplate(params, self)
         self._mock_templates[name] = t
@@ -212,15 +215,16 @@ class MockModel(object):
         new_storagepool = new_t.get(u'storagepool', '')
         try:
             self._get_storagepool(pool_name_from_uri(new_storagepool))
-        except Exception as e:
-            raise InvalidParameter("Storagepool specified is not valid: %s." % e.message)
+        except Exception:
+            msg_args = {'pool': new_storagepool, 'template': name}
+            raise InvalidParameter("KCHTMPL0004E", msg_args)
 
         for net_name in params.get(u'networks', []):
             try:
                 self._get_network(net_name)
             except NotFoundError:
-                raise InvalidParameter("Network '%s' specified by template "
-                                       "does not exist" % net_name)
+                msg_args = {'network': net_name, 'template': name}
+                raise InvalidParameter("KCHTMPL0003E", msg_args)
 
         self.template_delete(name)
         try:
@@ -243,7 +247,7 @@ class MockModel(object):
             else:
                 return t
         except KeyError:
-            raise NotFoundError()
+            raise NotFoundError("KCHTMPL0002E", {'name': name})
 
     def debugreport_lookup(self, name):
         path = config.get_debugreports_path()
@@ -251,7 +255,7 @@ class MockModel(object):
         try:
             file_target = glob.glob(file_pattern)[0]
         except IndexError:
-            raise NotFoundError('no such report')
+            raise NotFoundError("KCHDR0001E", {'name', name})
 
         ctime = os.stat(file_target).st_ctime
         ctime = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(ctime))
@@ -269,7 +273,7 @@ class MockModel(object):
         try:
             file_target = glob.glob(file_pattern)[0]
         except IndexError:
-            raise NotFoundError('no such report')
+            raise NotFoundError("KCHDR0001E", {'name', name})
 
         os.remove(file_target)
 
@@ -291,7 +295,7 @@ class MockModel(object):
         try:
             return self._mock_vms[name]
         except KeyError:
-            raise NotFoundError()
+            raise NotFoundError("KCHVM0002E", {'name': name})
 
     def storagepools_create(self, params):
         try:
@@ -304,9 +308,12 @@ class MockModel(object):
             else:
                 pool.info['autostart'] = False
         except KeyError, item:
-            raise MissingParameter(item)
+            raise MissingParameter("KCHPOOL0004E",
+                                   {'item': item, 'name': name})
+
         if name in self._mock_storagepools or name in (ISO_POOL_NAME,):
-            raise InvalidOperation("StoragePool already exists")
+            raise InvalidOperation("KCHPOOL0001E", {'name': name})
+
         self._mock_storagepools[name] = pool
         return name
 
@@ -318,7 +325,8 @@ class MockModel(object):
     def storagepool_update(self, name, params):
         autostart = params['autostart']
         if autostart not in [True, False]:
-            raise InvalidOperation("Autostart flag must be true or false")
+            raise InvalidOperation("KCHPOOL0003E")
+
         storagepool = self._get_storagepool(name)
         storagepool.info['autostart'] = autostart
         ident = storagepool.name
@@ -342,12 +350,15 @@ class MockModel(object):
         try:
             return self._mock_storagepools[name]
         except KeyError:
-            raise NotFoundError()
+            raise NotFoundError("KCHPOOL0002E", {'name': name})
 
     def storagevolumes_create(self, pool_name, params):
         pool = self._get_storagepool(pool_name)
         if pool.info['state'] == 'inactive':
-            raise InvalidOperation("StoragePool not active")
+            raise InvalidOperation("KCHVOL0003E",
+                                   {'pool': pool_name,
+                                    'volume': params['name']})
+
         try:
             name = params['name']
             volume = MockStorageVolume(pool, name, params)
@@ -356,15 +367,20 @@ class MockModel(object):
             volume.info['path'] = os.path.join(
                 pool.info['path'], name)
         except KeyError, item:
-            raise MissingParameter(item)
+            raise MissingParameter("KCHVOL0004E",
+                                   {'item': item, 'volume': name})
+
         if name in pool._volumes:
-            raise InvalidOperation("StorageVolume already exists")
+            raise InvalidOperation("KCHVOL0001E", {'name': name})
+
         pool._volumes[name] = volume
         return name
 
     def storagevolume_lookup(self, pool, name):
         if self._get_storagepool(pool).info['state'] != 'active':
-            raise InvalidOperation("StoragePool %s is not active" % pool)
+            raise InvalidOperation("KCHVOL0005E", {'pool': pool,
+                                                         'volume': name})
+
         storagevolume = self._get_storagevolume(pool, name)
         return storagevolume.info
 
@@ -384,8 +400,7 @@ class MockModel(object):
     def storagevolumes_get_list(self, pool):
         res = self._get_storagepool(pool)
         if res.info['state'] == 'inactive':
-            raise InvalidOperation(
-                "Unable to list volumes of inactive storagepool %s" % pool)
+            raise InvalidOperation("KCHVOL0006E", {'pool': pool})
         return res._volumes.keys()
 
     def isopool_lookup(self, name):
@@ -438,7 +453,7 @@ class MockModel(object):
             # Avoid inconsistent pool result because of lease between list and lookup
                 pass
 
-        raise NotFoundError("storage server %s not used by kimchi" % server)
+        raise NotFoundError("KCHSR0001E", {'server': server})
 
     def dummy_interfaces(self):
         interfaces = {}
@@ -461,7 +476,8 @@ class MockModel(object):
     def networks_create(self, params):
         name = params['name']
         if name in self.networks_get_list():
-            raise InvalidOperation("Network %s already exists" % name)
+            raise InvalidOperation("KCHNET0001E", {'name': name})
+
         network = MockNetwork(name)
         connection = params['connection']
         network.info['connection'] = connection
@@ -469,22 +485,23 @@ class MockModel(object):
             try:
                 interface = params['interface']
                 network.info['interface'] = interface
-            except KeyError, key:
-                raise MissingParameter(key)
+            except KeyError:
+                raise MissingParameter("KCHNET0004E",
+                                       {'name': name})
 
         subnet = params.get('subnet', '')
         if subnet:
             network.info['subnet'] = subnet
             try:
                 net = ipaddr.IPNetwork(subnet)
-            except ValueError, e:
-                raise InvalidParameter(e)
+            except ValueError:
+                msg_args = {'subnet':subnet, 'network': name}
+                raise InvalidParameter("KCHNET0003E", msg_args)
 
             network.info['dhcp'] = {
                 'start': str(net.network + net.numhosts / 2),
                 'stop': str(net.network + net.numhosts - 2)}
-        if name in self._mock_networks:
-            raise InvalidOperation("Network already exists")
+
         self._mock_networks[name] = network
         return name
 
@@ -492,7 +509,7 @@ class MockModel(object):
         try:
             return self._mock_networks[name]
         except KeyError:
-            raise NotFoundError("Network '%s'" % name)
+            raise NotFoundError("KCHNET0002E", {'name': name})
 
     def _get_vms_attach_to_a_network(self, network):
         vms = []
@@ -523,8 +540,9 @@ class MockModel(object):
     def vmifaces_create(self, vm, params):
         if (params["type"] == "network" and
             params["network"] not in self.networks_get_list()):
-            raise InvalidParameter("%s is not an available network" %
-                                   params["network"])
+            msg_args = {'network': params["network"], 'name': vm}
+            raise InvalidParameter("KCHVMIF0002E", msg_args)
+
         dom = self._get_vm(vm)
         iface = MockVMIface(params["network"])
         ("model" in params.keys() and
@@ -544,7 +562,7 @@ class MockModel(object):
         try:
             info = dom.ifaces[mac].info
         except KeyError:
-            raise NotFoundError('iface: "%s"' % mac)
+            raise NotFoundError("KCHVMIF0001E", {'iface': mac, 'name': vm})
         return info
 
     def vmiface_delete(self, vm, mac):
@@ -552,7 +570,7 @@ class MockModel(object):
         try:
            del dom.ifaces[mac]
         except KeyError:
-            raise NotFoundError('iface: "%s"' % mac)
+            raise NotFoundError("KCHVMIF0001E", {'iface': mac, 'name': vm})
 
     def tasks_get_list(self):
         with self.objstore as session:
@@ -573,7 +591,7 @@ class MockModel(object):
         try:
             return self._get_storagepool(pool)._volumes[name]
         except KeyError:
-            raise NotFoundError()
+            raise NotFoundError("KCHVOL0002E", {'name': name, 'pool': pool})
 
     def _get_distros(self):
         distroloader = DistroLoader()
@@ -586,7 +604,7 @@ class MockModel(object):
         try:
             return self.distros[name]
         except KeyError:
-            raise NotFoundError("distro '%s' not found" % name)
+            raise NotFoundError("KCHDISTRO0001E", {'name': name})
 
     def _gen_debugreport_file(self, ident):
         return self.add_task('', self._create_log, ident)
@@ -638,14 +656,14 @@ class MockModel(object):
         # Check for running vms before shutdown
         running_vms = self.vms_get_list_by_state('running')
         if len(running_vms) > 0:
-            raise OperationFailed("Shutdown not allowed: VMs are running!")
+            raise OperationFailed("KCHHOST0001E")
         cherrypy.engine.exit()
 
     def host_reboot(self, args=None):
         # Find running VMs
         running_vms = self.vms_get_list_by_state('running')
         if len(running_vms) > 0:
-            raise OperationFailed("Reboot not allowed: VMs are running!")
+            raise OperationFailed("KCHHOST0002E")
         cherrypy.engine.stop()
         time.sleep(10)
         cherrypy.engine.start()
@@ -656,8 +674,8 @@ class MockModel(object):
 
     def partition_lookup(self, name):
         if name not in disks.get_partitions_names():
-            raise NotFoundError("Partition %s not found in the host"
-                                % name)
+            raise NotFoundError("KCHPART0001E", {'name': name})
+
         return disks.get_partition_details(name)
 
     def config_lookup(self, name):
@@ -677,9 +695,12 @@ class MockVMTemplate(VMTemplate):
         try:
             pool = self.model._get_storagepool(pool_name)
         except NotFoundError:
-            raise InvalidParameter('Storage specified by template does not exist')
+            msg_args = {'pool': pool_name, 'template': self.name}
+            raise InvalidParameter("KCHTMPL0004E", msg_args)
+
         if pool.info['state'] != 'active':
-            raise InvalidParameter('Storage specified by template is not active')
+            msg_args = {'pool': pool_name, 'template': self.name}
+            raise InvalidParameter("KCHTMPL0005E", msg_args)
 
         return pool
 
diff --git a/src/kimchi/model/config.py b/src/kimchi/model/config.py
index 0e66e02..9b5814a 100644
--- a/src/kimchi/model/config.py
+++ b/src/kimchi/model/config.py
@@ -95,4 +95,4 @@ class DistroModel(object):
         try:
             return self._distros.distros[name]
         except KeyError:
-            raise NotFoundError("Distro '%s' not found." % name)
+            raise NotFoundError("KCHDISTRO0001E", {'name': name})
diff --git a/src/kimchi/model/debugreports.py b/src/kimchi/model/debugreports.py
index a1cb19c..2c5b13a 100644
--- a/src/kimchi/model/debugreports.py
+++ b/src/kimchi/model/debugreports.py
@@ -59,7 +59,7 @@ class DebugReportsModel(object):
         if gen_cmd is not None:
             return add_task('', gen_cmd, self.objstore, name)
 
-        raise OperationFailed("debugreport tool not found")
+        raise OperationFailed("KCHDR0002E")
 
     @staticmethod
     def sosreport_generate(cb, name):
@@ -68,9 +68,11 @@ class DebugReportsModel(object):
             retcode = subprocess.call(command, shell=True,
                                       stdout=subprocess.PIPE)
             if retcode < 0:
-                raise OperationFailed('Command terminated with signal')
+                raise OperationFailed("KCHDR0003E", {'name': name,
+                                                     'err': retcode})
             elif retcode > 0:
-                raise OperationFailed('Command failed: rc = %i' % retcode)
+                raise OperationFailed("KCHDR0003E", {'name': name,
+                                                     'err': retcode})
             pattern = '/tmp/sosreport-%s-*' % name
             for reportFile in glob.glob(pattern):
                 if not fnmatch.fnmatch(reportFile, '*.md5'):
@@ -83,8 +85,8 @@ class DebugReportsModel(object):
                 # runs successfully. In future we might have a general name
                 # mangling function in kimchi to format the name before passing
                 # it to sosreport. Then we can delete this exception.
-                raise OperationFailed('Can not find generated debug report '
-                                      'named by %s' % pattern)
+                raise OperationFailed("KCHDR0004E", {'name': pattern})
+
             ext = output.split('.', 1)[1]
             path = config.get_debugreports_path()
             target = os.path.join(path, name)
@@ -104,7 +106,7 @@ class DebugReportsModel(object):
             # and update the task status there
             log = logging.getLogger('Model')
             log.warning('Exception in generating debug file: %s', e)
-            raise OperationFailed(e)
+            raise OperationFailed("KCHDR0005E", {'name': name, 'err': e})
 
     @staticmethod
     def get_system_report_tool():
@@ -139,7 +141,7 @@ class DebugReportModel(object):
         try:
             file_target = glob.glob(file_pattern)[0]
         except IndexError:
-            raise NotFoundError('no such report')
+            raise NotFoundError("KCHDR0001E", {'name': name})
 
         ctime = os.stat(file_target).st_ctime
         ctime = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(ctime))
@@ -154,7 +156,7 @@ class DebugReportModel(object):
         try:
             file_target = glob.glob(file_pattern)[0]
         except IndexError:
-            raise NotFoundError('no such report')
+            raise NotFoundError("KCHDR0001E", {'name': name})
 
         os.remove(file_target)
 
diff --git a/src/kimchi/model/host.py b/src/kimchi/model/host.py
index a3d9e38..80f93db 100644
--- a/src/kimchi/model/host.py
+++ b/src/kimchi/model/host.py
@@ -67,7 +67,8 @@ class HostModel(object):
         # Check for running vms before shutdown
         running_vms = self._get_vms_list_by_state('running')
         if len(running_vms) > 0:
-            raise OperationFailed("Shutdown not allowed: VMs are running!")
+            raise OperationFailed("KCHHOST0001E")
+
         kimchi_log.info('Host is going to shutdown.')
         os.system('shutdown -h now')
 
@@ -75,7 +76,8 @@ class HostModel(object):
         # Find running VMs
         running_vms = self._get_vms_list_by_state('running')
         if len(running_vms) > 0:
-            raise OperationFailed("Reboot not allowed: VMs are running!")
+            raise OperationFailed("KCHHOST0002E")
+
         kimchi_log.info('Host is going to reboot.')
         os.system('reboot')
 
@@ -196,6 +198,6 @@ class PartitionModel(object):
 
     def lookup(self, name):
         if name not in disks.get_partitions_names():
-            raise NotFoundError("Partition %s not found in the host"
-                                % name)
+            raise NotFoundError("KCHPART0001E", {'name': name})
+
         return disks.get_partition_details(name)
diff --git a/src/kimchi/model/interfaces.py b/src/kimchi/model/interfaces.py
index 52c6bae..96b1261 100644
--- a/src/kimchi/model/interfaces.py
+++ b/src/kimchi/model/interfaces.py
@@ -42,5 +42,5 @@ class InterfaceModel(object):
     def lookup(self, name):
         try:
             return netinfo.get_interface_info(name)
-        except ValueError, e:
-            raise NotFoundError(e)
+        except ValueError:
+            raise NotFoundError("KCHIFACE0001E", {'name': name})
diff --git a/src/kimchi/model/libvirtstoragepool.py b/src/kimchi/model/libvirtstoragepool.py
index f4dbf2e..f9b395c 100644
--- a/src/kimchi/model/libvirtstoragepool.py
+++ b/src/kimchi/model/libvirtstoragepool.py
@@ -38,7 +38,7 @@ class StoragePoolDef(object):
         for klass in cls.__subclasses__():
             if poolArgs['type'] == klass.poolType:
                 return klass(poolArgs)
-        raise OperationFailed('Unsupported pool type: %s' % poolArgs['type'])
+        raise OperationFailed("KCHPOOL0014E", {'type': poolArgs['type']})
 
     def __init__(self, poolArgs):
         self.poolArgs = poolArgs
@@ -56,7 +56,7 @@ class StoragePoolDef(object):
         idempotent'''
         # TODO: When add new pool type, should also add the related test in
         # tests/test_storagepool.py
-        raise OperationFailed('self.xml is not implemented: %s' % self)
+        raise OperationFailed("KCHPOOL0015E", {'pool': self})
 
 
 class DirPoolDef(StoragePoolDef):
@@ -101,8 +101,7 @@ class NetfsPoolDef(StoragePoolDef):
                 run_command(mount_cmd, 30)
                 rollback.prependDefer(run_command, umount_cmd)
             except TimeoutExpired:
-                err = "Export path %s may block during nfs mount"
-                raise InvalidParameter(err % export_path)
+                raise InvalidParameter("KCHPOOL0012E", {'path': export_path})
 
             with open("/proc/mounts", "rb") as f:
                 rawMounts = f.read()
@@ -113,8 +112,7 @@ class NetfsPoolDef(StoragePoolDef):
                     mounted = True
 
             if not mounted:
-                err = "Export path %s mount failed during nfs mount"
-                raise InvalidParameter(err % export_path)
+                raise InvalidParameter("KCHPOOL0013E", {'path': export_path})
 
     @property
     def xml(self):
@@ -181,8 +179,8 @@ class IscsiPoolDef(StoragePoolDef):
     def prepare(self, conn):
         source = self.poolArgs['source']
         if not TargetClient(**source).validate():
-            raise OperationFailed("Can not login to iSCSI host %s target %s" %
-                                  (source['host'], source['target']))
+            msg_args = {'host': source['host'], 'target': source['target']}
+            raise OperationFailed("KCHISCSI0002E", msg_args)
         self._prepare_auth(conn)
 
     def _prepare_auth(self, conn):
diff --git a/src/kimchi/model/networks.py b/src/kimchi/model/networks.py
index b164141..05105df 100644
--- a/src/kimchi/model/networks.py
+++ b/src/kimchi/model/networks.py
@@ -39,7 +39,7 @@ class NetworksModel(object):
         conn = self.conn.get()
         name = params['name']
         if name in self.get_list():
-            raise InvalidOperation("Network %s already exists" % name)
+            raise InvalidOperation("KCHNET0001E", {'name': name})
 
         connection = params["connection"]
         # set forward mode, isolated do not need forward
@@ -60,7 +60,8 @@ class NetworksModel(object):
             network = conn.networkDefineXML(xml)
             network.setAutostart(True)
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHNET0008E",
+                                  {'name': name, 'err': e.get_error_message()})
 
         return name
 
@@ -80,13 +81,13 @@ class NetworksModel(object):
                 subnet and net_addrs.append(ipaddr.IPNetwork(subnet))
             netaddr = knetwork.get_one_free_network(net_addrs)
             if not netaddr:
-                raise OperationFailed("can not find a free IP address for "
-                                      "network '%s'" % params['name'])
+                raise OperationFailed("KCHNET0009E", {'name': params['name']})
 
         try:
             ip = ipaddr.IPNetwork(netaddr)
-        except ValueError as e:
-            raise InvalidParameter("%s" % e)
+        except ValueError:
+            raise InvalidParameter("KCHNET0003E", {'subent': netaddr,
+                                                   'network': params['name']})
 
         if ip.ip == ip.network:
             ip.ip = ip.ip + 1
@@ -101,10 +102,11 @@ class NetworksModel(object):
         try:
             iface = params['interface']
             if iface in self.get_all_networks_interfaces():
-                raise InvalidParameter("interface '%s' already in use." %
-                                       iface)
-        except KeyError, e:
-            raise MissingParameter(e)
+                msg_args = {'iface': iface, 'network': params['name']}
+                raise InvalidParameter("KCHNET0006E", msg_args)
+        except KeyError:
+            raise MissingParameter("KCHNET0004E", {'name': params['name']})
+
         if netinfo.is_bridge(iface):
             params['bridge'] = iface
         elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
@@ -115,8 +117,7 @@ class NetworksModel(object):
                     self._create_vlan_tagged_bridge(str(iface),
                                                     str(params['vlan_id']))
         else:
-            raise InvalidParameter("the interface should be bare nic, "
-                                   "bonding or bridge device.")
+            raise InvalidParameter("KCHNET0007E")
 
     def get_all_networks_interfaces(self):
         net_names = self.get_list()
@@ -144,7 +145,8 @@ class NetworksModel(object):
             vlan_tagged_br.create()
         except libvirt.libvirtError as e:
             conn.changeRollback()
-            raise OperationFailed(e.message)
+            raise OperationFailed("KCHNET0010E", {'iface': interface,
+                                                  'err': e.message})
         else:
             conn.changeCommit()
             return br_name
@@ -211,8 +213,8 @@ class NetworkModel(object):
     def delete(self, name):
         network = self._get_network(name)
         if network.isActive():
-            raise InvalidOperation(
-                "Unable to delete the active network %s" % name)
+            raise InvalidOperation("KCHNET0005E", {'name': name})
+
         self._remove_vlan_tagged_bridge(network)
         network.undefine()
 
@@ -220,9 +222,8 @@ class NetworkModel(object):
         conn = self.conn.get()
         try:
             return conn.networkLookupByName(name)
-        except libvirt.libvirtError as e:
-            raise NotFoundError("Network '%s' not found: %s" %
-                                (name, e.get_error_message()))
+        except libvirt.libvirtError:
+            raise NotFoundError("KCHNET0002E", {'name': name})
 
     @staticmethod
     def get_network_from_xml(xml):
diff --git a/src/kimchi/model/storagepools.py b/src/kimchi/model/storagepools.py
index 233a8a7..fa73ce9 100644
--- a/src/kimchi/model/storagepools.py
+++ b/src/kimchi/model/storagepools.py
@@ -55,7 +55,8 @@ class StoragePoolsModel(object):
             names += conn.listDefinedStoragePools()
             return sorted(names)
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHPOOL0006E",
+                                  {'err': e.get_error_message()})
 
     def create(self, params):
         task_id = None
@@ -63,19 +64,19 @@ class StoragePoolsModel(object):
         try:
             name = params['name']
             if name in (ISO_POOL_NAME, ):
-                raise InvalidOperation("StoragePool already exists")
+                raise InvalidOperation("KCHPOOL0001E", {'name': name})
 
             if params['type'] == 'kimchi-iso':
                 task_id = self._do_deep_scan(params)
             poolDef = StoragePoolDef.create(params)
             poolDef.prepare(conn)
             xml = poolDef.xml
-        except KeyError, key:
-            raise MissingParameter(key)
+        except KeyError, item:
+            raise MissingParameter("KCHPOOL0004E",
+                                   {'item': item, 'name': name})
 
         if name in self.get_list():
-            err = "The name %s has been used by a pool"
-            raise InvalidOperation(err % name)
+            raise InvalidOperation("KCHPOOL0001E", {'name': name})
 
         try:
             if task_id:
@@ -92,9 +93,9 @@ class StoragePoolsModel(object):
                 # disable autostart for others
                 pool.setAutostart(0)
         except libvirt.libvirtError as e:
-            msg = "Problem creating Storage Pool: %s"
-            kimchi_log.error(msg, e)
-            raise OperationFailed(e.get_error_message())
+            kimchi_log.error("Problem creating Storage Pool: %s", e)
+            raise OperationFailed("KCHPOOL0007E",
+                                  {'name': name, 'err': e.get_error_message()})
         return name
 
     def _clean_scan(self, pool_name):
@@ -144,7 +145,7 @@ class StoragePoolModel(object):
             return conn.storagePoolLookupByName(name)
         except libvirt.libvirtError as e:
             if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_POOL:
-                raise NotFoundError("Storage Pool '%s' not found" % name)
+                raise NotFoundError("KCHTMPL0002E", {'name': name})
             else:
                 raise
 
@@ -156,7 +157,8 @@ class StoragePoolModel(object):
             else:
                 return 0
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHPOOL0008E",
+                                  {'name': pool, 'err': e.get_error_message()})
 
     def _get_storage_source(self, pool_type, pool_xml):
         source = {}
@@ -203,7 +205,8 @@ class StoragePoolModel(object):
     def update(self, name, params):
         autostart = params['autostart']
         if autostart not in [True, False]:
-            raise InvalidOperation("Autostart flag must be true or false")
+            raise InvalidOperation("KCHPOOL0003E")
+
         pool = self.get_storagepool(name, self.conn)
         if autostart:
             pool.setAutostart(1)
@@ -217,24 +220,26 @@ class StoragePoolModel(object):
         try:
             pool.create(0)
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHPOOL0009E",
+                                  {'name': name, 'err': e.get_error_message()})
 
     def deactivate(self, name):
         pool = self.get_storagepool(name, self.conn)
         try:
             pool.destroy()
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHPOOL0010E",
+                                  {'name': name, 'err': e.get_error_message()})
 
     def delete(self, name):
         pool = self.get_storagepool(name, self.conn)
         if pool.isActive():
-            err = "Unable to delete the active storagepool %s"
-            raise InvalidOperation(err % name)
+            raise InvalidOperation("KCHPOOL0005E", {'name': name})
         try:
             pool.undefine()
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHPOOL0011E",
+                                  {'name': name, 'err': e.get_error_message()})
 
 
 class IsoPoolModel(object):
diff --git a/src/kimchi/model/storageservers.py b/src/kimchi/model/storageservers.py
index 6a7c14a..26e1f6f 100644
--- a/src/kimchi/model/storageservers.py
+++ b/src/kimchi/model/storageservers.py
@@ -75,4 +75,4 @@ class StorageServerModel(object):
                 # lookup
                 pass
 
-        raise NotFoundError('server %s does not used by kimchi' % server)
+        raise NotFoundError("KCHSR0001E", {'server': server})
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py
index 8440a76..e3f00ca 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -57,29 +57,33 @@ class StorageVolumesModel(object):
         params.setdefault('allocation', 0)
         params.setdefault('format', 'qcow2')
 
+        name = params['name']
         try:
             pool = StoragePoolModel.get_storagepool(pool, self.conn)
-            name = params['name']
             xml = vol_xml % params
-        except KeyError, key:
-            raise MissingParameter(key)
+        except KeyError, item:
+            raise MissingParameter("KCHVOL0004E", {'item': item,
+                                                   'volume': name})
 
         try:
             pool.createXML(xml, 0)
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHVOL0007E",
+                                  {'name': name, 'pool': pool,
+                                   'err': e.get_error_message()})
         return name
 
-    def get_list(self, pool):
-        pool = StoragePoolModel.get_storagepool(pool, self.conn)
+    def get_list(self, pool_name):
+        pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
         if not pool.isActive():
-            err = "Unable to list volumes in inactive storagepool %s"
-            raise InvalidOperation(err % pool.name())
+            raise InvalidOperation("KCHVOL0006E", {'pool': pool_name})
         try:
             pool.refresh(0)
             return pool.listVolumes()
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHVOL0008E",
+                                  {'pool': pool_name,
+                                   'err': e.get_error_message()})
 
 
 class StorageVolumeModel(object):
@@ -89,13 +93,13 @@ class StorageVolumeModel(object):
     def _get_storagevolume(self, pool, name):
         pool = StoragePoolModel.get_storagepool(pool, self.conn)
         if not pool.isActive():
-            err = "Unable to list volumes in inactive storagepool %s"
-            raise InvalidOperation(err % pool.name())
+            raise InvalidOperation("KCHVOL0006E", {'name': pool})
         try:
             return pool.storageVolLookupByName(name)
         except libvirt.libvirtError as e:
             if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_VOL:
-                raise NotFoundError("Storage Volume '%s' not found" % name)
+                raise NotFoundError("KCHVOL0002E", {'name': name,
+                                                    'pool': pool})
             else:
                 raise
 
@@ -131,14 +135,16 @@ class StorageVolumeModel(object):
         try:
             volume.wipePattern(libvirt.VIR_STORAGE_VOL_WIPE_ALG_ZERO, 0)
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHVOL0009E",
+                                  {'name': name, 'err': e.get_error_message()})
 
     def delete(self, pool, name):
         volume = self._get_storagevolume(pool, name)
         try:
             volume.delete(0)
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHVOL0010E",
+                                  {'name': name, 'err': e.get_error_message()})
 
     def resize(self, pool, name, size):
         size = size << 20
@@ -146,7 +152,8 @@ class StorageVolumeModel(object):
         try:
             volume.resize(size, 0)
         except libvirt.libvirtError as e:
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHVOL0011E",
+                                  {'name': name, 'err': e.get_error_message()})
 
 
 class IsoVolumesModel(object):
diff --git a/src/kimchi/model/templates.py b/src/kimchi/model/templates.py
index 03632a6..0eb7faa 100644
--- a/src/kimchi/model/templates.py
+++ b/src/kimchi/model/templates.py
@@ -25,7 +25,7 @@ import copy
 import libvirt
 
 from kimchi import xmlutils
-from kimchi.exception import InvalidOperation, InvalidParameter, NotFoundError
+from kimchi.exception import InvalidOperation, InvalidParameter
 from kimchi.utils import pool_name_from_uri
 from kimchi.vmtemplate import VMTemplate
 
@@ -44,20 +44,20 @@ class TemplatesModel(object):
             pool_name = pool_name_from_uri(pool_uri)
             try:
                 conn.storagePoolLookupByName(pool_name)
-            except Exception as e:
-                err = "Storagepool specified is not valid: %s."
-                raise InvalidParameter(err % e.message)
+            except Exception:
+                raise InvalidParameter("KCHTMPL0004E", {'pool': pool_name,
+                                                        'template': name})
 
         for net_name in params.get(u'networks', []):
             try:
                 conn.networkLookupByName(net_name)
-            except Exception, e:
-                raise InvalidParameter("Network '%s' specified by template "
-                                       "does not exist." % net_name)
+            except Exception:
+                raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
+                                                        'template': name})
 
         with self.objstore as session:
             if name in session.get_list('template'):
-                raise InvalidOperation("Template already exists")
+                raise InvalidOperation("KCHTMPL0001E", {'name': name})
             t = LibvirtVMTemplate(params, scan=True)
             session.store('template', name, t.info)
         return name
@@ -100,17 +100,17 @@ class TemplateModel(object):
         try:
             conn = self.conn.get()
             conn.storagePoolLookupByName(pool_name)
-        except Exception as e:
-            err = "Storagepool specified is not valid: %s."
-            raise InvalidParameter(err % e.message)
+        except Exception:
+            raise InvalidParameter("KCHTMPL0004E", {'pool': pool_name,
+                                                    'template': name})
 
         for net_name in params.get(u'networks', []):
             try:
                 conn = self.conn.get()
                 conn.networkLookupByName(net_name)
-            except Exception, e:
-                raise InvalidParameter("Network '%s' specified by template "
-                                       "does not exist" % net_name)
+            except Exception:
+                raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
+                                                        'template': name})
 
         self.delete(name)
         try:
@@ -133,12 +133,12 @@ class LibvirtVMTemplate(VMTemplate):
             conn = self.conn.get()
             pool = conn.storagePoolLookupByName(pool_name)
         except libvirt.libvirtError:
-            err = 'Storage specified by template does not exist'
-            raise InvalidParameter(err)
+            raise InvalidParameter("KCHTMPL0004E", {'pool': pool_name,
+                                                    'template': self.name})
 
         if not pool.isActive():
-            err = 'Storage specified by template is not active'
-            raise InvalidParameter(err)
+            raise InvalidParameter("KCHTMPL0005E", {'pool': pool_name,
+                                                    'template': self.name})
 
         return pool
 
@@ -149,12 +149,12 @@ class LibvirtVMTemplate(VMTemplate):
                 conn = self.conn.get()
                 network = conn.networkLookupByName(name)
             except libvirt.libvirtError:
-                err = 'Network specified by template does not exist'
-                raise InvalidParameter(err)
+                raise InvalidParameter("KCHTMPL0003E", {'network': name,
+                                                        'template': self.name})
 
             if not network.isActive():
-                err = 'Network specified by template is not active'
-                raise InvalidParameter(err)
+                raise InvalidParameter("KCHTMPL0007E", {'network': name,
+                                                        'template': self.name})
 
     def _get_storage_path(self):
         pool = self._storage_validate()
diff --git a/src/kimchi/model/utils.py b/src/kimchi/model/utils.py
index a27b867..b642f05 100644
--- a/src/kimchi/model/utils.py
+++ b/src/kimchi/model/utils.py
@@ -30,4 +30,4 @@ def get_vm_name(vm_name, t_name, name_list):
         vm_name = "%s-vm-%i" % (t_name, i)
         if vm_name not in name_list:
             return vm_name
-    raise OperationFailed("Unable to choose a VM name")
+    raise OperationFailed("KCHUTILS0003E")
diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py
index f3eddb2..f526e0d 100644
--- a/src/kimchi/model/vmifaces.py
+++ b/src/kimchi/model/vmifaces.py
@@ -52,13 +52,12 @@ class VMIfacesModel(object):
         networks = conn.listNetworks() + conn.listDefinedNetworks()
 
         if params["type"] == "network" and params["network"] not in networks:
-            raise InvalidParameter("%s is not an available network" %
-                                   params["network"])
+            raise InvalidParameter("KCHVMIF0002E",
+                                   {'name': vm, 'network': params["network"]})
 
         dom = VMModel.get_vm(vm, self.conn)
         if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
-            raise InvalidOperation("do not support hot plugging attach "
-                                   "guest interface")
+            raise InvalidOperation("KCHVMIF0003E")
 
         macs = (iface.mac.get('address')
                 for iface in self.get_vmifaces(vm, self.conn))
@@ -108,7 +107,7 @@ class VMIfaceModel(object):
 
         iface = self._get_vmiface(vm, mac)
         if iface is None:
-            raise NotFoundError('iface: "%s"' % mac)
+            raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
 
         info['type'] = iface.attrib['type']
         info['mac'] = iface.mac.get('address')
@@ -126,10 +125,10 @@ class VMIfaceModel(object):
         iface = self._get_vmiface(vm, mac)
 
         if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
-            raise InvalidOperation("do not support hot plugging detach "
-                                   "guest interface")
+            raise InvalidOperation("KCHVMIF0003E")
+
         if iface is None:
-            raise NotFoundError('iface: "%s"' % mac)
+            raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
 
         dom.detachDeviceFlags(etree.tostring(iface),
                               libvirt.VIR_DOMAIN_AFFECT_CURRENT)
diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py
index d4384a1..d9e4f20 100644
--- a/src/kimchi/model/vms.py
+++ b/src/kimchi/model/vms.py
@@ -163,7 +163,7 @@ class VMsModel(object):
         name = get_vm_name(params.get('name'), t_name, vm_list)
         # incoming text, from js json, is unicode, do not need decode
         if name in vm_list:
-            raise InvalidOperation("VM already exists")
+            raise InvalidOperation("KCHVM0001E", {'name': name})
 
         vm_overrides = dict()
         pool_uri = params.get('storagepool')
@@ -173,8 +173,7 @@ class VMsModel(object):
                                        vm_overrides)
 
         if not self.caps.qemu_stream and t.info.get('iso_stream', False):
-            err = "Remote ISO image is not supported by this server."
-            raise InvalidOperation(err)
+            raise InvalidOperation("KCHVM0005E")
 
         t.validate()
         vol_list = t.fork_vm_storage(vm_uuid)
@@ -201,7 +200,8 @@ class VMsModel(object):
             for v in vol_list:
                 vol = conn.storageVolLookupByPath(v['path'])
                 vol.delete(0)
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHVM0007E", {'name': name,
+                                                 'err': e.get_error_message()})
 
         return name
 
@@ -237,15 +237,16 @@ class VMModel(object):
         try:
             if 'name' in params:
                 if state == 'running':
-                    err = "VM name only can be updated when vm is powered off."
-                    raise InvalidParameter(err)
+                    msg_args = {'name': dom.name(), 'new_name': params['name']}
+                    raise InvalidParameter("KCHVM0003E", msg_args)
                 else:
                     dom.undefine()
             conn = self.conn.get()
             dom = conn.defineXML(new_xml)
         except libvirt.libvirtError as e:
             dom = conn.defineXML(old_xml)
-            raise OperationFailed(e.get_error_message())
+            raise OperationFailed("KCHVM0008E", {'name': dom.name(),
+                                                 'err': e.get_error_message()})
         return dom
 
     def _live_vm_update(self, dom, params):
@@ -308,8 +309,8 @@ class VMModel(object):
         except NotFoundError:
             return False
         except Exception, e:
-            err = "Unable to retrieve VM '%s': %s"
-            raise OperationFailed(err % (name, e.message))
+            raise OperationFailed("KCHVM0009E", {'name': name,
+                                                 'err': e.message})
 
     @staticmethod
     def get_vm(name, conn):
@@ -319,7 +320,7 @@ class VMModel(object):
             return conn.lookupByName(name.encode("utf-8"))
         except libvirt.libvirtError as e:
             if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
-                raise NotFoundError("Virtual Machine '%s' not found" % name)
+                raise NotFoundError("KCHVM0002E", {'name': name})
             else:
                 raise
 
@@ -384,8 +385,7 @@ class VMModel(object):
         if graphics_port is not None:
             vnc.add_proxy_token(name, graphics_port)
         else:
-            raise OperationFailed("Only able to connect to running vm's vnc "
-                                  "graphics.")
+            raise OperationFailed("KCHVM0010E", {'name': name})
 
     def _vmscreenshot_delete(self, vm_uuid):
         screenshot = VMScreenshotModel.get_screenshot(vm_uuid, self.objstore,
@@ -405,7 +405,7 @@ class VMScreenshotModel(object):
         d_info = dom.info()
         vm_uuid = dom.UUIDString()
         if DOM_STATE_MAP[d_info[0]] != 'running':
-            raise NotFoundError('No screenshot for stopped vm')
+            raise NotFoundError("KCHVM0004E", {'name': name})
 
         screenshot = self.get_screenshot(vm_uuid, self.objstore, self.conn)
         img_path = screenshot.lookup()
@@ -448,7 +448,7 @@ class LibvirtVMScreenshot(VMScreenshot):
                 stream.abort()
             except:
                 pass
-            raise NotFoundError("Screenshot not supported for %s" % vm_name)
+            raise NotFoundError("KCHVM0006E", {'name': vm_name})
         else:
             stream.finish()
         finally:
diff --git a/src/kimchi/objectstore.py b/src/kimchi/objectstore.py
index 7b567f3..5cb8ae1 100644
--- a/src/kimchi/objectstore.py
+++ b/src/kimchi/objectstore.py
@@ -54,7 +54,7 @@ class ObjectStoreSession(object):
             jsonstr = res.fetchall()[0][0]
         except IndexError:
             self.conn.rollback()
-            raise NotFoundError(ident)
+            raise NotFoundError("KCHOBJST0001E", {'item': ident})
         return json.loads(jsonstr)
 
     def delete(self, obj_type, ident, ignore_missing=False):
@@ -63,7 +63,7 @@ class ObjectStoreSession(object):
                   (obj_type, ident))
         if c.rowcount != 1 and not ignore_missing:
             self.conn.rollback()
-            raise NotFoundError(ident)
+            raise NotFoundError("KCHOBJST0001E", {'item': ident})
         self.conn.commit()
 
     def store(self, obj_type, ident, data):
diff --git a/src/kimchi/template.py b/src/kimchi/template.py
index 173e7c6..fd1d591 100644
--- a/src/kimchi/template.py
+++ b/src/kimchi/template.py
@@ -27,6 +27,7 @@ import json
 import os
 
 
+from kimchi.config import paths
 from Cheetah.Template import Template
 from glob import iglob
 
@@ -53,7 +54,6 @@ def get_lang():
 
 
 def get_support_languages():
-    paths = cherrypy.request.app.root.paths
     mopath = "%s/*" % paths.mo_dir
     return [path.rsplit('/', 1)[1] for path in iglob(mopath)]
 
diff --git a/src/kimchi/utils.py b/src/kimchi/utils.py
index 8795957..a1410c0 100644
--- a/src/kimchi/utils.py
+++ b/src/kimchi/utils.py
@@ -29,12 +29,10 @@ import urllib2
 from threading import Timer
 
 from cherrypy.lib.reprconf import Parser
-from kimchi.config import paths, PluginPaths
-from kimchi.exception import TimeoutExpired
-
 
 from kimchi.asynctask import AsyncTask
-from kimchi.exception import InvalidParameter
+from kimchi.config import paths, PluginPaths
+from kimchi.exception import InvalidParameter, TimeoutExpired
 
 
 kimchi_log = cherrypy.log.error_log
@@ -45,7 +43,7 @@ def _uri_to_name(collection, uri):
     expr = '/%s/(.*?)/?$' % collection
     m = re.match(expr, uri)
     if not m:
-        raise InvalidParameter(uri)
+        raise InvalidParameter("KCHUTILS0001E", {'uri': uri})
     return m.group(1)
 
 
@@ -169,7 +167,9 @@ def run_command(cmd, timeout=None):
             msg = ("subprocess is killed by signal.SIGKILL for "
                    "timeout %s seconds" % timeout)
             kimchi_log.error(msg)
-            raise TimeoutExpired(msg)
+
+            msg_args = {'cmd': cmd, 'seconds': timeout}
+            raise TimeoutExpired("KCHUTILS0002E", msg_args)
 
         return out, error, proc.returncode
     except TimeoutExpired:
diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
index 58147e3..7aa0a65 100644
--- a/src/kimchi/vmtemplate.py
+++ b/src/kimchi/vmtemplate.py
@@ -27,7 +27,6 @@ import urllib
 import urlparse
 
 
-from kimchi import isoinfo
 from kimchi import osinfo
 from kimchi.exception import InvalidParameter, IsoFormatError
 from kimchi.isoinfo import IsoImage
@@ -58,7 +57,7 @@ class VMTemplate(object):
 
             iso_prefixes = ['/', 'http', 'https', 'ftp', 'ftps', 'tftp']
             if len(filter(iso.startswith, iso_prefixes)) == 0:
-                raise InvalidParameter("Invalid parameter specified for cdrom.")
+                raise InvalidParameter("KCHTMPL0006E", {'param': iso})
 
             if not iso.startswith('/'):
                 self.info.update({'iso_stream': True})
@@ -66,8 +65,8 @@ class VMTemplate(object):
             try:
                 iso_img = IsoImage(iso)
                 iso_distro, iso_version = iso_img.probe()
-            except IsoFormatError, e:
-                raise InvalidParameter(e)
+            except IsoFormatError:
+                raise InvalidParameter("KCHISO0001E", {'filename': iso})
 
         # Fetch defaults based on the os distro and version
         os_distro = args.get('os_distro', iso_distro)
diff --git a/tests/test_exception.py b/tests/test_exception.py
index b64ab94..79c8e4f 100644
--- a/tests/test_exception.py
+++ b/tests/test_exception.py
@@ -77,8 +77,8 @@ class ExceptionTests(unittest.TestCase):
         # test 400 missing required parameter
         req = json.dumps({})
         resp = json.loads(request(host, port, '/vms', req, 'POST').read())
-        msg = u"Invalid parameter: 'u'template' is a required property'"
         self.assertEquals('400 Bad Request', resp.get('code'))
+        msg = u"KCHVM0016E: Specify a template to create a Virtual Machine from"
         self.assertEquals(msg, resp.get('reason'))
         self.assertNotIn('call_stack', resp)
 
@@ -107,7 +107,7 @@ class ExceptionTests(unittest.TestCase):
         # test 400 missing required parameter
         req = json.dumps({})
         resp = json.loads(request(host, port, '/vms', req, 'POST').read())
-        msg = u"Invalid parameter: 'u'template' is a required property'"
+        msg = u"KCHVM0016E: Specify a template to create a Virtual Machine from"
         self.assertEquals('400 Bad Request', resp.get('code'))
         self.assertEquals(msg, resp.get('reason'))
         self.assertIn('call_stack', resp)
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 0ed293b..4b58e18 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -568,7 +568,7 @@ class RestTests(unittest.TestCase):
         resp = self.request('/vms', req, 'POST')
         self.assertEquals(400, resp.status)
         resp = json.loads(resp.read())
-        self.assertIn('Invalid parameter', resp['reason'])
+        self.assertIn(u"KCHVM0016E:", resp['reason'])
 
     def test_create_vm_with_bad_template_uri(self):
         req = json.dumps({'name': 'vm-bad-template',
@@ -576,7 +576,7 @@ class RestTests(unittest.TestCase):
         resp = self.request('/vms', req, 'POST')
         self.assertEquals(400, resp.status)
         resp = json.loads(resp.read())
-        self.assertIn('Invalid parameter', resp['reason'])
+        self.assertIn(u"KCHVM0012E", resp['reason'])
 
     def test_get_storagepools(self):
         storagepools = json.loads(self.request('/storagepools').read())
diff --git a/tests/utils.py b/tests/utils.py
index 40dfae2..14c57d4 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -155,8 +155,9 @@ def patch_auth():
     def _authenticate(username, password, service="passwd"):
         try:
             return fake_user[username] == password
-        except KeyError:
-            raise OperationFailed('Bad login')
+        except KeyError, e:
+            raise OperationFailed("KCHAUTH0001E", {'userid': 'username',
+                                                   'code': e.message})
 
     import kimchi.auth
     kimchi.auth.authenticate = _authenticate
-- 
1.7.10.4




More information about the Kimchi-devel mailing list