Comment 2 for bug 1862635

Revision history for this message
Gorka Eguileor (gorka) wrote :

This is the traceback from the paste:

   File "C:\Program Files\Cloudbase Solutions\OpenStack\Cinder\Python\lib\site-packages\cinder\backup\manager.py", line 840, in export_record
     backup_url = backup.encode_record(driver_info=driver_info)
   File "C:\Program Files\Cloudbase Solutions\OpenStack\Cinder\Python\lib\site-packages\cinder\objects\backup.py", line 215, in encode_record
     for name, field in self.fields.items()}
   File "C:\Program Files\Cloudbase Solutions\OpenStack\Cinder\Python\lib\site-packages\cinder\objects\backup.py", line 215, in <dictcomp>
     for name, field in self.fields.items()}
   File "C:\Program Files\Cloudbase Solutions\OpenStack\Cinder\Python\lib\site-packages\oslo_versionedobjects\base.py", line 67, in getter
     self.obj_load_attr(name)
   File "C:\Program Files\Cloudbase Solutions\OpenStack\Cinder\Python\lib\site-packages\cinder\objects\backup.py", line 155, in obj_load_attr
     reason=_('attribute %s not lazy-loadable') % attrname)
oslo_versionedobjects.exception.ObjectActionError: Object action obj_load_attr failed because: attribute parent not lazy-loadable

Looking at the traceback, and the Backup OVO code it seems like we have 2 problems:
- We don't support lazy loading the parent
- We try to serialize the parent

Solution:
- Add 'parent' to OPTIONAL_FIELDS
      OPTIONAL_FIELDS = ('metadata', 'parent')

- Add support to lazy load the parent in `obj_load_attr`
    def obj_load_attr(self, attrname):
        if attrname not in self.OPTIONAL_FIELDS:
            raise exception.ObjectActionError(
                action='obj_load_attr',
                reason=_('attribute %s not lazy-loadable') % attrname)
        if not self._context:
            raise exception.OrphanedObjectError(method='obj_load_attr',
                                                objtype=self.obj_name())
        if attrname == 'parent':
            if self.parent_id:
                self.parent = self.get_by_id(self._context, self.parent_id)
            else:
                self.parent = None
        self.obj_reset_changes(fields=[attrname])

- Exclude the 'parent' in the dict comprehension in `encode_record`
        record = {name: field.to_primitive(self, name, getattr(self, name))
                  for name, field in self.fields.items()
                  if name != 'parent'}
  Here we could code this to check the field is not an `ObjectField` instead of checking the name.