示例#1
0
    def _storage_validate(self):
        pool_uri = self.info['storagepool']
        pool_name = pool_name_from_uri(pool_uri)
        try:
            conn = self.conn.get()
            pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
        except libvirt.libvirtError:
            raise InvalidParameter("KCHTMPL0004E", {
                'pool': pool_name,
                'template': self.name
            })

        if not pool.isActive():
            raise InvalidParameter("KCHTMPL0005E", {
                'pool': pool_name,
                'template': self.name
            })

        return pool
示例#2
0
 def create(self, params):
     ident = params.get('name').strip()
     # Generate a name with time and millisec precision, if necessary
     if ident is None or ident == "":
         ident = 'report-' + str(int(time.time() * 1000))
     else:
         if ident in self.get_list():
             raise InvalidParameter("KCHDR0008E", {"name": ident})
     taskid = self._gen_debugreport_file(ident)
     return self.task.lookup(taskid)
示例#3
0
    def clone(self, name):
        """Clone a virtual machine based on an existing one.

        The new virtual machine will have the exact same configuration as the
        original VM, except for the name, UUID, MAC addresses and disks. The
        name will have the form "<name>-clone-<number>", with <number> starting
        at 1; the UUID will be generated randomly; the MAC addresses will be
        generated randomly with no conflicts within the original and the new
        VM; and the disks will be new volumes [mostly] on the same storage
        pool, with the same content as the original disks. The storage pool
        'default' will always be used when cloning SCSI and iSCSI disks and
        when the original storage pool cannot hold the new volume.

        An exception will be raised if the virtual machine <name> is not
        shutoff, if there is no available space to copy a new volume to the
        storage pool 'default' (when there was also no space to copy it to the
        original storage pool) and if one of the virtual machine's disks belong
        to a storage pool not supported by Kimchi.

        Parameters:
        name -- The name of the existing virtual machine to be cloned.

        Return:
        A Task running the clone operation.
        """
        name = name.decode('utf-8')

        # VM must be shutoff in order to clone it
        info = self.lookup(name)
        if info['state'] != u'shutoff':
            raise InvalidParameter('KCHVM0033E', {'name': name})

        # the new VM's name will be used as the Task's 'target_uri' so it needs
        # to be defined now.

        vms_being_created = []

        # lookup names of VMs being created right now
        with self.objstore as session:
            task_names = session.get_list('task')
            for tn in task_names:
                t = session.get('task', tn)
                if t['target_uri'].startswith('/vms/'):
                    uri_name = t['target_uri'][5:]  # 5 = len('/vms/')
                    vms_being_created.append(uri_name)

        current_vm_names = self.vms.get_list() + vms_being_created
        new_name = get_next_clone_name(current_vm_names, name)

        # create a task with the actual clone function
        taskid = add_task(u'/vms/%s' % new_name, self._clone_task,
                          self.objstore,
                          {'name': name, 'new_name': new_name})

        return self.task.lookup(taskid)
示例#4
0
文件: utils.py 项目: zofuthan/kimchi
def validate_params(params, instance, action):
    root = cherrypy.request.app.root

    if hasattr(root, 'api_schema'):
        api_schema = root.api_schema
    else:
        return

    operation = model_fn(instance, action)
    validator = Draft3Validator(api_schema, format_checker=FormatChecker())
    request = {operation: params}

    try:
        validator.validate(request)
    except ValidationError, e:
        if e.schema.get('error'):
            raise InvalidParameter(e.schema['error'],
                                   {'value': str(e.instance)})
        else:
            raise InvalidParameter("KCHAPI0008E", {"err": str(e.message)})
示例#5
0
    def delete(self, pool, name):
        pool_info = StoragePoolModel(conn=self.conn,
                                     objstore=self.objstore).lookup(pool)
        if pool_info['type'] in READONLY_POOL_TYPE:
            raise InvalidParameter("KCHVOL0012E", {'type': pool_info['type']})

        volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
        try:
            volume.delete(0)
        except libvirt.libvirtError as e:
            raise OperationFailed("KCHVOL0010E",
                                  {'name': name, 'err': e.get_error_message()})
示例#6
0
    def addRepository(self, params):
        """
        Add and enable a new repository
        """
        config = params.get('config', {})
        extra_keys = list(
            set(config.keys()).difference(set(self._pkg_mnger.CONFIG_ENTRY)))
        if len(extra_keys) > 0:
            raise InvalidParameter("KCHREPOS0028E",
                                   {'items': ",".join(extra_keys)})

        return self._pkg_mnger.addRepo(params)
示例#7
0
    def update(self, name, params):
        old_t = self.lookup(name)
        new_t = copy.copy(old_t)
        new_t.update(params)
        ident = name

        conn = self.conn.get()
        pool_uri = new_t.get(u'storagepool', '')

        if pool_uri:
            try:
                pool_name = pool_name_from_uri(pool_uri)
                pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
            except Exception:
                raise InvalidParameter("KCHTMPL0004E", {
                    'pool': pool_name,
                    'template': name
                })
            tmp_volumes = [
                disk['volume'] for disk in new_t.get('disks', [])
                if 'volume' in disk
            ]
            self.templates.template_volume_validate(tmp_volumes, pool)

        for net_name in params.get(u'networks', []):
            try:
                conn.networkLookupByName(net_name)
            except Exception:
                raise InvalidParameter("KCHTMPL0003E", {
                    'network': net_name,
                    'template': name
                })

        self.delete(name)
        try:
            ident = self.templates.create(new_t)
        except:
            ident = self.templates.create(old_t)
            raise
        return ident
示例#8
0
    def _set_network_bridge(self, params):
        try:
            iface = params['interface']
            if iface in self.get_all_networks_interfaces():
                msg_args = {'iface': iface, 'network': params['name']}
                raise InvalidParameter("KCHNET0006E", msg_args)
        except KeyError:
            raise MissingParameter("KCHNET0004E", {'name': params['name']})

        self._ensure_iface_up(iface)
        if netinfo.is_bridge(iface):
            if 'vlan_id' in params:
                raise InvalidParameter('KCHNET0019E', {'name': iface})
            params['bridge'] = iface
        elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
            if params.get('vlan_id') is None:
                params['forward']['dev'] = iface
            else:
                params['bridge'] = \
                    self._create_vlan_tagged_bridge(str(iface),
                                                    str(params['vlan_id']))
        else:
            raise InvalidParameter("KCHNET0007E")
示例#9
0
    def vmifaces_create(self, vm, params):
        if (params["type"] == "network"
                and params["network"] not in self.networks_get_list()):
            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 iface.info.update({"model": params["model"]}))

        mac = iface.info['mac']
        dom.ifaces[mac] = iface
        return mac
示例#10
0
    def template_volume_validate(self, tmp_volumes, pool):
        kwargs = {'conn': self.conn, 'objstore': self.objstore}
        pool_type = xpath_get_text(pool.XMLDesc(0), "/pool/@type")[0]
        pool_name = unicode(pool.name(), 'utf-8')

        # as we discussion, we do not mix disks from 2 different types of
        # storage pools, for instance: we do not create a template with 2
        # disks, where one comes from a SCSI pool and other is a .img in
        # a DIR pool.
        if pool_type in ['iscsi', 'scsi']:
            if not tmp_volumes:
                raise InvalidParameter("KCHTMPL0018E")

            storagevolumes = __import__("kimchi.model.storagevolumes",
                                        fromlist=[''])
            pool_volumes = storagevolumes.StorageVolumesModel(
                **kwargs).get_list(pool_name)
            vols = set(tmp_volumes) - set(pool_volumes)
            if vols:
                raise InvalidParameter("KCHTMPL0019E", {
                    'pool': pool_name,
                    'volume': vols
                })
示例#11
0
    def create(self, params):
        name = params.get('name', '').strip()
        if not name:
            iso = params['cdrom']
            iso_name = os.path.splitext(iso[iso.rfind('/') + 1:])[0]
            name = iso_name + str(int(time.time() * 1000))
            params['name'] = name

        conn = self.conn.get()

        pool_uri = params.get(u'storagepool', '')
        if pool_uri:
            pool_name = pool_name_from_uri(pool_uri)
            try:
                conn.storagePoolLookupByName(pool_name.encode("utf-8"))
            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:
                raise InvalidParameter("KCHTMPL0003E", {
                    'network': net_name,
                    'template': name
                })

        with self.objstore as session:
            if name in session.get_list('template'):
                raise InvalidOperation("KCHTMPL0001E", {'name': name})
            t = LibvirtVMTemplate(params, scan=True)
            session.store('template', name, t.info)
        return name
示例#12
0
    def update(self, name, params):
        path = config.get_debugreports_path()
        file_pattern = os.path.join(path, name + '.*')
        try:
            file_source = glob.glob(file_pattern)[0]
        except IndexError:
            raise NotFoundError("KCHDR0001E", {'name': name})

        file_target = file_source.replace(name, params['name'])
        if os.path.isfile(file_target):
            raise InvalidParameter('KCHDR0008E', {'name': params['name']})

        shutil.move(file_source, file_target)
        kimchi_log.info('%s renamed to %s' % (file_source, file_target))
        return params['name']
示例#13
0
    def _vm_update_access_metadata(self, dom, params):
        users = groups = None
        if "users" in params:
            users = params["users"]
            for user in users:
                if not self.users.validate(user):
                    raise InvalidParameter("KCHVM0027E",
                                           {'users': user})
        if "groups" in params:
            groups = params["groups"]
            for group in groups:
                if not self.groups.validate(group):
                    raise InvalidParameter("KCHVM0028E",
                                           {'groups': group})

        if users is None and groups is None:
            return

        old_users, old_groups = self._get_access_info(dom)
        users = old_users if users is None else users
        groups = old_groups if groups is None else groups

        node = self._build_access_elem(users, groups)
        set_metadata_node(dom, node, self.caps.metadata_support)
示例#14
0
    def updateRepository(self, repo_id, new_repo={}):
        """
        Update the information of a given repository.
        The input is the repo_id of the repository to be updated and a dict
        with the information to be updated.
        """
        if (len(new_repo) == 0):
            raise InvalidParameter("KCHREPOS0013E")

        repo = self._repo_storage[repo_id]
        repo.update(new_repo)

        del self._repo_storage[repo_id]
        self._repo_storage[repo_id] = repo
        self._pkg_mnger.updateRepo(repo_id, self._repo_storage[repo_id])
示例#15
0
    def _static_vm_update(self, dom, params):
        state = dom.info['state']

        if 'name' in params:
            if state == 'running' or params['name'] in self.vms_get_list():
                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']
                self._mock_vms[dom.name] = dom

        for key, val in params.items():
            if key in VM_STATIC_UPDATE_PARAMS and key in dom.info:
                dom.info[key] = val
示例#16
0
def _check_cdrom_path(path):
    if check_url_path(path):
        src_type = 'network'
    # Check if path is a valid local path
    elif os.path.exists(path):
        if os.path.isfile(path):
            src_type = 'file'
        else:
            # Check if path is a valid cdrom drive
            with open('/proc/sys/dev/cdrom/info') as cdinfo:
                content = cdinfo.read()

            cds = re.findall("drive name:\t\t(.*)", content)
            if not cds:
                raise InvalidParameter("KCHCDROM0003E", {'value': path})

            drives = [os.path.join('/dev', p) for p in cds[0].split('\t')]
            if path not in drives:
                raise InvalidParameter("KCHCDROM0003E", {'value': path})

            src_type = 'block'
    else:
        raise InvalidParameter("KCHCDROM0003E", {'value': path})
    return src_type
示例#17
0
    def vmstorages_create(self, vm_name, params):
        path = params.get('path')
        if path.startswith('/') and not os.path.exists(path):
            raise InvalidParameter("KCHCDROM0003E", {'value': path})

        dom = self._get_vm(vm_name)
        dev = params.get('dev', None)
        if dev and dev in self.vmstorages_get_list(vm_name):
            return OperationFailed("KCHCDROM0004E", {'dev_name': dev,
                                                     'vm_name': vm_name})
        if not dev:
            index = len(dom.storagedevices.keys()) + 1
            params['dev'] = "hd" + string.ascii_lowercase[index]

        vmdev = MockVMStorageDevice(params)
        dom.storagedevices[params['dev']] = vmdev
        return params['dev']
示例#18
0
    def to_volume_list(self, vm_uuid):
        storage_path = self._get_storage_path()
        ret = []
        for i, d in enumerate(self.info['disks']):
            index = d.get('index', i)
            volume = "%s-%s.img" % (vm_uuid, index)

            info = {'name': volume,
                    'capacity': d['size'],
                    'format': d['format'],
                    'path': '%s/%s' % (storage_path, volume)}

            if 'logical' == self._get_storage_type() or \
               info['format'] not in ['qcow2', 'raw']:
                info['allocation'] = info['capacity']
            else:
                info['allocation'] = 0

            if 'base' in d:
                info['base'] = dict()
                base_fmt = imageinfo.probe_img_info(d['base'])['format']
                if base_fmt is None:
                    raise InvalidParameter("KCHTMPL0024E", {'path': d['base']})
                info['base']['path'] = d['base']
                info['base']['format'] = base_fmt

            v_tree = E.volume(E.name(info['name']))
            v_tree.append(E.allocation(str(info['allocation']), unit='G'))
            v_tree.append(E.capacity(str(info['capacity']), unit='G'))

            target_fmt = info['format']
            if 'base' in d:
                # target must be qcow2 in order to use a backing file
                target_fmt = 'qcow2'

                v_tree.append(E.backingStore(
                    E.path(info['base']['path']),
                    E.format(type=info['base']['format'])))

            target = E.target(
                E.format(type=target_fmt), E.path(info['path']))
            v_tree.append(target)
            info['xml'] = etree.tostring(v_tree)
            ret.append(info)
        return ret
示例#19
0
    def addRepo(self, repo={}):
        """
        Add a given repository in repositories.Repositories() format to APT
        """
        if len(repo) == 0:
            raise InvalidParameter("KCHREPOS0013E")

        if repo['url_args'] is not None:
            dist = repo['url_args'][0]
            args = repo['url_args'][1:]
        else:
            dist = None
            args = []

        _file = '%s/%s.list' % (self._etc_sparts, repo['repo_id'])

        self._repos.add('deb', repo['baseurl'], dist, args, file=_file)
        self._repos.save()
示例#20
0
    def _create_iface_xml(self, iface, net_params):
        m = E.interface(E.start(mode='onboot'), type='ethernet', name=iface)

        if net_params['ipaddr'] and net_params['netmask']:
            n = ipaddr.IPv4Network(
                '%s/%s' % (net_params['ipaddr'], net_params['netmask']))
            protocol_elem = E.protocol(E.ip(address=str(n.ip),
                                            prefix=str(n.prefixlen)),
                                       family='ipv4')

            if 'gateway' in net_params:
                protocol_elem.append((E.route(gateway=net_params['gateway'])))
            m.append(protocol_elem)

        elif net_params['ipaddr'] or net_params['netmask']:
            raise InvalidParameter('GINNET0012E')

        return ET.tostring(m)
示例#21
0
class StorageVolumesModel(object):
    def __init__(self, **kargs):
        self.conn = kargs['conn']
        self.objstore = kargs['objstore']

    def create(self, pool_name, params):
        vol_xml = """
        <volume>
          <name>%(name)s</name>
          <allocation unit="MiB">%(allocation)s</allocation>
          <capacity unit="MiB">%(capacity)s</capacity>
          <source>
          </source>
          <target>
            <format type='%(format)s'/>
          </target>
        </volume>
        """
        params.setdefault('allocation', 0)
        params.setdefault('format', 'qcow2')

        name = params['name']
        try:
            pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
            xml = vol_xml % params
        except KeyError, item:
            raise MissingParameter("KCHVOL0004E", {
                'item': str(item),
                'volume': name
            })

        pool_info = StoragePoolModel(conn=self.conn,
                                     objstore=self.objstore).lookup(pool_name)
        if pool_info['type'] in READONLY_POOL_TYPE:
            raise InvalidParameter("KCHVOL0012E", {'type': pool_info['type']})
        try:
            pool.createXML(xml, 0)
        except libvirt.libvirtError as e:
            raise OperationFailed("KCHVOL0007E", {
                'name': name,
                'pool': pool,
                'err': e.get_error_message()
            })
        return name
示例#22
0
    def templates_create(self, params):
        name = params.get('name', '').strip()
        if not name:
            iso = params['cdrom']
            iso_name = os.path.splitext(iso[iso.rfind('/') + 1:])[0]
            name = iso_name + str(int(time.time() * 1000))
            params['name'] = name

        if name in self._mock_templates:
            raise InvalidOperation("KCHTMPL0001E", {'name': name})

        for net_name in params.get(u'networks', []):
            try:
                self._get_network(net_name)
            except NotFoundError:
                msg_args = {'network': net_name, 'template': name}
                raise InvalidParameter("KCHTMPL0003E", msg_args)

        t = MockVMTemplate(params, self)
        self._mock_templates[name] = t
        return name
示例#23
0
    def create(self, vm, params):
        conn = self.conn.get()
        networks = conn.listNetworks() + conn.listDefinedNetworks()
        networks = map(lambda x: x.decode('utf-8'), networks)

        if params['type'] == 'network':
            network = params.get("network")

            if network is None:
                raise MissingParameter('KCHVMIF0007E')

            if network not in networks:
                raise InvalidParameter('KCHVMIF0002E', {
                    'name': vm,
                    'network': network
                })

        macs = (iface.mac.get('address')
                for iface in self.get_vmifaces(vm, self.conn))

        while True:
            params['mac'] = VMIfacesModel.random_mac()
            if params['mac'] not in macs:
                break

        dom = VMModel.get_vm(vm, self.conn)

        os_data = VMModel.vm_get_os_metadata(dom, self.caps.metadata_support)
        os_version, os_distro = os_data
        xml = get_iface_xml(params, conn.getInfo()[0], os_distro, os_version)

        flags = 0
        if dom.isPersistent():
            flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
        if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
            flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE

        dom.attachDeviceFlags(xml, flags)

        return params['mac']
示例#24
0
    def create(self, vm, params):
        def randomMAC():
            mac = [0x52, 0x54, 0x00,
                   random.randint(0x00, 0x7f),
                   random.randint(0x00, 0xff),
                   random.randint(0x00, 0xff)]
            return ':'.join(map(lambda x: "%02x" % x, mac))

        conn = self.conn.get()
        networks = conn.listNetworks() + conn.listDefinedNetworks()

        if params["type"] == "network" and params["network"] not in networks:
            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("KCHVMIF0003E")

        macs = (iface.mac.get('address')
                for iface in self.get_vmifaces(vm, self.conn))

        mac = randomMAC()
        while True:
            if mac not in macs:
                break
            mac = randomMAC()

        children = [E.mac(address=mac)]
        ("network" in params.keys() and
         children.append(E.source(network=params['network'])))
        ("model" in params.keys() and
         children.append(E.model(type=params['model'])))
        attrib = {"type": params["type"]}

        xml = etree.tostring(E.interface(*children, **attrib))

        dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)

        return mac
示例#25
0
    def get_list(self, _cap=None, _passthrough=None,
                 _passthrough_affected_by=None):
        if _passthrough_affected_by is not None:
            # _passthrough_affected_by conflicts with _cap and _passthrough
            if (_cap, _passthrough) != (None, None):
                raise InvalidParameter("KCHHOST0004E")
            return sorted(
                self._get_passthrough_affected_devs(_passthrough_affected_by))

        if _cap == 'fc_host':
            dev_names = self._get_devices_fc_host()
        else:
            dev_names = self._get_devices_with_capability(_cap)

        if _passthrough is not None and _passthrough.lower() == 'true':
            conn = self.conn.get()
            passthrough_names = [
                dev['name'] for dev in hostdev.get_passthrough_dev_infos(conn)]
            dev_names = list(set(dev_names) & set(passthrough_names))

        dev_names.sort()
        return dev_names
示例#26
0
    def _set_network_subnet(self, params):
        netaddr = params.get('subnet', '')
        # lookup a free network address for nat and isolated automatically
        if not netaddr:
            netaddr = self._get_available_address()
            if not netaddr:
                raise OperationFailed("KCHNET0009E", {'name': params['name']})

        try:
            ip = ipaddr.IPNetwork(netaddr)
        except ValueError:
            raise InvalidParameter("KCHNET0003E", {'subent': netaddr,
                                                   'network': params['name']})

        if ip.ip == ip.network:
            ip.ip = ip.ip + 1

        dhcp_start = str(ip.ip + ip.numhosts / 2)
        dhcp_end = str(ip.ip + ip.numhosts - 2)
        params.update({'net': str(ip),
                       'dhcp': {'range': {'start': dhcp_start,
                                'end': dhcp_end}}})
示例#27
0
    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']]
示例#28
0
    def _static_vm_update(self, dom, params):
        state = DOM_STATE_MAP[dom.info()[0]]

        old_xml = new_xml = dom.XMLDesc(0)

        for key, val in params.items():
            if key in VM_STATIC_UPDATE_PARAMS:
                xpath = VM_STATIC_UPDATE_PARAMS[key]
                new_xml = xmlutils.xml_item_update(new_xml, xpath, val)

        try:
            if 'name' in params:
                if state == 'running':
                    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("KCHVM0008E", {'name': dom.name(),
                                                 'err': e.get_error_message()})
        return dom
示例#29
0
 def _passthrough_device_validate(self, dev_name):
     eligible_dev_names = \
         DevicesModel(conn=self.conn).get_list(_passthrough='true')
     if dev_name not in eligible_dev_names:
         raise InvalidParameter('KCHVMHDEV0002E', {'dev_name': dev_name})
示例#30
0
    def create(self, params):
        name = params.get('name', '').strip()
        iso = params.get('cdrom')
        # check search permission
        if iso and iso.startswith('/') and os.path.exists(iso):
            st_mode = os.stat(iso).st_mode
            if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
                user = UserTests().probe_user()
                run_setfacl_set_attr(iso, user=user)
                ret, excp = probe_file_permission_as_user(iso, user)
                if ret is False:
                    raise InvalidParameter('KCHISO0008E', {
                        'filename': iso,
                        'user': user,
                        'err': excp
                    })

        cpu_info = params.get('cpu_info')
        if cpu_info:
            topology = cpu_info.get('topology')
            # Check, even though currently only topology
            #   is supported.
            if topology:
                sockets = topology['sockets']
                cores = topology['cores']
                threads = topology['threads']
                if params.get('cpus') is None:
                    params['cpus'] = sockets * cores * threads
                # check_topoology will raise the appropriate
                # exception if a topology is invalid.
                CPUInfoModel(conn=self.conn).\
                    check_topology(params['cpus'], topology)
        else:
            params['cpu_info'] = dict()

        conn = self.conn.get()
        pool_uri = params.get(u'storagepool', '')
        if pool_uri:
            try:
                pool_name = pool_name_from_uri(pool_uri)
                pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
            except Exception:
                raise InvalidParameter("KCHTMPL0004E", {
                    'pool': pool_name,
                    'template': name
                })

            tmp_volumes = [
                disk['volume'] for disk in params.get('disks', [])
                if 'volume' in disk
            ]
            self.template_volume_validate(tmp_volumes, pool)

        for net_name in params.get(u'networks', []):
            try:
                conn.networkLookupByName(net_name.encode('utf-8'))
            except Exception:
                raise InvalidParameter("KCHTMPL0003E", {
                    'network': net_name,
                    'template': name
                })
        # Creates the template class with necessary information
        # Checkings will be done while creating this class, so any exception
        # will be raised here
        t = LibvirtVMTemplate(params, scan=True, conn=self.conn)
        name = params['name']
        try:
            with self.objstore as session:
                if name in session.get_list('template'):
                    raise InvalidOperation("KCHTMPL0001E", {'name': name})
                session.store('template', name, t.info)
        except InvalidOperation:
            raise
        except Exception, e:
            raise OperationFailed('KCHTMPL0020E', {'err': e.message})