tricircle/tricircle/dispatcher/compute_manager.py

127 lines
5.3 KiB
Python

# Copyright 2015 Huawei Technologies Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import oslo_log.log as logging
import oslo_messaging as messaging
from tricircle.common.i18n import _LI
from tricircle.common.i18n import _LW
from tricircle.common.nova_lib import context as nova_context
from tricircle.common.nova_lib import exception
from tricircle.common.nova_lib import manager
from tricircle.common.nova_lib import objects
from tricircle.common.nova_lib import objects_base
from tricircle.common.nova_lib import rpc as nova_rpc
from tricircle.common import utils
LOG = logging.getLogger(__name__)
class DispatcherComputeManager(manager.Manager):
target = messaging.Target(version='4.0')
def __init__(self, site_manager=None, *args, **kwargs):
self._site_manager = site_manager
target = messaging.Target(topic="proxy", version='4.0')
serializer = objects_base.NovaObjectSerializer()
self.proxy_client = nova_rpc.get_client(target, '4.0', serializer)
super(DispatcherComputeManager, self).__init__(service_name="compute",
*args, **kwargs)
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 _copy_resources(self, compute_node, resources):
"""Copy resource values to initialise compute_node"""
# update the allocation ratios for the related ComputeNode object
compute_node.ram_allocation_ratio = 1
compute_node.cpu_allocation_ratio = 1
# now copy rest to compute_node
for key in resources:
compute_node[key] = resources[key]
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)})
# NOTE(zhiyuan) register fake compute node information in db so nova
# scheduler can properly select destination
def pre_start_hook(self):
site = self._site_manager.get_site(self.host)
node = site.get_nodes()[0]
resources = node.get_available_resource()
context = nova_context.get_admin_context()
self._init_compute_node(context, resources)
def build_and_run_instance(self, context, instance, image, request_spec,
filter_properties, admin_password=None,
injected_files=None, requested_networks=None,
security_groups=None, block_device_mapping=None,
node=None, limits=None):
version = '4.0'
cctxt = self.proxy_client.prepare(version=version)
cctxt.cast(context, 'build_and_run_instance', host=self.host,
instance=instance, image=image, request_spec=request_spec,
filter_properties=filter_properties,
admin_password=admin_password,
injected_files=injected_files,
requested_networks=requested_networks,
security_groups=security_groups,
block_device_mapping=block_device_mapping, node=node,
limits=limits)