Skip to content

Commit

Permalink
[ATMOSPHERE-479] fix: Directly import converted image to RBD (#2000)
Browse files Browse the repository at this point in the history
  • Loading branch information
ricolin authored Oct 30, 2024
1 parent 99651a6 commit de2ce3b
Showing 1 changed file with 152 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
From ddb4c87da6d20cc2cf37db70498f6890db1b2498 Mon Sep 17 00:00:00 2001
From: ricolin <[email protected]>
Date: Tue, 22 Oct 2024 18:31:52 +0800
Subject: [PATCH] Directly import converted image to RBD

For volume encryption from Glance image case,
once we cloned the image down, we do convert and import back to RBD.

This patch allows us to avoid another tempfile write and directly
upload image to RBD.

Related-Bug: #2055517
Change-Id: Ib5e15eeee6a02e2833d14ac34f6fdeb4a6548a67
---
cinder/tests/unit/volume/drivers/test_rbd.py | 2 -
cinder/volume/drivers/rbd.py | 57 ++++++++-----------
...verted-encrypt-image-005986a59d1027e1.yaml | 9 +++
3 files changed, 34 insertions(+), 34 deletions(-)
create mode 100644 releasenotes/notes/allow-direct-import-converted-encrypt-image-005986a59d1027e1.yaml

diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
index 13f67b3d4..291db326d 100644
--- a/cinder/volume/drivers/rbd.py
+++ b/cinder/volume/drivers/rbd.py
@@ -32,7 +32,6 @@ from oslo_log import log as logging
from oslo_service import loopingcall
from oslo_utils import encodeutils
from oslo_utils import excutils
-from oslo_utils import fileutils
from oslo_utils import units
try:
import rados
@@ -1992,11 +1991,10 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,
self._copy_image_to_volume(context, volume, image_service, image_id,
disable_sparse=disable_sparse)

- def _encrypt_image(self,
- context: context.RequestContext,
- volume: Volume,
- tmp_dir: str,
- src_image_path: Any) -> None:
+ def _encrypt_image_and_upload(
+ self, context: context.RequestContext,
+ volume: Volume, tmp_dir: str, src_image_path: Any
+ ) -> None:
encryption = volume_utils.check_encryption_provider(
volume,
context)
@@ -2010,6 +2008,19 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,
cipher_spec = image_utils.decode_cipher(encryption['cipher'],
encryption['key_size'])

+ _, conf, user_id, _ = self._get_config_tuple()
+ rbd_options = ''
+ if user_id:
+ rbd_options += f':id={user_id}'
+ if conf:
+ rbd_options += f':conf={conf}'
+
+ rbd_dest = 'rbd:%(pool_name)s/%(image_name)s%(rbd_options)s' % {
+ 'pool_name': self.configuration.rbd_pool,
+ 'image_name': volume.name,
+ 'rbd_options': rbd_options
+ }
+
tmp_dir = volume_utils.image_conversion_dir()

with tempfile.NamedTemporaryFile(prefix='luks_',
@@ -2017,18 +2028,10 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,
with open(pass_file.name, 'w') as f:
f.write(passphrase)

- # Convert the raw image to luks
- dest_image_path = src_image_path + '.luks'
- try:
- image_utils.convert_image(src_image_path, dest_image_path,
- 'luks', src_format='raw',
- cipher_spec=cipher_spec,
- passphrase_file=pass_file.name)
-
- # Replace the original image with the now encrypted image
- os.rename(dest_image_path, src_image_path)
- finally:
- fileutils.delete_if_exists(dest_image_path)
+ image_utils.convert_image(src_image_path, rbd_dest,
+ 'luks', src_format='raw',
+ cipher_spec=cipher_spec,
+ passphrase_file=pass_file.name)

def _copy_image_to_volume(self,
context: context.RequestContext,
@@ -2047,9 +2050,6 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,
size=volume.size,
disable_sparse=disable_sparse)

- if encrypted:
- self._encrypt_image(context, volume, tmp_dir, tmp.name)
-
@utils.retry(exception.VolumeIsBusy,
self.configuration.rados_connection_interval,
self.configuration.rados_connection_retries)
@@ -2058,17 +2058,21 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,

_delete_volume(volume)

- chunk_size = self.configuration.rbd_store_chunk_size * units.Mi
- order = int(math.log(chunk_size, 2))
- # keep using the command line import instead of librbd since it
- # detects zeroes to preserve sparseness in the image
- args = ['rbd', 'import',
- '--pool', self.configuration.rbd_pool,
- '--order', order,
- tmp.name, volume.name,
- '--new-format']
- args.extend(self._ceph_args())
- self._try_execute(*args)
+ if encrypted:
+ self._encrypt_image_and_upload(
+ context, volume, tmp_dir, tmp.name)
+ else:
+ chunk_size = self.configuration.rbd_store_chunk_size * units.Mi
+ order = int(math.log(chunk_size, 2))
+ # keep using the command line import instead of librbd since it
+ # detects zeroes to preserve sparseness in the image
+ args = ['rbd', 'import',
+ '--pool', self.configuration.rbd_pool,
+ '--order', order,
+ tmp.name, volume.name,
+ '--new-format']
+ args.extend(self._ceph_args())
+ self._try_execute(*args)
self._resize(volume)
# We may need to re-enable replication because we have deleted the
# original image and created a new one using the command line import.
diff --git a/releasenotes/notes/allow-direct-import-converted-encrypt-image-005986a59d1027e1.yaml b/releasenotes/notes/allow-direct-import-converted-encrypt-image-005986a59d1027e1.yaml
new file mode 100644
index 000000000..b1544214d
--- /dev/null
+++ b/releasenotes/notes/allow-direct-import-converted-encrypt-image-005986a59d1027e1.yaml
@@ -0,0 +1,9 @@
+---
+fixes:
+ - |
+ [Bug 255517](https://bugs.launchpad.net/cinder/+bug/2055517): Improve slow
+ on create encrypted volumes with temp file import.
+ For volume encryption from Glance image case, once we cloned the image
+ down, we do convert and import back to RBD. We now avoid another tempfile
+ write and directly upload image to RBD. And it is now directly upload to
+ RBD with qemu-img command without temprory converted image file generated.
--
2.25.1

0 comments on commit de2ce3b

Please sign in to comment.