Beispiel #1
0
    def disconnect_switch_port(
            self, vswitch_name, switch_port_name, delete_port):
        """Disconnects the switch port."""
        switch_svc = self._conn.Msvm_VirtualSwitchManagementService()[0]
        switch_port_path = self._get_switch_port_path_by_name(
            switch_port_name)
        if not switch_port_path:
            # Port not found. It happens when the VM was already deleted.
            return

        (ret_val, ) = switch_svc.DisconnectSwitchPort(
            SwitchPort=switch_port_path)
        if ret_val != 0:
            data = {'switch_port_name': switch_port_name,
                    'vswitch_name': vswitch_name,
                    'ret_val': ret_val}
            raise vmutils.HyperVException(
                _('Failed to disconnect port %(switch_port_name)s '
                  'from switch %(vswitch_name)s '
                  'with error %(ret_val)s') % data)
        if delete_port:
            (ret_val, ) = switch_svc.DeleteSwitchPort(
                SwitchPort=switch_port_path)
            if ret_val != 0:
                data = {'switch_port_name': switch_port_name,
                        'vswitch_name': vswitch_name,
                        'ret_val': ret_val}
                raise vmutils.HyperVException(
                    _('Failed to delete port %(switch_port_name)s '
                      'from switch %(vswitch_name)s '
                      'with error %(ret_val)s') % data)
Beispiel #2
0
    def _get_vnic_settings(self, vnic_name):
        vnic_settings = self._conn.Msvm_SyntheticEthernetPortSettingData(
            ElementName=vnic_name)
        vnic_settings += self._conn.Msvm_EmulatedEthernetPortSettingData(
            ElementName=vnic_name)

        if not vnic_settings:
            raise vmutils.HyperVException(_('Vnic not found: %s') %
                                          vnic_name)
        if len(vnic_settings) > 1:
            raise vmutils.HyperVException(_('Multiple vnics found with name: '
                                            '%s') % vnic_name)
        return vnic_settings[0]
Beispiel #3
0
    def create_default_reject_all_rules(self, switch_port_name):
        port, found = self._get_switch_port_allocation(switch_port_name, False)
        if not found:
            raise vmutils.HyperVException(
                _('Port Allocation not found: %s') % switch_port_name)

        acls = port.associators(wmi_result_class=self._PORT_EXT_ACL_SET_DATA)
        filtered_acls = [v for v in acls if v.Action == self._ACL_ACTION_DENY]

        if len(filtered_acls) >= self._REJECT_ACLS_COUNT:
            return

        for acl in filtered_acls:
            self._remove_virt_feature(acl)

        weight = 0
        ipv4_pair = (self._ACL_TYPE_IPV4, self._IPV4_ANY)
        ipv6_pair = (self._ACL_TYPE_IPV6, self._IPV6_ANY)
        for direction in [self._ACL_DIR_IN, self._ACL_DIR_OUT]:
            for acl_type, address in [ipv4_pair, ipv6_pair]:
                for protocol in [self._TCP_PROTOCOL,
                                 self._UDP_PROTOCOL,
                                 self._ICMP_PROTOCOL]:
                    self._bind_security_rule(
                        port, direction, acl_type, self._ACL_ACTION_DENY,
                        self._ACL_DEFAULT, protocol, address, weight)
                    weight += 1
Beispiel #4
0
 def _get_vswitch(self, vswitch_name):
     vswitch = self._conn.Msvm_VirtualEthernetSwitch(
         ElementName=vswitch_name)
     if not len(vswitch):
         raise vmutils.HyperVException(_('VSwitch not found: %s') %
                                       vswitch_name)
     return vswitch[0]
Beispiel #5
0
    def create_dynamic_vhd(self, path, max_internal_size, format):
        vhd_format = self._vhd_format_map.get(format)
        if not vhd_format:
            raise vmutils.HyperVException(_("Unsupported disk format: %s") %
                                          format)

        self._create_vhd(self._VHD_TYPE_DYNAMIC, vhd_format, path,
                         max_internal_size=max_internal_size)
Beispiel #6
0
    def _check_job_status(self, ret_val, jobpath):
        """Poll WMI job state for completion."""
        if not ret_val:
            return
        elif ret_val not in [WMI_JOB_STATE_STARTED, WMI_JOB_STATE_RUNNING]:
            raise vmutils.HyperVException(_('Job failed with error %d') %
                                          ret_val)

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

        while job.JobState == WMI_JOB_STATE_RUNNING:
            time.sleep(0.1)
            job = wmi.WMI(moniker=job_wmi_path)
        if job.JobState != 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 vmutils.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 vmutils.HyperVException(
                        _("WMI job failed with status %(job_state)d. "
                          "Error details: %(error)s") % data)
                else:
                    raise vmutils.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})
Beispiel #7
0
    def _wait_for_job(self, job_path):
        """Poll WMI job state and wait for completion."""
        job = self._get_wmi_obj(job_path)

        while job.JobState == constants.WMI_JOB_STATE_RUNNING:
            time.sleep(0.1)
            job = self._get_wmi_obj(job_path)
        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
                raise HyperVException(
                    _("WMI job failed with status "
                      "%(job_state)d. Error details: "
                      "%(err_sum_desc)s - %(err_desc)s - "
                      "Error code: %(err_code)d") % {
                          'job_state': job_state,
                          'err_sum_desc': err_sum_desc,
                          'err_desc': err_desc,
                          'err_code': err_code
                      })
            else:
                (error, ret_val) = job.GetError()
                if not ret_val and error:
                    raise HyperVException(
                        _("WMI job failed with status "
                          "%(job_state)d. Error details: "
                          "%(error)s") % {
                              'job_state': job_state,
                              'error': error
                          })
                else:
                    raise 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
Beispiel #8
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 HyperVException(_('Duplicate VM name found: %s') % vm_name)
     else:
         return vms[0]
Beispiel #9
0
    def create_dynamic_vhd(self, path, max_internal_size, format):
        if format != constants.DISK_FORMAT_VHD:
            raise vmutils.HyperVException(
                _("Unsupported disk format: %s") % format)

        image_man_svc = self._conn.Msvm_ImageManagementService()[0]

        (job_path, ret_val) = image_man_svc.CreateDynamicVirtualHardDisk(
            Path=path, MaxInternalSize=max_internal_size)
        self._vmutils.check_ret_val(ret_val, job_path)
Beispiel #10
0
    def create_differencing_vhd(self, path, parent_path, size=None):
        if size is not None:
            raise vmutils.HyperVException(
                _('VHD differencing disks cannot be '
                  'resized'))
        image_man_svc = self._conn.Msvm_ImageManagementService()[0]

        (job_path, ret_val) = image_man_svc.CreateDifferencingVirtualHardDisk(
            Path=path, ParentPath=parent_path)
        self._vmutils.check_ret_val(ret_val, job_path)
Beispiel #11
0
 def _get_vhd_dynamic_blk_size(self, vhd_path):
     blk_size_offset = VHD_BLK_SIZE_OFFSET
     try:
         with open(vhd_path, "rb") as f:
             f.seek(blk_size_offset)
             version = f.read(4)
     except IOError:
         raise vmutils.HyperVException(
             _("Unable to obtain block size from"
               " VHD %(vhd_path)s") % {"vhd_path": vhd_path})
     return struct.unpack('>i', version)[0]
Beispiel #12
0
 def _create_switch_port(self, vswitch_name, switch_port_name):
     """Creates a switch port."""
     switch_svc = self._conn.Msvm_VirtualSwitchManagementService()[0]
     vswitch_path = self._get_vswitch(vswitch_name).path_()
     (new_port, ret_val) = switch_svc.CreateSwitchPort(
         Name=switch_port_name,
         FriendlyName=switch_port_name,
         ScopeOfResidence="",
         VirtualSwitch=vswitch_path)
     if ret_val != 0:
         raise vmutils.HyperVException(
             _('Failed creating port for %s') % vswitch_name)
     return new_port
Beispiel #13
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 vmutils.HyperVException(_('Cannot get VM summary data '
                                            'for: %s') % port.ElementName)

        return summary_info[0].EnabledState is self._HYPERV_VM_STATE_ENABLED
Beispiel #14
0
    def get_internal_vhd_size_by_file_size(self, vhd_path, new_vhd_file_size):
        """VHDX Size = Header (1 MB)
                        + Log
                        + Metadata Region
                        + BAT
                        + Payload Blocks
            Chunk size = maximum number of bytes described by a SB block
                       = 2 ** 23 * LogicalSectorSize
        """
        vhd_format = self.get_vhd_format(vhd_path)
        if vhd_format == constants.DISK_FORMAT_VHD:
            return super(VHDUtilsV2, self).get_internal_vhd_size_by_file_size(
                vhd_path, new_vhd_file_size)
        else:
            vhd_info = self.get_vhd_info(vhd_path)
            vhd_type = vhd_info['Type']
            if vhd_type == self._VHD_TYPE_DIFFERENCING:
                vhd_parent = self.get_vhd_parent_path(vhd_path)
                return self.get_internal_vhd_size_by_file_size(
                    vhd_parent, new_vhd_file_size)
            else:
                try:
                    with open(vhd_path, 'rb') as f:
                        hs = VHDX_HEADER_SECTION_SIZE
                        bes = VHDX_BAT_ENTRY_SIZE

                        lss = vhd_info['LogicalSectorSize']
                        bs = self._get_vhdx_block_size(f)
                        ls = self._get_vhdx_log_size(f)
                        ms = self._get_vhdx_metadata_size_and_offset(f)[0]

                        chunk_ratio = (1 << 23) * lss / bs
                        size = new_vhd_file_size

                        max_internal_size = (
                            bs * chunk_ratio *
                            (size - hs - ls - ms - bes - bes / chunk_ratio) /
                            (bs * chunk_ratio + bes * chunk_ratio + bes))

                        return max_internal_size - (max_internal_size % bs)

                except IOError as ex:
                    raise vmutils.HyperVException(
                        _("Unable to obtain "
                          "internal size from VHDX: "
                          "%(vhd_path)s. Exception: "
                          "%(ex)s") % {
                              "vhd_path": vhd_path,
                              "ex": ex
                          })
Beispiel #15
0
    def set_host_nic_ip_address(self, nic_name, dhcp=False, ip_list=None,
                                netmask_list=None, gateway_list=None,
                                gateway_metrics_list=None):
        net_adapter_list = self._conn_cimv2.Win32_NetworkAdapter(
            NetConnectionID=nic_name)
        if not net_adapter_list:
            raise vmutils.HyperVException(_('Nic not found: %s') %
                                          nic_name)
        net_adapter = net_adapter_list[0]
        net_adapter_config = net_adapter.associators(
            wmi_result_class='Win32_NetworkAdapterConfiguration')[0]

        if dhcp:
            (ret_val,) = net_adapter_config.EnableDHCP()
            if ret_val not in [0, 1]:
                raise vmutils.HyperVException(
                    _('Enabling DHCP failed with error: %s') % ret_val)
        else:
            (ret_val,) = net_adapter_config.EnableStatic(
                IPAddress=ip_list,
                SubnetMask=netmask_list)
            if ret_val not in [0, 1]:
                raise vmutils.HyperVException(
                    _('Setting static IP addresses %(ip_list)s with netmasks '
                      '%(netmask_list)s on interface %(nic_name)s failed with '
                      'error: %(ret_val)s') %
                    {'ip_list': ip_list, 'nic_name': nic_name,
                     'netmask_list': netmask_list, 'ret_val': ret_val})

            if gateway_list:
                (ret_val,) = net_adapter_config.EnableGateways(
                    DefaultIPGateway=gateway_list,
                    GatewayCostMetric=netmask_list)
                if ret_val not in [0, 1]:
                    raise vmutils.HyperVException(
                        _('Setting a gateway failed with error: %s') %
                        ret_val)
Beispiel #16
0
    def create_vswitch(self, vswitch_name, external_port_name=None,
                       create_internal_port=False):
        LOG.debug('create_vswitch called. vswitch_name: %(vswitch_name)s, '
                  'external_port_name: %(external_port_name)s, '
                  'create_internal_port: %(create_internal_port)s' % locals())

        svc = self._conn.Msvm_VirtualEthernetSwitchManagementService()[0]
        vswitch_data = self._conn.Msvm_VirtualEthernetSwitchSettingData.new()
        vswitch_data.ElementName = vswitch_name

        resource_settings = []

        if external_port_name:
            ext_port_list = self._conn.Msvm_ExternalEthernetPort(
                ElementName=external_port_name)
            if not ext_port_list:
                ext_port_list = self._conn.Msvm_WiFiPort(
                    ElementName=external_port_name)
                if not ext_port_list:
                    raise vmutils.HyperVException(_('External port not found: '
                                                    '%s') % external_port_name)

            ext_port = ext_port_list[0]

            port_alloc_ext = self._get_default_setting_data(
                self._PORT_ALLOC_SET_DATA, self._ETH_CONN_RES_SUB_TYPE)
            port_alloc_ext.HostResource = [ext_port.path_()]
            port_alloc_ext.ElementName = vswitch_name

            resource_settings.append(port_alloc_ext.GetText_(1))

        if create_internal_port:
            port_alloc_int = self._get_default_setting_data(
                self._PORT_ALLOC_SET_DATA, self._ETH_CONN_RES_SUB_TYPE)

            host = self._conn.query("SELECT * from Msvm_ComputerSystem "
                                    "WHERE InstallDate is NULL")[0]
            port_alloc_int.HostResource = [host.path_()]
            port_alloc_int.ElementName = vswitch_name

            if external_port_name:
                port_alloc_int.Address = ext_port.PermanentAddress

            resource_settings.append(port_alloc_int.GetText_(1))

        (job_path, out_res_system, ret_val) = svc.DefineSystem(
            SystemSettings=vswitch_data.GetText_(1),
            ResourceSettings=resource_settings)
        self._check_job_status(ret_val, job_path)
Beispiel #17
0
    def get_vhd_format(self, path):
        with open(path, 'rb') as f:
            # Read header
            if f.read(8) == VHDX_SIGNATURE:
                return constants.DISK_FORMAT_VHDX

            # Read footer
            f.seek(0, 2)
            file_size = f.tell()
            if file_size >= 512:
                f.seek(-512, 2)
                if f.read(8) == VHD_SIGNATURE:
                    return constants.DISK_FORMAT_VHD

        raise vmutils.HyperVException(_('Unsupported virtual disk format'))
Beispiel #18
0
    def get_vm_summary_info(self, vm_name):
        vm = self._lookup_vm_check(vm_name)

        vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
        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) = 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 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
Beispiel #19
0
 def check_ret_val(self, ret_val, job_path, success_values=[0]):
     if ret_val == constants.WMI_JOB_STATUS_STARTED:
         return self._wait_for_job(job_path)
     elif ret_val not in success_values:
         raise HyperVException(
             _('Operation failed with return value: %s') % ret_val)
Beispiel #20
0
 def check_admin_permissions(self):
     if not self._conn.Msvm_VirtualSystemManagementService():
         msg = _("The Windows account running nova-compute on this Hyper-V"
                 " host doesn't have the required permissions to create or"
                 " operate the virtual machine.")
         raise HyperVAuthorizationException(msg)
Beispiel #21
0
 def _lookup_vm_check(self, vm_name):
     vm = self._lookup_vm(vm_name)
     if not vm:
         raise HyperVException(_('VM not found: %s') % vm_name)
     return vm
Beispiel #22
0
 def _get_switch_port_allocation_check(self, switch_port_name):
     port_alloc, found = self._get_switch_port_allocation(switch_port_name)
     if not found:
         raise vmutils.HyperVException(
             _('Port allocation not found: %s') % switch_port_name)
     return port_alloc
Beispiel #23
0
 def enable_vm_metrics_collection(self, vm_name):
     raise NotImplementedError(
         _("Metrics collection is not supported on "
           "this version of Hyper-V"))
Beispiel #24
0
 def enable_control_metrics(self, switch_port_name):
     raise NotImplementedError(_("Metrics collection is not supported on "
                                 "this version of Hyper-V"))