示例#1
0
    def _plug_vifs(self, node, instance, network_info):
        LOG.debug("plug: instance_uuid=%(uuid)s vif=%(network_info)s" % {
            'uuid': instance['uuid'],
            'network_info': network_info
        })
        # start by ensuring the ports are clear
        self._unplug_vifs(node, instance, network_info)

        icli = client_wrapper.IronicClientWrapper()
        ports = icli.call("node.list_ports", node.uuid)

        if len(network_info) > len(ports):
            raise exception.NovaException(
                _("Ironic node: %(id)s virtual to physical interface count"
                  "  missmatch"
                  " (Vif count: %(vif_count)d, Pif count: %(pif_count)d)") % {
                      'id': node.uuid,
                      'vif_count': len(network_info),
                      'pif_count': len(ports)
                  })

        if len(network_info) > 0:
            # not needed if no vif are defined
            for vif, pif in zip(network_info, ports):
                # attach what neutron needs directly to the port
                port_id = unicode(vif['id'])
                patch = [{
                    'op': 'add',
                    'path': '/extra/vif_port_id',
                    'value': port_id
                }]
                icli.call("port.update", pif.uuid, patch)
示例#2
0
 def macs_for_instance(self, instance):
     icli = client_wrapper.IronicClientWrapper()
     try:
         node = icli.call("node.get", instance['node'])
     except ironic_exception.NotFound:
         return []
     ports = icli.call("node.list_ports", node.uuid)
     return [p.address for p in ports]
示例#3
0
 def get_host_stats(self, refresh=False):
     caps = []
     icli = client_wrapper.IronicClientWrapper()
     node_list = icli.call("node.list")
     for node in node_list:
         data = self._node_resource(node)
         caps.append(data)
     return caps
示例#4
0
 def node_is_available(self, nodename):
     """Confirms a Nova hypervisor node exists in the Ironic inventory."""
     icli = client_wrapper.IronicClientWrapper()
     try:
         icli.call("node.get", nodename)
         return True
     except ironic_exception.NotFound:
         return False
示例#5
0
    def list_instance_uuids(self):
        """Return the UUIDs of all the instances provisioned.

        :returns: a list of instance UUIDs.

        """
        icli = client_wrapper.IronicClientWrapper()
        node_list = icli.call("node.list", associated=True)
        return list(set(n.instance_uuid for n in node_list))
示例#6
0
 def test__get_client_with_auth_token(self, mock_ir_cli):
     self.flags(admin_auth_token='fake-token', group='ironic')
     icli = client_wrapper.IronicClientWrapper()
     # dummy call to have _get_client() called
     icli.call("node.list")
     expected = {'os_auth_token': 'fake-token',
                 'ironic_url': CONF.ironic.api_endpoint}
     mock_ir_cli.assert_called_once_with(CONF.ironic.api_version,
                                         **expected)
示例#7
0
 def test_validate_instance_and_node_failed(self, mock_gbiui):
     icli = cw.IronicClientWrapper()
     mock_gbiui.side_effect = ironic_exception.NotFound()
     instance_uuid = uuidutils.generate_uuid(),
     instance = fake_instance.fake_instance_obj(self.ctx,
                                                uuid=instance_uuid)
     self.assertRaises(exception.InstanceNotFound,
                       ironic_driver.validate_instance_and_node, icli,
                       instance)
示例#8
0
 def list_instances(self):
     """Return the names of all the instances provisioned."""
     icli = client_wrapper.IronicClientWrapper()
     node_list = icli.call("node.list", associated=True)
     context = nova_context.get_admin_context()
     return [
         instance_obj.Instance.get_by_uuid(context, i.instance_uuid).name
         for i in node_list
     ]
示例#9
0
    def unplug_vifs(self, instance, network_info):
        """Unplug VIFs from networks.

        :param instance: The instance object.
        :param network_info: Instance network information.

        """
        icli = client_wrapper.IronicClientWrapper()
        node = icli.call("node.get", instance['node'])
        self._unplug_vifs(node, instance, network_info)
示例#10
0
 def power_on(self,
              context,
              instance,
              network_info,
              block_device_info=None,
              node=None):
     # TODO(nobodycam): check the current power state first.
     icli = client_wrapper.IronicClientWrapper()
     node = validate_instance_and_node(icli, instance)
     icli.call("node.set_power_state", node.uuid, 'on')
示例#11
0
    def power_off(self, instance):
        """Power off the specified instance.

        :param instance: The instance object.

        """
        # TODO(nobodycam): check the current power state first.
        icli = client_wrapper.IronicClientWrapper()
        node = validate_instance_and_node(icli, instance)
        icli.call("node.set_power_state", node.uuid, 'off')
示例#12
0
 def test_validate_instance_and_node_failed(self):
     icli = cw.IronicClientWrapper()
     with mock.patch.object(FAKE_CLIENT.node, 'get_by_instance_uuid') \
         as mock_gbiui:
         mock_gbiui.side_effect = ironic_exception.HTTPNotFound()
         instance_uuid = uuidutils.generate_uuid(),
         instance = fake_instance.fake_instance_obj(self.ctx,
                                                    uuid=instance_uuid)
         self.assertRaises(exception.InstanceNotFound,
                           ironic_driver.validate_instance_and_node, icli,
                           instance)
示例#13
0
    def test_validate_instance_and_node(self, mock_gbiui):
        node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
        instance_uuid = uuidutils.generate_uuid()
        node = ironic_utils.get_test_node(uuid=node_uuid,
                                          instance_uuid=instance_uuid)
        instance = fake_instance.fake_instance_obj(self.ctx,
                                                   uuid=instance_uuid)
        icli = cw.IronicClientWrapper()

        mock_gbiui.return_value = node
        result = ironic_driver.validate_instance_and_node(icli, instance)
        self.assertEqual(result.uuid, node_uuid)
示例#14
0
 def test__get_client_no_auth_token(self, mock_ir_cli):
     self.flags(admin_auth_token=None, group='ironic')
     icli = client_wrapper.IronicClientWrapper()
     # dummy call to have _get_client() called
     icli.call("node.list")
     expected = {'os_username': CONF.ironic.admin_username,
                 'os_password': CONF.ironic.admin_password,
                 'os_auth_url': CONF.ironic.admin_url,
                 'os_tenant_name': CONF.ironic.admin_tenant_name,
                 'os_service_type': 'baremetal',
                 'os_endpoint_type': 'public'}
     mock_ir_cli.assert_called_once_with(CONF.ironic.api_version,
                                         **expected)
示例#15
0
    def get_available_resource(self, node):
        """Retrieve resource information.

        This method is called when nova-compute launches, and
        as part of a periodic task that records the results in the DB.

        :param node: the uuid of the node
        :returns: dictionary describing resources

        """
        icli = client_wrapper.IronicClientWrapper()
        node = icli.call("node.get", node)
        return self._node_resource(node)
示例#16
0
    def get_available_nodes(self, refresh=False):
        nodes = []
        icli = client_wrapper.IronicClientWrapper()
        node_list = icli.call("node.list")

        for n in node_list:
            # for now we'll use the nodes power state. if power_state is None
            # we'll assume it is not ready to be presented to Nova.
            if n.power_state:
                nodes.append(n.uuid)

        LOG.debug("Returning Nodes: %s" % nodes)
        return nodes
示例#17
0
    def get_available_nodes(self, refresh=False):
        """Returns the UUIDs of all nodes in the Ironic inventory.

        :param refresh: Boolean value; If True run update first. Ignored by
            this driver.
        :returns: a list of UUIDs

        """
        icli = client_wrapper.IronicClientWrapper()
        node_list = icli.call("node.list")
        nodes = [n.uuid for n in node_list]
        LOG.debug("Returning %(num_nodes)s available node(s): %(nodes)s",
                  dict(num_nodes=len(nodes), nodes=nodes))
        return nodes
示例#18
0
    def test_validate_instance_and_node(self):
        node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
        instance_uuid = uuidutils.generate_uuid()
        node = ironic_utils.get_test_node(uuid=node_uuid,
                                          instance_uuid=instance_uuid)
        instance = fake_instance.fake_instance_obj(self.ctx,
                                                   uuid=instance_uuid)
        icli = cw.IronicClientWrapper()

        with mock.patch.object(FAKE_CLIENT.node, 'get_by_instance_uuid') \
            as mock_gbiui:
            mock_gbiui.return_value = node
            result = ironic_driver.validate_instance_and_node(icli, instance)
            self.assertEqual(result.uuid, node_uuid)
示例#19
0
    def get_host_stats(self, refresh=False):
        """Return the currently known stats for all Ironic nodes.

        :param refresh: Boolean value; If True run update first. Ignored by
            this driver.
        :returns: a list of dictionaries; each dictionary contains the
            stats for a node.

        """
        caps = []
        icli = client_wrapper.IronicClientWrapper()
        node_list = icli.call("node.list")
        for node in node_list:
            data = self._node_resource(node)
            caps.append(data)
        return caps
示例#20
0
    def instance_exists(self, instance):
        """Checks the existence of an instance.

        Checks the existence of an instance. This is an override of the
        base method for efficiency.

        :param instance: The instance object.
        :returns: True if the instance exists. False if not.

        """
        icli = client_wrapper.IronicClientWrapper()
        try:
            validate_instance_and_node(icli, instance)
            return True
        except exception.InstanceNotFound:
            return False
示例#21
0
    def instance_exists(self, instance):
        """Checks the existence of an instance.

        Checks the existence of an instance. This is an override of the
        base method for efficiency.

        :param instance: The instance object.
        :returns: True if the instance exists. False if not.

        """
        icli = client_wrapper.IronicClientWrapper()
        try:
            icli.call("node.get_by_instance_uuid", instance['uuid'])
            return True
        except ironic_exception.NotFound:
            return False
示例#22
0
    def macs_for_instance(self, instance):
        """List the MAC addresses of an instance.

        List of MAC addresses for the node which this instance is
        associated with.

        :param instance: the instance object.
        :returns: a list of MAC addresses.

        """
        icli = client_wrapper.IronicClientWrapper()
        try:
            node = icli.call("node.get", instance['node'])
        except ironic_exception.NotFound:
            return []
        ports = icli.call("node.list_ports", node.uuid)
        return [p.address for p in ports]
示例#23
0
    def _unplug_vifs(self, node, instance, network_info):
        LOG.debug("unplug: instance_uuid=%(uuid)s vif=%(network_info)s" % {
            'uuid': instance['uuid'],
            'network_info': network_info
        })
        if network_info and len(network_info) > 0:
            icli = client_wrapper.IronicClientWrapper()
            ports = icli.call("node.list_ports", node.uuid)

            # not needed if no vif are defined
            for vif, pif in zip(network_info, ports):
                # we can not attach a dict directly
                patch = [{'op': 'remove', 'path': '/extra/vif_port_id'}]
                try:
                    icli.call("port.update", pif.uuid, patch)
                except ironic_exception.BadRequest:
                    pass
示例#24
0
    def test__get_client_with_auth_token(self):
        self.flags(admin_auth_token='fake-token', group='ironic')

        # stop _get_client mock
        self.mock_cli_patcher.stop()
        self.mock_cli = None

        with mock.patch.object(nova_context, 'get_admin_context') as mock_ctx:
            mock_ctx.return_value = self.ctx
            with mock.patch.object(ironic_client, 'get_client') as mock_ir_cli:
                icli = cw.IronicClientWrapper()
                # dummy call to have _get_client() called
                icli.call("node.list")
                expected = {
                    'os_auth_token': 'fake-token',
                    'ironic_url': CONF.ironic.api_endpoint
                }
                mock_ir_cli.assert_called_once_with(CONF.ironic.api_version,
                                                    **expected)
示例#25
0
    def power_on(self,
                 context,
                 instance,
                 network_info,
                 block_device_info=None):
        """Power on the specified instance.

        :param context: The security context.
        :param instance: The instance object.
        :param network_info: Instance network information. Ignored by
            this driver.
        :param block_device_info: Instance block device
            information. Ignored by this driver.

        """
        # TODO(nobodycam): check the current power state first.
        icli = client_wrapper.IronicClientWrapper()
        node = validate_instance_and_node(icli, instance)
        icli.call("node.set_power_state", node.uuid, 'on')
示例#26
0
    def _cleanup_deploy(self, node, instance, network_info):
        icli = client_wrapper.IronicClientWrapper()
        patch = patcher.create(node).get_cleanup_patch(instance, network_info)

        # Unassociate the node
        patch.append({'op': 'remove', 'path': '/instance_uuid'})
        try:
            icli.call('node.update', node.uuid, patch)
        except ironic_exception.BadRequest:
            msg = (_("Failed clean up the parameters on node %(node)s "
                     "when unprovisioning the instance %(instance)s") % {
                         'node': node.uuid,
                         'instance': instance['uuid']
                     })
            LOG.error(msg)
            reason = _("Fail to clean up node %s parameters") % node.uuid
            raise exception.InstanceTerminationFailure(reason=reason)

        self._unplug_vifs(node, instance, network_info)
        self._stop_firewall(instance, network_info)
示例#27
0
    def get_info(self, instance):
        icli = client_wrapper.IronicClientWrapper()
        try:
            node = icli.call("node.get_by_instance_uuid", instance['uuid'])
        except ironic_exception.NotFound:
            return {
                'state': map_power_state(ironic_states.NOSTATE),
                'max_mem': 0,
                'mem': 0,
                'num_cpu': 0,
                'cpu_time': 0
            }

        return {
            'state': map_power_state(node.power_state),
            'max_mem': node.properties.get('memory_mb'),
            'mem': node.properties.get('memory_mb'),
            'num_cpu': node.properties.get('cpus'),
            'cpu_time': 0
        }
示例#28
0
    def destroy(self, context, instance, network_info, block_device_info=None):
        icli = client_wrapper.IronicClientWrapper()
        try:
            node = validate_instance_and_node(icli, instance)
        except exception.InstanceNotFound:
            LOG.debug("Destroy called on non-existing instance %s." %
                      instance['uuid'])
            # NOTE(deva): if nova.compute.ComputeManager._delete_instance()
            #             is called on a non-existing instance, the only way
            #             to delete it is to return from this method
            #             without raising any exceptions.
            return

        if node.provision_state in (ironic_states.ACTIVE,
                                    ironic_states.DEPLOYFAIL,
                                    ironic_states.ERROR,
                                    ironic_states.DEPLOYWAIT):
            self._unprovision(icli, instance, node)

        self._cleanup_deploy(node, instance, network_info)
示例#29
0
    def _add_driver_fields(self, node, instance, image_meta, flavor):
        icli = client_wrapper.IronicClientWrapper()
        patch = patcher.create(node).get_deploy_patch(instance, image_meta,
                                                      flavor)

        # Associate the node with an instance
        patch.append({
            'path': '/instance_uuid',
            'op': 'add',
            'value': instance['uuid']
        })
        try:
            icli.call('node.update', node.uuid, patch)
        except ironic_exception.BadRequest:
            msg = (_("Failed to add deploy parameters on node %(node)s "
                     "when provisioning the instance %(instance)s") % {
                         'node': node.uuid,
                         'instance': instance['uuid']
                     })
            LOG.error(msg)
            raise exception.InstanceDeployFailure(msg)
示例#30
0
    def test__get_client_no_auth_token(self):
        self.flags(admin_auth_token=None, group='ironic')

        # stop _get_client mock
        self.mock_cli_patcher.stop()
        self.mock_cli = None

        with mock.patch.object(nova_context, 'get_admin_context') as mock_ctx:
            mock_ctx.return_value = self.ctx
            with mock.patch.object(ironic_client, 'get_client') as mock_ir_cli:
                icli = cw.IronicClientWrapper()
                # dummy call to have _get_client() called
                icli.call("node.list")
                expected = {
                    'os_username': CONF.ironic.admin_username,
                    'os_password': CONF.ironic.admin_password,
                    'os_auth_url': CONF.ironic.admin_url,
                    'os_tenant_name': CONF.ironic.admin_tenant_name,
                    'os_service_type': 'baremetal',
                    'os_endpoint_type': 'public'
                }
                mock_ir_cli.assert_called_once_with(CONF.ironic.api_version,
                                                    **expected)