]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/ceph-disk/ceph_disk/main.py
update sources to v12.1.1
[ceph.git] / ceph / src / ceph-disk / ceph_disk / main.py
index a98350f99a0ce1836c91500cb897972504dc9272..ddc6bcfa23d98464bf1ae1922a06dfd8af8a498b 100755 (executable)
@@ -546,53 +546,6 @@ def command_check_call(arguments, exit=False):
         raise
 
 
-def platform_distro():
-    """
-    Returns a normalized, lower case string without any leading nor trailing
-    whitespace that represents the distribution name of the current machine.
-    """
-    distro = platform_information()[0] or ''
-    return distro.strip().lower()
-
-
-def platform_information():
-    if FREEBSD:
-        distro = platform.system()
-        release = platform.version().split()[1]
-        codename = platform.version().split()[3]
-        version = platform.version().split('-')[0][:-1]
-        major_version = version.split('.')[0]
-        major, minor = release.split('.')
-    else:
-        distro, release, codename = platform.linux_distribution()
-        # this could be an empty string in Debian
-        if not codename and 'debian' in distro.lower():
-            debian_codenames = {
-                '8': 'jessie',
-                '7': 'wheezy',
-                '6': 'squeeze',
-            }
-            major_version = release.split('.')[0]
-            codename = debian_codenames.get(major_version, '')
-
-            # In order to support newer jessie/sid,  wheezy/sid strings we test
-            # this if sid is buried in the minor, we should use sid anyway.
-            if not codename and '/' in release:
-                major, minor = release.split('/')
-                if minor == 'sid':
-                    codename = minor
-                else:
-                    codename = major
-        # this could be an empty string in Virtuozzo linux
-        if not codename and 'virtuozzo linux' in distro.lower():
-            codename = 'virtuozzo'
-
-    return (
-        str(distro).strip(),
-        str(release).strip(),
-        str(codename).strip()
-    )
-
 #
 # An alternative block_path implementation would be
 #
@@ -712,6 +665,30 @@ def get_dev_size(dev, size='megabytes'):
         os.close(fd)
 
 
+def stmode_is_diskdevice(dmode):
+    if stat.S_ISBLK(dmode):
+        return True
+    else:
+        # FreeBSD does not have block devices
+        # All disks are character devices
+        return FREEBSD and stat.S_ISCHR(dmode)
+
+
+def dev_is_diskdevice(dev):
+    dmode = os.stat(dev).st_mode
+    return stmode_is_diskdevice(dmode)
+
+
+def ldev_is_diskdevice(dev):
+    dmode = os.lstat(dev).st_mode
+    return stmode_is_diskdevice(dmode)
+
+
+def path_is_diskdevice(path):
+    dev = os.path.realpath(path)
+    return dev_is_diskdevice(dev)
+
+
 def get_partition_mpath(dev, pnum):
     part_re = "part{pnum}-mpath-".format(pnum=pnum)
     partitions = list_partitions_mpath(dev, part_re)
@@ -824,7 +801,7 @@ def get_partition_base(dev):
     Get the base device for a partition
     """
     dev = os.path.realpath(dev)
-    if not stat.S_ISBLK(os.lstat(dev).st_mode):
+    if not ldev_is_diskdevice(dev):
         raise Error('not a block device', dev)
 
     name = get_dev_name(dev)
@@ -866,7 +843,7 @@ def is_partition(dev):
 
     dev = os.path.realpath(dev)
     st = os.lstat(dev)
-    if not stat.S_ISBLK(st.st_mode):
+    if not stmode_is_diskdevice(st.st_mode):
         raise Error('not a block device', dev)
 
     name = get_dev_name(dev)
@@ -1579,14 +1556,7 @@ def update_partition(dev, description):
     command_check_call(['udevadm', 'settle', '--timeout=600'])
 
 
-def zap(dev):
-    """
-    Destroy the partition table and content of a given disk.
-    """
-    dev = os.path.realpath(dev)
-    dmode = os.stat(dev).st_mode
-    if not stat.S_ISBLK(dmode) or is_partition(dev):
-        raise Error('not full block device; cannot zap', dev)
+def zap_linux(dev):
     try:
         # Thoroughly wipe all partitions of any traces of
         # Filesystems or OSD Journals
@@ -1645,13 +1615,42 @@ def zap(dev):
                 dev,
             ],
         )
-
         update_partition(dev, 'zapped')
 
     except subprocess.CalledProcessError as e:
         raise Error(e)
 
 
+def zap_freebsd(dev):
+    try:
+        # For FreeBSD we just need to zap the partition.
+        command_check_call(
+            [
+                'gpart',
+                'destroy',
+                '-F',
+                dev,
+            ],
+        )
+
+    except subprocess.CalledProcessError as e:
+        raise Error(e)
+
+
+def zap(dev):
+    """
+    Destroy the partition table and content of a given disk.
+    """
+    dev = os.path.realpath(dev)
+    dmode = os.stat(dev).st_mode
+    if not stat.S_ISBLK(dmode) or is_partition(dev):
+        raise Error('not full block device; cannot zap', dev)
+    if FREEBSD:
+        zap_freebsd(dev)
+    else:
+        zap_linux(dev)
+
+
 def adjust_symlink(target, path):
     create = True
     if os.path.lexists(path):
@@ -1988,7 +1987,9 @@ class Prepare(object):
             formatter_class=argparse.RawDescriptionHelpFormatter,
             description=textwrap.fill(textwrap.dedent("""\
             If the --bluestore argument is given, a bluestore objectstore
-            will be used instead of the legacy filestore objectstore.
+            will be created.  If --filestore is provided, a legacy FileStore
+            objectstore will be created.  If neither is specified, we default
+            to BlueStore.
 
             When an entire device is prepared for bluestore, two
             partitions are created. The first partition is for metadata,
@@ -2086,9 +2087,16 @@ class PrepareBluestore(Prepare):
         parser = argparse.ArgumentParser(add_help=False)
         parser.add_argument(
             '--bluestore',
-            action='store_true', default=None,
+            dest='bluestore',
+            action='store_true', default=True,
             help='bluestore objectstore',
         )
+        parser.add_argument(
+            '--filestore',
+            dest='bluestore',
+            action='store_false',
+            help='filestore objectstore',
+        )
         return parser
 
     @staticmethod
@@ -2135,9 +2143,8 @@ class PrepareSpace(object):
     def set_type(self):
         name = self.name
         args = self.args
-        dmode = os.stat(args.data).st_mode
         if (self.wants_space() and
-                stat.S_ISBLK(dmode) and
+                dev_is_diskdevice(args.data) and
                 not is_partition(args.data) and
                 getattr(args, name) is None and
                 getattr(args, name + '_file') is None):
@@ -2160,7 +2167,7 @@ class PrepareSpace(object):
             return
 
         mode = os.stat(getattr(args, name)).st_mode
-        if stat.S_ISBLK(mode):
+        if stmode_is_diskdevice(mode):
             if getattr(args, name + '_file'):
                 raise Error('%s is not a regular file' % name.capitalize,
                             getattr(args, name))
@@ -2445,15 +2452,22 @@ class PrepareBluestoreBlockDB(PrepareSpace):
         super(PrepareBluestoreBlockDB, self).__init__(args)
 
     def get_space_size(self):
-        block_size = get_conf(
+        block_db_size = get_conf(
             cluster=self.args.cluster,
             variable='bluestore_block_db_size',
         )
 
-        if block_size is None:
-            return 20480  # MB, default value
+        if block_db_size is None or int(block_db_size) == 0:
+            block_size = get_conf(
+                cluster=self.args.cluster,
+                variable='bluestore_block_size',
+            )
+            if block_size is None:
+                return 1024  # MB
+            size = int(block_size) / 100 / 1048576
+            return max(size, 1024)  # MB
         else:
-            return int(block_size) / 1048576  # MB
+            return int(block_db_size) / 1048576  # MB
 
     def desired_partition_number(self):
         if getattr(self.args, 'block.db') == self.args.data:
@@ -2770,7 +2784,7 @@ class PrepareData(object):
 
         if stat.S_ISDIR(dmode):
             self.type = self.FILE
-        elif stat.S_ISBLK(dmode):
+        elif stmode_is_diskdevice(dmode):
             self.type = self.DEVICE
         else:
             raise Error('not a dir or block device', self.args.data)
@@ -2996,6 +3010,11 @@ class PrepareFilestoreData(PrepareData):
         self.set_data_partition()
         self.populate_data_path_device(*to_prepare_list)
 
+    def populate_data_path(self, path, *to_prepare_list):
+        super(PrepareFilestoreData, self).populate_data_path(path,
+                                                             *to_prepare_list)
+        write_one_line(path, 'type', 'filestore')
+
 
 class PrepareBluestoreData(PrepareData):
 
@@ -3081,7 +3100,7 @@ def mkfs(
                 '--setgroup', get_ceph_group(),
             ],
         )
-    else:
+    elif osd_type == 'filestore':
         ceph_osd_mkfs(
             [
                 'ceph-osd',
@@ -3098,6 +3117,8 @@ def mkfs(
                 '--setgroup', get_ceph_group(),
             ],
         )
+    else:
+        raise Error('unrecognized objectstore type %s' % osd_type)
 
 
 def auth_key(
@@ -3312,8 +3333,8 @@ def start_daemon(
         elif os.path.exists(os.path.join(path, 'bsdrc')):
             command_check_call(
                 [
-                    '/usr/local/etc/rc.d/ceph start osd.{osd_id}'
-                    .format(osd_id=osd_id),
+                    '/usr/sbin/service', 'ceph', 'start',
+                    'osd.{osd_id}'.format(osd_id=osd_id),
                 ],
             )
         else:
@@ -3718,7 +3739,7 @@ def main_activate(args):
 
     with activate_lock:
         mode = os.stat(args.path).st_mode
-        if stat.S_ISBLK(mode):
+        if stmode_is_diskdevice(mode):
             if (is_partition(args.path) and
                     (get_partition_type(args.path) ==
                      PTYPE['mpath']['osd']['ready']) and
@@ -4090,8 +4111,7 @@ def get_space_osd_uuid(name, path):
     if not os.path.exists(path):
         raise Error('%s does not exist' % path)
 
-    mode = os.stat(path).st_mode
-    if not stat.S_ISBLK(mode):
+    if path_is_diskdevice(path):
         raise Error('%s is not a block device' % path)
 
     if (is_partition(path) and
@@ -4680,7 +4700,7 @@ def is_suppressed(path):
     disk = os.path.realpath(path)
     try:
         if (not disk.startswith('/dev/') or
-                not stat.S_ISBLK(os.lstat(disk).st_mode)):
+                not ldev_is_diskdevice(disk)):
             return False
         base = get_dev_name(disk)
         while len(base):
@@ -4695,7 +4715,7 @@ def set_suppress(path):
     disk = os.path.realpath(path)
     if not os.path.exists(disk):
         raise Error('does not exist', path)
-    if not stat.S_ISBLK(os.lstat(path).st_mode):
+    if ldev_is_diskdevice(path):
         raise Error('not a block device', path)
     base = get_dev_name(disk)
 
@@ -4708,7 +4728,7 @@ def unset_suppress(path):
     disk = os.path.realpath(path)
     if not os.path.exists(disk):
         raise Error('does not exist', path)
-    if not stat.S_ISBLK(os.lstat(path).st_mode):
+    if not ldev_is_diskdevice(path):
         raise Error('not a block device', path)
     assert disk.startswith('/dev/')
     base = get_dev_name(disk)
@@ -4877,9 +4897,14 @@ def main_trigger(args):
 def main_fix(args):
     # A hash table containing 'path': ('uid', 'gid', blocking, recursive)
     fix_table = [
-        ('/etc/ceph', 'ceph', 'ceph', True, True),
+        ('/usr/bin/ceph-mon', 'root', 'root', True, False),
+        ('/usr/bin/ceph-mds', 'root', 'root', True, False),
+        ('/usr/bin/ceph-osd', 'root', 'root', True, False),
+        ('/usr/bin/radosgw', 'root', 'root', True, False),
+        ('/etc/ceph', 'root', 'root', True, True),
         ('/var/run/ceph', 'ceph', 'ceph', True, True),
         ('/var/log/ceph', 'ceph', 'ceph', True, True),
+        ('/var/log/radosgw', 'ceph', 'ceph', True, True),
         ('/var/lib/ceph', 'ceph', 'ceph', True, False),
     ]
 
@@ -4934,6 +4959,10 @@ def main_fix(args):
     # Use find to relabel + chown ~simultaenously
     if args.all:
         for directory, uid, gid, blocking, recursive in fix_table:
+            # Skip directories/files that are not installed
+            if not os.access(directory, os.F_OK):
+                continue
+
             c = [
                 'find',
                 directory,
@@ -4973,6 +5002,10 @@ def main_fix(args):
     # Fix permissions
     if args.permissions:
         for directory, uid, gid, blocking, recursive in fix_table:
+            # Skip directories/files that are not installed
+            if not os.access(directory, os.F_OK):
+                continue
+
             if recursive:
                 c = [
                     'chown',
@@ -5008,6 +5041,10 @@ def main_fix(args):
     # Fix SELinux labels
     if args.selinux:
         for directory, uid, gid, blocking, recursive in fix_table:
+            # Skip directories/files that are not installed
+            if not os.access(directory, os.F_OK):
+                continue
+
             if recursive:
                 c = [
                     'restorecon',
@@ -5631,7 +5668,9 @@ def main(argv):
         path = os.environ.get('PATH', os.defpath)
         os.environ['PATH'] = args.prepend_to_path + ":" + path
 
-    setup_statedir(args.statedir)
+    if args.func.__name__ != 'main_trigger':
+        # trigger may run when statedir is unavailable and does not use it
+        setup_statedir(args.statedir)
     setup_sysconfdir(args.sysconfdir)
 
     global CEPH_PREF_USER