Comment 3 for bug 1262566

Revision history for this message
Sean Dague (sdague) wrote :

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.