Remove 'scheduled_at' - DB cleanup
The 'scheduled_at' field is a part of the Nova instances. Currently, the 'scheduled_at' field is no longer updated by the Nova scheduler, instead the 'launched_at' field is updated for the same purpose. The 'scheduled_at' column is now redundant and should be removed as a part of DB clean up. Implements: blueprint cleanup-scheduled-at Change-Id: I66b55bbd4ad7c381e6a7203c22ac7c2d29e222f6
This commit is contained in:
parent
4a96b90623
commit
5e9df4baf9
@ -1581,7 +1581,7 @@ def _handle_objects_related_type_conversions(values):
|
|||||||
values[key] = str(values[key])
|
values[key] = str(values[key])
|
||||||
|
|
||||||
datetime_keys = ('created_at', 'deleted_at', 'updated_at',
|
datetime_keys = ('created_at', 'deleted_at', 'updated_at',
|
||||||
'launched_at', 'terminated_at', 'scheduled_at')
|
'launched_at', 'terminated_at')
|
||||||
convert_objects_related_datetimes(values, *datetime_keys)
|
convert_objects_related_datetimes(values, *datetime_keys)
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,7 +273,9 @@ class Instance(BASE, NovaBase):
|
|||||||
|
|
||||||
reservation_id = Column(String(255))
|
reservation_id = Column(String(255))
|
||||||
|
|
||||||
scheduled_at = Column(DateTime)
|
# NOTE(sbiswas7): 'scheduled_at' is still in the database
|
||||||
|
# and can be removed in the future release.
|
||||||
|
|
||||||
launched_at = Column(DateTime)
|
launched_at = Column(DateTime)
|
||||||
terminated_at = Column(DateTime)
|
terminated_at = Column(DateTime)
|
||||||
|
|
||||||
|
@ -158,6 +158,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||||||
|
|
||||||
'reservation_id': fields.StringField(nullable=True),
|
'reservation_id': fields.StringField(nullable=True),
|
||||||
|
|
||||||
|
# NOTE(sbiswas7): this field is depcrecated,
|
||||||
|
# will be removed in instance v2.0
|
||||||
'scheduled_at': fields.DateTimeField(nullable=True),
|
'scheduled_at': fields.DateTimeField(nullable=True),
|
||||||
'launched_at': fields.DateTimeField(nullable=True),
|
'launched_at': fields.DateTimeField(nullable=True),
|
||||||
'terminated_at': fields.DateTimeField(nullable=True),
|
'terminated_at': fields.DateTimeField(nullable=True),
|
||||||
@ -457,6 +459,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||||||
instance.deleted = db_inst['deleted'] == db_inst['id']
|
instance.deleted = db_inst['deleted'] == db_inst['id']
|
||||||
elif field == 'cleaned':
|
elif field == 'cleaned':
|
||||||
instance.cleaned = db_inst['cleaned'] == 1
|
instance.cleaned = db_inst['cleaned'] == 1
|
||||||
|
elif field == 'scheduled_at':
|
||||||
|
instance.scheduled_at = None
|
||||||
else:
|
else:
|
||||||
instance[field] = db_inst[field]
|
instance[field] = db_inst[field]
|
||||||
|
|
||||||
@ -569,6 +573,9 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||||||
updates = self.obj_get_changes()
|
updates = self.obj_get_changes()
|
||||||
expected_attrs = [attr for attr in INSTANCE_DEFAULT_FIELDS
|
expected_attrs = [attr for attr in INSTANCE_DEFAULT_FIELDS
|
||||||
if attr in updates]
|
if attr in updates]
|
||||||
|
if 'scheduled_at' in updates:
|
||||||
|
# NOTE(sbiswas7): 'scheduled_at' is not present in models.
|
||||||
|
del updates['scheduled_at']
|
||||||
if 'security_groups' in updates:
|
if 'security_groups' in updates:
|
||||||
updates['security_groups'] = [x.name for x in
|
updates['security_groups'] = [x.name for x in
|
||||||
updates['security_groups']]
|
updates['security_groups']]
|
||||||
@ -794,6 +801,10 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||||||
self._maybe_upgrade_flavor()
|
self._maybe_upgrade_flavor()
|
||||||
updates = {}
|
updates = {}
|
||||||
changes = self.obj_what_changed()
|
changes = self.obj_what_changed()
|
||||||
|
if 'scheduled_at' in changes:
|
||||||
|
# NOTE(sbiswas7): Since 'scheduled_at' is removed from models,
|
||||||
|
# we need to discard it.
|
||||||
|
changes.remove('scheduled_at')
|
||||||
|
|
||||||
for field in self.fields:
|
for field in self.fields:
|
||||||
# NOTE(danms): For object fields, we construct and call a
|
# NOTE(danms): For object fields, we construct and call a
|
||||||
@ -861,7 +872,6 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||||||
old_ref, inst_ref = db.instance_update_and_get_original(
|
old_ref, inst_ref = db.instance_update_and_get_original(
|
||||||
context, self.uuid, updates,
|
context, self.uuid, updates,
|
||||||
columns_to_join=_expected_cols(expected_attrs))
|
columns_to_join=_expected_cols(expected_attrs))
|
||||||
|
|
||||||
self._from_db_object(context, self, inst_ref,
|
self._from_db_object(context, self, inst_ref,
|
||||||
expected_attrs=expected_attrs)
|
expected_attrs=expected_attrs)
|
||||||
|
|
||||||
|
@ -108,7 +108,6 @@ def stub_instance(id, user_id='fake', project_id='fake', host=None,
|
|||||||
"user_data": "",
|
"user_data": "",
|
||||||
"reservation_id": reservation_id,
|
"reservation_id": reservation_id,
|
||||||
"mac_address": "",
|
"mac_address": "",
|
||||||
"scheduled_at": timeutils.utcnow(),
|
|
||||||
"launched_at": timeutils.utcnow(),
|
"launched_at": timeutils.utcnow(),
|
||||||
"terminated_at": timeutils.utcnow(),
|
"terminated_at": timeutils.utcnow(),
|
||||||
"availability_zone": "",
|
"availability_zone": "",
|
||||||
|
@ -543,7 +543,6 @@ def stub_instance(id=1, user_id=None, project_id=None, host=None,
|
|||||||
"user_data": user_data,
|
"user_data": user_data,
|
||||||
"reservation_id": reservation_id,
|
"reservation_id": reservation_id,
|
||||||
"mac_address": "",
|
"mac_address": "",
|
||||||
"scheduled_at": timeutils.utcnow(),
|
|
||||||
"launched_at": launched_at,
|
"launched_at": launched_at,
|
||||||
"terminated_at": terminated_at,
|
"terminated_at": terminated_at,
|
||||||
"availability_zone": availability_zone,
|
"availability_zone": availability_zone,
|
||||||
|
@ -329,7 +329,6 @@ class BaseTestCase(test.TestCase):
|
|||||||
'display_name': None,
|
'display_name': None,
|
||||||
'default_swap_device': None,
|
'default_swap_device': None,
|
||||||
'power_state': None,
|
'power_state': None,
|
||||||
'scheduled_at': None,
|
|
||||||
'access_ip_v6': None,
|
'access_ip_v6': None,
|
||||||
'access_ip_v4': None,
|
'access_ip_v4': None,
|
||||||
'key_name': None,
|
'key_name': None,
|
||||||
|
@ -1938,7 +1938,7 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
|||||||
'access_ip_v6': netaddr.IPAddress('::1'),
|
'access_ip_v6': netaddr.IPAddress('::1'),
|
||||||
}
|
}
|
||||||
dt_keys = ('created_at', 'deleted_at', 'updated_at',
|
dt_keys = ('created_at', 'deleted_at', 'updated_at',
|
||||||
'launched_at', 'terminated_at', 'scheduled_at')
|
'launched_at', 'terminated_at')
|
||||||
dt = timeutils.utcnow()
|
dt = timeutils.utcnow()
|
||||||
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
|
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
|
||||||
for key in dt_keys:
|
for key in dt_keys:
|
||||||
@ -1955,7 +1955,7 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
|||||||
'access_ip_v6': netaddr.IPAddress('::1'),
|
'access_ip_v6': netaddr.IPAddress('::1'),
|
||||||
}
|
}
|
||||||
dt_keys = ('created_at', 'deleted_at', 'updated_at',
|
dt_keys = ('created_at', 'deleted_at', 'updated_at',
|
||||||
'launched_at', 'terminated_at', 'scheduled_at')
|
'launched_at', 'terminated_at')
|
||||||
dt = timeutils.utcnow()
|
dt = timeutils.utcnow()
|
||||||
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
|
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
|
||||||
for key in dt_keys:
|
for key in dt_keys:
|
||||||
|
@ -766,6 +766,22 @@ class NovaMigrationsCheckers(test_migrations.ModelsMigrationsSync,
|
|||||||
# the point-of-view of unit tests, since they use SQLite
|
# the point-of-view of unit tests, since they use SQLite
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def filter_metadata_diff(self, diff):
|
||||||
|
# Overriding the parent method to decide on certain attributes
|
||||||
|
# that maybe present in the DB but not in the models.py
|
||||||
|
# Define a whitelist of columns that would be removed from the
|
||||||
|
# DB at a later release.
|
||||||
|
column_whitelist = {'instances': ['scheduled_at']}
|
||||||
|
for element in diff:
|
||||||
|
# Assuming that the diff structure will remain constant
|
||||||
|
# The 4th element in the diff is always the Column object
|
||||||
|
for key, values in column_whitelist.iteritems():
|
||||||
|
table_name = element[3].table.name
|
||||||
|
table_column = element[3].name
|
||||||
|
if key == table_name and table_column in values:
|
||||||
|
diff.remove(element)
|
||||||
|
return diff
|
||||||
|
|
||||||
|
|
||||||
class TestNovaMigrationsSQLite(NovaMigrationsCheckers,
|
class TestNovaMigrationsSQLite(NovaMigrationsCheckers,
|
||||||
test_base.DbTestCase,
|
test_base.DbTestCase,
|
||||||
|
@ -52,7 +52,6 @@ class _TestInstanceObject(object):
|
|||||||
access_ip_v6='::1')
|
access_ip_v6='::1')
|
||||||
db_inst['uuid'] = '34fd7606-2ed5-42c7-ad46-76240c088801'
|
db_inst['uuid'] = '34fd7606-2ed5-42c7-ad46-76240c088801'
|
||||||
db_inst['cell_name'] = 'api!child'
|
db_inst['cell_name'] = 'api!child'
|
||||||
db_inst['scheduled_at'] = None
|
|
||||||
db_inst['terminated_at'] = None
|
db_inst['terminated_at'] = None
|
||||||
db_inst['deleted_at'] = None
|
db_inst['deleted_at'] = None
|
||||||
db_inst['created_at'] = None
|
db_inst['created_at'] = None
|
||||||
@ -425,6 +424,17 @@ class _TestInstanceObject(object):
|
|||||||
inst.save()
|
inst.save()
|
||||||
self.assertTrue(save_mock.called)
|
self.assertTrue(save_mock.called)
|
||||||
|
|
||||||
|
@mock.patch('nova.db.instance_update_and_get_original')
|
||||||
|
@mock.patch.object(objects.Instance, '_from_db_object')
|
||||||
|
def test_save_skip_scheduled_at(self, mock_fdo, mock_update):
|
||||||
|
mock_update.return_value = None, None
|
||||||
|
inst = instance.Instance(context=self.context, id=123)
|
||||||
|
inst.uuid = 'foo'
|
||||||
|
inst.scheduled_at = None
|
||||||
|
inst.save()
|
||||||
|
self.assertNotIn('scheduled_at',
|
||||||
|
mock_update.call_args_list[0][0][2])
|
||||||
|
|
||||||
@mock.patch('nova.db.instance_update_and_get_original')
|
@mock.patch('nova.db.instance_update_and_get_original')
|
||||||
@mock.patch.object(objects.Instance, '_from_db_object')
|
@mock.patch.object(objects.Instance, '_from_db_object')
|
||||||
def test_save_does_not_refresh_pci_devices(self, mock_fdo, mock_update):
|
def test_save_does_not_refresh_pci_devices(self, mock_fdo, mock_update):
|
||||||
@ -823,6 +833,22 @@ class _TestInstanceObject(object):
|
|||||||
inst.obj_reset_changes()
|
inst.obj_reset_changes()
|
||||||
self.assertEqual(set(), inst.obj_what_changed())
|
self.assertEqual(set(), inst.obj_what_changed())
|
||||||
|
|
||||||
|
def test_create_skip_scheduled_at(self):
|
||||||
|
self.mox.StubOutWithMock(db, 'instance_create')
|
||||||
|
vals = {'host': 'foo-host',
|
||||||
|
'memory_mb': 128,
|
||||||
|
'system_metadata': {'foo': 'bar'},
|
||||||
|
'extra': {}}
|
||||||
|
fake_inst = fake_instance.fake_db_instance(**vals)
|
||||||
|
db.instance_create(self.context, vals).AndReturn(fake_inst)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
inst = instance.Instance(context=self.context,
|
||||||
|
host='foo-host', memory_mb=128,
|
||||||
|
scheduled_at=None,
|
||||||
|
system_metadata={'foo': 'bar'})
|
||||||
|
inst.create()
|
||||||
|
self.assertEqual(inst.host, 'foo-host')
|
||||||
|
|
||||||
def test_metadata_change_tracking(self):
|
def test_metadata_change_tracking(self):
|
||||||
self._test_metadata_change_tracking('metadata')
|
self._test_metadata_change_tracking('metadata')
|
||||||
|
|
||||||
@ -1412,7 +1438,6 @@ class _TestInstanceListObject(object):
|
|||||||
db_inst = fake_instance.fake_db_instance(id=2,
|
db_inst = fake_instance.fake_db_instance(id=2,
|
||||||
access_ip_v4='1.2.3.4',
|
access_ip_v4='1.2.3.4',
|
||||||
access_ip_v6='::1')
|
access_ip_v6='::1')
|
||||||
db_inst['scheduled_at'] = None
|
|
||||||
db_inst['terminated_at'] = None
|
db_inst['terminated_at'] = None
|
||||||
db_inst['deleted_at'] = None
|
db_inst['deleted_at'] = None
|
||||||
db_inst['created_at'] = None
|
db_inst['created_at'] = None
|
||||||
|
Loading…
Reference in New Issue
Block a user