Confirmed this issue in the code. The crux of the problem is as follows:
After listing the security groups, we call a list comprehension to format it (https://github.com/openstack/nova/blob/master/nova/api/openstack/compute/contrib/security_groups.py#L292-L293)
with translate_exceptions(): project_id = context.project_id raw_groups = self.security_group_api.list(context, project=project_id, search_opts=search_opts)
limited_list = common.limited(raw_groups, req) result = [self._format_security_group(context, group) for group in limited_list]
The _format call goes through and indirection then gets to:
def _format_security_group_rule(self, context, rule): sg_rule = {} sg_rule['id'] = rule['id'] sg_rule['parent_group_id'] = rule['parent_group_id'] sg_rule['ip_protocol'] = rule['protocol'] sg_rule['from_port'] = rule['from_port'] sg_rule['to_port'] = rule['to_port'] sg_rule['group'] = {} sg_rule['ip_range'] = {} if rule['group_id']: with translate_exceptions(): source_group = self.security_group_api.get(context, id=rule['group_id']) sg_rule['group'] = {'name': source_group.get('name'), 'tenant_id': source_group.get('project_id')} else: sg_rule['ip_range'] = {'cidr': rule['cidr']} return sg_rule
The security_group_api.get means we've got another trip to the db (for every rule), and any one of those could fail with the sg having been deleted in the time allotted.
Confirmed this issue in the code. The crux of the problem is as follows:
After listing the security groups, we call a list comprehension to format it (https:/ /github. com/openstack/ nova/blob/ master/ nova/api/ openstack/ compute/ contrib/ security_ groups. py#L292- L293)
with translate_ exceptions( ):
project_ id = context.project_id
raw_ groups = self.security_ group_api. list(context,
project= project_ id,
search_ opts=search_ opts)
result = [self._
The _format call goes through and indirection then gets to:
def _format_ security_ group_rule( self, context, rule):
sg_rule[ 'id'] = rule['id']
sg_rule[ 'parent_ group_id' ] = rule['parent_ group_id' ]
sg_rule[ 'ip_protocol' ] = rule['protocol']
sg_rule[ 'from_port' ] = rule['from_port']
sg_rule[ 'to_port' ] = rule['to_port']
sg_rule[ 'group' ] = {}
sg_rule[ 'ip_range' ] = {} exceptions( ):
source_ group = self.security_ group_api. get(context,
id=rule[ 'group_ id'])
sg_ rule['group' ] = {'name': source_ group.get( 'name') ,
'tenant_ id': source_ group.get( 'project_ id')}
sg_ rule['ip_ range'] = {'cidr': rule['cidr']}
sg_rule = {}
if rule['group_id']:
with translate_
else:
return sg_rule
The security_ group_api. get means we've got another trip to the db (for every rule), and any one of those could fail with the sg having been deleted in the time allotted.