+++ /dev/null
-from __future__ import print_function
-import argparse
-import os
-import pkg_resources
-import sys
-import logging
-
-import ceph_volume
-from ceph_volume.decorators import catches
-from ceph_volume import log, devices, configuration, conf, exceptions, terminal
-
-
-class Volume(object):
- _help = """
-ceph-volume: Deploy Ceph OSDs using different device technologies like lvm or
-physical disks.
-
-Version: {version}
-
-Log Path: {log_path}
-Ceph Conf: {ceph_path}
-
-{sub_help}
-{plugins}
-{environ_vars}
-{warning}
- """
-
- def __init__(self, argv=None, parse=True):
- self.mapper = {'lvm': devices.lvm.LVM, 'simple': devices.simple.Simple}
- self.plugin_help = "No plugins found/loaded"
- if argv is None:
- self.argv = sys.argv
- else:
- self.argv = argv
- if parse:
- self.main(self.argv)
-
- def help(self, warning=False):
- warning = 'See "ceph-volume --help" for full list of options.' if warning else ''
- return self._help.format(
- warning=warning,
- version=ceph_volume.__version__,
- log_path=conf.log_path,
- ceph_path=self.stat_ceph_conf(),
- plugins=self.plugin_help,
- sub_help=terminal.subhelp(self.mapper),
- environ_vars=self.get_environ_vars()
- )
-
- def get_environ_vars(self):
- environ_vars = []
- for key, value in os.environ.items():
- if key.startswith('CEPH_'):
- environ_vars.append("%s=%s" % (key, value))
- if not environ_vars:
- return ''
- else:
- environ_vars.insert(0, '\nEnviron Variables:')
- return '\n'.join(environ_vars)
-
- def enable_plugins(self):
- """
- Load all plugins available, add them to the mapper and extend the help
- string with the information from each one
- """
- plugins = _load_library_extensions()
- for plugin in plugins:
- self.mapper[plugin._ceph_volume_name_] = plugin
- self.plugin_help = '\n'.join(['%-19s %s\n' % (
- plugin.name, getattr(plugin, 'help_menu', ''))
- for plugin in plugins])
- if self.plugin_help:
- self.plugin_help = '\nPlugins:\n' + self.plugin_help
-
- def load_ceph_conf_path(self, cluster_name='ceph'):
- abspath = '/etc/ceph/%s.conf' % cluster_name
- conf.path = os.getenv('CEPH_CONF', abspath)
- conf.cluster = cluster_name
-
- def load_log_path(self):
- conf.log_path = os.getenv('CEPH_VOLUME_LOG_PATH', '/var/log/ceph')
-
- def stat_ceph_conf(self):
- try:
- configuration.load(conf.path)
- return terminal.green(conf.path)
- except exceptions.ConfigurationError as error:
- return terminal.red(error)
-
- def _get_split_args(self):
- subcommands = self.mapper.keys()
- slice_on_index = len(self.argv) + 1
- pruned_args = self.argv[1:]
- for count, arg in enumerate(pruned_args):
- if arg in subcommands:
- slice_on_index = count
- break
- return pruned_args[:slice_on_index], pruned_args[slice_on_index:]
-
- @catches()
- def main(self, argv):
- # these need to be available for the help, which gets parsed super
- # early
- self.load_ceph_conf_path()
- self.load_log_path()
- self.enable_plugins()
- main_args, subcommand_args = self._get_split_args()
- # no flags where passed in, return the help menu instead of waiting for
- # argparse which will end up complaning that there are no args
- if len(argv) <= 1:
- print(self.help(warning=True))
- return
- parser = argparse.ArgumentParser(
- prog='ceph-volume',
- formatter_class=argparse.RawDescriptionHelpFormatter,
- description=self.help(),
- )
- parser.add_argument(
- '--cluster',
- default='ceph',
- help='Cluster name (defaults to "ceph")',
- )
- parser.add_argument(
- '--log-level',
- default='debug',
- help='Change the file log level (defaults to debug)',
- )
- parser.add_argument(
- '--log-path',
- default='/var/log/ceph/',
- help='Change the log path (defaults to /var/log/ceph)',
- )
- args = parser.parse_args(main_args)
- conf.log_path = args.log_path
- if os.path.isdir(conf.log_path):
- conf.log_path = os.path.join(args.log_path, 'ceph-volume.log')
- log.setup()
- logger = logging.getLogger(__name__)
- # set all variables from args and load everything needed according to
- # them
- self.load_ceph_conf_path(cluster_name=args.cluster)
- try:
- conf.ceph = configuration.load(conf.path)
- except exceptions.ConfigurationError as error:
- # we warn only here, because it is possible that the configuration
- # file is not needed, or that it will be loaded by some other means
- # (like reading from lvm tags)
- logger.exception('ignoring inability to load ceph.conf')
- terminal.red(error)
- # dispatch to sub-commands
- terminal.dispatch(self.mapper, subcommand_args)
-
-
-def _load_library_extensions():
- """
- Locate all setuptools entry points by the name 'ceph_volume_handlers'
- and initialize them.
- Any third-party library may register an entry point by adding the
- following to their setup.py::
-
- entry_points = {
- 'ceph_volume_handlers': [
- 'plugin_name = mylib.mymodule:Handler_Class',
- ],
- },
-
- `plugin_name` will be used to load it as a sub command.
- """
- logger = logging.getLogger('ceph_volume.plugins')
- group = 'ceph_volume_handlers'
- entry_points = pkg_resources.iter_entry_points(group=group)
- plugins = []
- for ep in entry_points:
- try:
- logger.debug('loading %s' % ep.name)
- plugin = ep.load()
- plugin._ceph_volume_name_ = ep.name
- plugins.append(plugin)
- except Exception as error:
- logger.exception("Error initializing plugin %s: %s" % (ep, error))
- return plugins