コード例 #1
0
ファイル: repositories.py プロジェクト: xingchuang/gingerbase
    def toggleRepo(self, repo_id, enable):
        """
        Enable a given repository
        """
        r = self._get_source_entry(repo_id)
        if r is None:
            raise NotFoundError('GGBREPOS0012E', {'repo_id': repo_id})

        if enable and not r.disabled:
            raise InvalidOperation('GGBREPOS0015E', {'repo_id': repo_id})

        if not enable and r.disabled:
            raise InvalidOperation('GGBREPOS0016E', {'repo_id': repo_id})

        if enable:
            line = 'deb'
        else:
            line = '#deb'

        gingerBaseLock.acquire()
        try:
            repos = self._get_repos()
            repos.remove(r)
            repos.add(line, r.uri, r.dist, r.comps, file=self.filename)
            repos.save()
        except Exception:
            if enable:
                raise OperationFailed('GGBREPOS0020E', {'repo_id': repo_id})

            raise OperationFailed('GGBREPOS0021E', {'repo_id': repo_id})
        finally:
            gingerBaseLock.release()

        return repo_id
コード例 #2
0
ファイル: repositories.py プロジェクト: xingchuang/gingerbase
    def toggleRepo(self, repo_id, enable):
        repos = self._get_repos('GGBREPOS0011E')
        if repo_id not in repos.keys():
            raise NotFoundError('GGBREPOS0012E', {'repo_id': repo_id})

        entry = repos.get(repo_id)
        if enable and entry.enabled:
            raise InvalidOperation('GGBREPOS0015E', {'repo_id': repo_id})

        if not enable and not entry.enabled:
            raise InvalidOperation('GGBREPOS0016E', {'repo_id': repo_id})

        gingerBaseLock.acquire()
        try:
            if enable:
                entry.enable()
            else:
                entry.disable()

            write_repo_to_file(entry)
        except Exception:
            if enable:
                raise OperationFailed('GGBREPOS0020E', {'repo_id': repo_id})

            raise OperationFailed('GGBREPOS0021E', {'repo_id': repo_id})
        finally:
            gingerBaseLock.release()

        return repo_id
コード例 #3
0
ファイル: repositories.py プロジェクト: xingchuang/gingerbase
    def addRepo(self, params):
        """
        Add a given repository to YumBase
        """
        # At least one base url, or one mirror, must be given.
        baseurl = params.get('baseurl', '')

        config = params.get('config', {})
        mirrorlist = config.get('mirrorlist', '')
        metalink = config.get('metalink', '')
        if not baseurl and not mirrorlist and not metalink:
            raise MissingParameter('GGBREPOS0013E')

        if baseurl:
            validate_repo_url(get_expanded_url(baseurl))

        if mirrorlist:
            validate_repo_url(get_expanded_url(mirrorlist))

        if metalink:
            validate_repo_url(get_expanded_url(metalink))

        if mirrorlist and metalink:
            raise InvalidOperation('GGBREPOS0030E')

        repo_id = params.get('repo_id', None)
        if repo_id is None:
            repo_id = 'gingerbase_repo_%s' % str(int(time.time() * 1000))

        repos = self._get_repos('GGBREPOS0026E')
        if repo_id in repos.keys():
            raise InvalidOperation('GGBREPOS0022E', {'repo_id': repo_id})

        repo_name = config.get('repo_name', repo_id)
        repo = {
            'baseurl': baseurl,
            'mirrorlist': mirrorlist,
            'name': repo_name,
            'gpgcheck': 1,
            'gpgkey': [],
            'enabled': 1,
            'metalink': metalink
        }

        # write a repo file in the system with repo{} information.
        parser = SafeConfigParser()
        parser.add_section(repo_id)

        for key, value in repo.items():
            if value:
                parser.set(repo_id, key, value)

        repofile = os.path.join(self._confdir, repo_id + '.repo')
        try:
            with open(repofile, 'w') as fd:
                parser.write(fd)
        except Exception:
            raise OperationFailed('GGBREPOS0018E', {'repo_file': repofile})

        return repo_id
コード例 #4
0
    def delete(self, name):
        if self._pool_used_by_template(name):
            raise InvalidOperation('KCHPOOL0035E', {'name': name})

        pool = self.get_storagepool(name, self.conn)
        if pool.isActive():
            raise InvalidOperation("KCHPOOL0005E", {'name': name})
        try:
            pool.undefine()
        except libvirt.libvirtError as e:
            raise OperationFailed("KCHPOOL0011E",
                                  {'name': name, 'err': e.get_error_message()})
コード例 #5
0
    def delete(self, name):
        if self._is_network_in_use(name):
            vms = self._get_vms_attach_to_a_network(name)
            vms.sort()
            raise InvalidOperation("KCHNET0017E", {'name': name,
                                                   'vms': ', '.join(vms)})

        network = self.get_network(self.conn.get(), name)
        if network.isActive():
            raise InvalidOperation("KCHNET0005E", {'name': name})

        self._remove_vlan_tagged_bridge(network)
        network.undefine()
コード例 #6
0
ファイル: networks.py プロジェクト: zeropool/kimchi
    def delete(self, name):
        in_use, used_by_vms, used_by_tmpls = self._is_network_in_use(name)
        vms = 'N/A' if len(used_by_vms) == 0 else ', '.join(used_by_vms)
        tmpls = 'N/A' if len(used_by_tmpls) == 0 else ', '.join(used_by_tmpls)
        if in_use:
            raise InvalidOperation("KCHNET0017E", {'name': name,
                                                   'vms': vms,
                                                   'tmpls': tmpls})

        network = self.get_network(self.conn.get(), name)
        if network.isActive():
            raise InvalidOperation("KCHNET0005E", {'name': name})

        self._remove_bridge(network)
        network.undefine()
コード例 #7
0
    def _check_lvm(self, name, from_vg):
        vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')]
        output, error, returncode = run_command(vgdisplay_cmd)
        # From vgdisplay error codes:
        # 1  error reading VGDA
        # 2  volume group doesn't exist
        # 3  not all physical volumes of volume group online
        # 4  volume group not found
        # 5  no volume groups found at all
        # 6  error reading VGDA from lvmtab
        if from_vg and returncode in [2, 4, 5]:
            raise InvalidOperation("KCHPOOL0038E", {'name': name})

        if not from_vg and returncode not in [2, 4, 5]:
            raise InvalidOperation("KCHPOOL0036E", {'name': name})
コード例 #8
0
ファイル: vmstorages.py プロジェクト: pengoC/kimchi
    def delete(self, vm_name, dev_name):
        try:
            bus_type = self.lookup(vm_name, dev_name)['bus']
            dom = VMModel.get_vm(vm_name, self.conn)
        except NotFoundError:
            raise

        if (bus_type not in HOTPLUG_TYPE and
                DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
            raise InvalidOperation('KCHVMSTOR0011E')

        try:
            disk = get_device_node(dom, dev_name)
            path = get_vm_disk_info(dom, dev_name)['path']
            if path is None or len(path) < 1:
                path = self.lookup(vm_name, dev_name)['path']
            # This has to be done before it's detached. If it wasn't
            #   in the obj store, its ref count would have been updated
            #   by get_disk_used_by()
            if path is not None:
                used_by = get_disk_used_by(self.objstore, self.conn, path)
            else:
                wok_log.error("Unable to decrement volume used_by on"
                              " delete because no path could be found.")
            dom.detachDeviceFlags(etree.tostring(disk),
                                  get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0010E", {'error': e.message})

        if used_by is not None and vm_name in used_by:
            used_by.remove(vm_name)
            set_disk_used_by(self.objstore, path, used_by)
        else:
            wok_log.error("Unable to update %s:%s used_by on delete."
                          % (vm_name, dev_name))
コード例 #9
0
ファイル: base.py プロジェクト: Seccion7/dep-wok
    def create(self, params, *args):
        try:
            create = getattr(self.model, model_fn(self, 'create'))
        except AttributeError:
            e = InvalidOperation(
                'WOKAPI0005E', {'resource': get_class_name(self)})
            raise cherrypy.HTTPError(405, str(e))

        validate_params(params, self, 'create')
        args = self.model_args + [params]
        task = create(*args)
        cherrypy.response.status = 202

        # log request
        method = 'POST'
        code = self.getRequestMessage(method)
        reqParams = utf8_dict(self.log_args, params)
        log_id = log_request(
            code,
            reqParams,
            None,
            method,
            cherrypy.response.status,
            class_name=get_class_name(self),
        )
        save_request_log_id(log_id, task['id'])

        return wok.template.render('Task', task)
コード例 #10
0
ファイル: base.py プロジェクト: Seccion7/dep-wok
    def delete(self):
        try:
            fn = getattr(self.model, model_fn(self, 'delete'))
            task = fn(*self.model_args)
        except AttributeError:
            e = InvalidOperation(
                'WOKAPI0002E', {'resource': get_class_name(self)})
            raise cherrypy.HTTPError(405, str(e))

        cherrypy.response.status = 202

        # log request
        method = 'DELETE'
        code = self.getRequestMessage(method)
        reqParams = utf8_dict(self.log_args)
        log_id = log_request(
            code,
            reqParams,
            None,
            method,
            cherrypy.response.status,
            class_name=get_class_name(self),
        )
        save_request_log_id(log_id, task['id'])

        return wok.template.render('Task', task)
コード例 #11
0
ファイル: networks.py プロジェクト: Finn10111/kimchi
    def create(self, params):
        conn = self.conn.get()
        name = params['name']
        if name in self.get_list():
            raise InvalidOperation("KCHNET0001E", {'name': name})

        # handle connection type
        connection = params["connection"]
        if connection in ['nat', 'isolated']:
            if connection == 'nat':
                params['forward'] = {'mode': 'nat'}

            # set subnet; bridge/macvtap networks do not need subnet
            self._set_network_subnet(params)
        else:
            self._check_network_interface(params)
            if connection == 'macvtap':
                self._set_network_macvtap(params)
            elif connection == 'bridge':
                self._set_network_bridge(params)
            elif connection == 'vepa':
                self._set_network_vepa(params)

        # create network XML
        params['name'] = escape(params['name'])
        xml = to_network_xml(**params)

        try:
            network = conn.networkDefineXML(xml.encode("utf-8"))
            network.setAutostart(True)
        except libvirt.libvirtError as e:
            raise OperationFailed("KCHNET0008E",
                                  {'name': name, 'err': e.get_error_message()})

        return name
コード例 #12
0
    def deactivate(self, name):
        if self._pool_used_by_template(name):
            raise InvalidOperation('KCHPOOL0034E', {'name': name})

        pool = self.get_storagepool(name, self.conn)
        # FIXME: nfs workaround - do not try to deactivate a NFS pool
        # if the NFS server is not reachable.
        xml = pool.XMLDesc(0)
        pool_type = xpath_get_text(xml, "/pool/@type")[0]
        if pool_type == 'netfs' and not self._nfs_status_online(pool):
            # block the user from dactivating the pool.
            source = self._get_storage_source(pool_type, xml)
            raise OperationFailed("KCHPOOL0033E", {
                'name': name,
                'server': source['addr']
            })
            return
        try:
            persistent = pool.isPersistent()
            pool.destroy()
        except libvirt.libvirtError as e:
            raise OperationFailed("KCHPOOL0010E", {
                'name': name,
                'err': e.get_error_message()
            })
        # If pool was not persistent, then it was erased by destroy() and
        # must return nothing here, to trigger _redirect() and avoid errors
        if not persistent:
            return ""
コード例 #13
0
    def create(self, params):
        conn = self.conn.get()
        name = params['name']
        if name in self.get_list():
            raise InvalidOperation("KCHNET0001E", {'name': name})

        connection = params["connection"]
        # set forward mode, isolated do not need forward
        if connection != 'isolated':
            params['forward'] = {'mode': connection}

        # set subnet, bridge network do not need subnet
        if connection in ["nat", 'isolated']:
            self._set_network_subnet(params)

        # only bridge network need bridge(linux bridge) or interface(macvtap)
        if connection == 'bridge':
            self._set_network_bridge(params)

        params['name'] = escape(params['name'])
        xml = to_network_xml(**params)

        try:
            network = conn.networkDefineXML(xml.encode("utf-8"))
            network.setAutostart(True)
        except libvirt.libvirtError as e:
            raise OperationFailed("KCHNET0008E",
                                  {'name': name, 'err': e.get_error_message()})

        return name
コード例 #14
0
    def create(self, params):
        if utils.is_lun_scan_enabled():
            wok_log.error(
                "Lun scan is enabled. Cannot add/remove LUNs manually.")
            raise InvalidOperation("GS390XSTG00009")

        if 'hbaId' not in params:
            wok_log.error("hbaId is required for adding a LUN")
            raise MissingParameter("GS390XSTG00010")

        hbaId = params['hbaId']
        utils.validate_hba_id(hbaId)

        if 'remoteWwpn' not in params:
            wok_log.error("remoteWwpn is required for adding a LUN")
            raise MissingParameter("GS390XSTG00011")

        wwpn = params['remoteWwpn']
        utils.validate_wwpn_or_lun(wwpn)

        if 'lunId' not in params:
            wok_log.error("lunId is required for adding a LUN")
            raise MissingParameter("GS390XSTG00012")

        lunId = params['lunId']
        utils.validate_wwpn_or_lun(lunId)

        utils.add_lun(hbaId, wwpn, lunId)

        lun_path = hbaId + ":" + wwpn + ":" + lunId
        return lun_path
コード例 #15
0
def _tar_create_archive(directory_path, archive_id, include, exclude_flag):
    archive_file = os.path.join(directory_path, archive_id + '.tar.gz')
    backup_dir = os.path.join(
        PluginPaths('ginger').state_dir, 'ginger_backups')

    bkp = re.compile(backup_dir)
    if filter(bkp.match, include) and (len(include) == 1):
        raise InvalidOperation('GINHBK0012E', {'dir': backup_dir})

    exclude = ['--exclude=' + backup_dir]
    if exclude_flag:
        exclude.extend(
            ['--exclude=' + toExclude for toExclude in exclude_flag])
    cmd = [
        'tar', '--create', '--ignore-failed-read', '--gzip',
        '--absolute-names', '--file', archive_file, '--selinux', '--acl',
        '--xattrs'
    ] + exclude + include
    out, err, rc = run_command(cmd)
    if rc != 0:
        if 'file changed as we read it' in err:
            raise OperationFailed('GINHBK0010E', {'file': err.split(': ')[1]})
        raise OperationFailed('GINHBK0001E', {
            'name': archive_file,
            'cmd': ' '.join(cmd)
        })

    return archive_file
コード例 #16
0
    def create(self, params):
        task_id = None
        conn = self.conn.get()
        from_vg = params.get('source', {}).get('from_vg', False)

        try:
            name = params['name']
            if name == ISO_POOL_NAME:
                raise InvalidOperation("KCHPOOL0031E")

            # The user may want to create a logical pool with the same name
            # used before but a volume group will already exist with this name
            # So check the volume group does not exist to create the pool
            if params['type'] == 'logical':
                self._check_lvm(name, from_vg)

            if params['type'] == 'kimchi-iso':
                task_id = self._do_deep_scan(params)

            if params['type'] == 'scsi':
                adapter_name = params['source']['adapter_name']
                extra_params = self.device.lookup(adapter_name)
                # Adds name, adapter_type, wwpn and wwnn to source information
                params['source'].update(extra_params)
                params['fc_host_support'] = self.caps.fc_host_support

            poolDef = StoragePoolDef.create(params)
            poolDef.prepare(conn)
            xml = poolDef.xml.encode("utf-8")
        except KeyError, item:
            raise MissingParameter("KCHPOOL0004E", {
                'item': str(item),
                'name': name
            })
コード例 #17
0
ファイル: vmifaces.py プロジェクト: zmrblog/kimchi
    def update(self, vm, mac, params):
        dom = VMModel.get_vm(vm, self.conn)
        iface = self._get_vmiface(vm, mac)

        if iface is None:
            raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})

        # cannot change mac address in a running system
        if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
            raise InvalidOperation('KCHVMIF0011E')

        # mac address is a required parameter
        if 'mac' not in params:
            raise MissingParameter('KCHVMIF0008E')

        # new mac address must be unique
        if self._get_vmiface(vm, params['mac']) is not None:
            raise InvalidParameter('KCHVMIF0009E',
                                   {'name': vm, 'mac': params['mac']})

        flags = 0
        if dom.isPersistent():
            flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG

        # remove the current nic
        xml = etree.tostring(iface)
        dom.detachDeviceFlags(xml, flags=flags)

        # add the nic with the desired mac address
        iface.mac.attrib['address'] = params['mac']
        xml = etree.tostring(iface)
        dom.attachDeviceFlags(xml, flags=flags)

        return [vm, params['mac']]
コード例 #18
0
ファイル: smt.py プロジェクト: xingchuang/gingerbase
 def get_current_settings_s390x(self):
     """
     Method to return current SMT settings ('/proc/cmdline')
     for s390x architecture.
     Returns:
     current_smt_settings: dictionary {status, value}
     """
     command = ['cat', '/proc/cmdline']
     threads_per_core = LsCpu().get_threads_per_core()
     output, error, retcode = run_command(command)
     if retcode != 0:
         raise OperationFailed('GINSMT003E', {'error': error})
     elif (SMT_TWO in output or SMT not in output):
         status = 'enabled'
         value = threads_per_core
     elif SMT_ONE in output and threads_per_core < 2:
         status = 'enabled'
         value = 1
     elif NOSMT in output and threads_per_core < 2:
         status = 'disabled'
         value = NOSMT
     else:
         raise InvalidOperation('GINSMT0001E')
     current_smt_settings = {'status': status, 'smt': value}
     return current_smt_settings
コード例 #19
0
ファイル: templates.py プロジェクト: cclauss/kimchi
    def save_template(self, params):

        # Creates the template class with necessary information
        t = LibvirtVMTemplate(params, scan=True, conn=self.conn)

        # Validate cpu info
        t.cpuinfo_validate()

        # Validate memory
        t._validate_memory()

        # Validate volumes
        for disk in t.info.get('disks'):
            volume = disk.get('volume')
            # volume can be None
            if 'volume' in disk.keys():
                self.template_volume_validate(volume, disk['pool'])

        # template with the same name already exists: raise exception
        name = params['name']
        with self.objstore as session:
            if name in session.get_list('template'):
                raise InvalidOperation("KCHTMPL0001E", {'name': name})

        # Store template on objectstore
        try:
            with self.objstore as session:
                session.store('template', name, t.info,
                              get_kimchi_version())
        except InvalidOperation:
            raise
        except Exception, e:
            raise OperationFailed('KCHTMPL0020E', {'err': e.message})
コード例 #20
0
    def delete(self, path):
        if utils.is_lun_scan_enabled():
            wok_log.error(
                "Lun scan is enabled. Cannot add/remote LUNs manually.")
            raise InvalidOperation("GS390XSTG00009")

        path_components = utils.validate_lun_path(path)
        utils.remove_lun(*path_components)
コード例 #21
0
ファイル: smt.py プロジェクト: xingchuang/gingerbase
 def enable(self, name, smt_val):
     """
     Enables the SMT.
     """
     if ARCH.startswith('s390x'):
         self.enable_smt_s390x(name, smt_val)
     else:
         raise InvalidOperation('GINSMT0007E', {'name': 'enable'})
コード例 #22
0
ファイル: smt.py プロジェクト: xingchuang/gingerbase
 def disable(self, name):
     """
     Disables the SMT.
     """
     if ARCH.startswith('s390x'):
         self.disable_smt_s390x(name)
     else:
         raise InvalidOperation('GINSMT0007E', {'name': 'disable'})
コード例 #23
0
 def get_list(self, pool_name):
     pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
     if not pool.isActive():
         raise InvalidOperation("KCHVOL0006E", {'pool': pool_name})
     try:
         pool.refresh(0)
     except Exception, e:
         wok_log.error("Pool refresh failed: %s" % str(e))
コード例 #24
0
    def _detach_device(self, cb, params):
        cb('Detaching device')
        self._cb = cb
        vmid = params['vmid']
        dev_name = params['dev_name']
        dom = params['dom']
        hostdev = params['hostdev']
        lock = params['lock']

        with lock:
            pci_devs = {
                DeviceModel.deduce_dev_name(e, self.conn): e
                for e in hostdev
                if e.attrib['type'] == 'pci'
            }

            dev_info = self.dev_model.lookup(dev_name)
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != 'shutoff':
                raise InvalidOperation(
                    'KCHVMHDEV0006E', {'name': dev_info['name']})

            if not pci_devs.get(dev_name):
                raise NotFoundError(
                    'KCHVMHDEV0001E', {'vmid': vmid, 'dev_name': dev_name}
                )

            dev_name_elem = pci_devs[dev_name]
            self._managed = dev_name_elem.get('managed', 'no') == 'yes'

            # check for multifunction and detach all functions together
            try:
                multi = self.unplug_multifunction_pci(
                    dom, hostdev, dev_name_elem)
            except libvirt.libvirtError:
                multi = False

            # successfully detached all functions: finish operation
            if multi:
                if is_3D_device:
                    devsmodel = VMHostDevsModel(conn=self.conn)
                    devsmodel.update_mmio_guest(vmid, False)

                if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
                    cb('OK', True)
                return

            # detach individually
            xmlstr = etree.tostring(dev_name_elem)
            dom.detachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
            if dev_name_elem.attrib['type'] == 'pci':
                self._delete_affected_pci_devices(dom, dev_name, pci_devs)
            if is_3D_device:
                devsmodel = VMHostDevsModel(conn=self.conn)
                devsmodel.update_mmio_guest(vmid, False)

        if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
            cb('OK', True)
コード例 #25
0
    def delete(self, name):
        if self._pool_used_by_template(name):
            raise InvalidOperation('KCHPOOL0035E', {'name': name})

        pool = self.get_storagepool(name, self.conn)
        if pool.isActive():
            raise InvalidOperation('KCHPOOL0005E', {'name': name})

        vms = self._get_vms_attach_to_storagepool(name)
        if len(vms) > 0:
            raise InvalidOperation(
                'KCHPOOL0039E', {'name': name, 'vms': ','.join(vms)})
        try:
            pool.undefine()
        except libvirt.libvirtError as e:
            raise OperationFailed(
                'KCHPOOL0011E', {'name': name, 'err': e.get_error_message()}
            )
コード例 #26
0
ファイル: base.py プロジェクト: lcorreia/wok
 def delete(self):
     try:
         fn = getattr(self.model, model_fn(self, 'delete'))
         fn(*self.model_args)
         cherrypy.response.status = 204
     except AttributeError:
         e = InvalidOperation('WOKAPI0002E', {'resource':
                                              get_class_name(self)})
         raise cherrypy.HTTPError(405, e.message)
コード例 #27
0
ファイル: storagevolumes.py プロジェクト: zhikun0704/kimchi
 def get_list(self, pool_name):
     pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
     if not pool.isActive():
         raise InvalidOperation('KCHVOL0006E', {'pool': pool_name})
     try:
         pool.refresh(0)
     except Exception as e:
         wok_log.error(f'Pool refresh failed: {e}')
     return sorted(pool.listVolumes())
コード例 #28
0
    def deactivate(self, name):
        if self._is_network_in_use(name):
            vms = self._get_vms_attach_to_a_network(name)
            vms.sort()
            raise InvalidOperation("KCHNET0018E", {'name': name,
                                                   'vms': ', '.join(vms)})

        network = self.get_network(self.conn.get(), name)
        network.destroy()
コード例 #29
0
    def delete(self, name):
        try:

            vg_details = self.lookup(name)
            if vg_details['Cur LV'] > 0:
                raise InvalidOperation('GINVG00017E', {'name': name})

            utils._remove_vg(name)
        except OperationFailed:
            raise OperationFailed("GINVG00004E", {'name': name})
コード例 #30
0
 def delete(self):
     try:
         fn = getattr(self.model, model_fn(self, 'delete'))
         task = fn(*self.model_args)
     except AttributeError:
         e = InvalidOperation('WOKAPI0002E', {'resource':
                                              get_class_name(self)})
         raise cherrypy.HTTPError(405, e.message)
     except OperationFailed, e:
         raise cherrypy.HTTPError(500, e.message)