diff options
| author | Justin Santa Barbara <justin@fathomdb.com> | 2011-03-23 19:00:25 -0700 |
|---|---|---|
| committer | Justin Santa Barbara <justin@fathomdb.com> | 2011-03-23 19:00:25 -0700 |
| commit | 21f3fc7cecb4c2f0657bb6bc78098910dca2e6b7 (patch) | |
| tree | 96bada7d30eb2325f56328f54dcc0da9ad07ac12 /nova/compute | |
| parent | 3c295817f91eb7c76a64d157ff4a938c85075a36 (diff) | |
| parent | 0759158d08f3f98456ae094fd9d94d36b98216a5 (diff) | |
Merged with lp:nova, fixed conflicts
Diffstat (limited to 'nova/compute')
| -rw-r--r-- | nova/compute/api.py | 42 | ||||
| -rw-r--r-- | nova/compute/manager.py | 70 |
2 files changed, 89 insertions, 23 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index 32577af82..01eead4ac 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -253,6 +253,16 @@ class API(base.Base): return [dict(x.iteritems()) for x in instances] + def has_finished_migration(self, context, instance_id): + """Retrieves whether or not a finished migration exists for + an instance""" + try: + db.migration_get_by_instance_and_status(context, instance_id, + 'finished') + return True + except exception.NotFound: + return False + def ensure_default_security_group(self, context): """ Create security group for the security context if it does not already exist @@ -464,6 +474,8 @@ class API(base.Base): params = {'migration_id': migration_ref['id']} self._cast_compute_message('revert_resize', context, instance_id, migration_ref['dest_compute'], params=params) + self.db.migration_update(context, migration_ref['id'], + {'status': 'reverted'}) def confirm_resize(self, context, instance_id): """Confirms a migration/resize, deleting the 'old' instance in the @@ -479,17 +491,41 @@ class API(base.Base): self._cast_compute_message('confirm_resize', context, instance_id, migration_ref['source_compute'], params=params) - self.db.migration_update(context, migration_id, + self.db.migration_update(context, migration_ref['id'], {'status': 'confirmed'}) self.db.instance_update(context, instance_id, {'host': migration_ref['dest_compute'], }) - def resize(self, context, instance_id, flavor): + def resize(self, context, instance_id, flavor_id): """Resize a running instance.""" + instance = self.db.instance_get(context, instance_id) + current_instance_type = self.db.instance_type_get_by_name( + context, instance['instance_type']) + + new_instance_type = self.db.instance_type_get_by_flavor_id( + context, flavor_id) + current_instance_type_name = current_instance_type['name'] + new_instance_type_name = new_instance_type['name'] + LOG.debug(_("Old instance type %(current_instance_type_name)s, " + " new instance type %(new_instance_type_name)s") % locals()) + if not new_instance_type: + raise exception.ApiError(_("Requested flavor %(flavor_id)d " + "does not exist") % locals()) + + current_memory_mb = current_instance_type['memory_mb'] + new_memory_mb = new_instance_type['memory_mb'] + if current_memory_mb > new_memory_mb: + raise exception.ApiError(_("Invalid flavor: cannot downsize" + "instances")) + if current_memory_mb == new_memory_mb: + raise exception.ApiError(_("Invalid flavor: cannot use" + "the same flavor. ")) + self._cast_scheduler_message(context, {"method": "prep_resize", "args": {"topic": FLAGS.compute_topic, - "instance_id": instance_id, }},) + "instance_id": instance_id, + "flavor_id": flavor_id}}) def pause(self, context, instance_id): """Pause the given instance.""" diff --git a/nova/compute/manager.py b/nova/compute/manager.py index b67b27dd0..052db5ac6 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -441,26 +441,41 @@ class ComputeManager(manager.Manager): instance_ref = self.db.instance_get(context, instance_id) migration_ref = self.db.migration_get(context, migration_id) - #TODO(mdietz): we may want to split these into separate methods. - if migration_ref['source_compute'] == FLAGS.host: - #NOTE(justinsb): Naughty calling of internal method - self.driver._start(instance_ref) - self.db.migration_update(context, migration_id, - {'status': 'reverted'}) - else: - self.driver.destroy(instance_ref) - topic = self.db.queue_get_for(context, FLAGS.compute_topic, - instance_ref['host']) - rpc.cast(context, topic, - {'method': 'revert_resize', - 'args': { - 'migration_id': migration_ref['id'], - 'instance_id': instance_id, }, - }) + self.driver.destroy(instance_ref) + topic = self.db.queue_get_for(context, FLAGS.compute_topic, + instance_ref['host']) + rpc.cast(context, topic, + {'method': 'finish_revert_resize', + 'args': { + 'migration_id': migration_ref['id'], + 'instance_id': instance_id, }, + }) + + @exception.wrap_exception + @checks_instance_lock + def finish_revert_resize(self, context, instance_id, migration_id): + """Finishes the second half of reverting a resize, powering back on + the source instance and reverting the resized attributes in the + database""" + instance_ref = self.db.instance_get(context, instance_id) + migration_ref = self.db.migration_get(context, migration_id) + instance_type = self.db.instance_type_get_by_flavor_id(context, + migration_ref['old_flavor_id']) + + # Just roll back the record. There's no need to resize down since + # the 'old' VM already has the preferred attributes + self.db.instance_update(context, instance_id, + dict(memory_mb=instance_type['memory_mb'], + vcpus=instance_type['vcpus'], + local_gb=instance_type['local_gb'])) + + self.driver.revert_resize(instance_ref) + self.db.migration_update(context, migration_id, + {'status': 'reverted'}) @exception.wrap_exception @checks_instance_lock - def prep_resize(self, context, instance_id): + def prep_resize(self, context, instance_id, flavor_id): """Initiates the process of moving a running instance to another host, possibly changing the RAM and disk size in the process""" context = context.elevated() @@ -469,12 +484,17 @@ class ComputeManager(manager.Manager): raise exception.Error(_( 'Migration error: destination same as source!')) + instance_type = self.db.instance_type_get_by_flavor_id(context, + flavor_id) migration_ref = self.db.migration_create(context, {'instance_id': instance_id, 'source_compute': instance_ref['host'], 'dest_compute': FLAGS.host, 'dest_host': self.driver.get_host_ip_addr(), + 'old_flavor_id': instance_type['flavorid'], + 'new_flavor_id': flavor_id, 'status': 'pre-migrating'}) + LOG.audit(_('instance %s: migrating to '), instance_id, context=context) topic = self.db.queue_get_for(context, FLAGS.compute_topic, @@ -500,8 +520,6 @@ class ComputeManager(manager.Manager): self.db.migration_update(context, migration_id, {'status': 'post-migrating', }) - #TODO(mdietz): This is where we would update the VM record - #after resizing service = self.db.service_get_by_host_and_topic(context, migration_ref['dest_compute'], FLAGS.compute_topic) topic = self.db.queue_get_for(context, FLAGS.compute_topic, @@ -522,7 +540,19 @@ class ComputeManager(manager.Manager): migration_ref = self.db.migration_get(context, migration_id) instance_ref = self.db.instance_get(context, migration_ref['instance_id']) - + # TODO(mdietz): apply the rest of the instance_type attributes going + # after they're supported + instance_type = self.db.instance_type_get_by_flavor_id(context, + migration_ref['new_flavor_id']) + self.db.instance_update(context, instance_id, + dict(instance_type=instance_type['name'], + memory_mb=instance_type['memory_mb'], + vcpus=instance_type['vcpus'], + local_gb=instance_type['local_gb'])) + + # reload the updated instance ref + # FIXME(mdietz): is there reload functionality? + instance_ref = self.db.instance_get(context, instance_id) self.driver.finish_resize(instance_ref, disk_info) self.db.migration_update(context, migration_id, |
