Beispiel #1
0
    def _vm_update_access_metadata(self, dom, params):
        users = groups = None
        if "users" in params:
            users = params["users"]
            invalid_users = set(users) - set(self.users.get_list())
            if len(invalid_users) != 0:
                raise InvalidParameter("KCHVM0027E",
                                       {'users': ", ".join(invalid_users)})
        if "groups" in params:
            groups = params["groups"]
            invalid_groups = set(groups) - set(self.groups.get_list())
            if len(invalid_groups) != 0:
                raise InvalidParameter("KCHVM0028E",
                                       {'groups': ", ".join(invalid_groups)})

        if users is None and groups is None:
            return

        access_xml = (get_metadata_node(dom, "access")
                      or """<access></access>""")
        old_users = xpath_get_text(access_xml, "/access/user")
        old_groups = xpath_get_text(access_xml, "/access/group")
        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)
Beispiel #2
0
    def template_update(self, name, params):
        old_t = self.template_lookup(name)
        new_t = copy.copy(old_t)

        new_t.update(params)
        ident = name

        new_storagepool = new_t.get(u'storagepool', '')
        try:
            self._get_storagepool(pool_name_from_uri(new_storagepool))
        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:
                msg_args = {'network': net_name, 'template': name}
                raise InvalidParameter("KCHTMPL0003E", msg_args)

        self.template_delete(name)
        try:
            ident = self.templates_create(new_t)
        except:
            ident = self.templates_create(old_t)
            raise
        return ident
Beispiel #3
0
    def prepare(self, conn):
        mnt_point = tempfile.mkdtemp(dir='/tmp')
        export_path = "%s:%s" % (self.poolArgs['source']['host'],
                                 self.poolArgs['source']['path'])
        mount_cmd = [
            "mount", "-o", 'soft,timeo=100,retrans=3,retry=0', export_path,
            mnt_point
        ]
        umount_cmd = ["umount", "-f", export_path]
        mounted = False
        # Due to an NFS bug (See Red Hat BZ 1023059), NFSv4 exports may take
        # 10-15 seconds to mount the first time.
        cmd_timeout = 15

        with RollbackContext() as rollback:
            rollback.prependDefer(os.rmdir, mnt_point)
            try:
                run_command(mount_cmd, cmd_timeout)
                rollback.prependDefer(run_command, umount_cmd, cmd_timeout)
            except TimeoutExpired:
                raise InvalidParameter("KCHPOOL0012E", {'path': export_path})
            with open("/proc/mounts", "rb") as f:
                rawMounts = f.read()
            output_items = ['dev_path', 'mnt_point', 'type']
            mounts = parse_cmd_output(rawMounts, output_items)
            for item in mounts:
                if 'dev_path' in item and item['dev_path'] == export_path:
                    mounted = True

            if not mounted:
                raise InvalidParameter("KCHPOOL0013E", {'path': export_path})
Beispiel #4
0
    def update(self, name, params):
        old_t = self.lookup(name)
        new_t = copy.copy(old_t)
        new_t.update(params)
        ident = name

        pool_uri = new_t.get(u'storagepool', '')
        pool_name = pool_name_from_uri(pool_uri)
        try:
            conn = self.conn.get()
            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 = self.conn.get()
                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
Beispiel #5
0
    def prepare(self, conn):
        mnt_point = tempfile.mkdtemp(dir='/tmp')
        export_path = "%s:%s" % (self.poolArgs['source']['host'],
                                 self.poolArgs['source']['path'])
        mount_cmd = [
            "mount", "-o", 'soft,timeo=100,retrans=3,retry=0', export_path,
            mnt_point
        ]
        umount_cmd = ["umount", "-f", export_path]
        mounted = False
        # 2 seconds looks like a reasonable time to wait for a refresh
        # in the UI and enough time to verify that the NFS server
        # is down.
        cmd_timeout = 2

        with RollbackContext() as rollback:
            rollback.prependDefer(os.rmdir, mnt_point)
            try:
                run_command(mount_cmd, cmd_timeout)
                rollback.prependDefer(run_command, umount_cmd, cmd_timeout)
            except TimeoutExpired:
                raise InvalidParameter("KCHPOOL0012E", {'path': export_path})
            with open("/proc/mounts", "rb") as f:
                rawMounts = f.read()
            output_items = ['dev_path', 'mnt_point', 'type']
            mounts = parse_cmd_output(rawMounts, output_items)
            for item in mounts:
                if 'dev_path' in item and item['dev_path'] == export_path:
                    mounted = True

            if not mounted:
                raise InvalidParameter("KCHPOOL0013E", {'path': export_path})
Beispiel #6
0
    def _static_vm_update(self, dom, params):
        state = dom.info['state']

        for key, val in params.items():
            if key == 'name':
                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)

                del self._mock_vms[dom.name]
                dom.name = params['name']
                self._mock_vms[dom.name] = dom

            elif key == 'users':
                invalid_users = set(val) - set(self.users_get_list())
                if len(invalid_users) != 0:
                    raise InvalidParameter("KCHVM0027E",
                                           {'users': ", ".join(invalid_users)})

            elif key == 'groups':
                invalid_groups = set(val) - set(self.groups_get_list())
                if len(invalid_groups) != 0:
                    raise InvalidParameter(
                        "KCHVM0028E", {'groups': ", ".join(invalid_groups)})

            dom.info[key] = val
Beispiel #7
0
    def create(self, params):
        name = params.get('name', '').strip()
        iso = params['cdrom']
        # check search permission
        if iso.startswith('/') and os.path.isfile(iso):
            user = UserTests().probe_user()
            ret, excp = probe_file_permission_as_user(iso, user)
            if ret is False:
                raise InvalidParameter('KCHISO0008E', {
                    'filename': iso,
                    'user': user,
                    'err': excp
                })

        if not name:
            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:
            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)
            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)

        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 Exception as e:
            raise OperationFailed('KCHTMPL0020E', {'err': e.message})

        return name
Beispiel #8
0
    def update(self, name, params):
        if not self._is_interface_editable(name):
            raise InvalidParameter('GINNET0013E', {'name': name})

        try:
            iface_xml = self._create_iface_xml(name, params)
        except (ipaddr.AddressValueError, ipaddr.NetmaskValueError) as e:
            raise InvalidParameter('GINNET0003E', {'err': e.message})
        self._create_libvirt_network_iface(iface_xml)
Beispiel #9
0
 def get_iso_info(self, iso):
     iso_prefixes = ['/', 'http', 'https', 'ftp', 'ftps', 'tftp']
     if len(filter(iso.startswith, iso_prefixes)) == 0:
         raise InvalidParameter("KCHTMPL0006E", {'param': iso})
     try:
         iso_img = IsoImage(iso)
         return iso_img.probe()
     except IsoFormatError:
         raise InvalidParameter("KCHISO0001E", {'filename': iso})
Beispiel #10
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))

        # user defined customized mac address
        if 'mac' in params and params['mac']:
            # make sure it is unique
            if params['mac'] in macs:
                raise InvalidParameter('KCHVMIF0009E', {
                    'name': vm,
                    'mac': params['mac']
                })

        # otherwise choose a random mac address
        else:
            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']
Beispiel #11
0
def validate_repo_url(url):
    url_parts = url.split('://')  # [0] = prefix, [1] = rest of URL

    if url_parts[0] == '':
        raise InvalidParameter("KCHREPOS0002E")

    if url_parts[0] in ['http', 'https', 'ftp']:
        if not check_url_path(url):
            raise InvalidParameter("KCHUTILS0001E", {'uri': url})
    elif url_parts[0] == 'file':
        if not os.path.exists(url_parts[1]):
            raise InvalidParameter("KCHUTILS0001E", {'uri': url})
    else:
        raise InvalidParameter("KCHREPOS0002E")
Beispiel #12
0
    def _storage_validate(self):
        pool_uri = self.info['storagepool']
        pool_name = pool_name_from_uri(pool_uri)
        try:
            pool = self.model._get_storagepool(pool_name)
        except NotFoundError:
            msg_args = {'pool': pool_name, 'template': self.name}
            raise InvalidParameter("KCHTMPL0004E", msg_args)

        if pool.info['state'] != 'active':
            msg_args = {'pool': pool_name, 'template': self.name}
            raise InvalidParameter("KCHTMPL0005E", msg_args)

        return pool
Beispiel #13
0
    def get_list(self, _cap=None, _passthrough=None,
                 _passthrough_affected_by=None,
                 _available_only=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))

            if _available_only is not None and _available_only.lower() \
                    == 'true':
                unavailable_devs = self._get_unavailable_devices()
                dev_names = [dev for dev in dev_names
                             if dev not in unavailable_devs]

        dev_names.sort()
        return dev_names
Beispiel #14
0
def _get_disk_type(path):
    if check_url_path(path):
        return 'network'

    if not os.path.exists(path):
        raise InvalidParameter("KCHVMSTOR0003E", {'value': path})

    # Check if path is a valid local path
    if os.path.isfile(path):
        return 'file'

    r_path = os.path.realpath(path)
    if stat.S_ISBLK(os.stat(r_path).st_mode):
        return 'block'

    raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
Beispiel #15
0
def probe_image(image_path):
    if not os.path.isfile(image_path):
        raise InvalidParameter("KCHIMG0004E", {'filename': image_path})

    if not os.access(image_path, os.R_OK):
        raise ImageFormatError("KCHIMG0003E", {'filename': image_path})

    g = guestfs.GuestFS(python_return_dict=True)
    g.add_drive_opts(image_path, readonly=1)
    g.launch()

    try:
        roots = g.inspect_os()
    except:
        raise ImageFormatError("KCHIMG0001E")

    if len(roots) == 0:
        raise ImageFormatError("KCHIMG0002E")

    for root in roots:
        version = "%d.%d" % (g.inspect_get_major_version(root),
                             g.inspect_get_minor_version(root))
        distro = "%s" % (g.inspect_get_distro(root))

    return (distro, version)
Beispiel #16
0
    def networks_create(self, params):
        name = params['name']
        if name in self.networks_get_list():
            raise InvalidOperation("KCHNET0001E", {'name': name})

        network = MockNetwork(name)
        connection = params['connection']
        network.info['connection'] = connection
        if connection == "bridge":
            try:
                interface = params['interface']
                network.info['interface'] = interface
            except KeyError:
                raise MissingParameter("KCHNET0004E", {'name': name})

        subnet = params.get('subnet', '')
        if subnet:
            network.info['subnet'] = subnet
            try:
                net = ipaddr.IPNetwork(subnet)
            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)
            }

        self._mock_networks[name] = network
        return name
Beispiel #17
0
    def addRepo(self, repo={}):
        """
        Add a given repository in repositories.Repositories() format to YumBase
        """
        if len(repo) == 0:
            raise InvalidParameter("KCHREPOS0013E")

        # At least one base url, or one mirror, must be given.
        # baseurls must be a list of strings specifying the urls
        # mirrorlist must be a list of strings specifying a list of mirrors
        # Here we creates the lists, or set as None
        if repo['is_mirror']:
            mirrors = repo['baseurl']
            baseurl = None
        else:
            baseurl = [repo['baseurl']]
            mirrors = None

        self._yb.add_enable_repo(repo['repo_id'],
                                 baseurl,
                                 mirrors,
                                 name=repo['repo_name'],
                                 gpgcheck=repo['gpgcheck'],
                                 gpgkey=[repo['gpgkey']])

        # write a repo file in the system with repo{} information.
        self._write2disk(repo)
Beispiel #18
0
    def _create_volume_with_file(self, cb, params):
        pool_name = params.pop('pool')
        dir_path = StoragePoolModel(
            conn=self.conn, objstore=self.objstore).lookup(pool_name)['path']
        file_path = os.path.join(dir_path, params['name'])
        if os.path.exists(file_path):
            raise InvalidParameter('KCHVOL0001E', {'name': params['name']})

        upload_file = params['file']
        f_len = upload_file.fp.length
        try:
            size = 0
            with open(file_path, 'wb') as f:
                while True:
                    data = upload_file.file.read(READ_CHUNK_SIZE)
                    if not data:
                        break
                    size += len(data)
                    f.write(data)
                    cb('%s/%s' % (size, f_len))
        except Exception as e:
            raise OperationFailed('KCHVOL0007E', {
                'name': params['name'],
                'pool': pool_name,
                'err': e.message
            })

        # Refresh to make sure volume can be found in following lookup
        StoragePoolModel.get_storagepool(pool_name, self.conn).refresh(0)
        cb('OK', True)
Beispiel #19
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:
                if key == 'memory':
                    # Libvirt saves memory in KiB. Retrieved xml has memory
                    # in KiB too, so new valeu must be in KiB here
                    val = val * 1024
                if type(val) == int:
                    val = str(val)
                xpath = VM_STATIC_UPDATE_PARAMS[key]
                new_xml = xmlutils.xml_item_update(new_xml, xpath, val)

        conn = self.conn.get()
        try:
            if 'name' in params:
                if state == 'running':
                    msg_args = {'name': dom.name(), 'new_name': params['name']}
                    raise InvalidParameter("KCHVM0003E", msg_args)

                # Undefine old vm, only if name is going to change
                dom.undefine()

            root = ET.fromstring(new_xml)
            root.remove(root.find('.currentMemory'))
            dom = conn.defineXML(ET.tostring(root, encoding="utf-8"))
        except libvirt.libvirtError as e:
            dom = conn.defineXML(old_xml)
            raise OperationFailed("KCHVM0008E", {
                'name': dom.name(),
                'err': e.get_error_message()
            })
        return dom
Beispiel #20
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
                }
            }
        })
Beispiel #21
0
    def create(self, vm_name, params):
        dom = VMModel.get_vm(vm_name, self.conn)
        # Use device name passed or pick next
        dev_name = params.get('dev', None)
        if dev_name is None:
            params['dev'] = self._get_storage_device_name(vm_name)
        else:
            devices = self.get_list(vm_name)
            if dev_name in devices:
                raise OperationFailed('KCHVMSTOR0004E', {
                    'dev_name': dev_name,
                    'vm_name': vm_name
                })

        # Path will never be blank due to API.json verification.
        # There is no need to cover this case here.
        params['format'] = 'raw'
        if params.get('vol'):
            try:
                pool = params['pool']
                vol_info = StorageVolumeModel(conn=self.conn,
                                              objstore=self.objstore).lookup(
                                                  pool, params['vol'])
            except KeyError:
                raise InvalidParameter("KCHVMSTOR0012E")
            except Exception as e:
                raise InvalidParameter("KCHVMSTOR0015E", {'error': e})
            if vol_info['ref_cnt'] != 0:
                raise InvalidParameter("KCHVMSTOR0016E")
            params['format'] = vol_info['format']
            params['path'] = vol_info['path']
        params['src_type'] = _check_path(params['path'])
        params.setdefault('bus', _get_device_bus(params['type'], dom))
        if (params['bus'] not in HOTPLUG_TYPE
                and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
            raise InvalidOperation('KCHVMSTOR0011E')

        params.update(self._get_available_bus_address(params['bus'], vm_name))
        # Add device to VM
        dev_xml = _get_storage_xml(params)
        try:
            conn = self.conn.get()
            dom = conn.lookupByName(vm_name)
            dom.attachDeviceFlags(dev_xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
        return params['dev']
Beispiel #22
0
    def updateRepository(self, repo_id, new_repo={}):
        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
Beispiel #23
0
    def _network_validate(self):
        names = self.info['networks']
        for name in names:
            try:
                conn = self.conn.get()
                network = conn.networkLookupByName(name)
            except libvirt.libvirtError:
                raise InvalidParameter("KCHTMPL0003E", {
                    'network': name,
                    'template': self.name
                })

            if not network.isActive():
                raise InvalidParameter("KCHTMPL0007E", {
                    'network': name,
                    'template': self.name
                })
Beispiel #24
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:
                if key == 'memory':
                    # Libvirt saves memory in KiB. Retrieved xml has memory
                    # in KiB too, so new valeu must be in KiB here
                    val = val * 1024
                if type(val) == int:
                    val = str(val)
                xpath = VM_STATIC_UPDATE_PARAMS[key]
                new_xml = xml_item_update(new_xml, xpath, val)

        if 'graphics' in params:
            new_xml = self._update_graphics(dom, new_xml, params)

        snapshots_info = []
        vm_name = dom.name()
        conn = self.conn.get()
        try:
            if 'name' in params:
                if state == 'running':
                    msg_args = {'name': vm_name, 'new_name': params['name']}
                    raise InvalidParameter("KCHVM0003E", msg_args)

                lflags = libvirt.VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
                dflags = (libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
                          libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)

                for virt_snap in dom.listAllSnapshots(lflags):
                    snapshots_info.append({'xml': virt_snap.getXMLDesc(0),
                                           'current': virt_snap.isCurrent(0)})
                    self._backup_snapshots(virt_snap, snapshots_info)

                    virt_snap.delete(dflags)

                # Undefine old vm, only if name is going to change
                dom.undefine()

            root = ET.fromstring(new_xml)
            currentMem = root.find('.currentMemory')
            if currentMem is not None:
                root.remove(currentMem)

            dom = conn.defineXML(ET.tostring(root, encoding="utf-8"))
            if 'name' in params:
                self._redefine_snapshots(dom, snapshots_info)
        except libvirt.libvirtError as e:
            dom = conn.defineXML(old_xml)
            if 'name' in params:
                self._redefine_snapshots(dom, snapshots_info)

            raise OperationFailed("KCHVM0008E", {'name': vm_name,
                                                 'err': e.get_error_message()})
        return dom
Beispiel #25
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)
Beispiel #26
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

        node = self._build_access_elem(dom, users, groups)
        set_metadata_node(dom, node, self.caps.metadata_support)
Beispiel #27
0
    def check_topology(self, vcpus, topology):
        """
            param vcpus: should be an integer
            param iso_path: the path of the guest ISO
            param topology: {'sockets': x, 'cores': x, 'threads': x}
        """
        sockets = topology['sockets']
        cores = topology['cores']
        threads = topology['threads']

        if not self.guest_threads_enabled:
            raise InvalidOperation("KCHCPUINF0003E")
        if vcpus != sockets * cores * threads:
            raise InvalidParameter("KCHCPUINF0002E")
        if vcpus > self.cores_available * self.threads_per_core:
            raise InvalidParameter("KCHCPUINF0001E")
        if threads > self.threads_per_core:
            raise InvalidParameter("KCHCPUINF0002E")
Beispiel #28
0
    def update(self, name, params):
        old_t = self.lookup(name)
        new_t = copy.copy(old_t)
        new_t.update(params)

        if not self._validate_updated_cpu_params(new_t):
            raise InvalidParameter('KCHTMPL0025E')

        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.encode('utf-8'))
            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
Beispiel #29
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']
        vol_id = '%s:%s' % (pool_name, 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()
            })

        try:
            with self.objstore as session:
                session.store('storagevolume', vol_id, {'ref_cnt': 0})
        except Exception as e:
            # If the storage volume was created flawlessly, then lets hide this
            # error to avoid more error in the VM creation process
            kimchi_log.warning(
                'Unable to store storage volume id in '
                'objectstore due error: %s', e.message)

        return name
Beispiel #30
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