Add migration progress detail in DB

Add migration progress detail : memory_total,memory_processed,
memory_remaining,disk_total,disk_processed,disk_remaining
into migration DB.

Partially implements blueprint live-migration-progress-report
Co-Authored-By: ShaoHe Feng <shaohe.feng@intel.com>

Change-Id: Iea97d5d3b003fa42dd41cc923d6e026c67a14485
This commit is contained in:
yuntongjin 2015-12-17 12:45:28 +08:00 committed by ShaoHe Feng
parent 9d615b7eec
commit 2e48a60d82
9 changed files with 101 additions and 2 deletions

View File

@ -31,6 +31,10 @@ def output(migrations_obj):
From a MigrationsList's object this method returns a list of
primitive objects with the only necessary fields.
"""
detail_keys = ['memory_total', 'memory_processed', 'memory_remaining',
'disk_total', 'disk_processed', 'disk_remaining']
# Note(Shaohe Feng): We need to leverage the oslo.versionedobjects.
# Then we can pass the target version to it's obj_to_primitive.
objects = obj_base.obj_to_primitive(migrations_obj)
objects = [x for x in objects if not x['hidden']]
for obj in objects:
@ -38,6 +42,10 @@ def output(migrations_obj):
del obj['deleted_at']
del obj['migration_type']
del obj['hidden']
if 'memory_total' in obj:
for key in detail_keys:
del obj[key]
return objects

View File

@ -29,6 +29,10 @@ def output(migrations_obj):
From a MigrationsList's object this method returns a list of
primitive objects with the only necessary fields.
"""
detail_keys = ['memory_total', 'memory_processed', 'memory_remaining',
'disk_total', 'disk_processed', 'disk_remaining']
# Note(Shaohe Feng): We need to leverage the oslo.versionedobjects.
# Then we can pass the target version to it's obj_to_primitive.
objects = obj_base.obj_to_primitive(migrations_obj)
objects = [x for x in objects if not x['hidden']]
for obj in objects:
@ -36,6 +40,10 @@ def output(migrations_obj):
del obj['deleted_at']
del obj['migration_type']
del obj['hidden']
if 'memory_total' in obj:
for key in detail_keys:
del obj[key]
return objects

View File

@ -0,0 +1,30 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sqlalchemy import BigInteger
from sqlalchemy import Column
from sqlalchemy import MetaData
from sqlalchemy import Table
def upgrade(migrate_engine):
meta = MetaData(bind=migrate_engine)
migrations = Table('migrations', meta, autoload=True)
shadow_migrations = Table('shadow_migrations', meta, autoload=True)
columns = ['memory_total', 'memory_processed', 'memory_remaining',
'disk_total', 'disk_processed', 'disk_remaining']
for column_name in columns:
column = Column(column_name, BigInteger, nullable=True)
migrations.create_column(column)
shadow_migrations.create_column(column.copy())

View File

@ -751,6 +751,12 @@ class Migration(BASE, NovaBase, models.SoftDeleteMixin):
'evacuation'),
nullable=True)
hidden = Column(Boolean, default=False)
memory_total = Column(BigInteger, nullable=True)
memory_processed = Column(BigInteger, nullable=True)
memory_remaining = Column(BigInteger, nullable=True)
disk_total = Column(BigInteger, nullable=True)
disk_processed = Column(BigInteger, nullable=True)
disk_remaining = Column(BigInteger, nullable=True)
instance = orm.relationship("Instance", foreign_keys=instance_uuid,
primaryjoin='and_(Migration.instance_uuid == '

View File

@ -36,7 +36,8 @@ class Migration(base.NovaPersistentObject, base.NovaObject,
# Version 1.1: String attributes updated to support unicode
# Version 1.2: Added migration_type and hidden
# Version 1.3: Added get_by_id_and_instance()
VERSION = '1.3'
# Version 1.4: Added migration progress detail
VERSION = '1.4'
fields = {
'id': fields.IntegerField(),
@ -53,6 +54,12 @@ class Migration(base.NovaPersistentObject, base.NovaObject,
'live-migration', 'evacuation'],
nullable=False),
'hidden': fields.BooleanField(nullable=False, default=False),
'memory_total': fields.IntegerField(nullable=True),
'memory_processed': fields.IntegerField(nullable=True),
'memory_remaining': fields.IntegerField(nullable=True),
'disk_total': fields.IntegerField(nullable=True),
'disk_processed': fields.IntegerField(nullable=True),
'disk_remaining': fields.IntegerField(nullable=True),
}
@staticmethod
@ -74,6 +81,14 @@ class Migration(base.NovaPersistentObject, base.NovaObject,
if 'migration_type' in primitive:
del primitive['migration_type']
del primitive['hidden']
if target_version < (1, 4):
if 'memory_total' in primitive:
del primitive['memory_total']
del primitive['memory_processed']
del primitive['memory_remaining']
del primitive['disk_total']
del primitive['disk_processed']
del primitive['disk_remaining']
def obj_load_attr(self, attrname):
if attrname == 'migration_type':

View File

@ -41,6 +41,12 @@ fake_migrations = [
'new_instance_type_id': 2,
'migration_type': 'resize',
'hidden': False,
'memory_total': 123456,
'memory_processed': 12345,
'memory_remaining': 120000,
'disk_total': 234567,
'disk_processed': 23456,
'disk_remaining': 230000,
'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'deleted_at': None,
@ -59,6 +65,12 @@ fake_migrations = [
'new_instance_type_id': 6,
'migration_type': 'resize',
'hidden': False,
'memory_total': 456789,
'memory_processed': 56789,
'memory_remaining': 45000,
'disk_total': 96789,
'disk_processed': 6789,
'disk_remaining': 96000,
'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'deleted_at': None,

View File

@ -833,6 +833,20 @@ class NovaMigrationsCheckers(test_migrations.ModelsMigrationsSync,
'allocations_resource_provider_class_id_idx',
['resource_provider_id', 'resource_class_id'])
def _check_315(self, engine, data):
self.assertColumnExists(engine, 'migrations',
'memory_total')
self.assertColumnExists(engine, 'migrations',
'memory_processed')
self.assertColumnExists(engine, 'migrations',
'memory_remaining')
self.assertColumnExists(engine, 'migrations',
'disk_total')
self.assertColumnExists(engine, 'migrations',
'disk_processed')
self.assertColumnExists(engine, 'migrations',
'disk_remaining')
class TestNovaMigrationsSQLite(NovaMigrationsCheckers,
test_base.DbTestCase,

View File

@ -46,6 +46,12 @@ def fake_db_migration(**updates):
'status': 'migrating',
'migration_type': 'resize',
'hidden': False,
'memory_total': 123456,
'memory_processed': 12345,
'memory_remaining': 120000,
'disk_total': 234567,
'disk_processed': 23456,
'disk_remaining': 230000,
}
if updates:

View File

@ -1147,7 +1147,7 @@ object_data = {
'LibvirtLiveMigrateData': '1.1-4ecf40aae7fee7bb37fc3b2123e760de',
'KeyPair': '1.3-bfaa2a8b148cdf11e0c72435d9dd097a',
'KeyPairList': '1.2-58b94f96e776bedaf1e192ddb2a24c4e',
'Migration': '1.3-c245057c22d505a4e6462ab95fa27166',
'Migration': '1.4-17979b9f2ae7f28d97043a220b2a8350',
'MigrationContext': '1.0-d8c2f10069e410f639c49082b5932c92',
'MigrationList': '1.2-02c0ec0c50b75ca86a2a74c5e8c911cc',
'MonitorMetric': '1.1-53b1db7c4ae2c531db79761e7acc52ba',