Comment 4 for bug 1798917

Revision history for this message
Corey Bryant (corey.bryant) wrote : Re: Cinder backup of a volume is in error state with fail_reason: data must be bytes

After looking into this some more I think the current approach of utf-8 encoding in VolumeMetadataBackup.set() prior to the write and utf-8 decoding in VolumeMetadataBackup.get() after the read makes sense. More details:

On the way in json_meta is a json-encoded dict containing all metadata is actually set to in the calls to VolumeMetadataBackup.set(json_meta):
1) In CephBackupDriver._backup_metadata(), 'json_meta = self.get_metadata' is set before calling VolumeMetadataBackup.set(json_meta)
2) CephBackupDriver inherits from driver.BackupDriver (from cinder.backup import driver)
3) In cinder/backup/driver.py, class BackupDriver has get_metadata which calls BackupMetadataAPI.get.
4) BackupMetadataAPI.get() gets the volume metadata, returning jsonutils.dumps(container), a json-encoded dict containing all metadata [1].

And on the way back out from VolumeMetadataBackup.get(json_meta):
1) CephBackupDriver._restore_metadata() calls VolumeMetadataBackup.get() to read the object from ceph.
2) The result (meta) is then sent to self.put_metadata(volume_id, meta), from driver.BackupDriver.
3) put_metadata() calls BackupMetadataAPI.put()
4) BackupMetadataAPI.put() restores volume metadata to a volume, using jsonutils.loads(json_metadata) to decode the encoded dict.

jsonutils.dumps() is from oslo.serialization (oslo_serialization/jsonutils.py) and serialize an obj to a JSON formatted str. jsonutils.loads() deserializes the JSON formatted str back to an obj [1]

[1] For example:
>>> from oslo_serialization import jsonutils
>>> container = {'version': 1}
>>> jsonutils.dumps(container) # on the way in
'{"version": 1}'
>>> jsonutils.loads(jsonutils.dumps(container)) # on the way out
{'version': 1}