]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/ceph-volume/ceph_volume/devices/raw/prepare.py
import 15.2.5
[ceph.git] / ceph / src / ceph-volume / ceph_volume / devices / raw / prepare.py
index cb5c59ce40f5315946a9b1d0d2e3686793a7ec07..3c96eedacf34a6d6f30d7ce09eceeb595016092f 100644 (file)
@@ -1,15 +1,39 @@
 from __future__ import print_function
 import json
 import logging
+import os
 from textwrap import dedent
 from ceph_volume.util import prepare as prepare_utils
+from ceph_volume.util import encryption as encryption_utils
+from ceph_volume.util import disk
 from ceph_volume.util import system
-from ceph_volume import conf, decorators, terminal
+from ceph_volume import decorators, terminal
 from ceph_volume.devices.lvm.common import rollback_osd
 from .common import create_parser
 
 logger = logging.getLogger(__name__)
 
+def prepare_dmcrypt(key, device, device_type, fsid):
+    """
+    Helper for devices that are encrypted. The operations needed for
+    block, db, wal, or data/journal devices are all the same
+    """
+    if not device:
+        return ''
+    kname = disk.lsblk(device)['KNAME']
+    mapping = 'ceph-{}-{}-{}-dmcrypt'.format(fsid, kname, device_type)
+    # format data device
+    encryption_utils.luks_format(
+        key,
+        device
+    )
+    encryption_utils.luks_open(
+        key,
+        device,
+        mapping
+    )
+
+    return '/dev/mapper/{}'.format(mapping)
 
 def prepare_bluestore(block, wal, db, secrets, osd_id, fsid, tmpfs):
     """
@@ -22,6 +46,12 @@ def prepare_bluestore(block, wal, db, secrets, osd_id, fsid, tmpfs):
     """
     cephx_secret = secrets.get('cephx_secret', prepare_utils.create_key())
 
+    if secrets.get('dmcrypt_key'):
+        key = secrets['dmcrypt_key']
+        block = prepare_dmcrypt(key, block, 'block', fsid)
+        wal = prepare_dmcrypt(key, wal, 'wal', fsid)
+        db = prepare_dmcrypt(key, db, 'db', fsid)
+
     # create the directory
     prepare_utils.create_osd_path(osd_id, tmpfs=tmpfs)
     # symlink the block
@@ -64,21 +94,20 @@ class Prepare(object):
             logger.info('will rollback OSD ID creation')
             rollback_osd(self.args, self.osd_id)
             raise
-        terminal.success("ceph-volume raw prepare successful for: %s" % self.args.data)
-
-    def get_cluster_fsid(self):
-        """
-        Allows using --cluster-fsid as an argument, but can fallback to reading
-        from ceph.conf if that is unset (the default behavior).
-        """
-        if self.args.cluster_fsid:
-            return self.args.cluster_fsid
+        dmcrypt_log = 'dmcrypt' if args.dmcrypt else 'clear'
+        terminal.success("ceph-volume raw {} prepare successful for: {}".format(dmcrypt_log, self.args.data))
 
-        return conf.ceph.get('global', 'fsid')
 
     @decorators.needs_root
     def prepare(self):
         secrets = {'cephx_secret': prepare_utils.create_key()}
+        encrypted = 1 if self.args.dmcrypt else 0
+        cephx_lockbox_secret = '' if not encrypted else prepare_utils.create_key()
+
+        if encrypted:
+            secrets['dmcrypt_key'] = os.getenv('CEPH_VOLUME_DMCRYPT_SECRET')
+            secrets['cephx_lockbox_secret'] = cephx_lockbox_secret # dummy value to make `ceph osd new` not complaining
+
         osd_fsid = system.generate_uuid()
         crush_device_class = self.args.crush_device_class
         if crush_device_class:
@@ -94,6 +123,7 @@ class Prepare(object):
         # reuse a given ID if it exists, otherwise create a new ID
         self.osd_id = prepare_utils.create_id(
             osd_fsid, json.dumps(secrets))
+
         prepare_bluestore(
             self.args.data,
             wal,
@@ -112,8 +142,6 @@ class Prepare(object):
         Once the OSD is ready, an ad-hoc systemd unit will be enabled so that
         it can later get activated and the OSD daemon can get started.
 
-        Encryption is not supported.
-
             ceph-volume raw prepare --bluestore --data {device}
 
         DB and WAL devices are supported.
@@ -132,5 +160,10 @@ class Prepare(object):
         if not self.args.bluestore:
             terminal.error('must specify --bluestore (currently the only supported backend)')
             raise SystemExit(1)
+        if self.args.dmcrypt and not os.getenv('CEPH_VOLUME_DMCRYPT_SECRET'):
+            terminal.error('encryption was requested (--dmcrypt) but environment variable ' \
+                           'CEPH_VOLUME_DMCRYPT_SECRET is not set, you must set ' \
+                           'this variable to provide a dmcrypt secret.')
+            raise SystemExit(1)
 
         self.safe_prepare(self.args)