]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume: util: create the module with prepare, activate, and system utilities
authorAlfredo Deza <adeza@redhat.com>
Tue, 11 Jul 2017 20:30:14 +0000 (16:30 -0400)
committerAlfredo Deza <adeza@redhat.com>
Fri, 4 Aug 2017 14:25:57 +0000 (10:25 -0400)
Signed-off-by: Alfredo Deza <adeza@redhat.com>
src/ceph-volume/ceph_volume/util/__init__.py [new file with mode: 0644]
src/ceph-volume/ceph_volume/util/activate.py [new file with mode: 0644]
src/ceph-volume/ceph_volume/util/constants.py [new file with mode: 0644]
src/ceph-volume/ceph_volume/util/prepare.py [new file with mode: 0644]
src/ceph-volume/ceph_volume/util/system.py [new file with mode: 0644]

diff --git a/src/ceph-volume/ceph_volume/util/__init__.py b/src/ceph-volume/ceph_volume/util/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/ceph-volume/ceph_volume/util/activate.py b/src/ceph-volume/ceph_volume/util/activate.py
new file mode 100644 (file)
index 0000000..48a8d38
--- /dev/null
@@ -0,0 +1,28 @@
+import os
+from ceph_volume import process, conf
+
+
+def add_osd_to_mon(osd_id):
+    """
+    Register the previously prepared OSD to the monitor. A call will look like::
+
+        ceph --cluster ceph --name client.bootstrap-osd
+        --keyring /var/lib/ceph/bootstrap-osd/ceph.keyring \
+        auth add osd.0 -i /var/lib/ceph/osd/ceph-0/keyring
+        osd "allow *" mon "allow profile osd"
+    """
+    path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
+    osd_keyring = os.path.join(path, 'keyring')
+    bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/ceph.keyring'
+
+    process.run([
+        'sudo',
+        'ceph',
+        '--cluster', conf.cluster,
+        '--name', 'client.bootstrap-osd',
+        '--keyring', bootstrap_keyring,
+        'auth', 'add', 'osd.%s' % osd_id,
+        '-i', osd_keyring,
+        'osd', 'allow *',
+        'mon', 'allow profile osd',
+    ])
diff --git a/src/ceph-volume/ceph_volume/util/constants.py b/src/ceph-volume/ceph_volume/util/constants.py
new file mode 100644 (file)
index 0000000..07df5a4
--- /dev/null
@@ -0,0 +1,17 @@
+
+# mount flags
+mount = dict(
+    xfs='noatime,inode64',
+)
+
+
+# format flags
+mkfs = dict(
+    xfs=[
+        # force overwriting previous fs
+        '-f',
+        # set the inode size to 2kb
+        '-i', 'size=2048',
+    ],
+)
+
diff --git a/src/ceph-volume/ceph_volume/util/prepare.py b/src/ceph-volume/ceph_volume/util/prepare.py
new file mode 100644 (file)
index 0000000..ba224b8
--- /dev/null
@@ -0,0 +1,143 @@
+"""
+These utilities for prepare provide all the pieces needed to prepare a device
+but also a compounded ("single call") helper to do them in order. Some plugins
+may want to change some part of the process, while others might want to consume
+the single-call helper
+"""
+import os
+import logging
+from ceph_volume import process, conf, terminal
+from ceph_volume.util import system, constants
+
+logger = logging.getLogger(__name__)
+
+
+def create_id(fsid):
+    stdout, stderr, returncode = process.call(
+        [
+            'ceph',
+            '--cluster', conf.cluster,
+            '--name', 'client.bootstrap-osd',
+            '--keyring', '/var/lib/ceph/bootstrap-osd/ceph.keyring',
+            'osd', 'create', fsid
+        ],
+        terminal_logging=True
+    )
+    if returncode != 0:
+        for line in stdout:
+            terminal.write(line)
+        for line in stderr:
+            terminal.write(line)
+        raise RuntimeError()
+    return ' '.join(stdout).strip()
+
+
+def create_path(osd_id):
+    system.mkdir_p('/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id))
+
+
+def format_device(device):
+    # only supports xfs
+    command = ['sudo', 'mkfs', '-t', 'xfs']
+
+    # get the mkfs options if any for xfs,
+    # fallback to the default options defined in constants.mkfs
+    flags = conf.ceph.get_list(
+        'osd',
+        'osd_mkfs_options_xfs',
+        default=constants.mkfs.get('xfs'),
+        split=' ',
+    )
+
+    # always force
+    if '-f' not in flags:
+        flags.insert(0, '-f')
+
+    command.extend(flags)
+    command.append(device)
+    process.run(command)
+
+
+def mount_osd(device, osd_id):
+    destination = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id)
+    command = ['sudo', 'mount', '-t', 'xfs', '-o']
+    flags = conf.ceph.get_list(
+        'osd',
+        'osd_mount_options_xfs',
+        default=constants.mount.get('xfs'),
+        split=' ',
+    )
+    command.append(flags)
+    command.append(device)
+    command.append(destination)
+    process.run(command)
+
+
+def link_journal(journal_device, osd_id):
+    journal_path = '/var/lib/ceph/osd/%s-%s/journal' % (
+        conf.cluster,
+        osd_id
+    )
+    command = ['sudo', 'ln', '-s', journal_device, journal_path]
+    process.run(command)
+
+
+def get_monmap(osd_id):
+    """
+    Before creating the OSD files, a monmap needs to be retrieved so that it
+    can be used to tell the monitor(s) about the new OSD. A call will look like::
+
+        ceph --cluster ceph --name client.bootstrap-osd \
+             --keyring /var/lib/ceph/bootstrap-osd/ceph.keyring \
+             mon getmap -o /var/lib/ceph/osd/ceph-0/activate.monmap
+    """
+    path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
+    bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/ceph.keyring'
+    monmap_destination = os.path.join(path, 'activate.monmap')
+
+    process.run([
+        'sudo',
+        'ceph',
+        '--cluster', conf.cluster,
+        '--name', 'client.bootstrap-osd',
+        '--keyring', bootstrap_keyring,
+        'mon', 'getmap', '-o', monmap_destination
+    ])
+
+
+def osd_mkfs(osd_id, fsid):
+    """
+    Create the files for the OSD to function. A normal call will look like:
+
+          ceph-osd --cluster ceph --mkfs --mkkey -i 0 \
+                   --monmap /var/lib/ceph/osd/ceph-0/activate.monmap \
+                   --osd-data /var/lib/ceph/osd/ceph-0 \
+                   --osd-journal /var/lib/ceph/osd/ceph-0/journal \
+                   --osd-uuid 8d208665-89ae-4733-8888-5d3bfbeeec6c \
+                   --keyring /var/lib/ceph/osd/ceph-0/keyring \
+                   --setuser ceph --setgroup ceph
+
+    """
+    path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
+    monmap = os.path.join(path, 'activate.monmap')
+    journal = os.path.join(path, 'journal')
+    keyring = os.path.join(path, 'keyring')
+
+    system.chown(journal)
+    system.chown(path)
+
+    process.run([
+        'sudo',
+        'ceph-osd',
+        '--cluster', conf.cluster,
+        '--mkfs',
+        '--mkkey',
+        '-i', osd_id,
+        '--monmap', monmap,
+        '--osd-data', path,
+        '--osd-journal', journal,
+        '--osd-uuid', fsid,
+        '--keyring', keyring,
+        '--setuser', 'ceph',
+        '--setgroup', 'ceph'
+    ])
diff --git a/src/ceph-volume/ceph_volume/util/system.py b/src/ceph-volume/ceph_volume/util/system.py
new file mode 100644 (file)
index 0000000..f64ffa3
--- /dev/null
@@ -0,0 +1,48 @@
+import errno
+import os
+import pwd
+import uuid
+from ceph_volume import process
+
+
+def generate_uuid():
+    return str(uuid.uuid4())
+
+
+def get_ceph_user_ids():
+    """
+    Return the id and gid of the ceph user
+    """
+    try:
+        user = pwd.getpwnam('ceph')
+    except KeyError:
+        # is this even possible?
+        raise RuntimeError('"ceph" user is not available in the current system')
+    return user[2], user[3]
+
+
+def mkdir_p(path, chown=True):
+    """
+    A `mkdir -p` that defaults to chown the path to the ceph user
+    """
+    try:
+        os.mkdir(path)
+    except OSError as e:
+        if e.errno == errno.EEXIST:
+            pass
+        else:
+            raise
+    else:
+        uid, gid = get_ceph_user_ids()
+        os.chown(path, uid, gid)
+
+
+def chown(path, ceph_user=True):
+    """
+    ``chown`` a path to the ceph user (uid and guid fetched at runtime)
+    """
+    uid, gid = get_ceph_user_ids()
+    if os.path.islink(path):
+        path = os.path.realpath(path)
+    process.run(['chown', '-R', 'ceph:ceph', path])
+    #os.chown(path, uid, gid)