Avoid circular reference during serialization
When an instance with numa topology is re-scheduled the conductor
migrate task blows with circular reference during request spec
serialization. It happens because there are ovos in the request spec
that jsonutils.dumps only serialize if requested explicitly.
This patch makes the explicit request.
This is a stable only bug fix as the borken code was removed in Stein by
the feature patch I4244f7dd8fe74565180f73684678027067b4506e
Closes-Bug: #1864665
Change-Id: I1942bfa9bd1baf8738d34c287216db7b59000a36
(cherry picked from commit 3871b38fe0
)
This commit is contained in:
parent
78e53bd388
commit
54ca5d9afb
|
@ -9,6 +9,7 @@
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
import functools
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
|
@ -288,7 +289,17 @@ class MigrationTask(base.TaskBase):
|
||||||
# oslo.messaging #1529084 to transform datetime values into strings.
|
# oslo.messaging #1529084 to transform datetime values into strings.
|
||||||
# tl;dr: datetimes in dicts are not accepted as correct values by the
|
# tl;dr: datetimes in dicts are not accepted as correct values by the
|
||||||
# rpc fake driver.
|
# rpc fake driver.
|
||||||
legacy_spec = jsonutils.loads(jsonutils.dumps(legacy_spec))
|
# NOTE(gibi): convert_instances=True is needed as the legacy_spec might
|
||||||
|
# contain ovo instances in the numa_topology field and those are
|
||||||
|
# causing circular reference during serialization otherwise.
|
||||||
|
legacy_spec = jsonutils.loads(
|
||||||
|
jsonutils.dumps(
|
||||||
|
legacy_spec,
|
||||||
|
default=functools.partial(
|
||||||
|
jsonutils.to_primitive, convert_instances=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
LOG.debug("Calling prep_resize with selected host: %s; "
|
LOG.debug("Calling prep_resize with selected host: %s; "
|
||||||
"Selected node: %s; Alternates: %s", host, node,
|
"Selected node: %s; Alternates: %s", host, node,
|
||||||
|
|
|
@ -10,8 +10,11 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import functools
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
from nova.compute import rpcapi as compute_rpcapi
|
from nova.compute import rpcapi as compute_rpcapi
|
||||||
from nova.conductor.tasks import migrate
|
from nova.conductor.tasks import migrate
|
||||||
from nova import context
|
from nova import context
|
||||||
|
@ -115,7 +118,14 @@ class MigrationTaskTestCase(test.NoDBTestCase):
|
||||||
self.request_spec.requested_destination)
|
self.request_spec.requested_destination)
|
||||||
|
|
||||||
task = self._generate_task()
|
task = self._generate_task()
|
||||||
legacy_request_spec = self.request_spec.to_legacy_request_spec_dict()
|
legacy_request_spec = jsonutils.loads(
|
||||||
|
jsonutils.dumps(
|
||||||
|
self.request_spec.to_legacy_request_spec_dict(),
|
||||||
|
default=functools.partial(
|
||||||
|
jsonutils.to_primitive, convert_instances=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
gmv_mock.return_value = 23
|
gmv_mock.return_value = 23
|
||||||
|
|
||||||
# We just need this hook point to set a uuid on the
|
# We just need this hook point to set a uuid on the
|
||||||
|
@ -218,6 +228,18 @@ class MigrationTaskTestCase(test.NoDBTestCase):
|
||||||
task.instance, task._migration,
|
task.instance, task._migration,
|
||||||
task._held_allocations)
|
task._held_allocations)
|
||||||
|
|
||||||
|
def test_execute_with_cpu_topoloy(self):
|
||||||
|
self.request_spec = objects.RequestSpec(
|
||||||
|
numa_topology=objects.InstanceNUMATopology(
|
||||||
|
cells=[
|
||||||
|
objects.InstanceNUMACell(
|
||||||
|
cpu_topology=objects.VirtCPUTopology()
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self._test_execute()
|
||||||
|
|
||||||
|
|
||||||
class MigrationTaskAllocationUtils(test.NoDBTestCase):
|
class MigrationTaskAllocationUtils(test.NoDBTestCase):
|
||||||
@mock.patch('nova.objects.ComputeNode.get_by_host_and_nodename')
|
@mock.patch('nova.objects.ComputeNode.get_by_host_and_nodename')
|
||||||
|
|
Loading…
Reference in New Issue