コード例 #1
0
def _get_class(class_type, *args, **kwargs):
    if class_type not in utils_map:
        raise exceptions.HyperVException(
            _('Class type %s does '
              'not exist') % class_type)

    windows_version = utils.get_windows_version()
    build = list(map(int, windows_version.split('.')))
    windows_version = float("%i.%i" % (build[0], build[1]))

    existing_classes = utils_map.get(class_type)
    for class_variant in existing_classes.keys():
        utils_class = existing_classes.get(class_variant)
        if (utils_class['min_version'] <= windows_version
                and (utils_class['max_version'] is None
                     or windows_version < utils_class['max_version'])):
            return importutils.import_object(utils_class['path'], *args,
                                             **kwargs)

    raise exceptions.HyperVException(
        _('Could not find any %(class)s class for'
          'this Windows version: %(win_version)s') % {
              'class': class_type,
              'win_version': windows_version
          })
コード例 #2
0
def _get_class(class_type, *args, **kwargs):
    if class_type not in utils_map:
        raise exceptions.HyperVException(
            _('Class type %s does '
              'not exist') % class_type)

    windows_version = utils.get_windows_version()
    build = list(map(int, windows_version.split('.')))
    windows_version = float("%i.%i" % (build[0], build[1]))

    existing_classes = utils_map.get(class_type, [])
    for class_variant in existing_classes:
        min_version = class_variant.get('min_version', DEFAULT_MIN_VERSION)
        max_version = class_variant.get('max_version', DEFAULT_MAX_VERSION)
        class_path = class_variant['path']
        if (min_version <= windows_version
                and (max_version is None or windows_version < max_version)):
            return importutils.import_object(class_path, *args, **kwargs)

    raise exceptions.HyperVException(
        _('Could not find any %(class)s class for'
          'this Windows version: %(win_version)s') % {
              'class': class_type,
              'win_version': windows_version
          })
コード例 #3
0
 def check_live_migration_config(self):
     migration_svc = (
         self._compat_conn.Msvm_VirtualSystemMigrationService()[0])
     vsmssd = (
         self._compat_conn.Msvm_VirtualSystemMigrationServiceSettingData())
     vsmssd = vsmssd[0]
     if not vsmssd.EnableVirtualSystemMigration:
         raise exceptions.HyperVException(
             _('Live migration is not enabled on this host'))
     if not migration_svc.MigrationServiceListenerIPAddressList:
         raise exceptions.HyperVException(
             _('Live migration networks are not configured on this host'))
コード例 #4
0
 def check_live_migration_config(self):
     conn_v2 = self._get_conn_v2()
     migration_svc = conn_v2.Msvm_VirtualSystemMigrationService()[0]
     vsmssds = migration_svc.associators(
         wmi_association_class='Msvm_ElementSettingData',
         wmi_result_class='Msvm_VirtualSystemMigrationServiceSettingData')
     vsmssd = vsmssds[0]
     if not vsmssd.EnableVirtualSystemMigration:
         raise exceptions.HyperVException(
             _('Live migration is not enabled on this host'))
     if not migration_svc.MigrationServiceListenerIPAddressList:
         raise exceptions.HyperVException(
             _('Live migration networks are not configured on this host'))
コード例 #5
0
    def _wait_for_job(self, job_path):
        """Poll WMI job state and wait for completion."""

        job_wmi_path = job_path.replace('\\', '/')
        job = wmi.WMI(moniker=job_wmi_path)

        while job.JobState == constants.WMI_JOB_STATE_RUNNING:
            time.sleep(0.1)
            job = wmi.WMI(moniker=job_wmi_path)

        if job.JobState == constants.JOB_STATE_KILLED:
            LOG.debug("WMI job killed with status %s.", job.JobState)
            return job

        if job.JobState != constants.WMI_JOB_STATE_COMPLETED:
            job_state = job.JobState
            if job.path().Class == "Msvm_ConcreteJob":
                err_sum_desc = job.ErrorSummaryDescription
                err_desc = job.ErrorDescription
                err_code = job.ErrorCode
                data = {
                    'job_state': job_state,
                    'err_sum_desc': err_sum_desc,
                    'err_desc': err_desc,
                    'err_code': err_code
                }
                raise exceptions.HyperVException(
                    _("WMI job failed with status %(job_state)d. "
                      "Error details: %(err_sum_desc)s - %(err_desc)s - "
                      "Error code: %(err_code)d") % data)
            else:
                (error, ret_val) = job.GetError()
                if not ret_val and error:
                    data = {'job_state': job_state, 'error': error}
                    raise exceptions.HyperVException(
                        _("WMI job failed with status %(job_state)d. "
                          "Error details: %(error)s") % data)
                else:
                    raise exceptions.HyperVException(
                        _("WMI job failed with status %d. No error "
                          "description available") % job_state)
        desc = job.Description
        elap = job.ElapsedTime
        LOG.debug("WMI job succeeded: %(desc)s, Elapsed=%(elap)s", {
            'desc': desc,
            'elap': elap
        })
        return job
コード例 #6
0
ファイル: networkutils.py プロジェクト: mateimicu/os-win
    def _set_switch_port_security_settings(self, switch_port_name, **kwargs):
        port_alloc = self._get_switch_port_allocation(switch_port_name)[0]
        sec_settings = self._get_security_setting_data_from_port_alloc(
            port_alloc)

        if sec_settings:
            if all(getattr(sec_settings, k) == v for k, v in kwargs.items()):
                # All desired properties already properly set. Nothing to do.
                return

            # Removing the feature because it cannot be modified
            # due to a wmi exception.
            self._jobutils.remove_virt_feature(sec_settings)
        else:
            sec_settings = self._create_default_setting_data(
                self._PORT_SECURITY_SET_DATA)

        for k, v in kwargs.items():
            setattr(sec_settings, k, v)

        self._jobutils.add_virt_feature(sec_settings, port_alloc)

        # TODO(claudiub): This will help solve the missing VSID issue, but it
        # comes with a performance cost. The root cause of the problem must
        # be solved.
        sec_settings = self._get_security_setting_data_from_port_alloc(
            port_alloc)
        if not sec_settings:
            raise exceptions.HyperVException(
                _('Port Security Settings not found: %s') % switch_port_name)
コード例 #7
0
 def _get_vnic_settings(self, vnic_name):
     vnic_settings = self._conn.Msvm_SyntheticEthernetPortSettingData(
         ElementName=vnic_name)
     if not vnic_settings:
         raise exceptions.HyperVException(message=_('Vnic not found: %s') %
                                          vnic_name)
     return vnic_settings[0]
コード例 #8
0
 def execute(self, *args, **kwargs):
     stdout_value, stderr_value = _utils.execute(*args, **kwargs)
     if stdout_value.find('The operation completed successfully') == -1:
         raise exceptions.HyperVException(
             _('An error has occurred when calling the iscsi initiator: %s')
             % stdout_value)
     return stdout_value
コード例 #9
0
    def set_vswitch_port_vlan_id(self, vlan_id, switch_port_name):
        port_alloc = self._get_switch_port_allocation(switch_port_name)[0]

        vlan_settings = self._get_vlan_setting_data_from_port_alloc(port_alloc)
        if vlan_settings:
            if (vlan_settings.OperationMode == self._OPERATION_MODE_ACCESS
                    and vlan_settings.AccessVlanId == vlan_id):
                # VLAN already set to corect value, no need to change it.
                return

            # Removing the feature because it cannot be modified
            # due to a wmi exception.
            self._jobutils.remove_virt_feature(vlan_settings)

            # remove from cache.
            self._vlan_sds.pop(port_alloc.InstanceID, None)

        vlan_settings = self._create_default_setting_data(
            self._PORT_VLAN_SET_DATA)
        vlan_settings.AccessVlanId = vlan_id
        vlan_settings.OperationMode = self._OPERATION_MODE_ACCESS
        self._jobutils.add_virt_feature(vlan_settings, port_alloc)

        # TODO(claudiub): This will help solve the missing VLAN issue, but it
        # comes with a performance cost. The root cause of the problem must
        # be solved.
        vlan_settings = self._get_vlan_setting_data_from_port_alloc(port_alloc)
        if not vlan_settings:
            raise exceptions.HyperVException(
                _('Port VLAN not found: %s') % switch_port_name)
コード例 #10
0
    def set_vswitch_port_vsid(self, vsid, switch_port_name):
        port_alloc = self._get_switch_port_allocation(switch_port_name)[0]

        vsid_settings = self._get_security_setting_data_from_port_alloc(
            port_alloc)

        if vsid_settings:
            if vsid_settings.VirtualSubnetId == vsid:
                # VSID already added, no need to readd it.
                return
            # Removing the feature because it cannot be modified
            # due to a wmi exception.
            self._jobutils.remove_virt_feature(vsid_settings)

            # remove from cache.
            self._vsid_sds.pop(port_alloc.InstanceID, None)

        vsid_settings = self._create_default_setting_data(
            self._PORT_SECURITY_SET_DATA)
        vsid_settings.VirtualSubnetId = vsid
        self._jobutils.add_virt_feature(vsid_settings, port_alloc)

        # TODO(claudiub): This will help solve the missing VSID issue, but it
        # comes with a performance cost. The root cause of the problem must
        # be solved.
        vsid_settings = self._get_security_setting_data_from_port_alloc(
            port_alloc)
        if not vsid_settings:
            raise exceptions.HyperVException(
                _('Port VSID not found: %s') % switch_port_name)
コード例 #11
0
 def get_device_number_from_device_name(self, device_name):
     matches = self._phys_dev_name_regex.findall(device_name)
     if matches:
         return matches[0]
     else:
         err_msg = _("Could not find device number for device: %s")
         raise exceptions.HyperVException(err_msg % device_name)
コード例 #12
0
 def _get_vswitch(self, vswitch_name):
     vswitch = self._conn.Msvm_VirtualEthernetSwitch(
         ElementName=vswitch_name)
     if not len(vswitch):
         raise exceptions.HyperVException(
             _('VSwitch not found: %s') % vswitch_name)
     return vswitch[0]
コード例 #13
0
ファイル: jobutils.py プロジェクト: sitoader-zz/os-win
    def check_ret_val(self, ret_val, job_path, success_values=[0]):
        """Checks that the job represented by the given arguments succeeded.

        Some Hyper-V operations are not atomic, and will return a reference
        to a job. In this case, this method will wait for the job's
        completion.

        :param ret_val: integer, representing the return value of the job.
            if the value is WMI_JOB_STATUS_STARTED or WMI_JOB_STATE_RUNNING,
            a job_path cannot be None.
        :param job_path: string representing the WMI object path of a
            Hyper-V job.
        :param success_values: list of return values that can be considered
            successful. WMI_JOB_STATUS_STARTED and WMI_JOB_STATE_RUNNING
            values are ignored.
        :raises exceptions.HyperVException: if the given ret_val is
            WMI_JOB_STATUS_STARTED or WMI_JOB_STATE_RUNNING and the state of
            job represented by the given job_path is not
            WMI_JOB_STATE_COMPLETED, or if the given ret_val is not in the
            list of given success_values.
        """
        if ret_val in [
                constants.WMI_JOB_STATUS_STARTED,
                constants.WMI_JOB_STATE_RUNNING
        ]:
            return self._wait_for_job(job_path)
        elif ret_val not in success_values:
            raise exceptions.HyperVException(
                _('Operation failed with return value: %s') % ret_val)
コード例 #14
0
 def _get_vm(self, conn_v2, vm_name):
     vms = conn_v2.Msvm_ComputerSystem(ElementName=vm_name)
     n = len(vms)
     if not n:
         raise exceptions.HyperVVMNotFoundException(vm_name=vm_name)
     elif n > 1:
         raise exceptions.HyperVException(
             _('Duplicate VM name found: %s') % vm_name)
     return vms[0]
コード例 #15
0
    def get_free_controller_slot(self, scsi_controller_path):
        attached_disks = self.get_attached_disks(scsi_controller_path)
        used_slots = [int(disk.AddressOnParent) for disk in attached_disks]

        for slot in range(constants.SCSI_CONTROLLER_SLOTS_NUMBER):
            if slot not in used_slots:
                return slot
        raise exceptions.HyperVException(
            _("Exceeded the maximum number of slots"))
コード例 #16
0
 def check_ret_val(self, ret_val, job_path, success_values=[0]):
     if ret_val in [
             constants.WMI_JOB_STATUS_STARTED,
             constants.WMI_JOB_STATE_RUNNING
     ]:
         return self._wait_for_job(job_path)
     elif ret_val not in success_values:
         raise exceptions.HyperVException(
             _('Operation failed with return value: %s') % ret_val)
コード例 #17
0
 def _get_planned_vm(self, vm_name, conn_v2=None, fail_if_not_found=False):
     if not conn_v2:
         conn_v2 = self._conn
     planned_vm = conn_v2.Msvm_PlannedComputerSystem(ElementName=vm_name)
     if planned_vm:
         return planned_vm[0]
     elif fail_if_not_found:
         raise exceptions.HyperVException(
             _('Cannot find planned VM with name: %s') % vm_name)
     return None
コード例 #18
0
 def _lookup_vm(self, vm_name):
     vms = self._conn.Msvm_ComputerSystem(ElementName=vm_name)
     n = len(vms)
     if n == 0:
         return None
     elif n > 1:
         raise exceptions.HyperVException(
             _('Duplicate VM name found: %s') % vm_name)
     else:
         return vms[0]
コード例 #19
0
    def test_remove_sg_port_rules_exception(self):
        mock_rule = mock.MagicMock()
        self._driver._sec_group_rules[self._FAKE_ID] = [mock_rule]
        self._driver._utils.remove_security_rules.side_effect = (
            exceptions.HyperVException(msg='Generated Exception for testing.'))

        self.assertRaises(exceptions.HyperVException,
                          self._driver._remove_sg_port_rules, self._FAKE_ID,
                          [mock_rule])

        self.assertIn(mock_rule, self._driver._sec_group_rules[self._FAKE_ID])
コード例 #20
0
    def test_add_sg_port_rules_exception(self):
        mock_port = self._get_port()
        mock_rule = mock.MagicMock()
        self._driver._sec_group_rules[self._FAKE_ID] = []
        self._driver._utils.create_security_rules.side_effect = (
            exceptions.HyperVException(msg='Generated Exception for testing.'))

        self.assertRaises(exceptions.HyperVException,
                          self._driver._add_sg_port_rules,
                          mock_port, [mock_rule])

        self.assertNotIn(mock_rule,
                         self._driver._sec_group_rules[self._FAKE_ID])
コード例 #21
0
    def _is_port_vm_started(self, port):
        vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
        vmsettings = port.associators(
            wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA)
        # See http://msdn.microsoft.com/en-us/library/cc160706%28VS.85%29.aspx
        (ret_val, summary_info) = vs_man_svc.GetSummaryInformation(
            [self._VM_SUMMARY_ENABLED_STATE], [v.path_() for v in vmsettings])
        if ret_val or not summary_info:
            raise exceptions.HyperVException(
                _('Cannot get VM summary data '
                  'for: %s') % port.ElementName)

        return summary_info[0].EnabledState is self._HYPERV_VM_STATE_ENABLED
コード例 #22
0
    def _is_port_vm_started(self, port):
        vmsettings_instance_id = port.InstanceID.split('\\')[0]
        vmsettings = self._conn.Msvm_VirtualSystemSettingData(
            InstanceID=vmsettings_instance_id)
        # See http://msdn.microsoft.com/en-us/library/cc160706%28VS.85%29.aspx
        (ret_val, summary_info) = self._vs_man_svc.GetSummaryInformation(
            [self._VM_SUMMARY_ENABLED_STATE], [v.path_() for v in vmsettings])
        if ret_val or not summary_info:
            raise exceptions.HyperVException(
                _('Cannot get VM summary data '
                  'for: %s') % port.ElementName)

        return summary_info[0].EnabledState is self._HYPERV_VM_STATE_ENABLED
コード例 #23
0
    def get_external_vswitch(self, vswitch_name):
        if vswitch_name:
            vswitches = self._conn.Msvm_VirtualEthernetSwitch(
                ElementName=vswitch_name)
            if not len(vswitches):
                raise exceptions.HyperVException(
                    _('vswitch "%s" not found') % vswitch_name)
        else:
            # Find the vswitch that is connected to the first physical nic.
            ext_port = self._conn.Msvm_ExternalEthernetPort(IsBound='TRUE')[0]
            lep = ext_port.associators(wmi_result_class='Msvm_LANEndpoint')[0]
            lep1 = lep.associators(wmi_result_class='Msvm_LANEndpoint')[0]
            esw = lep1.associators(
                wmi_result_class='Msvm_EthernetSwitchPort')[0]
            vswitches = esw.associators(
                wmi_result_class='Msvm_VirtualEthernetSwitch')

            if not len(vswitches):
                raise exceptions.HyperVException(
                    _('No external vswitch found'))

        return vswitches[0].path_()
コード例 #24
0
    def login_storage_target(self,
                             target_lun,
                             target_iqn,
                             target_portal,
                             auth_username=None,
                             auth_password=None):
        """Ensure that the target is logged in."""

        self._login_target_portal(target_portal)

        retry_count = CONF.hyperv.volume_attach_retry_count

        # If the target is not connected, at least two iterations are needed:
        # one for performing the login and another one for checking if the
        # target was logged in successfully.
        if retry_count < 2:
            retry_count = 2

        for attempt in range(retry_count):
            target = self._conn_storage.query("SELECT * FROM MSFT_iSCSITarget "
                                              "WHERE NodeAddress='%s' " %
                                              target_iqn)

            if target and target[0].IsConnected:
                if attempt == 0:
                    # The target was already connected but an update may be
                    # required
                    target[0].Update()
                return
            try:
                target = self._conn_storage.MSFT_iSCSITarget
                auth = {}
                if auth_username and auth_password:
                    auth['AuthenticationType'] = self._CHAP_AUTH_TYPE
                    auth['ChapUsername'] = auth_username
                    auth['ChapSecret'] = auth_password
                target.Connect(NodeAddress=target_iqn,
                               IsPersistent=True,
                               **auth)
                time.sleep(CONF.hyperv.volume_attach_retry_interval)
            except wmi.x_wmi as exc:
                LOG.debug("Attempt %(attempt)d to connect to target  "
                          "%(target_iqn)s failed. Retrying. "
                          "WMI exception: %(exc)s " % {
                              'target_iqn': target_iqn,
                              'exc': exc,
                              'attempt': attempt
                          })
        raise exceptions.HyperVException(
            _('Failed to login target %s') % target_iqn)
コード例 #25
0
 def _get_conn_v2(self, host='localhost'):
     try:
         return self._get_wmi_obj(self._wmi_namespace % host)
     except wmi.x_wmi as ex:
         LOG.exception(_LE('Get version 2 connection error'))
         if ex.com_error.hresult == -2147217394:
             msg = (_('Live migration is not supported on target host "%s"')
                    % host)
         elif ex.com_error.hresult == -2147023174:
             msg = (_('Target live migration host "%s" is unreachable')
                    % host)
         else:
             msg = _('Live migration failed: %s') % ex.message
         raise exceptions.HyperVException(msg)
コード例 #26
0
 def _lookup_vm(self, vm_name, as_vssd=True, for_update=False):
     if as_vssd:
         conn = self._compat_conn if for_update else self._conn
         vms = conn.Msvm_VirtualSystemSettingData(
             ElementName=vm_name,
             VirtualSystemType=self._VIRTUAL_SYSTEM_TYPE_REALIZED)
     else:
         vms = self._conn.Msvm_ComputerSystem(ElementName=vm_name)
     n = len(vms)
     if n == 0:
         return None
     elif n > 1:
         raise exceptions.HyperVException(
             _('Duplicate VM name found: %s') % vm_name)
     else:
         return vms[0]
コード例 #27
0
    def login_storage_target(self,
                             target_lun,
                             target_iqn,
                             target_portal,
                             auth_username=None,
                             auth_password=None):
        """Ensure that the target is logged in."""

        self._login_target_portal(target_portal)
        # Listing targets
        self.execute('iscsicli.exe', 'ListTargets')

        retry_count = CONF.hyperv.volume_attach_retry_count

        # If the target is not connected, at least two iterations are needed:
        # one for performing the login and another one for checking if the
        # target was logged in successfully.
        if retry_count < 2:
            retry_count = 2

        for attempt in range(retry_count):
            try:
                session_info = self.execute('iscsicli.exe', 'SessionList')
                if session_info.find(target_iqn) == -1:
                    # Sending login
                    self.execute('iscsicli.exe', 'qlogintarget', target_iqn,
                                 auth_username, auth_password)
                else:
                    return
            except exceptions.HyperVException as exc:
                LOG.debug(
                    "Attempt %(attempt)d to connect to target  "
                    "%(target_iqn)s failed. Retrying. "
                    "Exceptipn: %(exc)s ", {
                        'target_iqn': target_iqn,
                        'exc': exc,
                        'attempt': attempt
                    })
                time.sleep(CONF.hyperv.volume_attach_retry_interval)

        raise exceptions.HyperVException(
            _('Failed to login target %s') % target_iqn)
コード例 #28
0
    def set_vswitch_port_profile_id(self, switch_port_name, profile_id,
                                    profile_data, profile_name, vendor_name,
                                    **kwargs):
        """Sets up the port profile id.

        :param switch_port_name: The ElementName of the vSwitch port.
        :param profile_id: The profile id to be set for the given switch port.
        :param profile_data: Additional data for the Port Profile.
        :param profile_name: The name of the Port Profile.
        :param net_cfg_instance_id: Unique device identifier of the
            sub-interface.
        :param cdn_label_id: The CDN Label Id.
        :param cdn_label_string: The CDN label string.
        :param vendor_id: The id of the Vendor defining the profile.
        :param vendor_name: The name of the Vendor defining the profile.
        """
        port_alloc = self._get_switch_port_allocation(switch_port_name)[0]
        port_profile = self._get_profile_setting_data_from_port_alloc(
            port_alloc)

        new_port_profile = self._prepare_profile_sd(profile_id=profile_id,
                                                    profile_data=profile_data,
                                                    profile_name=profile_name,
                                                    vendor_name=vendor_name,
                                                    **kwargs)

        if port_profile:
            # Removing the feature because it cannot be modified
            # due to a wmi exception.
            self._jobutils.remove_virt_feature(port_profile)

            # remove from cache.
            self._profile_sds.pop(port_alloc.InstanceID, None)

        try:
            self._jobutils.add_virt_feature(new_port_profile, port_alloc)
        except Exception as ex:
            raise exceptions.HyperVException(
                'Unable to set port profile settings %(port_profile)s '
                'for port %(port)s. Error: %(error)s' %
                dict(port_profile=new_port_profile, port=port_alloc, error=ex))
コード例 #29
0
    def set_vswitch_port_vlan_id(self, vlan_id, switch_port_name):
        port_alloc, found = self._get_switch_port_allocation(switch_port_name)
        if not found:
            raise exceptions.HyperVException(
                _('Port Allocation not found: %s') % switch_port_name)

        vlan_settings = self._get_vlan_setting_data_from_port_alloc(port_alloc)
        if vlan_settings:
            if (vlan_settings.OperationMode == self._OPERATION_MODE_ACCESS
                    and vlan_settings.AccessVlanId == vlan_id):
                # VLAN already set to corect value, no need to change it.
                return

            # Removing the feature because it cannot be modified
            # due to a wmi exception.
            self._jobutils.remove_virt_feature(vlan_settings)

        (vlan_settings, found) = self._get_vlan_setting_data(switch_port_name)
        vlan_settings.AccessVlanId = vlan_id
        vlan_settings.OperationMode = self._OPERATION_MODE_ACCESS
        self._jobutils.add_virt_feature(vlan_settings, port_alloc)
コード例 #30
0
    def get_vm_summary_info(self, vm_name):
        vm = self._lookup_vm_check(vm_name)

        vmsettings = vm.associators(
            wmi_association_class=self._SETTINGS_DEFINE_STATE_CLASS,
            wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
        settings_paths = [v.path_() for v in vmsettings]
        # See http://msdn.microsoft.com/en-us/library/cc160706%28VS.85%29.aspx
        (ret_val, summary_info) = self._vs_man_svc.GetSummaryInformation([
            constants.VM_SUMMARY_NUM_PROCS, constants.VM_SUMMARY_ENABLED_STATE,
            constants.VM_SUMMARY_MEMORY_USAGE, constants.VM_SUMMARY_UPTIME
        ], settings_paths)
        if ret_val:
            raise exceptions.HyperVException(
                _('Cannot get VM summary data for: %s') % vm_name)

        si = summary_info[0]
        memory_usage = None
        if si.MemoryUsage is not None:
            memory_usage = int(si.MemoryUsage)
        up_time = None
        if si.UpTime is not None:
            up_time = int(si.UpTime)

        # Nova requires a valid state to be returned. Hyper-V has more
        # states than Nova, typically intermediate ones and since there is
        # no direct mapping for those, ENABLED is the only reasonable option
        # considering that in all the non mappable states the instance
        # is running.
        enabled_state = self._enabled_states_map.get(
            si.EnabledState, constants.HYPERV_VM_STATE_ENABLED)

        summary_info_dict = {
            'NumberOfProcessors': si.NumberOfProcessors,
            'EnabledState': enabled_state,
            'MemoryUsage': memory_usage,
            'UpTime': up_time
        }
        return summary_info_dict