Exemple #1
0
    def _instance_supported(self, host_state, image_props,
                            hypervisor_version):
        img_arch = image_props.get('architecture', None)
        img_h_type = image_props.get('hypervisor_type', None)
        img_vm_mode = image_props.get('vm_mode', None)
        checked_img_props = (
            arch.canonicalize(img_arch),
            hv_type.canonicalize(img_h_type),
            vm_mode.canonicalize(img_vm_mode)
        )

        # Supported if no compute-related instance properties are specified
        if not any(checked_img_props):
            return True

        supp_instances = host_state.supported_instances
        # Not supported if an instance property is requested but nothing
        # advertised by the host.
        if not supp_instances:
            LOG.debug("Instance contains properties %(image_props)s, "
                        "but no corresponding supported_instances are "
                        "advertised by the compute node",
                      {'image_props': image_props})
            return False

        def _compare_props(props, other_props):
            for i in props:
                if i and i not in other_props:
                    return False
            return True

        def _compare_product_version(hyper_version, image_props):
            version_required = image_props.get('hypervisor_version_requires')
            if not(hypervisor_version and version_required):
                return True
            img_prop_predicate = versionpredicate.VersionPredicate(
                'image_prop (%s)' % version_required)
            hyper_ver_str = utils.convert_version_to_str(hyper_version)
            return img_prop_predicate.satisfied_by(hyper_ver_str)

        for supp_inst in supp_instances:
            if _compare_props(checked_img_props, supp_inst):
                if _compare_product_version(hypervisor_version, image_props):
                    return True

        LOG.debug("Instance contains properties %(image_props)s "
                    "that are not provided by the compute node "
                    "supported_instances %(supp_instances)s or "
                    "hypervisor version %(hypervisor_version)s do not match",
                  {'image_props': image_props,
                   'supp_instances': supp_instances,
                   'hypervisor_version': hypervisor_version})
        return False
    def _instance_supported(self, host_state, image_props, hypervisor_version):
        img_arch = image_props.get('architecture', None)
        img_h_type = image_props.get('hypervisor_type', None)
        img_vm_mode = image_props.get('vm_mode', None)
        checked_img_props = (arch.canonicalize(img_arch),
                             hv_type.canonicalize(img_h_type),
                             vm_mode.canonicalize(img_vm_mode))

        # Supported if no compute-related instance properties are specified
        if not any(checked_img_props):
            return True

        supp_instances = host_state.supported_instances
        # Not supported if an instance property is requested but nothing
        # advertised by the host.
        if not supp_instances:
            LOG.debug(
                "Instance contains properties %(image_props)s, "
                "but no corresponding supported_instances are "
                "advertised by the compute node", {'image_props': image_props})
            return False

        def _compare_props(props, other_props):
            for i in props:
                if i and i not in other_props:
                    return False
            return True

        def _compare_product_version(hyper_version, image_props):
            version_required = image_props.get('hypervisor_version_requires')
            if not (hypervisor_version and version_required):
                return True
            img_prop_predicate = versionpredicate.VersionPredicate(
                'image_prop (%s)' % version_required)
            hyper_ver_str = utils.convert_version_to_str(hyper_version)
            return img_prop_predicate.satisfied_by(hyper_ver_str)

        for supp_inst in supp_instances:
            if _compare_props(checked_img_props, supp_inst):
                if _compare_product_version(hypervisor_version, image_props):
                    return True

        LOG.debug(
            "Instance contains properties %(image_props)s "
            "that are not provided by the compute node "
            "supported_instances %(supp_instances)s or "
            "hypervisor version %(hypervisor_version)s do not match", {
                'image_props': image_props,
                'supp_instances': supp_instances,
                'hypervisor_version': hypervisor_version
            })
        return False
Exemple #3
0
def get_arch(image_meta):
    """Determine the architecture of the guest (or host).

    This method determines the CPU architecture that must be supported by
    the hypervisor. It gets the (guest) arch info from image_meta properties,
    and it will fallback to the patron-compute (host) arch if no architecture
    info is provided in image_meta.

    :param image_meta: the metadata associated with the instance image

    :returns: guest (or host) architecture
    """
    if image_meta:
        image_arch = image_meta.get('properties', {}).get('architecture')
        if image_arch is not None:
            return arch.canonicalize(image_arch)

    return arch.from_host()
Exemple #4
0
def get_arch(image_meta):
    """Determine the architecture of the guest (or host).

    This method determines the CPU architecture that must be supported by
    the hypervisor. It gets the (guest) arch info from image_meta properties,
    and it will fallback to the patron-compute (host) arch if no architecture
    info is provided in image_meta.

    :param image_meta: the metadata associated with the instance image

    :returns: guest (or host) architecture
    """
    if image_meta:
        image_arch = image_meta.get('properties', {}).get('architecture')
        if image_arch is not None:
            return arch.canonicalize(image_arch)

    return arch.from_host()
Exemple #5
0
def to_supported_instances(host_capabilities):
    if not host_capabilities:
        return []

    result = []
    for capability in host_capabilities:
        try:
            # 'capability'is unicode but we want arch/ostype
            # to be strings to match the standard constants
            capability = str(capability)

            ostype, _version, guestarch = capability.split("-")

            guestarch = arch.canonicalize(guestarch)
            ostype = vm_mode.canonicalize(ostype)

            result.append((guestarch, hv_type.XEN, ostype))
        except ValueError:
            LOG.warning(_LW("Failed to extract instance support from %s"),
                        capability)

    return result
Exemple #6
0
def to_supported_instances(host_capabilities):
    if not host_capabilities:
        return []

    result = []
    for capability in host_capabilities:
        try:
            # 'capability'is unicode but we want arch/ostype
            # to be strings to match the standard constants
            capability = str(capability)

            ostype, _version, guestarch = capability.split("-")

            guestarch = arch.canonicalize(guestarch)
            ostype = vm_mode.canonicalize(ostype)

            result.append((guestarch, hv_type.XEN, ostype))
        except ValueError:
            LOG.warning(_LW("Failed to extract instance support from %s"),
                        capability)

    return result
Exemple #7
0
    def _node_resource(self, node):
        """Helper method to create resource dict from node stats."""
        vcpus = int(node.properties.get('cpus', 0))
        memory_mb = int(node.properties.get('memory_mb', 0))
        local_gb = int(node.properties.get('local_gb', 0))
        raw_cpu_arch = node.properties.get('cpu_arch', None)
        try:
            cpu_arch = arch.canonicalize(raw_cpu_arch)
        except exception.InvalidArchitectureName:
            cpu_arch = None
        if not cpu_arch:
            LOG.warning(_LW("cpu_arch not defined for node '%s'"), node.uuid)

        nodes_extra_specs = {}

        # NOTE(deva): In Havana and Icehouse, the flavor was required to link
        # to an arch-specific deploy kernel and ramdisk pair, and so the flavor
        # also had to have extra_specs['cpu_arch'], which was matched against
        # the ironic node.properties['cpu_arch'].
        # With Juno, the deploy image(s) may be referenced directly by the
        # node.driver_info, and a flavor no longer needs to contain any of
        # these three extra specs, though the cpu_arch may still be used
        # in a heterogeneous environment, if so desired.
        # NOTE(dprince): we use the raw cpu_arch here because extra_specs
        # filters aren't canonicalized
        nodes_extra_specs['cpu_arch'] = raw_cpu_arch

        # NOTE(gilliard): To assist with more precise scheduling, if the
        # node.properties contains a key 'capabilities', we expect the value
        # to be of the form "k1:v1,k2:v2,etc.." which we add directly as
        # key/value pairs into the node_extra_specs to be used by the
        # ComputeCapabilitiesFilter
        capabilities = node.properties.get('capabilities')
        if capabilities:
            for capability in str(capabilities).split(','):
                parts = capability.split(':')
                if len(parts) == 2 and parts[0] and parts[1]:
                    nodes_extra_specs[parts[0]] = parts[1]
                else:
                    LOG.warning(
                        _LW("Ignoring malformed capability '%s'. "
                            "Format should be 'key:val'."), capability)

        vcpus_used = 0
        memory_mb_used = 0
        local_gb_used = 0

        if self._node_resources_used(node):
            # Node is in the process of deploying, is deployed, or is in
            # the process of cleaning up from a deploy. Report all of its
            # resources as in use.
            vcpus_used = vcpus
            memory_mb_used = memory_mb
            local_gb_used = local_gb
        elif self._node_resources_unavailable(node):
            # The node's current state is such that it should not present any
            # of its resources to Nova
            vcpus = 0
            memory_mb = 0
            local_gb = 0

        dic = {
            'hypervisor_hostname':
            str(node.uuid),
            'hypervisor_type':
            self._get_hypervisor_type(),
            'hypervisor_version':
            self._get_hypervisor_version(),
            # The Ironic driver manages multiple hosts, so there are
            # likely many different CPU models in use. As such it is
            # impossible to provide any meaningful info on the CPU
            # model of the "host"
            'cpu_info':
            None,
            'vcpus':
            vcpus,
            'vcpus_used':
            vcpus_used,
            'local_gb':
            local_gb,
            'local_gb_used':
            local_gb_used,
            'disk_available_least':
            local_gb - local_gb_used,
            'memory_mb':
            memory_mb,
            'memory_mb_used':
            memory_mb_used,
            'supported_instances':
            jsonutils.dumps(_get_nodes_supported_instances(cpu_arch)),
            'stats':
            jsonutils.dumps(nodes_extra_specs),
        }
        return dic
Exemple #8
0
 def test_canonicalize_case(self):
     self.assertEqual(arch.X86_64, arch.canonicalize("X86_64"))
Exemple #9
0
 def test_canonicalize_compat_xen2(self):
     self.assertEqual(arch.I686, arch.canonicalize("x86_32p"))
Exemple #10
0
 def test_canonicalize_i386(self):
     self.assertEqual(arch.I686, arch.canonicalize("i386"))
Exemple #11
0
 def test_canonicalize_amd64(self):
     self.assertEqual(arch.X86_64, arch.canonicalize("amd64"))
Exemple #12
0
 def test_canonicalize_compat_xen2(self):
     self.assertEqual(arch.I686, arch.canonicalize("x86_32p"))
Exemple #13
0
 def test_canonicalize_case(self):
     self.assertEqual(arch.X86_64, arch.canonicalize("X86_64"))
Exemple #14
0
 def test_canonicalize_amd64(self):
     self.assertEqual(arch.X86_64, arch.canonicalize("amd64"))
Exemple #15
0
 def test_canonicalize_i386(self):
     self.assertEqual(arch.I686, arch.canonicalize("i386"))
Exemple #16
0
    def _node_resource(self, node):
        """Helper method to create resource dict from node stats."""
        vcpus = int(node.properties.get('cpus', 0))
        memory_mb = int(node.properties.get('memory_mb', 0))
        local_gb = int(node.properties.get('local_gb', 0))
        raw_cpu_arch = node.properties.get('cpu_arch', None)
        try:
            cpu_arch = arch.canonicalize(raw_cpu_arch)
        except exception.InvalidArchitectureName:
            cpu_arch = None
        if not cpu_arch:
            LOG.warning(_LW("cpu_arch not defined for node '%s'"), node.uuid)

        nodes_extra_specs = {}

        # NOTE(deva): In Havana and Icehouse, the flavor was required to link
        # to an arch-specific deploy kernel and ramdisk pair, and so the flavor
        # also had to have extra_specs['cpu_arch'], which was matched against
        # the ironic node.properties['cpu_arch'].
        # With Juno, the deploy image(s) may be referenced directly by the
        # node.driver_info, and a flavor no longer needs to contain any of
        # these three extra specs, though the cpu_arch may still be used
        # in a heterogeneous environment, if so desired.
        # NOTE(dprince): we use the raw cpu_arch here because extra_specs
        # filters aren't canonicalized
        nodes_extra_specs['cpu_arch'] = raw_cpu_arch

        # NOTE(gilliard): To assist with more precise scheduling, if the
        # node.properties contains a key 'capabilities', we expect the value
        # to be of the form "k1:v1,k2:v2,etc.." which we add directly as
        # key/value pairs into the node_extra_specs to be used by the
        # ComputeCapabilitiesFilter
        capabilities = node.properties.get('capabilities')
        if capabilities:
            for capability in str(capabilities).split(','):
                parts = capability.split(':')
                if len(parts) == 2 and parts[0] and parts[1]:
                    nodes_extra_specs[parts[0]] = parts[1]
                else:
                    LOG.warning(_LW("Ignoring malformed capability '%s'. "
                                    "Format should be 'key:val'."), capability)

        vcpus_used = 0
        memory_mb_used = 0
        local_gb_used = 0

        if self._node_resources_used(node):
            # Node is in the process of deploying, is deployed, or is in
            # the process of cleaning up from a deploy. Report all of its
            # resources as in use.
            vcpus_used = vcpus
            memory_mb_used = memory_mb
            local_gb_used = local_gb
        elif self._node_resources_unavailable(node):
            # The node's current state is such that it should not present any
            # of its resources to Nova
            vcpus = 0
            memory_mb = 0
            local_gb = 0

        dic = {
            'hypervisor_hostname': str(node.uuid),
            'hypervisor_type': self._get_hypervisor_type(),
            'hypervisor_version': self._get_hypervisor_version(),
            # The Ironic driver manages multiple hosts, so there are
            # likely many different CPU models in use. As such it is
            # impossible to provide any meaningful info on the CPU
            # model of the "host"
            'cpu_info': None,
            'vcpus': vcpus,
            'vcpus_used': vcpus_used,
            'local_gb': local_gb,
            'local_gb_used': local_gb_used,
            'disk_available_least': local_gb - local_gb_used,
            'memory_mb': memory_mb,
            'memory_mb_used': memory_mb_used,
            'supported_instances': jsonutils.dumps(
                _get_nodes_supported_instances(cpu_arch)),
            'stats': jsonutils.dumps(nodes_extra_specs),
        }
        return dic