Fixed and improved the way instance "states" are set. Instead of relying on solely the power_state of a VM, there are now explicitly defined VM states and VM task states which respectively define the current state of the VM and the task which is currently being performed by the VM.

This commit is contained in:
Brian Lamar
2011-08-31 22:55:34 +00:00
committed by Tarmac
3 changed files with 35 additions and 23 deletions

View File

@@ -38,6 +38,7 @@ from nova import test
from nova import utils from nova import utils
from nova.api.ec2 import cloud from nova.api.ec2 import cloud
from nova.api.ec2 import ec2utils from nova.api.ec2 import ec2utils
from nova.compute import vm_states
from nova.image import fake from nova.image import fake
@@ -1161,7 +1162,7 @@ class CloudTestCase(test.TestCase):
self.compute = self.start_service('compute') self.compute = self.start_service('compute')
def _wait_for_state(self, ctxt, instance_id, predicate): def _wait_for_state(self, ctxt, instance_id, predicate):
"""Wait for an stopping instance to be a given state""" """Wait for a stopped instance to be a given state"""
id = ec2utils.ec2_id_to_id(instance_id) id = ec2utils.ec2_id_to_id(instance_id)
while True: while True:
info = self.cloud.compute_api.get(context=ctxt, instance_id=id) info = self.cloud.compute_api.get(context=ctxt, instance_id=id)
@@ -1172,12 +1173,16 @@ class CloudTestCase(test.TestCase):
def _wait_for_running(self, instance_id): def _wait_for_running(self, instance_id):
def is_running(info): def is_running(info):
return info['state_description'] == 'running' vm_state = info["vm_state"]
task_state = info["task_state"]
return vm_state == vm_states.ACTIVE and task_state == None
self._wait_for_state(self.context, instance_id, is_running) self._wait_for_state(self.context, instance_id, is_running)
def _wait_for_stopped(self, instance_id): def _wait_for_stopped(self, instance_id):
def is_stopped(info): def is_stopped(info):
return info['state_description'] == 'stopped' vm_state = info["vm_state"]
task_state = info["task_state"]
return vm_state == vm_states.STOPPED and task_state == None
self._wait_for_state(self.context, instance_id, is_stopped) self._wait_for_state(self.context, instance_id, is_stopped)
def _wait_for_terminate(self, instance_id): def _wait_for_terminate(self, instance_id):
@@ -1560,7 +1565,7 @@ class CloudTestCase(test.TestCase):
'id': 0, 'id': 0,
'root_device_name': '/dev/sdh', 'root_device_name': '/dev/sdh',
'security_groups': [{'name': 'fake0'}, {'name': 'fake1'}], 'security_groups': [{'name': 'fake0'}, {'name': 'fake1'}],
'state_description': 'stopping', 'vm_state': vm_states.STOPPED,
'instance_type': {'name': 'fake_type'}, 'instance_type': {'name': 'fake_type'},
'kernel_id': 1, 'kernel_id': 1,
'ramdisk_id': 2, 'ramdisk_id': 2,
@@ -1604,7 +1609,7 @@ class CloudTestCase(test.TestCase):
self.assertEqual(groupSet, expected_groupSet) self.assertEqual(groupSet, expected_groupSet)
self.assertEqual(get_attribute('instanceInitiatedShutdownBehavior'), self.assertEqual(get_attribute('instanceInitiatedShutdownBehavior'),
{'instance_id': 'i-12345678', {'instance_id': 'i-12345678',
'instanceInitiatedShutdownBehavior': 'stop'}) 'instanceInitiatedShutdownBehavior': 'stopped'})
self.assertEqual(get_attribute('instanceType'), self.assertEqual(get_attribute('instanceType'),
{'instance_id': 'i-12345678', {'instance_id': 'i-12345678',
'instanceType': 'fake_type'}) 'instanceType': 'fake_type'})

View File

@@ -24,6 +24,7 @@ from nova import compute
from nova.compute import instance_types from nova.compute import instance_types
from nova.compute import manager as compute_manager from nova.compute import manager as compute_manager
from nova.compute import power_state from nova.compute import power_state
from nova.compute import vm_states
from nova import context from nova import context
from nova import db from nova import db
from nova.db.sqlalchemy import models from nova.db.sqlalchemy import models
@@ -763,8 +764,8 @@ class ComputeTestCase(test.TestCase):
'block_migration': False, 'block_migration': False,
'disk': None}}).\ 'disk': None}}).\
AndRaise(rpc.RemoteError('', '', '')) AndRaise(rpc.RemoteError('', '', ''))
dbmock.instance_update(c, i_ref['id'], {'state_description': 'running', dbmock.instance_update(c, i_ref['id'], {'vm_state': vm_states.ACTIVE,
'state': power_state.RUNNING, 'task_state': None,
'host': i_ref['host']}) 'host': i_ref['host']})
for v in i_ref['volumes']: for v in i_ref['volumes']:
dbmock.volume_update(c, v['id'], {'status': 'in-use'}) dbmock.volume_update(c, v['id'], {'status': 'in-use'})
@@ -795,8 +796,8 @@ class ComputeTestCase(test.TestCase):
'block_migration': False, 'block_migration': False,
'disk': None}}).\ 'disk': None}}).\
AndRaise(rpc.RemoteError('', '', '')) AndRaise(rpc.RemoteError('', '', ''))
dbmock.instance_update(c, i_ref['id'], {'state_description': 'running', dbmock.instance_update(c, i_ref['id'], {'vm_state': vm_states.ACTIVE,
'state': power_state.RUNNING, 'task_state': None,
'host': i_ref['host']}) 'host': i_ref['host']})
self.compute.db = dbmock self.compute.db = dbmock
@@ -841,8 +842,8 @@ class ComputeTestCase(test.TestCase):
c = context.get_admin_context() c = context.get_admin_context()
instance_id = self._create_instance() instance_id = self._create_instance()
i_ref = db.instance_get(c, instance_id) i_ref = db.instance_get(c, instance_id)
db.instance_update(c, i_ref['id'], {'state_description': 'migrating', db.instance_update(c, i_ref['id'], {'vm_state': vm_states.MIGRATING,
'state': power_state.PAUSED}) 'power_state': power_state.PAUSED})
v_ref = db.volume_create(c, {'size': 1, 'instance_id': instance_id}) v_ref = db.volume_create(c, {'size': 1, 'instance_id': instance_id})
fix_addr = db.fixed_ip_create(c, {'address': '1.1.1.1', fix_addr = db.fixed_ip_create(c, {'address': '1.1.1.1',
'instance_id': instance_id}) 'instance_id': instance_id})
@@ -903,7 +904,7 @@ class ComputeTestCase(test.TestCase):
instances = db.instance_get_all(context.get_admin_context()) instances = db.instance_get_all(context.get_admin_context())
LOG.info(_("After force-killing instances: %s"), instances) LOG.info(_("After force-killing instances: %s"), instances)
self.assertEqual(len(instances), 1) self.assertEqual(len(instances), 1)
self.assertEqual(power_state.SHUTOFF, instances[0]['state']) self.assertEqual(power_state.NOSTATE, instances[0]['power_state'])
def test_get_all_by_name_regexp(self): def test_get_all_by_name_regexp(self):
"""Test searching instances by name (display_name)""" """Test searching instances by name (display_name)"""
@@ -1323,25 +1324,28 @@ class ComputeTestCase(test.TestCase):
"""Test searching instances by state""" """Test searching instances by state"""
c = context.get_admin_context() c = context.get_admin_context()
instance_id1 = self._create_instance({'state': power_state.SHUTDOWN}) instance_id1 = self._create_instance({
'power_state': power_state.SHUTDOWN,
})
instance_id2 = self._create_instance({ instance_id2 = self._create_instance({
'id': 2, 'id': 2,
'state': power_state.RUNNING}) 'power_state': power_state.RUNNING,
})
instance_id3 = self._create_instance({ instance_id3 = self._create_instance({
'id': 10, 'id': 10,
'state': power_state.RUNNING}) 'power_state': power_state.RUNNING,
})
instances = self.compute_api.get_all(c, instances = self.compute_api.get_all(c,
search_opts={'state': power_state.SUSPENDED}) search_opts={'power_state': power_state.SUSPENDED})
self.assertEqual(len(instances), 0) self.assertEqual(len(instances), 0)
instances = self.compute_api.get_all(c, instances = self.compute_api.get_all(c,
search_opts={'state': power_state.SHUTDOWN}) search_opts={'power_state': power_state.SHUTDOWN})
self.assertEqual(len(instances), 1) self.assertEqual(len(instances), 1)
self.assertEqual(instances[0].id, instance_id1) self.assertEqual(instances[0].id, instance_id1)
instances = self.compute_api.get_all(c, instances = self.compute_api.get_all(c,
search_opts={'state': power_state.RUNNING}) search_opts={'power_state': power_state.RUNNING})
self.assertEqual(len(instances), 2) self.assertEqual(len(instances), 2)
instance_ids = [instance.id for instance in instances] instance_ids = [instance.id for instance in instances]
self.assertTrue(instance_id2 in instance_ids) self.assertTrue(instance_id2 in instance_ids)
@@ -1349,7 +1353,7 @@ class ComputeTestCase(test.TestCase):
# Test passing a list as search arg # Test passing a list as search arg
instances = self.compute_api.get_all(c, instances = self.compute_api.get_all(c,
search_opts={'state': [power_state.SHUTDOWN, search_opts={'power_state': [power_state.SHUTDOWN,
power_state.RUNNING]}) power_state.RUNNING]})
self.assertEqual(len(instances), 3) self.assertEqual(len(instances), 3)

View File

@@ -23,6 +23,8 @@ import time
from nova import db from nova import db
from nova import utils from nova import utils
from nova.compute import task_states
from nova.compute import vm_states
def stub_out_db_instance_api(stubs): def stub_out_db_instance_api(stubs):
@@ -64,7 +66,8 @@ def stub_out_db_instance_api(stubs):
'image_ref': values['image_ref'], 'image_ref': values['image_ref'],
'kernel_id': values['kernel_id'], 'kernel_id': values['kernel_id'],
'ramdisk_id': values['ramdisk_id'], 'ramdisk_id': values['ramdisk_id'],
'state_description': 'scheduling', 'vm_state': vm_states.BUILDING,
'task_state': task_states.SCHEDULING,
'user_id': values['user_id'], 'user_id': values['user_id'],
'project_id': values['project_id'], 'project_id': values['project_id'],
'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),