diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 0cdd5f5320ac..d07d41c3f02b 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2638,9 +2638,16 @@ def _instance_extra_create(context, values): def instance_extra_update_by_uuid(context, instance_uuid, values): - return model_query(context, models.InstanceExtra).\ + rows_updated = model_query(context, models.InstanceExtra).\ filter_by(instance_uuid=instance_uuid).\ update(values) + if not rows_updated: + LOG.debug("Created instance_extra for %s" % instance_uuid) + create_values = copy.copy(values) + create_values["instance_uuid"] = instance_uuid + _instance_extra_create(context, create_values) + rows_updated = 1 + return rows_updated def instance_extra_get_by_instance_uuid(context, instance_uuid, diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index 7aeebc41a8a5..08a472f5b730 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -2737,6 +2737,21 @@ class InstanceExtraTestCase(test.TestCase): self.ctxt, self.instance['uuid']) self.assertEqual('changed', inst_extra.numa_topology) + def test_instance_extra_update_by_uuid_and_create(self): + sqlalchemy_api.model_query(self.ctxt, models.InstanceExtra).\ + filter_by(instance_uuid=self.instance['uuid']).\ + delete() + inst_extra = db.instance_extra_get_by_instance_uuid( + self.ctxt, self.instance['uuid']) + self.assertIsNone(inst_extra) + + db.instance_extra_update_by_uuid(self.ctxt, self.instance['uuid'], + {'numa_topology': 'changed'}) + + inst_extra = db.instance_extra_get_by_instance_uuid( + self.ctxt, self.instance['uuid']) + self.assertEqual('changed', inst_extra.numa_topology) + def test_instance_extra_get_with_columns(self): extra = db.instance_extra_get_by_instance_uuid( self.ctxt, self.instance['uuid'],