diff --git a/nova/api/openstack/compute/contrib/attach_interfaces.py b/nova/api/openstack/compute/contrib/attach_interfaces.py index dd64128ecd0a..c33d941fbaee 100644 --- a/nova/api/openstack/compute/contrib/attach_interfaces.py +++ b/nova/api/openstack/compute/contrib/attach_interfaces.py @@ -99,7 +99,8 @@ class InterfaceAttachmentController(object): raise exc.HTTPBadRequest() try: - instance = self.compute_api.get(context, server_id) + instance = self.compute_api.get(context, server_id, + want_objects=True) LOG.audit(_("Attach interface"), instance=instance) vif = self.compute_api.attach_interface(context, instance, network_id, port_id, req_ip) @@ -134,7 +135,8 @@ class InterfaceAttachmentController(object): port_id = id try: - instance = self.compute_api.get(context, server_id) + instance = self.compute_api.get(context, server_id, + want_objects=True) LOG.audit(_("Detach interface %s"), port_id, instance=instance) except exception.NotFound: diff --git a/nova/api/openstack/compute/plugins/v3/attach_interfaces.py b/nova/api/openstack/compute/plugins/v3/attach_interfaces.py index c5c126079f1b..d87aa18640ca 100644 --- a/nova/api/openstack/compute/plugins/v3/attach_interfaces.py +++ b/nova/api/openstack/compute/plugins/v3/attach_interfaces.py @@ -99,7 +99,7 @@ class InterfaceAttachmentController(object): raise exc.HTTPBadRequest() instance = common.get_instance(self.compute_api, context, - server_id) + server_id, want_objects=True) LOG.audit(_("Attach interface to %s"), instance=instance) try: @@ -131,7 +131,8 @@ class InterfaceAttachmentController(object): authorize(context) port_id = id - instance = common.get_instance(self.compute_api, context, server_id) + instance = common.get_instance(self.compute_api, context, server_id, + want_objects=True) LOG.audit(_("Detach interface %s"), port_id, instance=instance) try: self.compute_api.detach_interface(context, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 237cac95d769..ab1794a5fdb0 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -414,7 +414,7 @@ class ComputeVirtAPI(virtapi.VirtAPI): class ComputeManager(manager.Manager): """Manages the running instances from creation to destruction.""" - target = messaging.Target(version='3.16') + target = messaging.Target(version='3.17') def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -4077,6 +4077,7 @@ class ComputeManager(manager.Manager): except exception.NotFound: pass + @object_compat def attach_interface(self, context, instance, network_id, port_id, requested_ip): """Use hotplug to add an network adapter to an instance.""" @@ -4095,6 +4096,7 @@ class ComputeManager(manager.Manager): self.driver.attach_interface(instance, image_meta, network_info[0]) return network_info[0] + @object_compat def detach_interface(self, context, instance, port_id): """Detach an network adapter from an instance.""" # FIXME(comstud): Why does this need elevated context? diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index 1a29b8d0e3ce..4421f4d7c26d 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -232,6 +232,7 @@ class ComputeAPI(object): 3.16 - Make reserve_block_device_name and attach_volume use new-world objects, and add disk_bus and device_type params to reserve_block_device_name, and bdm param to attach_volume + 3.17 - Update attach_interface and detach_interface to take an object ''' VERSION_ALIASES = { @@ -301,12 +302,15 @@ class ComputeAPI(object): def attach_interface(self, ctxt, instance, network_id, port_id, requested_ip): # NOTE(russellb) Havana compat - version = self._get_compat_version('3.0', '2.25') - instance_p = jsonutils.to_primitive(instance) + if self.client.can_send_version('3.17'): + version = '3.17' + else: + version = self._get_compat_version('3.0', '2.25') + instance = jsonutils.to_primitive(instance) cctxt = self.client.prepare(server=_compute_host(None, instance), version=version) return cctxt.call(ctxt, 'attach_interface', - instance=instance_p, network_id=network_id, + instance=instance, network_id=network_id, port_id=port_id, requested_ip=requested_ip) def attach_volume(self, ctxt, instance, volume_id, mountpoint, bdm=None): @@ -379,12 +383,15 @@ class ComputeAPI(object): def detach_interface(self, ctxt, instance, port_id): # NOTE(russellb) Havana compat - version = self._get_compat_version('3.0', '2.25') - instance_p = jsonutils.to_primitive(instance) + if self.client.can_send_version('3.17'): + version = '3.17' + else: + version = self._get_compat_version('3.0', '2.25') + instance = jsonutils.to_primitive(instance) cctxt = self.client.prepare(server=_compute_host(None, instance), version=version) cctxt.cast(ctxt, 'detach_interface', - instance=instance_p, port_id=port_id) + instance=instance, port_id=port_id) def detach_volume(self, ctxt, instance, volume_id): # NOTE(russellb) Havana compat diff --git a/nova/tests/api/openstack/compute/contrib/test_attach_interfaces.py b/nova/tests/api/openstack/compute/contrib/test_attach_interfaces.py index 009e2be2cae5..95767e840c8d 100644 --- a/nova/tests/api/openstack/compute/contrib/test_attach_interfaces.py +++ b/nova/tests/api/openstack/compute/contrib/test_attach_interfaces.py @@ -113,7 +113,7 @@ def fake_detach_interface(self, context, instance, port_id): raise exception.PortNotFound(port_id=port_id) -def fake_get_instance(self, context, intance_id): +def fake_get_instance(self, context, intance_id, want_objects=False): return {} diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index d4108c950131..a2ccbc843a2e 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -8410,10 +8410,8 @@ class ComputeAPITestCase(BaseTestCase): new_type = flavors.get_flavor_by_flavor_id('4') sys_meta = flavors.save_flavor_info({}, new_type) - instance = { - 'image_ref': 'foo', - 'system_metadata': sys_meta, - } + instance = instance_obj.Instance(image_ref='foo', + system_metadata=sys_meta) self.mox.StubOutWithMock(self.compute.network_api, 'allocate_port_for_instance') nwinfo = [fake_network_cache_model.new_vif()] @@ -8439,7 +8437,8 @@ class ComputeAPITestCase(BaseTestCase): self.stubs.Set(self.compute.network_api, 'deallocate_port_for_instance', lambda a, b, c: []) - self.compute.detach_interface(self.context, {}, port_id) + instance = instance_obj.Instance() + self.compute.detach_interface(self.context, instance, port_id) self.assertEqual(self.compute.driver._interfaces, {}) def test_attach_volume(self): diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 0486a5aa44a2..8b661a2aa990 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -120,7 +120,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_attach_interface(self): self._test_compute_api('attach_interface', 'call', instance=self.fake_instance, network_id='id', port_id='id2', - requested_ip='192.168.1.50') + version='3.17', requested_ip='192.168.1.50') # NOTE(russellb) Havana compat self.flags(compute='havana', group='upgrade_levels') @@ -205,7 +205,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_detach_interface(self): self._test_compute_api('detach_interface', 'cast', - instance=self.fake_instance, port_id='fake_id') + version='3.17', instance=self.fake_instance, port_id='fake_id') # NOTE(russellb) Havana compat self.flags(compute='havana', group='upgrade_levels') diff --git a/nova/virt/driver.py b/nova/virt/driver.py index cab77c2c7b13..71c948ebde22 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -413,11 +413,17 @@ class ComputeDriver(object): raise NotImplementedError() def attach_interface(self, instance, image_meta, vif): - """Attach an interface to the instance.""" + """Attach an interface to the instance. + + :param instance: nova.objects.instance.Instance + """ raise NotImplementedError() def detach_interface(self, instance, vif): - """Detach an interface from the instance.""" + """Detach an interface from the instance. + + :param instance: nova.objects.instance.Instance + """ raise NotImplementedError() def migrate_disk_and_power_off(self, context, instance, dest,