summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Young <sleepsonthefloor@gmail.com>2011-01-27 22:51:36 -0800
committerAnthony Young <sleepsonthefloor@gmail.com>2011-01-27 22:51:36 -0800
commit7b34f59ef8d2f6a752dcd94be3f5d14f0f93d3b2 (patch)
tree5a9ffd06faa572e29640129472e43553593d72bf
parent2a64ccb8139eb30aab394391cf137d4cb83ce55e (diff)
fixes for bug #709057
-rw-r--r--nova/db/sqlalchemy/api.py6
-rw-r--r--nova/db/sqlalchemy/models.py6
-rw-r--r--nova/tests/test_compute.py58
3 files changed, 61 insertions, 9 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 895e7eabe..50c4b2189 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -672,6 +672,9 @@ def instance_destroy(context, instance_id):
with session.begin():
instance_ref = instance_get(context, instance_id, session=session)
instance_ref.delete(session=session)
+ session.execute('update security_group_instance_association'
+ ' set deleted=1 where instance_id=:id',
+ {'id': instance_id})
@require_context
@@ -1583,6 +1586,9 @@ def security_group_destroy(context, security_group_id):
# TODO(vish): do we have to use sql here?
session.execute('update security_groups set deleted=1 where id=:id',
{'id': security_group_id})
+ session.execute('update security_group_instance_association'
+ ' set deleted=1 where security_group_id=:id',
+ {'id': security_group_id})
session.execute('update security_group_rules set deleted=1 '
'where group_id=:id',
{'id': security_group_id})
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index c54ebe3ba..1399e29ad 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -311,10 +311,14 @@ class SecurityGroup(BASE, NovaBase):
secondary="security_group_instance_association",
primaryjoin='and_('
'SecurityGroup.id == '
- 'SecurityGroupInstanceAssociation.security_group_id,'
+ 'SecurityGroupInstanceAssociation.security_group_id,'
+ 'SecurityGroupInstanceAssociation.deleted == False,'
'SecurityGroup.deleted == False)',
secondaryjoin='and_('
'SecurityGroupInstanceAssociation.instance_id == Instance.id,'
+ # (anthony) the condition below shouldn't be necessary now that the
+ # association is being marked as deleted. However, removing this
+ # may cause existing deployments to choke, so I'm leaving it
'Instance.deleted == False)',
backref='security_groups')
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 09f6ee94a..ad2ac8375 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -49,7 +49,7 @@ class ComputeTestCase(test.TestCase):
self.manager = manager.AuthManager()
self.user = self.manager.create_user('fake', 'fake', 'fake')
self.project = self.manager.create_project('fake', 'fake', 'fake')
- self.context = context.get_admin_context()
+ self.context = context.RequestContext('fake', 'fake', False)
def tearDown(self):
self.manager.delete_user(self.user)
@@ -69,6 +69,13 @@ class ComputeTestCase(test.TestCase):
inst['ami_launch_index'] = 0
return db.instance_create(self.context, inst)['id']
+ def _create_group(self):
+ values = {'name': 'testgroup',
+ 'description': 'testgroup',
+ 'user_id': self.user.id,
+ 'project_id': self.project.id}
+ return db.security_group_create(self.context, values)
+
def test_create_instance_defaults_display_name(self):
"""Verify that an instance cannot be created without a display_name."""
cases = [dict(), dict(display_name=None)]
@@ -82,23 +89,58 @@ class ComputeTestCase(test.TestCase):
def test_create_instance_associates_security_groups(self):
"""Make sure create associates security groups"""
- values = {'name': 'default',
- 'description': 'default',
- 'user_id': self.user.id,
- 'project_id': self.project.id}
- group = db.security_group_create(self.context, values)
+ group = self._create_group()
ref = self.compute_api.create(
self.context,
instance_type=FLAGS.default_instance_type,
image_id=None,
- security_group=['default'])
+ security_group=['testgroup'])
try:
self.assertEqual(len(db.security_group_get_by_instance(
- self.context, ref[0]['id'])), 1)
+ self.context, ref[0]['id'])), 1)
+ group = db.security_group_get(self.context, group['id'])
+ self.assert_(len(group.instances) == 1)
finally:
db.security_group_destroy(self.context, group['id'])
db.instance_destroy(self.context, ref[0]['id'])
+ def test_destroy_instance_disassociates_security_groups(self):
+ """Make sure destroying disassociates security groups"""
+ group = self._create_group()
+
+ ref = self.compute_api.create(
+ self.context,
+ instance_type=FLAGS.default_instance_type,
+ image_id=None,
+ security_group=['testgroup'])
+ try:
+ db.instance_destroy(self.context, ref[0]['id'])
+ instance = db.instance_get(context.get_admin_context(
+ read_deleted=True), ref[0]['id'])
+
+ group = db.security_group_get(self.context, group['id'])
+ self.assert_(len(group.instances) == 0)
+ finally:
+ db.security_group_destroy(self.context, group['id'])
+
+ def test_destroy_security_group_disassociates_instances(self):
+ """Make sure destroying security groups disassociates instances"""
+ group = self._create_group()
+
+ ref = self.compute_api.create(
+ self.context,
+ instance_type=FLAGS.default_instance_type,
+ image_id=None,
+ security_group=['testgroup'])
+
+ try:
+ db.security_group_destroy(self.context, group['id'])
+ group = db.security_group_get(context.get_admin_context(
+ read_deleted=True), group['id'])
+ self.assert_(len(group.instances) == 0)
+ finally:
+ db.instance_destroy(self.context, ref[0]['id'])
+
def test_run_terminate(self):
"""Make sure it is possible to run and terminate instance"""
instance_id = self._create_instance()