]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/ceph-volume/ceph_volume/util/encryption.py
import quincy beta 17.1.0
[ceph.git] / ceph / src / ceph-volume / ceph_volume / util / encryption.py
index 0abe9b6c189d0d7f6e9b9c7d77f1225ec25202fc..2a2c03337b61f0db47d34c6349435f11f6c16f0b 100644 (file)
@@ -3,26 +3,35 @@ import os
 import logging
 from ceph_volume import process, conf
 from ceph_volume.util import constants, system
+from ceph_volume.util.device import Device
 from .prepare import write_keyring
 from .disk import lsblk, device_family, get_part_entry_type
 
 logger = logging.getLogger(__name__)
 
-
-def create_dmcrypt_key():
+def get_key_size_from_conf():
     """
-    Create the secret dm-crypt key used to decrypt a device.
+    Return the osd dmcrypt key size from config file.
+    Default is 512.
     """
-    # get the customizable dmcrypt key size (in bits) from ceph.conf fallback
-    # to the default of 1024
-    dmcrypt_key_size = conf.ceph.get_safe(
+    default_key_size = '512'
+    key_size = conf.ceph.get_safe(
         'osd',
         'osd_dmcrypt_key_size',
-        default=1024,
-    )
-    # The size of the key is defined in bits, so we must transform that
-    # value to bytes (dividing by 8) because we read in bytes, not bits
-    random_string = os.urandom(dmcrypt_key_size / 8)
+        default='512')
+
+    if key_size not in ['256', '512']:
+        logger.warning(("Invalid value set for osd_dmcrypt_key_size ({}). "
+                        "Falling back to {}bits".format(key_size, default_key_size)))
+        return default_key_size
+
+    return key_size
+
+def create_dmcrypt_key():
+    """
+    Create the secret dm-crypt key (KEK) used to encrypt/decrypt the Volume Key.
+    """
+    random_string = os.urandom(128)
     key = base64.b64encode(random_string).decode('utf-8')
     return key
 
@@ -37,6 +46,8 @@ def luks_format(key, device):
     command = [
         'cryptsetup',
         '--batch-mode', # do not prompt
+        '--key-size',
+        get_key_size_from_conf(),
         '--key-file', # misnomer, should be key
         '-',          # because we indicate stdin for the key here
         'luksFormat',
@@ -59,6 +70,7 @@ def plain_open(key, device, mapping):
         'cryptsetup',
         '--key-file',
         '-',
+        '--allow-discards',  # allow discards (aka TRIM) requests for device
         'open',
         device,
         mapping,
@@ -81,8 +93,11 @@ def luks_open(key, device, mapping):
     """
     command = [
         'cryptsetup',
+        '--key-size',
+        get_key_size_from_conf(),
         '--key-file',
         '-',
+        '--allow-discards',  # allow discards (aka TRIM) requests for device
         'luksOpen',
         device,
         mapping,
@@ -96,7 +111,12 @@ def dmcrypt_close(mapping):
 
     :param mapping:
     """
-    process.run(['cryptsetup', 'remove', mapping])
+    if not os.path.exists(mapping):
+        logger.debug('device mapper path does not exist %s' % mapping)
+        logger.debug('will skip cryptsetup removal')
+        return
+    # don't be strict about the remove call, but still warn on the terminal if it fails
+    process.run(['cryptsetup', 'remove', mapping], stop_on_error=False)
 
 
 def get_dmcrypt_key(osd_id, osd_fsid, lockbox_keyring=None):
@@ -144,7 +164,7 @@ def write_lockbox_keyring(osd_id, osd_fsid, secret):
     For filestore: The path for the OSD would exist at this point even if no
     OSD data device is mounted, so the keyring is written to fetch the key, and
     then the data device is mounted on that directory, making the keyring
-    "dissapear".
+    "disappear".
     """
     if os.path.exists('/var/lib/ceph/osd/%s-%s/lockbox.keyring' % (conf.cluster, osd_id)):
         return
@@ -185,7 +205,8 @@ def status(device):
         'status',
         device,
     ]
-    out, err, code = process.call(command, show_command=True)
+    out, err, code = process.call(command, show_command=True, verbose_on_failure=False)
+
     metadata = {}
     if code != 0:
         logger.warning('failed to detect device mapper information')
@@ -246,9 +267,9 @@ def legacy_encrypted(device):
         return metadata
     parent_device = disk_meta['PKNAME']
     # With the parent device set, we can now look for the lockbox listing associated devices
-    devices = device_family(parent_device)
-    for i in devices:
-        if 'lockbox' in i.get('PARTLABEL', ''):
-            metadata['lockbox'] = i['NAME']
+    devices = [Device(i['NAME']) for i in device_family(parent_device)]
+    for d in devices:
+        if d.ceph_disk.type == 'lockbox':
+            metadata['lockbox'] = d.abspath
             break
     return metadata