1 from __future__
import print_function
8 from ceph_volume
.decorators
import catches
9 from ceph_volume
import log
, devices
, configuration
, conf
, exceptions
, terminal
, inventory
, drive_group
14 ceph-volume: Deploy Ceph OSDs using different device technologies like lvm or
18 Ceph Conf: {ceph_path}
26 def __init__(self
, argv
=None, parse
=True):
28 'lvm': devices
.lvm
.LVM
,
29 'simple': devices
.simple
.Simple
,
30 'raw': devices
.raw
.Raw
,
31 'inventory': inventory
.Inventory
,
32 'drive-group': drive_group
.Deploy
,
34 self
.plugin_help
= "No plugins found/loaded"
42 def help(self
, warning
=False):
43 warning
= 'See "ceph-volume --help" for full list of options.' if warning
else ''
44 return self
._help
.format(
46 log_path
=conf
.log_path
,
47 ceph_path
=self
.stat_ceph_conf(),
48 plugins
=self
.plugin_help
,
49 sub_help
=terminal
.subhelp(self
.mapper
),
50 environ_vars
=self
.get_environ_vars()
53 def get_environ_vars(self
):
55 for key
, value
in os
.environ
.items():
56 if key
.startswith('CEPH_'):
57 environ_vars
.append("%s=%s" % (key
, value
))
61 environ_vars
.insert(0, '\nEnviron Variables:')
62 return '\n'.join(environ_vars
)
64 def enable_plugins(self
):
66 Load all plugins available, add them to the mapper and extend the help
67 string with the information from each one
69 plugins
= _load_library_extensions()
70 for plugin
in plugins
:
71 self
.mapper
[plugin
._ceph
_volume
_name
_] = plugin
72 self
.plugin_help
= '\n'.join(['%-19s %s\n' % (
73 plugin
.name
, getattr(plugin
, 'help_menu', ''))
74 for plugin
in plugins
])
76 self
.plugin_help
= '\nPlugins:\n' + self
.plugin_help
78 def load_log_path(self
):
79 conf
.log_path
= os
.getenv('CEPH_VOLUME_LOG_PATH', '/var/log/ceph')
81 def stat_ceph_conf(self
):
83 configuration
.load(conf
.path
)
84 return terminal
.green(conf
.path
)
85 except exceptions
.ConfigurationError
as error
:
86 return terminal
.red(error
)
88 def _get_split_args(self
):
89 subcommands
= self
.mapper
.keys()
90 slice_on_index
= len(self
.argv
) + 1
91 pruned_args
= self
.argv
[1:]
92 for count
, arg
in enumerate(pruned_args
):
93 if arg
in subcommands
:
94 slice_on_index
= count
96 return pruned_args
[:slice_on_index
], pruned_args
[slice_on_index
:]
100 # these need to be available for the help, which gets parsed super
102 configuration
.load_ceph_conf_path()
104 self
.enable_plugins()
105 main_args
, subcommand_args
= self
._get
_split
_args
()
106 # no flags where passed in, return the help menu instead of waiting for
107 # argparse which will end up complaning that there are no args
109 print(self
.help(warning
=True))
111 parser
= argparse
.ArgumentParser(
113 formatter_class
=argparse
.RawDescriptionHelpFormatter
,
114 description
=self
.help(),
119 help='Cluster name (defaults to "ceph")',
124 help='Change the file log level (defaults to debug)',
128 default
='/var/log/ceph/',
129 help='Change the log path (defaults to /var/log/ceph)',
131 args
= parser
.parse_args(main_args
)
132 conf
.log_path
= args
.log_path
133 if os
.path
.isdir(conf
.log_path
):
134 conf
.log_path
= os
.path
.join(args
.log_path
, 'ceph-volume.log')
137 logger
= logging
.getLogger(__name__
)
138 logger
.info("Running command: ceph-volume %s %s", " ".join(main_args
), " ".join(subcommand_args
))
139 # set all variables from args and load everything needed according to
141 configuration
.load_ceph_conf_path(cluster_name
=args
.cluster
)
143 conf
.ceph
= configuration
.load(conf
.path
)
144 except exceptions
.ConfigurationError
as error
:
145 # we warn only here, because it is possible that the configuration
146 # file is not needed, or that it will be loaded by some other means
147 # (like reading from lvm tags)
148 logger
.exception('ignoring inability to load ceph.conf')
150 # dispatch to sub-commands
151 terminal
.dispatch(self
.mapper
, subcommand_args
)
154 def _load_library_extensions():
156 Locate all setuptools entry points by the name 'ceph_volume_handlers'
158 Any third-party library may register an entry point by adding the
159 following to their setup.py::
162 'ceph_volume_handlers': [
163 'plugin_name = mylib.mymodule:Handler_Class',
167 `plugin_name` will be used to load it as a sub command.
169 logger
= logging
.getLogger('ceph_volume.plugins')
170 group
= 'ceph_volume_handlers'
171 entry_points
= pkg_resources
.iter_entry_points(group
=group
)
173 for ep
in entry_points
:
175 logger
.debug('loading %s' % ep
.name
)
177 plugin
._ceph
_volume
_name
_ = ep
.name
178 plugins
.append(plugin
)
179 except Exception as error
:
180 logger
.exception("Error initializing plugin %s: %s" % (ep
, error
))