コード例 #1
0
ファイル: core.py プロジェクト: EdDev/vdsm
 def update_device_info(cls, vm, device_conf):
     conf_aliases = frozenset([getattr(conf, 'alias')
                               for conf in device_conf
                               if hasattr(conf, 'alias')])
     dev_aliases = frozenset([dev['alias']
                              for dev in vm.conf['devices']
                              if 'alias' in dev])
     for element in vm.domain.get_device_elements('memory'):
         address, alias = parse_device_ident(element)
         node = int(vmxml.text(vmxml.find_first(element, 'node')))
         size = int(vmxml.text(vmxml.find_first(element, 'size')))
         if alias not in conf_aliases:
             for conf in device_conf:
                 if not hasattr(conf, 'alias') and \
                    conf.node == node and \
                    conf.size == size:
                     conf.address = address
                     conf.alias = alias
                     break
         if alias not in dev_aliases:
             for dev in vm.conf['devices']:
                 if dev['type'] == hwclass.MEMORY and \
                    dev.get('alias') is None and \
                    dev.get('node') == node and \
                    dev.get('size', 0) * 1024 == size:
                     dev['address'] = address
                     dev['alias'] = alias
                     break
コード例 #2
0
ファイル: vmtune.py プロジェクト: EdDev/vdsm
def io_tune_dom_to_values(dom):
    """
    This method converts the VmDiskDeviceTuneLimits structure from its
    XML representation to the dictionary representation.

    :param dom: XML DOM object to parse
    :return: The structure in the dictionary form
    """
    values = {}

    if vmxml.attr(dom, "name"):
        values["name"] = vmxml.attr(dom, "name")

    if vmxml.attr(dom, "path"):
        values["path"] = vmxml.attr(dom, "path")

    element = vmxml.find_first(dom, "guaranteed", None)
    if element is not None:
        values["guaranteed"] = {}
        collect_inner_elements(element, values["guaranteed"])

    element = vmxml.find_first(dom, "maximum", None)
    if element is not None:
        values["maximum"] = {}
        collect_inner_elements(element, values["maximum"])

    return values
コード例 #3
0
ファイル: core.py プロジェクト: EdDev/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = parse_device_params(dev)
     target = vmxml.find_first(dev, 'target')
     params['size'] = (
         int(vmxml.text(vmxml.find_first(target, 'size'))) / 1024
     )
     params['node'] = vmxml.text(vmxml.find_first(target, 'node'))
     return cls(log, **params)
コード例 #4
0
ファイル: lease.py プロジェクト: EdDev/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = {
         'lease_id': vmxml.text(vmxml.find_first(dev, 'key')),
         'sd_id': vmxml.text(vmxml.find_first(dev, 'lockspace')),
         'path': vmxml.find_attr(dev, 'target', 'path'),
         'offset': vmxml.find_attr(dev, 'target', 'offset'),
     }
     return cls(log, **params)
コード例 #5
0
ファイル: hostdevice.py プロジェクト: nirs/vdsm
 def update_from_xml(cls, vm, device_conf, device_xml):
     alias = core.find_device_alias(device_xml)
     source = vmxml.find_first(device_xml, 'source')
     address = vmxml.find_first(source, 'address')
     uuid = address.attrib['uuid']
     for dev in device_conf:
         if isinstance(dev, MdevDevice) and uuid == dev.mdev_uuid:
             dev.alias = alias
             return
コード例 #6
0
ファイル: common.py プロジェクト: nirs/vdsm
def dev_elems_from_xml(vm, xml):
    """
    Return device instance building elements from provided XML.

    The XML must contain <devices> element with a single device subelement, the
    one to create the instance for.  Depending on the device kind <metadata>
    element may be required to provide device metadata; the element may and
    needn't contain unrelated metadata.  This function is used in device
    hot(un)plugs.

    Example `xml` value (top element tag may be arbitrary):

      <?xml version='1.0' encoding='UTF-8'?>
      <hotplug>
        <devices>
          <interface type="bridge">
            <mac address="66:55:44:33:22:11"/>
            <model type="virtio" />
            <source bridge="ovirtmgmt" />
            <filterref filter="vdsm-no-mac-spoofing" />
            <link state="up" />
            <bandwidth />
          </interface>
        </devices>
        <metadata xmlns:ns0="http://ovirt.org/vm/tune/1.0"
                  xmlns:ovirt-vm="http://ovirt.org/vm/1.0">
          <ovirt-vm:vm xmlns:ovirt-vm="http://ovirt.org/vm/1.0">
            <ovirt-vm:device mac_address='66:55:44:33:22:11'>
              <ovirt-vm:network>test</ovirt-vm:network>
              <ovirt-vm:portMirroring>
                <ovirt-vm:network>network1</ovirt-vm:network>
                <ovirt-vm:network>network2</ovirt-vm:network>
              </ovirt-vm:portMirroring>
            </ovirt-vm:device>
          </ovirt-vm:vm>
        </metadata>
      </hotplug>

    :param xml: XML specifying the device as described above.
    :type xml: basestring
    :returns: Triplet (device_class, device_element, device_meta) where
      `device_class` is the class to be used to create the device instance;
      `device_element` and `device_meta` are objects to be passed as arguments
      to device_class `from_xml_tree` method.
    """
    dom = xmlutils.fromstring(xml)
    devices = vmxml.find_first(dom, 'devices')
    dev_elem = next(vmxml.children(devices))
    _dev_type, dev_class = identify_from_xml_elem(dev_elem)
    meta = vmxml.find_first(dom, 'metadata', None)
    if meta is None:
        md_desc = metadata.Descriptor()
    else:
        md_desc = metadata.Descriptor.from_xml(xmlutils.tostring(meta))
    dev_meta = _get_metadata_from_elem_xml(vm.id, md_desc, dev_class, dev_elem)
    return dev_class, dev_elem, dev_meta
コード例 #7
0
ファイル: core.py プロジェクト: EdDev/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = parse_device_params(dev, attrs=('model', ))
     params['specParams'] = parse_device_attrs(
         vmxml.find_first(dev, 'rate'),
         ('period', 'bytes')
     )
     params['specParams']['source'] = rngsources.get_source_name(
         vmxml.text(vmxml.find_first(dev, 'backend'))
     )
     params['vmid'] = meta['vmid']
     return cls(log, **params)
コード例 #8
0
ファイル: lease.py プロジェクト: oVirt/vdsm
def parse_xml(dev, meta):
    params = {
        'type': dev.tag,
        'device': core.find_device_type(dev),
        'lease_id': vmxml.text(vmxml.find_first(dev, 'key')),
        'sd_id': vmxml.text(vmxml.find_first(dev, 'lockspace')),
        'path': vmxml.find_attr(dev, 'target', 'path'),
        'offset': vmxml.find_attr(dev, 'target', 'offset'),
    }
    core.update_device_params(params, dev)
    core.update_device_params_from_meta(params, meta)
    return params
コード例 #9
0
ファイル: storagexml.py プロジェクト: nirs/vdsm
def update_disk_element_from_object(disk_element, vm_drive, log,
                                    replace_attribs=False):
    # key: (old_value, new_value)
    changes = {}

    # the only change relevant for floppies is the path,
    # because their only usage left is sysprep - aka payload devices.
    device = disk_element.attrib.get('device')
    old_disk_type = disk_element.attrib.get('type')
    disk_type = vm_drive.diskType

    if device != 'floppy':
        vmxml.set_attr(disk_element, 'type', disk_type)
        changes['type'] = (old_disk_type, disk_type)

    # update the path
    source = vmxml.find_first(disk_element, 'source')
    old_disk_attr = storage.SOURCE_ATTR[old_disk_type]
    # on resume, empty CDroms may lack the 'file' attribute
    old_path = source.attrib.get(old_disk_attr, None)
    if old_path is not None and replace_attribs:
        del source.attrib[old_disk_attr]
    disk_attr = storage.SOURCE_ATTR[disk_type]
    vmxml.set_attr(source, disk_attr, vm_drive.path)
    changes['path'] = (
        '%s=%s' % (old_disk_attr, '' if old_path is None else old_path),
        # We intentionally create the new value using a different format
        # - note leading asterisk - to force the _log_changes function to
        # always log this information.
        # We want to see how good is Engine at predicting drive paths,
        # and how often Vdsm needs to correct that.
        '*%s=%s' % (disk_attr, vm_drive.path),
    )

    if device != 'floppy':
        # update the format (the disk might have been collapsed)
        driver = vmxml.find_first(disk_element, 'driver')
        drive_format = 'qcow2' if vm_drive.format == 'cow' else 'raw'
        # on resume, CDroms may have minimal 'driver' attribute
        old_drive_format = driver.attrib.get('type')
        vmxml.set_attr(driver, 'type', drive_format)
        changes['format'] = (old_drive_format, drive_format)

    # dynamic_ownership workaround
    if (disk_type == storage.DISK_TYPE.FILE or
            disk_type == storage.DISK_TYPE.BLOCK):
        try:
            vmxml.find_first(source, 'seclabel')
        except vmxml.NotFound:
            storage.disable_dynamic_ownership(source)

    _log_changes(log, 'drive', vm_drive.name, changes)
コード例 #10
0
ファイル: vmxml_test.py プロジェクト: EdDev/vdsm
 def test_find_first_nested(self):
     XML = u'''<?xml version="1.0" ?>
     <topelement>
       <subelement id="1">
           <subelement id="2"/>
       </subelement>
     </topelement>
     '''
     dom = vmxml.parse_xml(XML)
     sub1 = vmxml.find_first(dom, 'subelement')  # outermost
     sub2 = vmxml.find_first(sub1, 'subelement')  # innermost
     last = vmxml.find_first(sub2, 'subelement')
     self.assertIsNot(sub2, last)
コード例 #11
0
ファイル: core.py プロジェクト: nirs/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = {
         'device': dev.tag,
         'type': find_device_type(dev),
     }
     update_device_params(params, dev)
     target = vmxml.find_first(dev, 'target')
     params['size'] = (
         int(vmxml.text(vmxml.find_first(target, 'size'))) // 1024
     )
     params['node'] = vmxml.text(vmxml.find_first(target, 'node'))
     update_device_params_from_meta(params, meta)
     return cls(log, **params)
コード例 #12
0
ファイル: graphics.py プロジェクト: oVirt/vdsm
def _make_spec_params(dev, meta):
    spec_params = {
        'copyPasteEnable': _is_feature_flag_enabled(
            dev, 'clipboard', 'copypaste'
        ),
        'fileTransferEnable': _is_feature_flag_enabled(
            dev, 'filetransfer', 'enable'
        ),
    }
    key_map = dev.attrib.get('keymap')
    if key_map:
        spec_params['keyMap'] = key_map
    # we need some overrides to undo legacy defaults
    display_network = meta.get('display_network')
    if display_network:
        spec_params['displayNetwork'] = display_network
    listen = vmxml.find_first(dev, 'listen')
    if listen.attrib.get('type') == 'network':
        xml_display_network = listen.attrib.get('network')
        if xml_display_network:
            spec_params['displayNetwork'] = libvirtnetwork.netname_l2o(
                xml_display_network
            )
    elif listen.attrib.get('type') == 'address':
        spec_params['displayIp'] = listen.attrib.get('address', '0')
    return spec_params
コード例 #13
0
ファイル: common.py プロジェクト: nirs/vdsm
def _update_unknown_device_info(vm):
    """
    Obtain info about unknown devices from libvirt domain and update the
    corresponding device structures.  Unknown device is a device that has an
    address but wasn't passed during VM creation request.

    :param vm: VM for which the device info should be updated
    :type vm: `class:Vm` instance

    """
    def isKnownDevice(alias):
        for dev in vm.conf['devices']:
            if dev.get('alias') == alias:
                return True
        return False

    for x in vmxml.children(vm.domain.devices):
        # Ignore empty nodes and devices without address
        if vmxml.find_first(x, 'address', None) is None:
            continue

        alias = core.find_device_alias(x)
        if not isKnownDevice(alias):
            address = vmxml.device_address(x)
            # In general case we assume that device has attribute 'type',
            # if it hasn't dom_attribute returns ''.
            device = vmxml.attr(x, 'type')
            newDev = {'type': vmxml.tag(x),
                      'alias': alias,
                      'device': device,
                      'address': address}
            vm.conf['devices'].append(newDev)
コード例 #14
0
ファイル: hostdevice.py プロジェクト: EdDev/vdsm
    def update_from_xml(cls, vm, device_conf, device_xml):
        alias = core.find_device_alias(device_xml)
        address = vmxml.device_address(device_xml)
        source = vmxml.find_first(device_xml, 'source')
        device = pci_address_to_name(**vmxml.device_address(source))

        # We can assume the device name to be correct since we're
        # inspecting source element. For the address, we may look at
        # both addresses and determine the correct one.
        if pci_address_to_name(**address) == device:
            address = vmxml.device_address(device_xml, 1)

        known_device = False
        for dev in device_conf:
            if dev.device == device:
                dev.alias = alias
                dev.address = address
                known_device = True

        for dev in vm.conf['devices']:
            if dev['device'] == device:
                dev['alias'] = alias
                dev['address'] = address

        if not known_device:
            device = pci_address_to_name(**vmxml.device_address(source))

            hostdevice = {
                'type': hwclass.HOSTDEV,
                'device': device,
                'alias': alias,
                'address': address,
            }
            vm.conf['devices'].append(hostdevice)
コード例 #15
0
ファイル: vmxml_test.py プロジェクト: EdDev/vdsm
 def test_remove_child(self):
     top = vmxml.find_first(self._dom, 'topelement')
     hello = list(vmxml.find_all(top, 'hello'))
     old = hello[1]
     vmxml.remove_child(top, old)
     updated_hello = list(vmxml.find_all(top, 'hello'))
     hello = hello[:1] + hello[2:]
     self.assertEqual(updated_hello, hello)
コード例 #16
0
ファイル: core.py プロジェクト: nirs/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = {'type': find_device_type(dev)}
     update_device_params(params, dev, attrs=('model', ))
     params['device'] = params['model']
     rate = vmxml.find_first(dev, 'rate', None)
     if rate is not None:
         params['specParams'] = parse_device_attrs(
             rate, ('period', 'bytes')
         )
     else:
         params['specParams'] = {}
     params['specParams']['source'] = rngsources.get_source_name(
         vmxml.text(vmxml.find_first(dev, 'backend'))
     )
     update_device_params_from_meta(params, meta)
     params['vmid'] = meta['vmid']
     return cls(log, **params)
コード例 #17
0
ファイル: vmxml_test.py プロジェクト: EdDev/vdsm
 def test_find_all(self, start_tag, tag, number):
     dom = self._dom
     if start_tag is not None:
         dom = vmxml.find_first(self._dom, 'topelement')
     elements = vmxml.find_all(dom, tag)
     matches = [vmxml.tag(e) == tag for e in elements]
     self.assertTrue(all(matches))
     self.assertEqual(len(matches), number)
コード例 #18
0
ファイル: core.py プロジェクト: EdDev/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = parse_device_params(dev)
     # override
     params['device'] = vmxml.find_attr(dev, 'model', 'type')
     params['specParams'] = parse_device_attrs(
         vmxml.find_first(dev, 'model'),
         ('vram', 'heads', 'vgamem', 'ram')
     )
     return cls(log, **params)
コード例 #19
0
ファイル: core.py プロジェクト: EdDev/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = parse_device_params(dev)
     specParams = parse_device_attrs(dev, ('model',))
     backend = vmxml.find_first(dev, 'backend')
     specParams['mode'] = vmxml.attr(backend, 'type')
     specParams['path'] = vmxml.find_attr(
         dev, 'device', 'path')
     params['specParams'] = specParams
     return cls(log, **params)
コード例 #20
0
ファイル: device_test.py プロジェクト: nirs/vdsm
 def test_restore_paths(self):
     xml = self.XML
     second_disk_path = '/path/secondary-drive'
     snapshot_params = {'path': '/path/snapshot-path',
                        'volume_id': 'aaa',
                        'device': '/dev/random',
                        'second_disk_path': second_disk_path,
                        }
     engine_params = {'path': '/path/engine-path',
                      'volume_id': 'bbb',
                      'device': '/dev/urandom',
                      'second_disk_path': second_disk_path,
                      }
     snapshot_xml = xml.format(**snapshot_params)
     engine_xml = xml.format(**engine_params)
     params = {'_srcDomXML': snapshot_xml,
               'xml': engine_xml,
               'restoreState': {
                   'device': 'disk',
                   'imageID': u'111',
                   'poolID': u'222',
                   'domainID': u'333',
                   'volumeID': u'bbb',
               },
               'restoreFromSnapshot': True,
               }
     with fake.VM(params) as vm:
         vm._normalizeVdsmImg = lambda *args: None
         devices = vm._make_devices()
         vm_xml = vm.conf['xml']
     # Check that unrelated devices are taken from the snapshot untouched,
     # not from the XML provided from Engine:
     for d in devices[hwclass.RNG]:
         self.assertEqual(d.specParams['source'],
                          os.path.basename(snapshot_params['device']))
         break
     else:
         raise Exception('RNG device not found')
     tested_drives = (('1234', engine_params['path'],),
                      ('5678', second_disk_path,),)
     for serial, path in tested_drives:
         for d in devices[hwclass.DISK]:
             if d.serial == serial:
                 self.assertEqual(d.path, path)
                 break
         else:
             raise Exception('Tested drive not found', serial)
     dom = xmlutils.fromstring(vm_xml)
     random = vmxml.find_first(dom, 'backend')
     self.assertEqual(random.text, snapshot_params['device'])
     for serial, path in tested_drives:
         for d in dom.findall(".//disk[serial='{}']".format(serial)):
             self.assertEqual(vmxml.find_attr(d, 'source', 'file'), path)
             break
         else:
             raise Exception('Tested drive not found', serial)
     self.assertEqual(vm_xml, vm._domain.xml)
コード例 #21
0
ファイル: storagexml.py プロジェクト: nirs/vdsm
def _update_driver_params(params, dev):
    driver = vmxml.find_first(dev, 'driver', None)
    if driver is not None:
        driver_params, spec_params = _get_driver_params(driver)
        params.update(driver_params)
        params['specParams'].update(spec_params)
    else:
        # the initialization code always checks this parameter
        params['propagateErrors'] = 'off'
コード例 #22
0
ファイル: hostdevice.py プロジェクト: nirs/vdsm
def _get_device_name(dev, dev_type):
    src_dev = vmxml.find_first(dev, 'source')
    src_addr = vmxml.device_address(src_dev)
    if dev_type == 'scsi':
        src_addr = _normalize_scsi_address(dev, src_addr)
    elif dev_type == 'pci':
        src_addr = _normalize_pci_address(**src_addr)
    elif dev_type == 'mdev':
        return src_addr['uuid']

    return device_name_from_address(dev_type, src_addr)
コード例 #23
0
ファイル: storagexml.py プロジェクト: nirs/vdsm
def _update_iotune_params(params, dev):
    iotune = vmxml.find_first(dev, 'iotune', None)
    if iotune is None:
        return

    iotune_params = {
        setting.tag: int(setting.text)
        for setting in iotune
    }
    if iotune_params:
        params['iotune'] = iotune_params
コード例 #24
0
ファイル: domxml_preprocess_test.py プロジェクト: nirs/vdsm
    def _check_leases(self, xml_str, vol_infos):
        xml_dom = xmlutils.fromstring(xml_str)
        lease_elems = xml_dom.findall('./devices/lease')
        self.assertEqual(len(lease_elems), len(vol_infos))

        for lease_elem, vol_info in zip(lease_elems, vol_infos):
            target = vmxml.find_first(lease_elem, 'target')
            self.assertEqual(
                target.attrib['path'], str(vol_info['leasePath']))
            self.assertEqual(
                target.attrib['offset'], str(vol_info['leaseOffset']))
コード例 #25
0
ファイル: storage.py プロジェクト: EdDev/vdsm
def _get_drive_identification(dom):
    source = vmxml.find_first(dom, 'source', None)
    if source is not None:
        devPath = (vmxml.attr(source, 'file') or
                   vmxml.attr(source, 'dev') or
                   vmxml.attr(source, 'name'))
    else:
        devPath = ''
    name = vmxml.find_attr(dom, 'target', 'dev')
    alias = core.find_device_alias(dom)
    return alias, devPath, name
コード例 #26
0
ファイル: core.py プロジェクト: nirs/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = {
         'device': vmxml.find_attr(dev, 'model', 'type'),
         'type': find_device_type(dev),
     }
     update_device_params(params, dev)
     params['specParams'] = parse_device_attrs(
         vmxml.find_first(dev, 'model'),
         ('vram', 'heads', 'vgamem', 'ram')
     )
     update_device_params_from_meta(params, meta)
     return cls(log, **params)
コード例 #27
0
ファイル: storagexml.py プロジェクト: nirs/vdsm
def _update_auth_params(params, auth):
    # auth may be None, and this is OK
    if auth is None:
        return
    secret = vmxml.find_first(auth, 'secret', None)
    if secret is None:
        return
    params['auth'] = {
        'username': auth.attrib.get('username'),
        'type': secret.attrib.get('type'),
        'uuid': secret.attrib.get('uuid'),
    }
コード例 #28
0
ファイル: metadata_storage_test.py プロジェクト: nirs/vdsm
    def test_disk_ignore_volumeinfo_from_metadata_xml(self):
        xml_snippet = u'''<volumeInfo>
            <path>/rhev/data-center/omitted/for/brevity</path>
            <volType>path</volType>
        </volumeInfo>'''

        root = xmlutils.fromstring(_DISK_DATA.metadata_xml)
        dev = vmxml.find_first(root, 'device')
        vmxml.append_child(dev, etree_child=xmlutils.fromstring(xml_snippet))
        data = _TestData(
            copy.deepcopy(_DISK_DATA.conf), xmlutils.tostring(root))
        self._check_drive_from_metadata_xml(data)
コード例 #29
0
ファイル: lookup.py プロジェクト: nirs/vdsm
def drive_from_element(disk_devices, disk_element):
    # we try serial first for backward compatibility
    # REQUIRED_FOR: vdsm <= 4.2
    serial_elem = vmxml.find_first(disk_element, 'serial', None)
    if serial_elem is not None:
        serial = vmxml.text(serial_elem)
        try:
            return drive_by_serial(disk_devices, serial)
        except LookupError:
            pass  # try again by alias before to give up

    alias = core.find_device_alias(disk_element)
    return device_by_alias(disk_devices, alias)
コード例 #30
0
ファイル: storagexml.py プロジェクト: nirs/vdsm
def parse(dev, meta):
    """Parse the XML configuration of a storage device and returns
    the corresponding params, such as

    xmlutils.tostring(dev) is equivalent to

    params = parse(dev, meta)
    xmlutils.tostring(vmdevices.storage.Drive(log, **params).getXML())

    Args:
        dev (ElementTree.Element): Root of the XML configuration snippet.
        meta (dict): Device-specific metadata.

    Returns:
        dict: params to be used to configure a storage.Drive.
    """
    disk_type = core.find_device_type(dev)
    params = {
        'device': dev.attrib.get('device', None) or dev.tag,
        'type': dev.tag,
        'diskType': disk_type,
        'specParams': {},
    }
    core.update_device_params(params, dev, ('sgio',))
    _update_meta_params(params, meta)
    _update_source_params(
        params, disk_type, vmxml.find_first(dev, 'source', None)
    )
    _update_payload_params(params, meta)
    _update_auth_params(params, vmxml.find_first(dev, 'auth', None))
    _update_driver_params(params, dev)
    _update_interface_params(params, dev)
    _update_iotune_params(params, dev)
    _update_readonly_params(params, dev)
    _update_boot_params(params, dev)
    _update_serial_params(params, dev)

    add_vdsm_parameters(params)
    return params
コード例 #31
0
 def test_append_child_etree(self):
     empty = vmxml.find_first(self._dom, 'empty')
     vmxml.append_child(empty, etree_child=vmxml.parse_xml('<new/>'))
     self.assertIsNotNone(vmxml.find_first(self._dom, 'new', None))
     empty = vmxml.find_first(self._dom, 'empty')
     self.assertIsNotNone(vmxml.find_first(empty, 'new', None))
コード例 #32
0
ファイル: domain_descriptor.py プロジェクト: akashihi/vdsm
 def metadata(self):
     return vmxml.find_first(self._dom, 'metadata', None)
コード例 #33
0
ファイル: storage.py プロジェクト: minqf/vdsm
    def update_device_info(cls, vm, device_conf):
        # FIXME!  We need to gather as much info as possible from the libvirt.
        # In the future we can return this real data to management instead of
        # vm's conf
        for x in vm.domain.get_device_elements('disk'):
            alias, devPath, name = _get_drive_identification(x)
            readonly = vmxml.find_first(x, 'readonly', None) is not None
            bootOrder = vmxml.find_attr(x, 'boot', 'order')

            devType = vmxml.attr(x, 'device')
            if devType == 'disk':
                # raw/qcow2
                drv = vmxml.find_attr(x, 'driver', 'type')
            else:
                drv = 'raw'
            # Get disk address
            address = vmxml.device_address(x)

            # Keep data as dict for easier debugging
            deviceDict = {
                'path': devPath,
                'name': name,
                'readonly': readonly,
                'bootOrder': bootOrder,
                'address': address,
                'type': devType
            }

            # display indexed pairs of ordered values from 2 dicts
            # such as {key_1: (valueA_1, valueB_1), ...}
            def mergeDicts(deviceDef, dev):
                return dict((k, (deviceDef[k], getattr(dev, k, None)))
                            for k in deviceDef)

            vm.log.debug('Looking for drive with attributes %s', deviceDict)
            for d in device_conf:
                # When we analyze a disk device that was already discovered in
                # the past (generally as soon as the VM is created) we should
                # verify that the cached path is the one used in libvirt.
                # We already hit few times the problem that after a live
                # migration the paths were not in sync anymore (BZ#1059482).
                if (hasattr(d, 'alias') and d.alias == alias
                        and d.path != devPath):
                    vm.log.warning('updating drive %s path from %s to %s',
                                   d.alias, d.path, devPath)
                    d.path = devPath
                if d.path == devPath:
                    d.name = name
                    d.type = devType
                    d.drv = drv
                    d.alias = alias
                    d.address = address
                    d.readonly = readonly
                    if bootOrder:
                        d.bootOrder = bootOrder
                    vm.log.debug('Matched %s', mergeDicts(deviceDict, d))
            # Update vm's conf with address for known disk devices
            knownDev = False
            for dev in vm.conf['devices']:
                # See comment in previous loop. This part is used to update
                # the vm configuration as well.
                if ('alias' in dev and dev['alias'] == alias
                        and dev['path'] != devPath):
                    vm.log.warning(
                        'updating drive %s config path from %s '
                        'to %s', dev['alias'], dev['path'], devPath)
                    dev['path'] = devPath
                if (dev['type'] == hwclass.DISK and dev['path'] == devPath):
                    dev['name'] = name
                    dev['address'] = address
                    dev['alias'] = alias
                    dev['readonly'] = str(readonly)
                    if bootOrder:
                        dev['bootOrder'] = bootOrder
                    vm.log.debug('Matched %s', mergeDicts(deviceDict, dev))
                    knownDev = True
            # Add unknown disk device to vm's conf
            if not knownDev:
                archIface = DEFAULT_INTERFACE_FOR_ARCH[vm.arch]
                iface = archIface if address['type'] == 'drive' else 'pci'
                diskDev = {
                    'type': hwclass.DISK,
                    'device': devType,
                    'iface': iface,
                    'path': devPath,
                    'name': name,
                    'address': address,
                    'alias': alias,
                    'readonly': str(readonly)
                }
                if bootOrder:
                    diskDev['bootOrder'] = bootOrder
                vm.log.warning('Found unknown drive: %s', diskDev)
                vm.conf['devices'].append(diskDev)
コード例 #34
0
ファイル: lease.py プロジェクト: xin49/vdsm
 def get_identifying_attrs(cls, dev_elem):
     return {
         'devtype': core.dev_class_from_dev_elem(dev_elem),
         'name': vmxml.text(vmxml.find_first(dev_elem, 'key')),
     }
コード例 #35
0
 def test_text(self, tag, result):
     element = vmxml.find_first(self._dom, tag)
     text = vmxml.text(element)
     self.assertEqual(text, result)
コード例 #36
0
 def test_children(self, start_tag, tag, number):
     element = vmxml.find_first(self._dom, start_tag)
     self.assertEqual(len(list(vmxml.children(element, tag))), number)
コード例 #37
0
ファイル: network.py プロジェクト: olegtikhonov/vdsm
    def update_device_info(cls, vm, device_conf):
        for x in vm.domain.get_device_elements('interface'):
            devType = vmxml.attr(x, 'type')
            mac = vmxml.find_attr(x, 'mac', 'address')
            alias = core.find_device_alias(x)
            xdrivers = vmxml.find_first(x, 'driver', None)
            driver = ({
                'name': vmxml.attr(xdrivers, 'name'),
                'queues': vmxml.attr(xdrivers, 'queues')
            } if xdrivers is not None else {})
            if devType == 'hostdev':
                name = alias
                model = 'passthrough'
            else:
                name = vmxml.find_attr(x, 'target', 'dev')
                model = vmxml.find_attr(x, 'model', 'type')
            if model == 'virtio':
                # Reverse action of the conversion in __init__.
                model = 'pv'

            network = None
            try:
                if vmxml.find_attr(x, 'link', 'state') == 'down':
                    linkActive = False
                else:
                    linkActive = True
            except IndexError:
                linkActive = True
            source = vmxml.find_first(x, 'source', None)
            if source is not None:
                network = vmxml.attr(source, 'bridge')
                if not network:
                    network = libvirtnetwork.netname_l2o(
                        vmxml.attr(source, 'network'))

            address = core.find_device_guest_address(x)

            for nic in device_conf:
                if nic.macAddr.lower() == mac.lower():
                    nic.name = name
                    nic.alias = alias
                    nic.address = address
                    nic.linkActive = linkActive
                    if driver:
                        # If a driver was reported, pass it back to libvirt.
                        # Engine (vm's conf) is not interested in this value.
                        nic.driver = driver
            # Update vm's conf with address for known nic devices
            knownDev = False
            for dev in vm.conf['devices']:
                if (dev['type'] == hwclass.NIC
                        and dev['macAddr'].lower() == mac.lower()):
                    dev['address'] = address
                    dev['alias'] = alias
                    dev['name'] = name
                    dev['linkActive'] = linkActive
                    knownDev = True
            # Add unknown nic device to vm's conf
            if not knownDev:
                nicDev = {
                    'type': hwclass.NIC,
                    'device': devType,
                    'macAddr': mac,
                    'nicModel': model,
                    'address': address,
                    'alias': alias,
                    'name': name,
                    'linkActive': linkActive
                }
                if network:
                    nicDev['network'] = network
                vm.conf['devices'].append(nicDev)
コード例 #38
0
ファイル: storagexml.py プロジェクト: rollandf/vdsm
def _update_driver_params(params, dev):
    driver = vmxml.find_first(dev, 'driver', None)
    if driver is not None:
        driver_params, spec_params = _get_driver_params(driver)
        params.update(driver_params)
        params['specParams'].update(spec_params)
コード例 #39
0
 def test_restore_paths(self):
     xml = self.XML
     second_disk_path = '/path/secondary-drive'
     snapshot_params = {
         'path': '/path/snapshot-path',
         'volume_id': 'aaa',
         'device': '/dev/random',
         'second_disk_path': second_disk_path,
     }
     engine_params = {
         'path': '/path/engine-path',
         'volume_id': 'bbb',
         'device': '/dev/urandom',
         'second_disk_path': second_disk_path,
     }
     snapshot_xml = xml.format(**snapshot_params)
     engine_xml = xml.format(**engine_params)
     params = {
         '_srcDomXML': snapshot_xml,
         'xml': engine_xml,
         'restoreState': {
             'device': 'disk',
             'imageID': u'111',
             'poolID': u'222',
             'domainID': u'333',
             'volumeID': u'bbb',
         },
         'restoreFromSnapshot': True,
     }
     with fake.VM(params) as vm:
         vm._normalizeVdsmImg = lambda *args: None
         devices = vm._make_devices()
         vm_xml = vm.conf['xml']
     # Check that unrelated devices are taken from the snapshot untouched,
     # not from the XML provided from Engine:
     for d in devices[hwclass.RNG]:
         self.assertEqual(d.specParams['source'],
                          os.path.basename(snapshot_params['device']))
         break
     else:
         raise Exception('RNG device not found')
     tested_drives = (
         (
             '1234',
             engine_params['path'],
         ),
         (
             '5678',
             second_disk_path,
         ),
     )
     for serial, path in tested_drives:
         for d in devices[hwclass.DISK]:
             if d.serial == serial:
                 self.assertEqual(d.path, path)
                 break
         else:
             raise Exception('Tested drive not found', serial)
     dom = xmlutils.fromstring(vm_xml)
     random = vmxml.find_first(dom, 'backend')
     self.assertEqual(random.text, snapshot_params['device'])
     for serial, path in tested_drives:
         for d in dom.findall(".//disk[serial='{}']".format(serial)):
             self.assertEqual(vmxml.find_attr(d, 'source', 'file'), path)
             break
         else:
             raise Exception('Tested drive not found', serial)
     self.assertEqual(vm_xml, vm._domain.xml)
コード例 #40
0
ファイル: storagexml.py プロジェクト: vjuranek/vdsm
def _update_readonly_params(params, dev):
    if vmxml.find_first(dev, 'readonly', None) is not None:
        params['readonly'] = True
コード例 #41
0
ファイル: domain_descriptor.py プロジェクト: dong-df/vdsm
 def nvram(self):
     """
     :return: NVRAM element defining NVRAM store (used to store UEFI or
       SecureBoot variables) or None if the VM has no NVRAM store.
     """
     return vmxml.find_first(self._dom, 'os/nvram', None)
コード例 #42
0
ファイル: network.py プロジェクト: kobihk/vdsm
 def from_xml_tree(cls, log, dev, meta):
     params = {
         'device': core.find_device_type(dev),
         'type': dev.tag,
         'custom': meta.get('custom', {}),
         'vmid': meta['vmid'],
         'vm_custom': {},
         'specParams': {},
     }
     core.update_device_params(params, dev)
     params.update(core.get_xml_elem(dev, 'macAddr', 'mac', 'address'))
     params.update(core.get_xml_elem(dev, 'nicModel', 'model', 'type'))
     params.update(core.get_xml_elem(dev, 'bootOrder', 'boot', 'order'))
     if params['device'] == 'hostdev':
         params.update(_get_hostdev_params(dev))
     link = vmxml.find_first(dev, 'link', None)
     if link is not None:
         if link.attrib.get('state', 'down') == 'down':
             params['linkActive'] = False
         else:
             params['linkActive'] = True
     vlan = vmxml.find_first(dev, 'vlan', None)
     if vlan is not None:
         params['specParams']['vlanid'] = vmxml.find_attr(
             vlan, 'tag', 'id'
         )
     mtu = vmxml.find_first(dev, "mtu", None)
     if mtu is not None:
         params['mtu'] = int(vmxml.attr(mtu, 'size'))
     filterref = vmxml.find_first(dev, 'filterref', None)
     if filterref is not None:
         params['filter'] = vmxml.attr(filterref, 'filter')
         params['filterParameters'] = [
             {
                 'name': param.attrib['name'],
                 'value': param.attrib['value'],
             }
             for param in vmxml.find_all(filterref, 'parameter')
         ]
     driver = vmxml.find_first(dev, 'driver', None)
     if driver is not None:
         params['custom'].update(
             core.parse_device_attrs(driver, ('queues',))
         )
     sndbuf = dev.find('./tune/sndbuf')
     if sndbuf is not None:
         params['vm_custom']['sndbuf'] = vmxml.text(sndbuf)
     bandwidth = vmxml.find_first(dev, 'bandwidth', None)
     if bandwidth is not None:
         for mode in ('inbound', 'outbound'):
             elem = vmxml.find_first(bandwidth, mode, None)
             if elem is not None:
                 params['specParams'][mode] = elem.attrib.copy()
     net = (
         meta.get('network', None) or
         vmxml.find_attr(dev, 'source', 'bridge')
     )
     if net is None:
         raise MissingNetwork("no network to join")
     params['network'] = net
     _update_port_mirroring(params, meta)
     core.update_device_params_from_meta(params, meta)
     return cls(log, **params)
コード例 #43
0
 def test_append_child_noargs(self):
     empty = vmxml.find_first(self._dom, 'empty')
     self.assertRaises(RuntimeError, vmxml.append_child, empty)
コード例 #44
0
def add_mediated_device(dom, mdev_uuid):
    devs = vmxml.find_first(dom, 'devices')
    hostdev = libvirtxml.make_mdev_element(mdev_uuid)
    devs.append(hostdev)
コード例 #45
0
 def test_append_child_too_many_args(self):
     empty = vmxml.find_first(self._dom, 'empty')
     self.assertRaises(RuntimeError, vmxml.append_child, empty,
                       vmxml.Element('new'), xmlutils.fromstring('<new/>'))
コード例 #46
0
 def test_append_child(self):
     empty = vmxml.find_first(self._dom, 'empty')
     vmxml.append_child(empty, vmxml.Element('new'))
     self.assertIsNotNone(vmxml.find_first(self._dom, 'new', None))
     empty = vmxml.find_first(self._dom, 'empty')
     self.assertIsNotNone(vmxml.find_first(empty, 'new', None))
コード例 #47
0
 def devices(self):
     return vmxml.find_first(self._dom, 'devices', None)
コード例 #48
0
ファイル: storagexml.py プロジェクト: vjuranek/vdsm
def _update_serial_params(params, dev):
    serial = vmxml.find_first(dev, 'serial', None)
    if serial is not None:
        params['serial'] = vmxml.text(serial)
コード例 #49
0
 def test_append_child_etree(self):
     empty = vmxml.find_first(self._dom, 'empty')
     vmxml.append_child(empty, etree_child=xmlutils.fromstring('<new/>'))
     self.assertIsNotNone(vmxml.find_first(self._dom, 'new', None))
     empty = vmxml.find_first(self._dom, 'empty')
     self.assertIsNotNone(vmxml.find_first(empty, 'new', None))