def _get_compute_node(self, context):
     """Returns compute node for the host and nodename."""
     try:
         return objects.ComputeNode.get_by_host_and_nodename(
             context, self.host, utils.get_node_name(self.host))
     except exception.NotFound:
         LOG.warning(_LW("No compute node record for %(host)s:%(node)s"),
                     {'host': self.host,
                      'node': utils.get_node_name(self.host)})
    def _init_compute_node(self, context, resources):
        """Initialise the compute node if it does not already exist.

        The nova scheduler will be inoperable if compute_node
        is not defined. The compute_node will remain undefined if
        we fail to create it or if there is no associated service
        registered.
        If this method has to create a compute node it needs initial
        values - these come from resources.
        :param context: security context
        :param resources: initial values
        """

        # try to get the compute node record from the
        # database. If we get one we use resources to initialize
        compute_node = self._get_compute_node(context)
        if compute_node:
            self._copy_resources(compute_node, resources)
            compute_node.save()
            return

        # there was no local copy and none in the database
        # so we need to create a new compute node. This needs
        # to be initialised with resource values.
        compute_node = objects.ComputeNode(context)
        service = objects.Service.get_by_host_and_binary(
            context, self.host, 'nova-compute')
        compute_node.host = self.host
        compute_node.service_id = service['id']
        self._copy_resources(compute_node, resources)
        compute_node.create()
        LOG.info(_LI('Compute_service record created for '
                     '%(host)s:%(node)s'),
                 {'host': self.host, 'node': utils.get_node_name(self.host)})
    def __init__(self, name):
        self.name = name

        # We currently just hold one aggregate subnode representing the
        # resources owned by all the site's nodes.
        self._aggragate_node = Node(utils.get_node_name(name))

        self._instance_launch_information = {}
    def _do_build_and_run_instance(self, context, host, instance, image,
                                   request_spec, filter_properties,
                                   admin_password, injected_files,
                                   requested_networks, security_groups,
                                   block_device_mapping, node=None,
                                   limits=None):

        try:
            LOG.debug(_('Starting instance...'), context=context,
                      instance=instance)
            instance.vm_state = vm_states.BUILDING
            instance.task_state = None
            instance.save(expected_task_state=(task_states.SCHEDULING, None))
        except exception.InstanceNotFound:
            msg = 'Instance disappeared before build.'
            LOG.debug(msg, instance=instance)
            return
        except exception.UnexpectedTaskStateError as e:
            LOG.debug(e.format_message(), instance=instance)
            return

        # b64 decode the files to inject:
        decoded_files = self._decode_files(injected_files)

        if limits is None:
            limits = {}

        if node is None:
            node = t_utils.get_node_name(host)
            LOG.debug('No node specified, defaulting to %s', node,
                      instance=instance)

        try:
            self._build_and_run_instance(
                context, host, instance, image, request_spec, decoded_files,
                admin_password, requested_networks, security_groups,
                block_device_mapping, node, limits, filter_properties)
        except exception.RescheduledException as e:
            LOG.debug(e.format_message(), instance=instance)
            retry = filter_properties.get('retry', None)
            if not retry:
                # no retry information, do not reschedule.
                LOG.debug("Retry info not present, will not reschedule",
                          instance=instance)
                self._cleanup_allocated_networks(context, instance,
                                                 requested_networks)
                compute_utils.add_instance_fault_from_exc(
                    context, instance, e, sys.exc_info())
                self._set_instance_obj_error_state(context, instance,
                                                   clean_task_state=True)
                return
            retry['exc'] = traceback.format_exception(*sys.exc_info())

            self.network_api.cleanup_instance_network_on_host(
                context, instance, self.host)

            instance.task_state = task_states.SCHEDULING
            instance.save()

            self.compute_task_api.build_instances(
                context, [instance], image, filter_properties, admin_password,
                injected_files, requested_networks, security_groups,
                block_device_mapping)
        except (exception.InstanceNotFound,
                exception.UnexpectedDeletingTaskStateError):
            msg = 'Instance disappeared during build.'
            LOG.debug(msg, instance=instance)
            self._cleanup_allocated_networks(context, instance,
                                             requested_networks)
        except exception.BuildAbortException as e:
            LOG.exception(e.format_message(), instance=instance)
            self._cleanup_allocated_networks(context, instance,
                                             requested_networks)
            self._cleanup_volumes(context, instance.uuid,
                                  block_device_mapping, raise_exc=False)
            compute_utils.add_instance_fault_from_exc(
                context, instance, e, sys.exc_info())
            self._set_instance_obj_error_state(context, instance,
                                               clean_task_state=True)
        except Exception as e:
            # should not reach here.
            msg = _LE('Unexpected build failure, not rescheduling build.')
            LOG.exception(msg, instance=instance)
            self._cleanup_allocated_networks(context, instance,
                                             requested_networks)
            self._cleanup_volumes(context, instance.uuid,
                                  block_device_mapping, raise_exc=False)
            compute_utils.add_instance_fault_from_exc(context, instance,
                                                      e, sys.exc_info())
            self._set_instance_obj_error_state(context, instance,
                                               clean_task_state=True)