]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-disk: add trigger subcommand
authorSage Weil <sage@redhat.com>
Mon, 31 Aug 2015 19:20:10 +0000 (15:20 -0400)
committerSage Weil <sage@redhat.com>
Tue, 1 Sep 2015 15:33:33 +0000 (11:33 -0400)
Either trigger a systemd event, or do it synchronously if there is no
systemd.

Signed-off-by: Sage Weil <sage@redhat.com>
src/ceph-disk

index 10a7b64fafd4ba8a0a27df5c2e0311fac1c5a353..c6c4c9bcef6924d0bc59452d3e7dedade8d07c51 100755 (executable)
@@ -232,6 +232,15 @@ class ExecutableNotFound(CephDiskException):
 
 ####### utils
 
+def is_systemd():
+    """
+    Detect whether systemd is running
+    """
+    with file('/proc/1/comm', 'rb') as i:
+        for line in i:
+            if 'systemd' in line:
+                return True
+    return False
 
 def maybe_mkdir(*a, **kw):
     """
@@ -2604,6 +2613,22 @@ def get_dev_fs(dev):
     else:
         return None
 
+def get_dev_udev_properties(dev):
+    out, _ = command(
+        [
+            '/sbin/blkid',
+            '-o',
+            'udev',
+            '-p',
+            dev,
+        ]
+    )
+    p = {}
+    for line in out.split('\n'):
+        if line:
+            (key, value) = line.split('=')
+            p[key] = value
+    return p
 
 def split_dev_base_partnum(dev):
     if is_mpath(dev):
@@ -2943,6 +2968,170 @@ def main_zap(args):
 
 ###########################
 
+def main_trigger(args):
+    if is_systemd() and not args.sync:
+        service='ceph-disk@{dev}.service'.format(dev=args.dev)
+        LOG.info('systemd detected, triggering %s' % service)
+        command(
+            [
+                'systemctl',
+                '--no-block',
+                'start',
+                service,
+            ]
+        )
+        return
+
+    p = get_dev_udev_properties(args.dev)
+
+    if 'ID_PART_ENTRY_TYPE' not in p:
+        raise Error('no ID_PART_ENTRY_TYPE for %s' % args.dev)
+    parttype = p['ID_PART_ENTRY_TYPE']
+
+    if 'ID_PART_ENTRY_UUID' not in p:
+        raise Error('no ID_PART_ENTRY_UUID for %s' % args.dev)
+    partid = p['ID_PART_ENTRY_UUID']
+
+    if parttype in [OSD_UUID, MPATH_OSD_UUID]:
+        command(
+            [
+                'ceph-disk',
+                'activate',
+                args.dev,
+            ]
+        )
+    elif parttype in [JOURNAL_UUID, MPATH_JOURNAL_UUID]:
+        command(
+            [
+                'ceph-disk',
+                'activate-journal',
+                args.dev,
+            ]
+        )
+
+        # journals are easy: map, chown, activate-journal
+    elif parttype == DMCRYPT_JOURNAL_UUID:
+        command(
+            [
+                '/sbin/cryptsetup',
+                '--key-file',
+                '/etc/ceph/dmcrypt-keys/{partid}'.format(partid=partid),
+                '--key-size',
+                '256',
+                'create',
+                partid,
+                args.dev,
+            ]
+        )
+        newdev='/dev/mapper/' + partid
+        count=0
+        while not os.path.exists(newdev) and count <= 10:
+            time.sleep(1)
+            count += 1
+        command(
+            [
+                '/bin/chown',
+                'ceph:ceph',
+                newdev,
+            ]
+        )
+        command(
+            [
+                '/usr/sbin/ceph-disk',
+                'activate-journal',
+                newdev,
+            ]
+            )
+    elif parttype == DMCRYPT_LUKS_JOURNAL_UUID:
+        command(
+            [
+                '/sbin/cryptsetup',
+                '--key-file',
+                '/etc/ceph/dmcrypt-keys/{partid}.luks.key'.format(
+                    partid=partid),
+                'luksOpen',
+                args.dev,
+                partid,
+            ]
+        )
+        newdev='/dev/mapper/' + partid
+        count=0
+        while not os.path.exists(newdev) and count <= 10:
+            time.sleep(1)
+            count += 1
+        command(
+            [
+                '/bin/chown',
+                'ceph:ceph',
+                newdev,
+            ]
+        )
+        command(
+            [
+                '/usr/sbin/ceph-disk',
+                'activate-journal',
+                newdev,
+            ]
+            )
+
+        # osd data: map, activate
+    elif parttype == DMCRYPT_OSD_UUID:
+        command(
+            [
+                '/sbin/cryptsetup',
+                '--key-file',
+                '/etc/ceph/dmcrypt-keys/{partid}'.format(partid=partid),
+                '--key-size',
+                '256',
+                'create',
+                partid,
+                args.dev,
+            ]
+        )
+        newdev='/dev/mapper/' + partid
+        count=0
+        while not os.path.exists(newdev) and count <= 10:
+            time.sleep(1)
+            count += 1
+        command(
+            [
+                '/usr/sbin/ceph-disk',
+                'activate',
+                newdev,
+            ]
+        )
+
+    elif parttype == DMCRYPT_LUKS_OSD_UUID:
+        command(
+            [
+                '/sbin/cryptsetup',
+                '--key-file',
+                '/etc/ceph/dmcrypt-keys/{partid}.luks.key'.format(
+                    partid=partid),
+                'luksOpen',
+                args.dev,
+                partid,
+            ]
+        )
+        newdev='/dev/mapper/' + partid
+        count=0
+        while not os.path.exists(newdev) and count <= 10:
+            time.sleep(1)
+            count += 1
+        command(
+            [
+                '/usr/sbin/ceph-disk',
+                'activate',
+                newdev,
+            ]
+        )
+
+    else:
+        raise Error('unrecognized partition type %s' % parttype)
+
+
+
+###########################
 
 def setup_statedir(dir):
     # XXX The following use of globals makes linting
@@ -3021,10 +3210,27 @@ def parse_args(argv):
     make_list_parser(subparsers)
     make_suppress_parser(subparsers)
     make_zap_parser(subparsers)
+    make_trigger_parser(subparsers)
 
     args = parser.parse_args(argv)
     return args
 
+def make_trigger_parser(subparsers):
+    trigger_parser = subparsers.add_parser('trigger', help='Trigger an event (caled by udev)')
+    trigger_parser.add_argument(
+        'dev',
+        help=('device'),
+        )
+    trigger_parser.add_argument(
+        '--sync',
+        action='store_true', default=None,
+        help=('do operation synchronously; do not trigger systemd'),
+        )
+    trigger_parser.set_defaults(
+        func=main_trigger,
+        )
+    return trigger_parser
+
 def make_prepare_parser(subparsers):
     prepare_parser = subparsers.add_parser('prepare', help='Prepare a directory or disk for a Ceph OSD')
     prepare_parser.add_argument(