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:
Sudipta Biswas 2015-08-03 16:58:15 +05:30
parent 4a96b90623
commit 5e9df4baf9
9 changed files with 60 additions and 10 deletions

View File

@ -1581,7 +1581,7 @@ def _handle_objects_related_type_conversions(values):
values[key] = str(values[key])
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)

View File

@ -273,7 +273,9 @@ class Instance(BASE, NovaBase):
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)
terminated_at = Column(DateTime)

View File

@ -158,6 +158,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
'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),
'launched_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']
elif field == 'cleaned':
instance.cleaned = db_inst['cleaned'] == 1
elif field == 'scheduled_at':
instance.scheduled_at = None
else:
instance[field] = db_inst[field]
@ -569,6 +573,9 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
updates = self.obj_get_changes()
expected_attrs = [attr for attr in INSTANCE_DEFAULT_FIELDS
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:
updates['security_groups'] = [x.name for x in
updates['security_groups']]
@ -794,6 +801,10 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
self._maybe_upgrade_flavor()
updates = {}
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:
# 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(
context, self.uuid, updates,
columns_to_join=_expected_cols(expected_attrs))
self._from_db_object(context, self, inst_ref,
expected_attrs=expected_attrs)

View File

@ -108,7 +108,6 @@ def stub_instance(id, user_id='fake', project_id='fake', host=None,
"user_data": "",
"reservation_id": reservation_id,
"mac_address": "",
"scheduled_at": timeutils.utcnow(),
"launched_at": timeutils.utcnow(),
"terminated_at": timeutils.utcnow(),
"availability_zone": "",

View File

@ -543,7 +543,6 @@ def stub_instance(id=1, user_id=None, project_id=None, host=None,
"user_data": user_data,
"reservation_id": reservation_id,
"mac_address": "",
"scheduled_at": timeutils.utcnow(),
"launched_at": launched_at,
"terminated_at": terminated_at,
"availability_zone": availability_zone,

View File

@ -329,7 +329,6 @@ class BaseTestCase(test.TestCase):
'display_name': None,
'default_swap_device': None,
'power_state': None,
'scheduled_at': None,
'access_ip_v6': None,
'access_ip_v4': None,
'key_name': None,

View File

@ -1938,7 +1938,7 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
'access_ip_v6': netaddr.IPAddress('::1'),
}
dt_keys = ('created_at', 'deleted_at', 'updated_at',
'launched_at', 'terminated_at', 'scheduled_at')
'launched_at', 'terminated_at')
dt = timeutils.utcnow()
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
for key in dt_keys:
@ -1955,7 +1955,7 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
'access_ip_v6': netaddr.IPAddress('::1'),
}
dt_keys = ('created_at', 'deleted_at', 'updated_at',
'launched_at', 'terminated_at', 'scheduled_at')
'launched_at', 'terminated_at')
dt = timeutils.utcnow()
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
for key in dt_keys:

View File

@ -766,6 +766,22 @@ class NovaMigrationsCheckers(test_migrations.ModelsMigrationsSync,
# the point-of-view of unit tests, since they use SQLite
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,
test_base.DbTestCase,

View File

@ -52,7 +52,6 @@ class _TestInstanceObject(object):
access_ip_v6='::1')
db_inst['uuid'] = '34fd7606-2ed5-42c7-ad46-76240c088801'
db_inst['cell_name'] = 'api!child'
db_inst['scheduled_at'] = None
db_inst['terminated_at'] = None
db_inst['deleted_at'] = None
db_inst['created_at'] = None
@ -425,6 +424,17 @@ class _TestInstanceObject(object):
inst.save()
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.object(objects.Instance, '_from_db_object')
def test_save_does_not_refresh_pci_devices(self, mock_fdo, mock_update):
@ -823,6 +833,22 @@ class _TestInstanceObject(object):
inst.obj_reset_changes()
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):
self._test_metadata_change_tracking('metadata')
@ -1412,7 +1438,6 @@ class _TestInstanceListObject(object):
db_inst = fake_instance.fake_db_instance(id=2,
access_ip_v4='1.2.3.4',
access_ip_v6='::1')
db_inst['scheduled_at'] = None
db_inst['terminated_at'] = None
db_inst['deleted_at'] = None
db_inst['created_at'] = None