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:
@@ -61,7 +61,7 @@ class ApiError(Error):
|
||||
super(ApiError, self).__init__(outstr)
|
||||
|
||||
|
||||
class BuildInProgress(Error):
|
||||
class RebuildRequiresActiveInstance(Error):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ from nova import log as logging
|
||||
from nova import rpc
|
||||
from nova import utils
|
||||
from nova.compute import power_state
|
||||
from nova.compute import vm_states
|
||||
from nova.api.ec2 import ec2utils
|
||||
|
||||
|
||||
@@ -104,10 +105,8 @@ class Scheduler(object):
|
||||
dest, block_migration)
|
||||
|
||||
# Changing instance_state.
|
||||
db.instance_set_state(context,
|
||||
instance_id,
|
||||
power_state.PAUSED,
|
||||
'migrating')
|
||||
values = {"vm_state": vm_states.MIGRATING}
|
||||
db.instance_update(context, instance_id, values)
|
||||
|
||||
# Changing volume state
|
||||
for volume_ref in instance_ref['volumes']:
|
||||
@@ -129,8 +128,7 @@ class Scheduler(object):
|
||||
"""
|
||||
|
||||
# Checking instance is running.
|
||||
if (power_state.RUNNING != instance_ref['state'] or \
|
||||
'running' != instance_ref['state_description']):
|
||||
if instance_ref['power_state'] != power_state.RUNNING:
|
||||
instance_id = ec2utils.id_to_ec2_id(instance_ref['id'])
|
||||
raise exception.InstanceNotRunning(instance_id=instance_id)
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ from nova.scheduler import driver
|
||||
from nova.scheduler import manager
|
||||
from nova.scheduler import multi
|
||||
from nova.compute import power_state
|
||||
from nova.compute import vm_states
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
@@ -94,6 +95,9 @@ class SchedulerTestCase(test.TestCase):
|
||||
inst['vcpus'] = kwargs.get('vcpus', 1)
|
||||
inst['memory_mb'] = kwargs.get('memory_mb', 10)
|
||||
inst['local_gb'] = kwargs.get('local_gb', 20)
|
||||
inst['vm_state'] = kwargs.get('vm_state', vm_states.ACTIVE)
|
||||
inst['power_state'] = kwargs.get('power_state', power_state.RUNNING)
|
||||
inst['task_state'] = kwargs.get('task_state', None)
|
||||
return db.instance_create(ctxt, inst)
|
||||
|
||||
def test_fallback(self):
|
||||
@@ -271,8 +275,9 @@ class SimpleDriverTestCase(test.TestCase):
|
||||
inst['memory_mb'] = kwargs.get('memory_mb', 20)
|
||||
inst['local_gb'] = kwargs.get('local_gb', 30)
|
||||
inst['launched_on'] = kwargs.get('launghed_on', 'dummy')
|
||||
inst['state_description'] = kwargs.get('state_description', 'running')
|
||||
inst['state'] = kwargs.get('state', power_state.RUNNING)
|
||||
inst['vm_state'] = kwargs.get('vm_state', vm_states.ACTIVE)
|
||||
inst['task_state'] = kwargs.get('task_state', None)
|
||||
inst['power_state'] = kwargs.get('power_state', power_state.RUNNING)
|
||||
return db.instance_create(self.context, inst)['id']
|
||||
|
||||
def _create_volume(self):
|
||||
@@ -664,14 +669,14 @@ class SimpleDriverTestCase(test.TestCase):
|
||||
block_migration=False)
|
||||
|
||||
i_ref = db.instance_get(self.context, instance_id)
|
||||
self.assertTrue(i_ref['state_description'] == 'migrating')
|
||||
self.assertTrue(i_ref['vm_state'] == vm_states.MIGRATING)
|
||||
db.instance_destroy(self.context, instance_id)
|
||||
db.volume_destroy(self.context, v_ref['id'])
|
||||
|
||||
def test_live_migration_src_check_instance_not_running(self):
|
||||
"""The instance given by instance_id is not running."""
|
||||
|
||||
instance_id = self._create_instance(state_description='migrating')
|
||||
instance_id = self._create_instance(power_state=power_state.NOSTATE)
|
||||
i_ref = db.instance_get(self.context, instance_id)
|
||||
|
||||
try:
|
||||
|
||||
@@ -38,6 +38,7 @@ from nova import test
|
||||
from nova import utils
|
||||
from nova.api.ec2 import cloud
|
||||
from nova.api.ec2 import ec2utils
|
||||
from nova.compute import vm_states
|
||||
from nova.image import fake
|
||||
|
||||
|
||||
@@ -1161,7 +1162,7 @@ class CloudTestCase(test.TestCase):
|
||||
self.compute = self.start_service('compute')
|
||||
|
||||
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)
|
||||
while True:
|
||||
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 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)
|
||||
|
||||
def _wait_for_stopped(self, instance_id):
|
||||
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)
|
||||
|
||||
def _wait_for_terminate(self, instance_id):
|
||||
@@ -1560,7 +1565,7 @@ class CloudTestCase(test.TestCase):
|
||||
'id': 0,
|
||||
'root_device_name': '/dev/sdh',
|
||||
'security_groups': [{'name': 'fake0'}, {'name': 'fake1'}],
|
||||
'state_description': 'stopping',
|
||||
'vm_state': vm_states.STOPPED,
|
||||
'instance_type': {'name': 'fake_type'},
|
||||
'kernel_id': 1,
|
||||
'ramdisk_id': 2,
|
||||
@@ -1604,7 +1609,7 @@ class CloudTestCase(test.TestCase):
|
||||
self.assertEqual(groupSet, expected_groupSet)
|
||||
self.assertEqual(get_attribute('instanceInitiatedShutdownBehavior'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'instanceInitiatedShutdownBehavior': 'stop'})
|
||||
'instanceInitiatedShutdownBehavior': 'stopped'})
|
||||
self.assertEqual(get_attribute('instanceType'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'instanceType': 'fake_type'})
|
||||
|
||||
@@ -24,6 +24,7 @@ from nova import compute
|
||||
from nova.compute import instance_types
|
||||
from nova.compute import manager as compute_manager
|
||||
from nova.compute import power_state
|
||||
from nova.compute import vm_states
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova.db.sqlalchemy import models
|
||||
@@ -763,8 +764,8 @@ class ComputeTestCase(test.TestCase):
|
||||
'block_migration': False,
|
||||
'disk': None}}).\
|
||||
AndRaise(rpc.RemoteError('', '', ''))
|
||||
dbmock.instance_update(c, i_ref['id'], {'state_description': 'running',
|
||||
'state': power_state.RUNNING,
|
||||
dbmock.instance_update(c, i_ref['id'], {'vm_state': vm_states.ACTIVE,
|
||||
'task_state': None,
|
||||
'host': i_ref['host']})
|
||||
for v in i_ref['volumes']:
|
||||
dbmock.volume_update(c, v['id'], {'status': 'in-use'})
|
||||
@@ -795,8 +796,8 @@ class ComputeTestCase(test.TestCase):
|
||||
'block_migration': False,
|
||||
'disk': None}}).\
|
||||
AndRaise(rpc.RemoteError('', '', ''))
|
||||
dbmock.instance_update(c, i_ref['id'], {'state_description': 'running',
|
||||
'state': power_state.RUNNING,
|
||||
dbmock.instance_update(c, i_ref['id'], {'vm_state': vm_states.ACTIVE,
|
||||
'task_state': None,
|
||||
'host': i_ref['host']})
|
||||
|
||||
self.compute.db = dbmock
|
||||
@@ -841,8 +842,8 @@ class ComputeTestCase(test.TestCase):
|
||||
c = context.get_admin_context()
|
||||
instance_id = self._create_instance()
|
||||
i_ref = db.instance_get(c, instance_id)
|
||||
db.instance_update(c, i_ref['id'], {'state_description': 'migrating',
|
||||
'state': power_state.PAUSED})
|
||||
db.instance_update(c, i_ref['id'], {'vm_state': vm_states.MIGRATING,
|
||||
'power_state': power_state.PAUSED})
|
||||
v_ref = db.volume_create(c, {'size': 1, 'instance_id': instance_id})
|
||||
fix_addr = db.fixed_ip_create(c, {'address': '1.1.1.1',
|
||||
'instance_id': instance_id})
|
||||
@@ -903,7 +904,7 @@ class ComputeTestCase(test.TestCase):
|
||||
instances = db.instance_get_all(context.get_admin_context())
|
||||
LOG.info(_("After force-killing instances: %s"), instances)
|
||||
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):
|
||||
"""Test searching instances by name (display_name)"""
|
||||
@@ -1323,25 +1324,28 @@ class ComputeTestCase(test.TestCase):
|
||||
"""Test searching instances by state"""
|
||||
|
||||
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({
|
||||
'id': 2,
|
||||
'state': power_state.RUNNING})
|
||||
'power_state': power_state.RUNNING,
|
||||
})
|
||||
instance_id3 = self._create_instance({
|
||||
'id': 10,
|
||||
'state': power_state.RUNNING})
|
||||
|
||||
'power_state': power_state.RUNNING,
|
||||
})
|
||||
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)
|
||||
|
||||
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(instances[0].id, instance_id1)
|
||||
|
||||
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)
|
||||
instance_ids = [instance.id for instance in instances]
|
||||
self.assertTrue(instance_id2 in instance_ids)
|
||||
@@ -1349,7 +1353,7 @@ class ComputeTestCase(test.TestCase):
|
||||
|
||||
# Test passing a list as search arg
|
||||
instances = self.compute_api.get_all(c,
|
||||
search_opts={'state': [power_state.SHUTDOWN,
|
||||
search_opts={'power_state': [power_state.SHUTDOWN,
|
||||
power_state.RUNNING]})
|
||||
self.assertEqual(len(instances), 3)
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import time
|
||||
|
||||
from nova import db
|
||||
from nova import utils
|
||||
from nova.compute import task_states
|
||||
from nova.compute import vm_states
|
||||
|
||||
|
||||
def stub_out_db_instance_api(stubs):
|
||||
@@ -64,7 +66,8 @@ def stub_out_db_instance_api(stubs):
|
||||
'image_ref': values['image_ref'],
|
||||
'kernel_id': values['kernel_id'],
|
||||
'ramdisk_id': values['ramdisk_id'],
|
||||
'state_description': 'scheduling',
|
||||
'vm_state': vm_states.BUILDING,
|
||||
'task_state': task_states.SCHEDULING,
|
||||
'user_id': values['user_id'],
|
||||
'project_id': values['project_id'],
|
||||
'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
|
||||
|
||||
Reference in New Issue
Block a user