Merge "Add online migration to store keypairs with instances"

This commit is contained in:
Jenkins 2016-05-13 20:17:03 +00:00 committed by Gerrit Code Review
commit a4113da58b
3 changed files with 80 additions and 1 deletions

View File

@ -81,6 +81,7 @@ from nova import exception
from nova.i18n import _ from nova.i18n import _
from nova import objects from nova import objects
from nova.objects import flavor as flavor_obj from nova.objects import flavor as flavor_obj
from nova.objects import instance as instance_obj
from nova import quota from nova import quota
from nova import rpc from nova import rpc
from nova import utils from nova import utils
@ -725,6 +726,7 @@ class DbCommands(object):
db.aggregate_uuids_online_data_migration, db.aggregate_uuids_online_data_migration,
flavor_obj.migrate_flavors, flavor_obj.migrate_flavors,
flavor_obj.migrate_flavor_reset_autoincrement, flavor_obj.migrate_flavor_reset_autoincrement,
instance_obj.migrate_instance_keypairs,
) )
def __init__(self): def __init__(self):

View File

@ -20,13 +20,16 @@ from oslo_log import log as logging
from oslo_serialization import jsonutils from oslo_serialization import jsonutils
from oslo_utils import timeutils from oslo_utils import timeutils
from oslo_utils import versionutils from oslo_utils import versionutils
from sqlalchemy.orm import joinedload
from nova.cells import opts as cells_opts from nova.cells import opts as cells_opts
from nova.cells import rpcapi as cells_rpcapi from nova.cells import rpcapi as cells_rpcapi
from nova.cells import utils as cells_utils from nova.cells import utils as cells_utils
from nova import db from nova import db
from nova.db.sqlalchemy import api as db_api
from nova.db.sqlalchemy import models
from nova import exception from nova import exception
from nova.i18n import _LE from nova.i18n import _LE, _LW
from nova import notifications from nova import notifications
from nova import objects from nova import objects
from nova.objects import base from nova.objects import base
@ -1260,3 +1263,38 @@ class InstanceList(base.ObjectListBase, base.NovaObject):
instance.obj_reset_changes(['fault']) instance.obj_reset_changes(['fault'])
return faults_by_uuid.keys() return faults_by_uuid.keys()
@db_api.main_context_manager.writer
def _migrate_instance_keypairs(ctxt, count):
db_extras = ctxt.session.query(models.InstanceExtra).\
options(joinedload('instance')).\
filter_by(keypairs=None).\
filter_by(deleted=0).\
limit(count).\
all()
count_all = len(db_extras)
count_hit = 0
for db_extra in db_extras:
key_name = db_extra.instance.key_name
keypairs = objects.KeyPairList(objects=[])
if key_name:
try:
key = objects.KeyPair.get_by_name(ctxt,
db_extra.instance.user_id,
key_name)
keypairs.objects.append(key)
except exception.KeypairNotFound:
LOG.warning(
_LW('Instance %(uuid)s keypair %(keyname)s not found'),
{'uuid': db_extra.instance_uuid, 'keyname': key_name})
db_extra.keypairs = jsonutils.dumps(keypairs.obj_to_primitive())
db_extra.save(ctxt.session)
count_hit += 1
return count_all, count_hit
def migrate_instance_keypairs(ctxt, count):
return _migrate_instance_keypairs(ctxt, count)

View File

@ -23,6 +23,7 @@ from oslo_utils import timeutils
from nova.cells import rpcapi as cells_rpcapi from nova.cells import rpcapi as cells_rpcapi
from nova.compute import flavors from nova.compute import flavors
from nova import context
from nova import db from nova import db
from nova import exception from nova import exception
from nova.network import model as network_model from nova.network import model as network_model
@ -1731,3 +1732,41 @@ class TestInstanceObjectMisc(test.TestCase):
self.assertEqual(['metadata', 'extra', 'extra.numa_topology'], self.assertEqual(['metadata', 'extra', 'extra.numa_topology'],
instance._expected_cols(['metadata', instance._expected_cols(['metadata',
'numa_topology'])) 'numa_topology']))
def test_migrate_instance_keypairs(self):
ctxt = context.RequestContext('foo', 'bar')
key = objects.KeyPair(context=ctxt,
user_id=ctxt.user_id,
name='testkey',
public_key='keydata',
type='ssh')
key.create()
inst1 = objects.Instance(context=ctxt,
user_id=ctxt.user_id,
project_id=ctxt.project_id,
key_name='testkey')
inst1.create()
inst2 = objects.Instance(context=ctxt,
user_id=ctxt.user_id,
project_id=ctxt.project_id,
key_name='testkey',
keypairs=objects.KeyPairList(
objects=[key]))
inst2.create()
inst3 = objects.Instance(context=ctxt,
user_id=ctxt.user_id,
project_id=ctxt.project_id,
key_name='missingkey')
inst3.create()
hit, done = instance.migrate_instance_keypairs(ctxt, 10)
self.assertEqual(2, hit)
self.assertEqual(2, done)
db_extra = db.instance_extra_get_by_instance_uuid(
ctxt, inst1.uuid, ['keypairs'])
self.assertIsNotNone(db_extra.keypairs)
db_extra = db.instance_extra_get_by_instance_uuid(
ctxt, inst3.uuid, ['keypairs'])
obj = base.NovaObject.obj_from_primitive(
jsonutils.loads(db_extra['keypairs']))
self.assertEqual([], obj.objects)