]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
qa/tasks/qemu: use formatted clones on encrypted disks 40363/head
authorOr Ozeri <oro@il.ibm.com>
Sun, 10 Jul 2022 10:54:56 +0000 (13:54 +0300)
committerOr Ozeri <oro@il.ibm.com>
Thu, 25 Aug 2022 15:41:48 +0000 (18:41 +0300)
This commit changes the format for encrypted disks to have
the child image and the parent image encrypted with different keys.
This to allow testing of the new formatted clones feature in librbd/crypto.

Signed-off-by: Or Ozeri <oro@il.ibm.com>
qa/suites/rbd/encryption/workloads/qemu_xfstests_luks1.yaml
qa/suites/rbd/encryption/workloads/qemu_xfstests_luks1_luks1.yaml [new file with mode: 0644]
qa/suites/rbd/encryption/workloads/qemu_xfstests_luks1_luks2.yaml [new file with mode: 0644]
qa/suites/rbd/encryption/workloads/qemu_xfstests_luks2.yaml
qa/suites/rbd/encryption/workloads/qemu_xfstests_luks2_luks1.yaml [new file with mode: 0644]
qa/suites/rbd/encryption/workloads/qemu_xfstests_luks2_luks2.yaml [new file with mode: 0644]
qa/suites/rbd/encryption/workloads/qemu_xfstests_none_luks1.yaml [new file with mode: 0644]
qa/suites/rbd/encryption/workloads/qemu_xfstests_none_luks2.yaml [new file with mode: 0644]
qa/tasks/qemu.py
qa/tasks/rbd.py

index 7f3f3776f2a607b23d080c3270808fc088b0ed9e..cb3659f9751720e326a3285faf1eba97c0a5a2c8 100644 (file)
@@ -6,7 +6,7 @@ tasks:
 - qemu:
     all:
       clone: true
-      encryption_format: luks1
+      parent_encryption_format: luks1
       type: block
       disks: 3
       test: qa/run_xfstests_qemu.sh
diff --git a/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks1_luks1.yaml b/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks1_luks1.yaml
new file mode 100644 (file)
index 0000000..1db50d6
--- /dev/null
@@ -0,0 +1,14 @@
+overrides:
+  install:
+    ceph:
+      extra_packages: [rbd-nbd]
+tasks:
+- qemu:
+    all:
+      clone: true
+      parent_encryption_format: luks1
+      encryption_format: luks1
+      type: block
+      disks: 3
+      test: qa/run_xfstests_qemu.sh
+exclude_arch: armv7l
diff --git a/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks1_luks2.yaml b/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks1_luks2.yaml
new file mode 100644 (file)
index 0000000..a8ef5f2
--- /dev/null
@@ -0,0 +1,14 @@
+overrides:
+  install:
+    ceph:
+      extra_packages: [rbd-nbd]
+tasks:
+- qemu:
+    all:
+      clone: true
+      parent_encryption_format: luks1
+      encryption_format: luks2
+      type: block
+      disks: 3
+      test: qa/run_xfstests_qemu.sh
+exclude_arch: armv7l
index c9d9829a99f70bfd066c8f3f8ddce296e0f28377..203372d60e45978006ec1ca29a545c6c814d119d 100644 (file)
@@ -6,7 +6,7 @@ tasks:
 - qemu:
     all:
       clone: true
-      encryption_format: luks2
+      parent_encryption_format: luks2
       type: block
       disks: 3
       test: qa/run_xfstests_qemu.sh
diff --git a/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks2_luks1.yaml b/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks2_luks1.yaml
new file mode 100644 (file)
index 0000000..727e5c3
--- /dev/null
@@ -0,0 +1,14 @@
+overrides:
+  install:
+    ceph:
+      extra_packages: [rbd-nbd]
+tasks:
+- qemu:
+    all:
+      clone: true
+      parent_encryption_format: luks2
+      encryption_format: luks1
+      type: block
+      disks: 3
+      test: qa/run_xfstests_qemu.sh
+exclude_arch: armv7l
diff --git a/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks2_luks2.yaml b/qa/suites/rbd/encryption/workloads/qemu_xfstests_luks2_luks2.yaml
new file mode 100644 (file)
index 0000000..43ded12
--- /dev/null
@@ -0,0 +1,14 @@
+overrides:
+  install:
+    ceph:
+      extra_packages: [rbd-nbd]
+tasks:
+- qemu:
+    all:
+      clone: true
+      parent_encryption_format: luks2
+      encryption_format: luks2
+      type: block
+      disks: 3
+      test: qa/run_xfstests_qemu.sh
+exclude_arch: armv7l
diff --git a/qa/suites/rbd/encryption/workloads/qemu_xfstests_none_luks1.yaml b/qa/suites/rbd/encryption/workloads/qemu_xfstests_none_luks1.yaml
new file mode 100644 (file)
index 0000000..7f3f377
--- /dev/null
@@ -0,0 +1,13 @@
+overrides:
+  install:
+    ceph:
+      extra_packages: [rbd-nbd]
+tasks:
+- qemu:
+    all:
+      clone: true
+      encryption_format: luks1
+      type: block
+      disks: 3
+      test: qa/run_xfstests_qemu.sh
+exclude_arch: armv7l
diff --git a/qa/suites/rbd/encryption/workloads/qemu_xfstests_none_luks2.yaml b/qa/suites/rbd/encryption/workloads/qemu_xfstests_none_luks2.yaml
new file mode 100644 (file)
index 0000000..c9d9829
--- /dev/null
@@ -0,0 +1,13 @@
+overrides:
+  install:
+    ceph:
+      extra_packages: [rbd-nbd]
+tasks:
+- qemu:
+    all:
+      clone: true
+      encryption_format: luks2
+      type: block
+      disks: 3
+      test: qa/run_xfstests_qemu.sh
+exclude_arch: armv7l
index 3fe8049b72f08b1cf4f657c7638b0adff73d9829..ae02983eeb6afded26160dadcfd21fbf0c130ffc 100644 (file)
@@ -32,6 +32,8 @@ def normalize_disks(config):
         image_url = client_config.get('image_url', DEFAULT_IMAGE_URL)
         device_type = client_config.get('type', 'filesystem')
         encryption_format = client_config.get('encryption_format', 'none')
+        parent_encryption_format = client_config.get(
+            'parent_encryption_format', 'none')
 
         disks = client_config.get('disks', DEFAULT_NUM_DISKS)
         if not isinstance(disks, list):
@@ -59,7 +61,10 @@ def normalize_disks(config):
             disk['device_letter'] = chr(ord('a') + i)
 
             if 'encryption_format' not in disk:
-                disk['encryption_format'] = encryption_format
+                if clone:
+                    disk['encryption_format'] = parent_encryption_format
+                else:
+                    disk['encryption_format'] = encryption_format
             assert disk['encryption_format'] in ['none', 'luks1', 'luks2'], 'invalid encryption format'
 
         assert disks, 'at least one rbd device must be used'
@@ -73,6 +78,13 @@ def normalize_disks(config):
                 clone['parent_name'] = clone['image_name']
                 clone['image_name'] += '-clone'
                 del disk['device_letter']
+
+                clone['encryption_format'] = encryption_format
+                assert clone['encryption_format'] in ['none', 'luks1', 'luks2'], 'invalid encryption format'
+
+                clone['parent_encryption_format'] = parent_encryption_format
+                assert clone['parent_encryption_format'] in ['none', 'luks1', 'luks2'], 'invalid encryption format'
+
                 disks.append(clone)
 
 def create_images(ctx, config, managers):
@@ -109,7 +121,8 @@ def create_clones(ctx, config, managers):
             create_config = {
                 client: {
                     'image_name': disk['image_name'],
-                    'parent_name': disk['parent_name']
+                    'parent_name': disk['parent_name'],
+                    'encryption_format': disk['encryption_format'],
                     }
                 }
             managers.append(
@@ -121,7 +134,8 @@ def create_encrypted_devices(ctx, config, managers):
     for client, client_config in config.items():
         disks = client_config['disks']
         for disk in disks:
-            if disk['encryption_format'] == 'none' or \
+            if (disk['encryption_format'] == 'none' and
+                disk.get('parent_encryption_format', 'none') == 'none') or \
                     'device_letter' not in disk:
                 continue
 
@@ -223,7 +237,8 @@ def generate_iso(ctx, config):
                     'device_letter' not in disk or \
                     'image_url' in disk:
                 continue
-            if disk['encryption_format'] == 'none':
+            if disk['encryption_format'] == 'none' and \
+                    disk.get('parent_encryption_format', 'none') == 'none':
                 dev_name = 'vd' + disk['device_letter']
             else:
                 # encrypted disks use if=ide interface, instead of if=virtio
@@ -519,7 +534,8 @@ def run_qemu(ctx, config):
             if 'device_letter' not in disk:
                 continue
 
-            if disk['encryption_format'] == 'none':
+            if disk['encryption_format'] == 'none' and \
+                    disk.get('parent_encryption_format', 'none') == 'none':
                 interface = 'virtio'
                 disk_spec = 'rbd:rbd/{img}:id={id}'.format(
                     img=disk['image_name'],
index 6b9786f220ae8d1e8282716b44517e5b6a36ebc1..b0ffaba83861dcdf99fbf1212be311f4ecc73dac 100644 (file)
@@ -23,6 +23,7 @@ os.environ["RBD_FORCE_ALLOW_V1"] = "1"
 log = logging.getLogger(__name__)
 
 ENCRYPTION_PASSPHRASE = "password"
+CLONE_ENCRYPTION_PASSPHRASE = "password2"
 
 @contextlib.contextmanager
 def create_image(ctx, config):
@@ -142,6 +143,7 @@ def clone_image(ctx, config):
             client.0:
                 parent_name: testimage
                 image_name: cloneimage
+                encryption_format: luks2
     """
     assert isinstance(config, dict) or isinstance(config, list), \
         "task clone_image only supports a list or dictionary for configuration"
@@ -152,6 +154,7 @@ def clone_image(ctx, config):
         images = [(role, None) for role in config]
 
     testdir = teuthology.get_testdir(ctx)
+    clone_passphrase_file = '{tdir}/clone-passphrase'.format(tdir=testdir)
     for role, properties in images:
         if properties is None:
             properties = {}
@@ -165,9 +168,29 @@ def clone_image(ctx, config):
         (remote,) = ctx.cluster.only(role).remotes.keys()
         log.info('Clone image {parent} to {child}'.format(parent=parent_name,
                                                           child=name))
-        for cmd in [('snap', 'create', parent_spec),
+
+        commands = [('snap', 'create', parent_spec),
                     ('snap', 'protect', parent_spec),
-                    ('clone', parent_spec, name)]:
+                    ('clone', parent_spec, name)
+                    ]
+
+        encryption_format = properties.get('encryption_format', 'none')
+        if encryption_format != 'none':
+            remote.run(
+                args=[
+                    'echo',
+                    CLONE_ENCRYPTION_PASSPHRASE,
+                    run.Raw('>'),
+                    clone_passphrase_file
+                    ]
+                )
+
+            commands.append(
+                ('encryption', 'format', name, encryption_format,
+                 clone_passphrase_file)
+            )
+
+        for cmd in commands:
             args = [
                     'adjust-ulimits',
                     'ceph-coverage',
@@ -181,6 +204,7 @@ def clone_image(ctx, config):
         yield
     finally:
         log.info('Deleting rbd clones...')
+        remote.run(args=['rm', '-f', clone_passphrase_file])
         for role, properties in images:
             if properties is None:
                 properties = {}
@@ -260,6 +284,7 @@ def dev_create(ctx, config):
             client.0:
                 image_name: testimage.client.0
                 encryption_format: luks2
+                parent_encryption_format: luks1
     """
     assert isinstance(config, dict) or isinstance(config, list), \
         "task dev_create only supports a list or dictionary for configuration"
@@ -273,31 +298,64 @@ def dev_create(ctx, config):
 
     testdir = teuthology.get_testdir(ctx)
     passphrase_file = '{tdir}/passphrase'.format(tdir=testdir)
+    clone_passphrase_file = '{tdir}/clone-passphrase'.format(tdir=testdir)
     device_path = {}
 
     for role, properties in images:
         if properties is None:
             properties = {}
         name = properties.get('image_name', default_image_name(role))
-        encryption_format = properties.get('encryption_format', 'none')
+        parent_encryption_format = properties.get('parent_encryption_format',
+                                                  'none')
+        encryption_format = properties.get('encryption_format',
+                                           parent_encryption_format)
         (remote,) = ctx.cluster.only(role).remotes.keys()
 
-        if encryption_format == 'none':
+        if encryption_format == 'none' and parent_encryption_format == 'none':
             device_path[role] = '/dev/rbd/rbd/{image}'.format(image=name)
             device_specific_args = []
         else:
-            remote.run(
-                args=[
-                    'echo',
-                    ENCRYPTION_PASSPHRASE,
-                    run.Raw('>'),
-                    passphrase_file
-                    ]
-                )
-            device_specific_args = [
-                '-t', 'nbd', '-o',
-                'encryption-format=%s,encryption-passphrase-file=%s' % (
-                    encryption_format, passphrase_file)]
+            device_specific_args = ['-t', 'nbd', '-o']
+
+            is_cloned = properties.get('parent_name') is not None
+            encryption_args = ""
+            if is_cloned and properties.get('encryption_format') != 'none':
+                remote.run(
+                    args=[
+                        'echo',
+                        CLONE_ENCRYPTION_PASSPHRASE,
+                        run.Raw('>'),
+                        clone_passphrase_file
+                        ]
+                    )
+
+                encryption_args = \
+                    'encryption-format=%s,encryption-passphrase-file=%s' % (
+                        encryption_format, clone_passphrase_file)
+
+            if not is_cloned or parent_encryption_format != 'none':
+                remote.run(
+                    args=[
+                        'echo',
+                        ENCRYPTION_PASSPHRASE,
+                        run.Raw('>'),
+                        passphrase_file
+                        ]
+                    )
+
+                if is_cloned and properties.get('encryption_format') != 'none':
+                    encryption_args += ","
+
+                if parent_encryption_format != 'none':
+                    encryption_args += \
+                        'encryption-format=%s,encryption-passphrase-file=%s' % (
+                            parent_encryption_format, passphrase_file)
+                else:
+                    encryption_args += \
+                        'encryption-format=%s,encryption-passphrase-file=%s' % (
+                            encryption_format, passphrase_file)
+
+            device_specific_args.append(encryption_args)
 
         map_fp = StringIO()
         remote.run(
@@ -314,7 +372,7 @@ def dev_create(ctx, config):
             stdout=map_fp,
             )
 
-        if encryption_format != 'none':
+        if encryption_format != 'none' or parent_encryption_format != 'none':
             device_path[role] = map_fp.getvalue().rstrip()
             properties['device_path'] = device_path[role]
             remote.run(args=['sudo', 'chmod', '666', device_path[role]])
@@ -322,7 +380,7 @@ def dev_create(ctx, config):
         yield
     finally:
         log.info('Unmapping rbd devices...')
-        remote.run(args=['rm', '-f', passphrase_file])
+        remote.run(args=['rm', '-f', passphrase_file, clone_passphrase_file])
         for role, properties in images:
             if not device_path.get(role):
                 continue
@@ -330,9 +388,12 @@ def dev_create(ctx, config):
             if properties is None:
                 properties = {}
             encryption_format = properties.get('encryption_format', 'none')
+            parent_encryption_format = properties.get(
+                'parent_encryption_format', 'none')
             (remote,) = ctx.cluster.only(role).remotes.keys()
 
-            if encryption_format == 'none':
+            if encryption_format == 'none' and \
+                    parent_encryption_format == 'none':
                 device_specific_args = []
             else:
                 device_specific_args = ['-t', 'nbd']