Move to proper target_cell calling convention

When target_cell was originally written, the intent was to yield the
context that should be used. It currently mutates the input context,
which means you don't have to actually use the yielded one, because
we have a lot of stuff that would break otherwise. This fixes all the
current uses of it to be proper, and adjusts tests accordingly. This
is separate from changing target_cell's behavior to not mutate the
input context specifically to isolate the mechanical changes from ones
that actually need different behavior.

In addition to code that was already using target_cell() but not
depending on the yielded context, the _create_block_device_mapping()
method in conductor/manager.py was still depending on the shared
context switching to target the BDM objects on create. Since these
were prepared with the context prior to having determined where the
instanace was going to end up, we need to explicitly target the
object context on create (like the rest of the boot workflow does
for other objects in schedule_and_build_instances()).

Related to blueprint cells-aware-api

Change-Id: I35206e665f2c81531a2269dd66f8c5c0df834245
This commit is contained in:
Dan Smith 2017-04-20 11:36:07 -07:00
parent ffd6a42c00
commit bb7c6ebb56
20 changed files with 155 additions and 132 deletions

View File

@ -686,8 +686,8 @@ def get_metadata_by_instance_id(instance_id, address, ctxt=None):
expected_attrs=attrs)
return InstanceMetadata(instance, address)
with context.target_cell(ctxt, im.cell_mapping):
instance = objects.Instance.get_by_uuid(ctxt, instance_id,
with context.target_cell(ctxt, im.cell_mapping) as cctxt:
instance = objects.Instance.get_by_uuid(cctxt, instance_id,
expected_attrs=attrs)
return InstanceMetadata(instance, address)

View File

@ -73,9 +73,10 @@ class ServerExternalEventsController(wsgi.Controller):
# Load migration_context and info_cache here in a single DB
# operation because we need them later on
with nova_context.target_cell(context, cell_mapping):
with nova_context.target_cell(context,
cell_mapping) as cctxt:
instance = objects.Instance.get_by_uuid(
context, event.instance_uuid,
cctxt, event.instance_uuid,
expected_attrs=['migration_context', 'info_cache'])
instances[event.instance_uuid] = instance
except (exception.InstanceNotFound,

View File

@ -72,8 +72,8 @@ class ServerTagsController(wsgi.Controller):
try:
im = objects.InstanceMapping.get_by_instance_uuid(context,
server_id)
with nova_context.target_cell(context, im.cell_mapping):
exists = objects.Tag.exists(context, server_id, id)
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
exists = objects.Tag.exists(cctxt, server_id, id)
except (exception.InstanceNotFound,
exception.InstanceMappingNotFound) as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
@ -92,8 +92,8 @@ class ServerTagsController(wsgi.Controller):
try:
im = objects.InstanceMapping.get_by_instance_uuid(context,
server_id)
with nova_context.target_cell(context, im.cell_mapping):
tags = objects.TagList.get_by_resource_id(context, server_id)
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
tags = objects.TagList.get_by_resource_id(cctxt, server_id)
except (exception.InstanceNotFound,
exception.InstanceMappingNotFound) as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
@ -108,8 +108,8 @@ class ServerTagsController(wsgi.Controller):
context.can(st_policies.POLICY_ROOT % 'update')
im = _get_instance_mapping(context, server_id)
with nova_context.target_cell(context, im.cell_mapping):
self._check_instance_in_valid_state(context, server_id,
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
self._check_instance_in_valid_state(cctxt, server_id,
'update tag')
try:
@ -121,8 +121,8 @@ class ServerTagsController(wsgi.Controller):
raise webob.exc.HTTPBadRequest(explanation=msg)
try:
with nova_context.target_cell(context, im.cell_mapping):
tags = objects.TagList.get_by_resource_id(context, server_id)
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
tags = objects.TagList.get_by_resource_id(cctxt, server_id)
except exception.InstanceNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
@ -135,10 +135,9 @@ class ServerTagsController(wsgi.Controller):
# NOTE(snikitin): server already has specified tag
return webob.Response(status_int=204)
tag = objects.Tag(context=context, resource_id=server_id, tag=id)
try:
with nova_context.target_cell(context, im.cell_mapping):
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
tag = objects.Tag(context=cctxt, resource_id=server_id, tag=id)
tag.create()
except exception.InstanceNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
@ -156,13 +155,13 @@ class ServerTagsController(wsgi.Controller):
context.can(st_policies.POLICY_ROOT % 'update_all')
im = _get_instance_mapping(context, server_id)
with nova_context.target_cell(context, im.cell_mapping):
self._check_instance_in_valid_state(context, server_id,
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
self._check_instance_in_valid_state(cctxt, server_id,
'update tags')
try:
with nova_context.target_cell(context, im.cell_mapping):
tags = objects.TagList.create(context, server_id, body['tags'])
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
tags = objects.TagList.create(cctxt, server_id, body['tags'])
except exception.InstanceNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
@ -176,13 +175,13 @@ class ServerTagsController(wsgi.Controller):
context.can(st_policies.POLICY_ROOT % 'delete')
im = _get_instance_mapping(context, server_id)
with nova_context.target_cell(context, im.cell_mapping):
self._check_instance_in_valid_state(context, server_id,
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
self._check_instance_in_valid_state(cctxt, server_id,
'delete tag')
try:
with nova_context.target_cell(context, im.cell_mapping):
objects.Tag.destroy(context, server_id, id)
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
objects.Tag.destroy(cctxt, server_id, id)
except (exception.InstanceTagNotFound,
exception.InstanceNotFound) as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
@ -195,13 +194,13 @@ class ServerTagsController(wsgi.Controller):
context.can(st_policies.POLICY_ROOT % 'delete_all')
im = _get_instance_mapping(context, server_id)
with nova_context.target_cell(context, im.cell_mapping):
self._check_instance_in_valid_state(context, server_id,
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
self._check_instance_in_valid_state(cctxt, server_id,
'delete tags')
try:
with nova_context.target_cell(context, im.cell_mapping):
objects.TagList.destroy(context, server_id)
with nova_context.target_cell(context, im.cell_mapping) as cctxt:
objects.TagList.destroy(cctxt, server_id)
except exception.InstanceNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())

View File

@ -109,11 +109,11 @@ class SimpleTenantUsageController(wsgi.Controller):
all_instances = []
cells = objects.CellMappingList.get_all(context)
for cell in cells:
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
try:
instances = (
objects.InstanceList.get_active_by_window_joined(
context, period_start, period_stop, tenant_id,
cctxt, period_start, period_stop, tenant_id,
expected_attrs=['flavor'], limit=limit,
marker=marker))
except exception.MarkerNotFound:

View File

@ -687,8 +687,8 @@ class DbCommands(object):
try:
cell_mapping = objects.CellMapping.get_by_uuid(ctxt,
objects.CellMapping.CELL0_UUID)
with context.target_cell(ctxt, cell_mapping):
migration.db_sync(version, context=ctxt)
with context.target_cell(ctxt, cell_mapping) as cctxt:
migration.db_sync(version, context=cctxt)
except exception.CellMappingNotFound:
print(_('WARNING: cell0 mapping not found - not'
' syncing cell0.'))
@ -1167,9 +1167,9 @@ class CellV2Commands(object):
ctxt, objects.CellMapping.CELL0_UUID)
# Run migrations so cell0 is usable
with context.target_cell(ctxt, cell0_mapping):
with context.target_cell(ctxt, cell0_mapping) as cctxt:
try:
migration.db_sync(None, context=ctxt)
migration.db_sync(None, context=cctxt)
except db_exc.DBError as ex:
print(_('Unable to sync cell0 schema: %s') % ex)

View File

@ -290,8 +290,8 @@ class UpgradeCommands(object):
ctxt = nova_context.get_admin_context()
num_computes = 0
for cell_mapping in cell_mappings:
with nova_context.target_cell(ctxt, cell_mapping):
num_computes += self._count_compute_nodes(ctxt)
with nova_context.target_cell(ctxt, cell_mapping) as cctxt:
num_computes += self._count_compute_nodes(cctxt)
else:
# There are no cell mappings, cells v2 was maybe not deployed in
# Newton, but placement might have been, so let's check the single

View File

@ -1737,10 +1737,9 @@ class API(base.Base):
return None, None
else:
cell = inst_map.cell_mapping
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
try:
instance = objects.Instance.get_by_uuid(context,
uuid)
instance = objects.Instance.get_by_uuid(cctxt, uuid)
except exception.InstanceNotFound:
# Since the cell_mapping exists we know the instance is in
# the cell, however InstanceNotFound means it's already
@ -1799,9 +1798,11 @@ class API(base.Base):
if instance is not None:
# If instance is None it has already been deleted.
if cell:
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
# FIXME: When the instance context is targeted,
# we can remove this
with compute_utils.notify_about_instance_delete(
self.notifier, context, instance):
self.notifier, cctxt, instance):
instance.destroy()
else:
instance.destroy()
@ -1873,31 +1874,35 @@ class API(base.Base):
# We have to get the flavor from the instance while the
# context is still targeted to where the instance lives.
with nova_context.target_cell(context, cell):
# If the instance has the targeted context in it then
# we don't need the context manager.
with nova_context.target_cell(context, cell) as cctxt:
# FIXME: If the instance has the targeted context in
# it then we don't need the context manager.
quota_flavor = self._get_flavor_for_reservation(
instance)
with nova_context.target_cell(context, None):
with nova_context.target_cell(context, None) as cctxt:
# This is confusing but actually decrements quota usage
quotas = self._create_reservations(
context, instance, instance.task_state,
cctxt, instance, instance.task_state,
project_id, user_id, flavor=quota_flavor)
try:
# Now destroy the instance from the cell it lives in.
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
# If the instance has the targeted context in it
# then we don't need the context manager.
with compute_utils.notify_about_instance_delete(
self.notifier, context, instance):
self.notifier, cctxt, instance):
instance.destroy()
# Now commit the quota reservation to decrement usage.
with nova_context.target_cell(context, None):
# NOTE(danms): When target_cell yields a context copy,
# we can remove this targeting.
with nova_context.target_cell(context, None) as cctxt:
quotas.commit()
except exception.InstanceNotFound:
with nova_context.target_cell(context, None):
# NOTE(danms): When target_cell yields a context copy,
# we can remove this targeting.
with nova_context.target_cell(context, None) as cctxt:
quotas.rollback()
# The instance was deleted or is already gone.
return
@ -2557,10 +2562,10 @@ class API(base.Base):
except exception.CellMappingNotFound:
cell0_instances = objects.InstanceList(objects=[])
else:
with nova_context.target_cell(context, cell0_mapping):
with nova_context.target_cell(context, cell0_mapping) as cctxt:
try:
cell0_instances = self._get_instances_by_filters(
context, filters, limit=limit, marker=marker,
cctxt, filters, limit=limit, marker=marker,
expected_attrs=expected_attrs, sort_keys=sort_keys,
sort_dirs=sort_dirs)
except exception.MarkerNotFound:
@ -2714,8 +2719,10 @@ class API(base.Base):
# look up the instance in the cell database
if inst_map and (inst_map.cell_mapping is not None) and (
not CONF.cells.enable):
with nova_context.target_cell(context, inst_map.cell_mapping):
instance.save()
with nova_context.target_cell(context,
inst_map.cell_mapping) as cctxt:
with instance.obj_alternate_context(cctxt):
instance.save()
else:
# If inst_map.cell_mapping does not point at a cell then cell
# migration has not happened yet.
@ -2756,10 +2763,11 @@ class API(base.Base):
inst_map = self._get_instance_map_or_none(context,
instance.uuid)
if inst_map and (inst_map.cell_mapping is not None):
with nova_context.target_cell(context,
inst_map.cell_mapping):
with nova_context.target_cell(
context,
inst_map.cell_mapping) as cctxt:
instance = objects.Instance.get_by_uuid(
context, instance.uuid,
cctxt, instance.uuid,
expected_attrs=expected_attrs)
instance.update(updates)
instance.save()
@ -4161,9 +4169,9 @@ class API(base.Base):
for cell in CELLS:
if cell.uuid == objects.CellMapping.CELL0_UUID:
continue
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
migrations.extend(objects.MigrationList.get_by_filters(
context, filters).objects)
cctxt, filters).objects)
return objects.MigrationList(objects=migrations)
def get_migrations_in_progress_by_instance(self, context, instance_uuid,
@ -4239,9 +4247,9 @@ class API(base.Base):
# TODO(salv-orlando): Handle exceptions raised by the rpc api layer
# in order to ensure that a failure in processing events on a host
# will not prevent processing events on other hosts
with nova_context.target_cell(context, cell_mapping):
with nova_context.target_cell(context, cell_mapping) as cctxt:
self.compute_rpcapi.external_instance_event(
context, instances_by_host[host], events_by_host[host],
cctxt, instances_by_host[host], events_by_host[host],
host=host)
def _get_relevant_hosts(self, context, instance):
@ -4406,9 +4414,9 @@ class HostAPI(base.Base):
load_cells()
services = []
for cell in CELLS:
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
cell_services = objects.ServiceList.get_all(
context, disabled, set_zones=set_zones)
cctxt, disabled, set_zones=set_zones)
services.extend(cell_services)
else:
services = objects.ServiceList.get_all(context, disabled,
@ -4444,8 +4452,8 @@ class HostAPI(base.Base):
for cell in CELLS:
# NOTE(danms): Services can be in cell0, so don't skip it here
try:
with nova_context.target_cell(context, cell):
cell_service = objects.Service.get_by_id(context,
with nova_context.target_cell(context, cell) as cctxt:
cell_service = objects.Service.get_by_id(cctxt,
service_id)
except exception.ServiceNotFound:
# NOTE(danms): Keep looking in other cells
@ -4523,9 +4531,9 @@ class HostAPI(base.Base):
for cell in CELLS:
if cell.uuid == objects.CellMapping.CELL0_UUID:
continue
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
try:
return objects.ComputeNode.get_by_id(context,
return objects.ComputeNode.get_by_id(cctxt,
int(compute_id))
except exception.ComputeHostNotFound:
# NOTE(danms): Keep looking in other cells
@ -4540,10 +4548,10 @@ class HostAPI(base.Base):
for cell in CELLS:
if cell.uuid == objects.CellMapping.CELL0_UUID:
continue
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
try:
cell_computes = objects.ComputeNodeList.get_by_pagination(
context, limit=limit, marker=marker)
cctxt, limit=limit, marker=marker)
except exception.MarkerNotFound:
# NOTE(danms): Keep looking through cells
continue
@ -4570,9 +4578,9 @@ class HostAPI(base.Base):
for cell in CELLS:
if cell.uuid == objects.CellMapping.CELL0_UUID:
continue
with nova_context.target_cell(context, cell):
with nova_context.target_cell(context, cell) as cctxt:
cell_computes = objects.ComputeNodeList.get_by_hypervisor(
context, hypervisor_match)
cctxt, hypervisor_match)
computes.extend(cell_computes)
return objects.ComputeNodeList(objects=computes)

View File

@ -205,7 +205,7 @@ def obj_target_cell(obj, cell):
"""Run with object's context set to a specific cell"""
with try_target_cell(obj._context, cell) as target:
with obj.obj_alternate_context(target):
yield
yield target
@profiler.trace_cls("rpc")
@ -830,7 +830,7 @@ class ComputeTaskManager(base.Base):
size = instance_type.get('ephemeral_gb', 0)
return size
def _create_block_device_mapping(self, instance_type, instance_uuid,
def _create_block_device_mapping(self, cell, instance_type, instance_uuid,
block_device_mapping):
"""Create the BlockDeviceMapping objects in the db.
@ -843,7 +843,8 @@ class ComputeTaskManager(base.Base):
for bdm in instance_block_device_mapping:
bdm.volume_size = self._volume_size(instance_type, bdm)
bdm.instance_uuid = instance_uuid
bdm.update_or_create()
with obj_target_cell(bdm, cell):
bdm.update_or_create()
return instance_block_device_mapping
def _bury_in_cell0(self, context, request_spec, exc,
@ -971,12 +972,12 @@ class ComputeTaskManager(base.Base):
notifications.send_update_with_states(context, instance, None,
vm_states.BUILDING, None, None, service="conductor")
with obj_target_cell(instance, cell):
with obj_target_cell(instance, cell) as cctxt:
objects.InstanceAction.action_start(
context, instance.uuid, instance_actions.CREATE,
cctxt, instance.uuid, instance_actions.CREATE,
want_result=False)
instance_bdms = self._create_block_device_mapping(
instance.flavor, instance.uuid, block_device_mapping)
cell, instance.flavor, instance.uuid, block_device_mapping)
# Update mapping for instance. Normally this check is guarded by
# a try/except but if we're here we know that a newer nova-api
@ -999,9 +1000,9 @@ class ComputeTaskManager(base.Base):
legacy_secgroups = [s.identifier
for s in request_spec.security_groups]
with obj_target_cell(instance, cell):
with obj_target_cell(instance, cell) as cctxt:
self.compute_rpcapi.build_and_run_instance(
context, instance=instance, image=image,
cctxt, instance=instance, image=image,
request_spec=request_spec,
filter_properties=filter_props,
admin_password=admin_password,

View File

@ -119,11 +119,11 @@ class ConsoleAuthManager(manager.Manager):
mapping = objects.InstanceMapping.get_by_instance_uuid(context,
instance_uuid)
with nova_context.target_cell(context, mapping.cell_mapping):
instance = objects.Instance.get_by_uuid(context, instance_uuid)
with nova_context.target_cell(context, mapping.cell_mapping) as cctxt:
instance = objects.Instance.get_by_uuid(cctxt, instance_uuid)
return self.compute_rpcapi.validate_console_port(
context,
cctxt,
instance,
token['port'],
token['console_type'])

View File

@ -218,13 +218,14 @@ def discover_hosts(ctxt, cell_uuid=None, status_fn=None):
else:
status_fn(_("Getting compute nodes from cell: %(uuid)s") %
{'uuid': cm.uuid})
with context.target_cell(ctxt, cm):
with context.target_cell(ctxt, cm) as cctxt:
compute_nodes = objects.ComputeNodeList.get_all_by_not_mapped(
ctxt, 1)
cctxt, 1)
status_fn(_('Found %(num)s unmapped computes in cell: %(uuid)s') %
{'num': len(compute_nodes),
'uuid': cm.uuid})
added_hm = _check_and_create_host_mappings(ctxt, cm, compute_nodes,
added_hm = _check_and_create_host_mappings(cctxt, cm,
compute_nodes,
status_fn)
host_mappings.extend(added_hm)

View File

@ -423,9 +423,9 @@ class HostManager(object):
if not computes_by_cell:
computes_by_cell = {}
for cell in self.cells:
with context_module.target_cell(context, cell):
with context_module.target_cell(context, cell) as cctxt:
cell_cns = objects.ComputeNodeList.get_all(
context).objects
cctxt).objects
computes_by_cell[cell] = cell_cns
count += len(cell_cns)
@ -444,9 +444,9 @@ class HostManager(object):
filters = {"host": [curr_node.host
for curr_node in curr_nodes],
"deleted": False}
with context_module.target_cell(context, cell):
with context_module.target_cell(context, cell) as cctxt:
result = objects.InstanceList.get_by_filters(
context.elevated(), filters)
cctxt.elevated(), filters)
instances = result.objects
LOG.debug("Adding %s instances for hosts %s-%s",
len(instances), start_node, end_node)
@ -603,19 +603,18 @@ class HostManager(object):
for cell in cells:
LOG.debug('Getting compute nodes and services for cell %(cell)s',
{'cell': cell.identity})
with context_module.target_cell(context, cell):
with context_module.target_cell(context, cell) as cctxt:
if compute_uuids is None:
compute_nodes[cell.uuid].extend(
objects.ComputeNodeList.get_all(
context))
objects.ComputeNodeList.get_all(cctxt))
else:
compute_nodes[cell.uuid].extend(
objects.ComputeNodeList.get_all_by_uuids(
context, compute_uuids))
cctxt, compute_uuids))
services.update(
{service.host: service
for service in objects.ServiceList.get_by_binary(
context, 'nova-compute',
cctxt, 'nova-compute',
include_disabled=True)})
return compute_nodes, services
@ -708,8 +707,8 @@ class HostManager(object):
def _get_instances_by_host(self, context, host_name):
hm = objects.HostMapping.get_by_host(context, host_name)
with context_module.target_cell(context, hm.cell_mapping):
inst_list = objects.InstanceList.get_by_host(context, host_name)
with context_module.target_cell(context, hm.cell_mapping) as cctxt:
inst_list = objects.InstanceList.get_by_host(cctxt, host_name)
return {inst.uuid: inst for inst in inst_list}
def _get_instance_info(self, context, compute):

View File

@ -112,9 +112,9 @@ class IronicHostManager(host_manager.HostManager):
if not computes_by_cell:
computes_by_cell = {}
for cell in self.cells:
with context_module.target_cell(context, cell):
with context_module.target_cell(context, cell) as cctxt:
computes_by_cell[cell] = (
objects.ComputeNodeList.get_all(context).objects)
objects.ComputeNodeList.get_all(cctxt).objects)
non_ironic_computes = {cell: [c for c in compute_nodes
if not self._is_ironic_compute(c)]

View File

@ -52,16 +52,16 @@ class ConnectionSwitchTestCase(test.NoDBTestCase):
mapping.create()
# Create an instance in the cell database
uuid = uuidutils.generate_uuid()
with context.target_cell(ctxt, mapping):
with context.target_cell(ctxt, mapping) as cctxt:
# Must set project_id because instance get specifies
# project_only=True to model_query, which means non-admin
# users can only read instances for their project
instance = objects.Instance(context=ctxt, uuid=uuid,
instance = objects.Instance(context=cctxt, uuid=uuid,
project_id='fake-project')
instance.create()
# Verify the instance is found in the cell database
inst = objects.Instance.get_by_uuid(ctxt, uuid)
inst = objects.Instance.get_by_uuid(cctxt, uuid)
self.assertEqual(uuid, inst.uuid)
# Verify the instance isn't found in the main database
@ -95,35 +95,35 @@ class CellDatabasesTestCase(test.NoDBTestCase):
# Create an instance and read it from cell1
uuid = uuidutils.generate_uuid()
with context.target_cell(ctxt, mapping1):
instance = objects.Instance(context=ctxt, uuid=uuid,
with context.target_cell(ctxt, mapping1) as cctxt:
instance = objects.Instance(context=cctxt, uuid=uuid,
project_id='fake-project')
instance.create()
inst = objects.Instance.get_by_uuid(ctxt, uuid)
inst = objects.Instance.get_by_uuid(cctxt, uuid)
self.assertEqual(uuid, inst.uuid)
# Make sure it can't be read from cell2
with context.target_cell(ctxt, mapping2):
with context.target_cell(ctxt, mapping2) as cctxt:
self.assertRaises(exception.InstanceNotFound,
objects.Instance.get_by_uuid, ctxt, uuid)
objects.Instance.get_by_uuid, cctxt, uuid)
# Make sure it can still be read from cell1
with context.target_cell(ctxt, mapping1):
inst = objects.Instance.get_by_uuid(ctxt, uuid)
with context.target_cell(ctxt, mapping1) as cctxt:
inst = objects.Instance.get_by_uuid(cctxt, uuid)
self.assertEqual(uuid, inst.uuid)
# Create an instance and read it from cell2
uuid = uuidutils.generate_uuid()
with context.target_cell(ctxt, mapping2):
instance = objects.Instance(context=ctxt, uuid=uuid,
with context.target_cell(ctxt, mapping2) as cctxt:
instance = objects.Instance(context=cctxt, uuid=uuid,
project_id='fake-project')
instance.create()
inst = objects.Instance.get_by_uuid(ctxt, uuid)
inst = objects.Instance.get_by_uuid(cctxt, uuid)
self.assertEqual(uuid, inst.uuid)
# Make sure it can't be read from cell1
with context.target_cell(ctxt, mapping1):
with context.target_cell(ctxt, mapping1) as cctxt:
self.assertRaises(exception.InstanceNotFound,
objects.Instance.get_by_uuid, ctxt, uuid)
objects.Instance.get_by_uuid, cctxt, uuid)

View File

@ -335,7 +335,8 @@ class ServerGroupTestV21(test.NoDBTestCase):
# delete an instance
im = objects.InstanceMapping.get_by_instance_uuid(ctx,
instances[1].uuid)
with context.target_cell(ctx, im.cell_mapping):
with context.target_cell(ctx, im.cell_mapping) as cctxt:
instances[1]._context = cctxt
instances[1].destroy()
# check that the instance does not exist

View File

@ -7922,6 +7922,7 @@ class ComputeTestCase(BaseTestCase):
minimum_server_version.return_value = 15
im_get_by_instance.return_value = mock.Mock()
target_cell.return_value.__enter__.return_value = self.context
instance = self._create_fake_instance_obj()
instance.host = None
@ -7987,6 +7988,7 @@ class ComputeTestCase(BaseTestCase):
self, br_get_by_instance, notify, im_get_by_instance, target_cell,
instance_destroy):
target_cell.return_value.__enter__.return_value = self.context
instance = self._create_fake_instance_obj()
instance.host = None
instance.save()
@ -10899,8 +10901,8 @@ def _create_service_entries(ctxt, values=[['avail_zone1', ['fake_host1',
# NOTE(danms): spread these services across cells
cell = cells[index % len(cells)]
index += 1
with context.target_cell(ctxt, cell):
s = objects.Service(context=ctxt,
with context.target_cell(ctxt, cell) as cctxt:
s = objects.Service(context=cctxt,
host=host,
binary='nova-compute',
topic='compute',

View File

@ -1440,6 +1440,7 @@ class _ComputeAPIUnitTestMixIn(object):
instance = self._create_instance_obj({'host': None})
cell0 = objects.CellMapping(uuid=objects.CellMapping.CELL0_UUID)
quota_mock = mock.MagicMock()
target_cell_mock().__enter__.return_value = mock.sentinel.cctxt
with test.nested(
mock.patch.object(self.compute_api, '_delete_while_booting',
@ -1462,7 +1463,7 @@ class _ComputeAPIUnitTestMixIn(object):
self.context, instance.uuid)
_get_flavor_for_reservation.assert_called_once_with(instance)
_create_reservations.assert_called_once_with(
self.context, instance, instance.task_state,
mock.sentinel.cctxt, instance, instance.task_state,
self.context.project_id, instance.user_id,
flavor=instance.flavor)
quota_mock.commit.assert_called_once_with()
@ -1482,7 +1483,7 @@ class _ComputeAPIUnitTestMixIn(object):
]
target_cell_mock.assert_has_calls(expected_target_cell_calls)
notify_mock.assert_called_once_with(
self.compute_api.notifier, self.context, instance)
self.compute_api.notifier, mock.sentinel.cctxt, instance)
destroy_mock.assert_called_once_with()
@mock.patch('nova.context.target_cell')
@ -1503,6 +1504,7 @@ class _ComputeAPIUnitTestMixIn(object):
quota_mock = mock.MagicMock()
destroy_mock.side_effect = exception.InstanceNotFound(
instance_id=instance.uuid)
target_cell_mock().__enter__.return_value = mock.sentinel.cctxt
with test.nested(
mock.patch.object(self.compute_api, '_delete_while_booting',
@ -1525,11 +1527,11 @@ class _ComputeAPIUnitTestMixIn(object):
self.context, instance.uuid)
_get_flavor_for_reservation.assert_called_once_with(instance)
_create_reservations.assert_called_once_with(
self.context, instance, instance.task_state,
mock.sentinel.cctxt, instance, instance.task_state,
self.context.project_id, instance.user_id,
flavor=instance.flavor)
notify_mock.assert_called_once_with(
self.compute_api.notifier, self.context, instance)
self.compute_api.notifier, mock.sentinel.cctxt, instance)
destroy_mock.assert_called_once_with()
expected_target_cell_calls = [
# Get the instance.flavor.
@ -1591,6 +1593,7 @@ class _ComputeAPIUnitTestMixIn(object):
@mock.patch.object(context, 'target_cell')
def test_lookup_instance_cell_mapping(self, mock_target_cell):
instance = self._create_instance_obj()
mock_target_cell.return_value.__enter__.return_value = self.context
inst_map = objects.InstanceMapping(
cell_mapping=objects.CellMapping(database_connection='',
@ -4692,6 +4695,8 @@ class _ComputeAPIUnitTestMixIn(object):
objects.CellMapping(uuid=uuids.cell1, name='1'),
]
cctxt = mock_target_cell.return_value.__enter__.return_value
with mock.patch.object(self.compute_api,
'_get_instances_by_filters') as mock_inst_get:
mock_inst_get.side_effect = [objects.InstanceList(
@ -4709,7 +4714,7 @@ class _ComputeAPIUnitTestMixIn(object):
if self.cell_type is None:
for cm in mock_cm_get_all.return_value:
mock_target_cell.assert_any_call(self.context, cm)
inst_get_calls = [mock.call(self.context, {'foo': 'bar'},
inst_get_calls = [mock.call(cctxt, {'foo': 'bar'},
limit=10, marker='fake-marker',
expected_attrs=None, sort_keys=['baz'],
sort_dirs=['desc']),
@ -4747,6 +4752,7 @@ class _ComputeAPIUnitTestMixIn(object):
cell_mapping,
objects.CellMapping(uuid=uuids.cell1, name='1'),
]
cctxt = mock_target_cell.return_value.__enter__.return_value
with mock.patch.object(self.compute_api,
'_get_instances_by_filters') as mock_inst_get:
@ -4765,7 +4771,7 @@ class _ComputeAPIUnitTestMixIn(object):
if self.cell_type is None:
for cm in mock_cm_get_all.return_value:
mock_target_cell.assert_any_call(self.context, cm)
inst_get_calls = [mock.call(self.context, {'foo': 'bar'},
inst_get_calls = [mock.call(cctxt, {'foo': 'bar'},
limit=8, marker='fake-marker',
expected_attrs=None, sort_keys=['baz'],
sort_dirs=['desc']),
@ -4804,6 +4810,7 @@ class _ComputeAPIUnitTestMixIn(object):
objects.CellMapping(uuid=uuids.cell1, name='1'),
]
marker = uuids.marker
cctxt = mock_target_cell.return_value.__enter__.return_value
with mock.patch.object(self.compute_api,
'_get_instances_by_filters') as mock_inst_get:
@ -4822,7 +4829,7 @@ class _ComputeAPIUnitTestMixIn(object):
if self.cell_type is None:
for cm in mock_cm_get_all.return_value:
mock_target_cell.assert_any_call(self.context, cm)
inst_get_calls = [mock.call(self.context, {'foo': 'bar'},
inst_get_calls = [mock.call(cctxt, {'foo': 'bar'},
limit=10, marker=marker,
expected_attrs=None, sort_keys=['baz'],
sort_dirs=['desc']),

View File

@ -176,8 +176,8 @@ class ComputeHostAPITestCase(test.TestCase):
def test_service_get_all_cells(self):
cells = objects.CellMappingList.get_all(self.ctxt)
for cell in cells:
with context.target_cell(self.ctxt, cell):
objects.Service(context=self.ctxt,
with context.target_cell(self.ctxt, cell) as cctxt:
objects.Service(context=cctxt,
binary='nova-compute',
host='host-%s' % cell.uuid).create()
services = self.host_api.service_get_all(self.ctxt, all_cells=True)

View File

@ -1479,9 +1479,9 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
# NOTE(danms): Assert that we created the InstanceAction in the
# correct cell
for cell in cells:
with context.target_cell(self.context, cell):
with context.target_cell(self.context, cell) as cctxt:
actions = objects.InstanceActionList.get_by_instance_uuid(
self.context, instance_uuid)
cctxt, instance_uuid)
if cell.name == 'cell1':
self.assertEqual(1, len(actions))
else:

View File

@ -939,7 +939,7 @@ class HostManagerTestCase(test.NoDBTestCase):
@contextlib.contextmanager
def fake_set_target(context, cell):
yield
yield mock.sentinel.cctxt
mock_target.side_effect = fake_set_target
@ -955,8 +955,8 @@ class HostManagerTestCase(test.NoDBTestCase):
# targeted one if we honored the only-cell destination requirement,
# and only looked up services and compute nodes in one
mock_target.assert_called_once_with(context, cells[1])
mock_cn.assert_called_once_with(context)
mock_sl.assert_called_once_with(context, 'nova-compute',
mock_cn.assert_called_once_with(mock.sentinel.cctxt)
mock_sl.assert_called_once_with(mock.sentinel.cctxt, 'nova-compute',
include_disabled=True)

View File

@ -552,7 +552,7 @@ Archiving.....stopped
mock_target_cell.assert_called_once_with(ctxt, 'map')
db_sync_calls = [
mock.call(4, context=ctxt),
mock.call(4, context=cell_ctxt),
mock.call(4)
]
mock_db_sync.assert_has_calls(db_sync_calls)
@ -1268,6 +1268,8 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
transport_url='fake:///mq')
cell_mapping.create()
mock_target_cell.return_value.__enter__.return_value = ctxt
self.commands.discover_hosts(cell_uuid=cell_mapping.uuid)
# Check that the host mappings were created
@ -1343,10 +1345,12 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
compute_nodes = self._return_compute_nodes(ctxt, num=2)
# Create the first compute node in cell1's db
with context.target_cell(ctxt, cell_mapping1):
with context.target_cell(ctxt, cell_mapping1) as cctxt:
compute_nodes[0]._context = cctxt
compute_nodes[0].create()
# Create the first compute node in cell2's db
with context.target_cell(ctxt, cell_mapping2):
with context.target_cell(ctxt, cell_mapping2) as cctxt:
compute_nodes[1]._context = cctxt
compute_nodes[1].create()
self.commands.discover_hosts(verbose=True)