mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 11:00:25 +00:00
rbd: move image metadata key migration to its own function
The new MigrateMetadata() function can be used to get the metadata of an image with a deprecated and new key. Renaming metadata keys can be done easily this way. A default value will be set in the image metadata when it is missing completely. But if the deprecated key was set, the data is stored under the new key and the deprecated key is removed. Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
parent
6691951453
commit
607129171d
@ -1593,6 +1593,56 @@ func (ri *rbdImage) SetMetadata(key, value string) error {
|
|||||||
return image.SetMetadata(key, value)
|
return image.SetMetadata(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveMetadata deletes the key and data from the metadata of the image.
|
||||||
|
func (ri *rbdImage) RemoveMetadata(key string) error {
|
||||||
|
image, err := ri.open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer image.Close()
|
||||||
|
|
||||||
|
return image.RemoveMetadata(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MigrateMetadata reads the metadata contents from oldKey and stores it in
|
||||||
|
// newKey. In case oldKey was not set, the defaultValue is stored in newKey.
|
||||||
|
// Once done, oldKey will be removed as well.
|
||||||
|
func (ri *rbdImage) MigrateMetadata(oldKey, newKey, defaultValue string) (string, error) {
|
||||||
|
value, err := ri.GetMetadata(newKey)
|
||||||
|
if err == nil {
|
||||||
|
return value, nil
|
||||||
|
} else if !errors.Is(err, librbd.ErrNotFound) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// migrate contents from oldKey to newKey
|
||||||
|
removeOldKey := true
|
||||||
|
value, err = ri.GetMetadata(oldKey)
|
||||||
|
if errors.Is(err, librbd.ErrNotFound) {
|
||||||
|
// in case oldKey was not set, set newKey to defaultValue
|
||||||
|
value = defaultValue
|
||||||
|
removeOldKey = false
|
||||||
|
} else if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// newKey was not set, set it now to prevent regular error cases for missing metadata
|
||||||
|
err = ri.SetMetadata(newKey, value)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// the newKey was set with data from oldKey, oldKey is not needed anymore
|
||||||
|
if removeOldKey {
|
||||||
|
err = ri.RemoveMetadata(oldKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
// setThickProvisioned records in the image metadata that it has been
|
// setThickProvisioned records in the image metadata that it has been
|
||||||
// thick-provisioned.
|
// thick-provisioned.
|
||||||
func (ri *rbdImage) setThickProvisioned() error {
|
func (ri *rbdImage) setThickProvisioned() error {
|
||||||
@ -1604,40 +1654,11 @@ func (ri *rbdImage) setThickProvisioned() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setThinProvisioned records in the image metadata that it has been
|
|
||||||
// thin-provisioned.
|
|
||||||
func (ri *rbdImage) setThinProvisioned() error {
|
|
||||||
err := ri.SetMetadata(thickProvisionMetaKey, thinProvisionMetaData)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to set metadata %q for %q: %w", thinProvisionMetaData, ri, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// isThickProvisioned checks in the image metadata if the image has been marked
|
// isThickProvisioned checks in the image metadata if the image has been marked
|
||||||
// as thick-provisioned. This can be used while expanding the image, so that
|
// as thick-provisioned. This can be used while expanding the image, so that
|
||||||
// the expansion can be allocated too.
|
// the expansion can be allocated too.
|
||||||
func (ri *rbdImage) isThickProvisioned() (bool, error) {
|
func (ri *rbdImage) isThickProvisioned() (bool, error) {
|
||||||
value, err := ri.GetMetadata(thickProvisionMetaKey)
|
value, err := ri.MigrateMetadata(deprecatedthickProvisionMetaKey, thickProvisionMetaKey, thinProvisionMetaData)
|
||||||
if errors.Is(err, librbd.ErrNotFound) {
|
|
||||||
// check if the image is having deprecated metadata key.
|
|
||||||
value, err = ri.GetMetadata(deprecatedthickProvisionMetaKey)
|
|
||||||
if errors.Is(err, librbd.ErrNotFound) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
// If we reach here means the image has deprecated metakey set. Set the
|
|
||||||
// new metakey so that we dont need to check for deprecated key again.
|
|
||||||
if value == thickProvisionMetaData {
|
|
||||||
err = ri.setThickProvisioned()
|
|
||||||
} else {
|
|
||||||
value = thinProvisionMetaData
|
|
||||||
// If we reach here means the image is thin provisioned. Set thin
|
|
||||||
// provisioned metadata on the image so that we dont need to check
|
|
||||||
// for thick metakey or deprecated thick metakey.
|
|
||||||
err = ri.setThinProvisioned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("failed to get metadata %q for %q: %w", thickProvisionMetaKey, ri, err)
|
return false, fmt.Errorf("failed to get metadata %q for %q: %w", thickProvisionMetaKey, ri, err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user