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
, activate
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 'activate': activate
.Activate
,
33 'drive-group': drive_group
.Deploy
,
35 self
.plugin_help
= "No plugins found/loaded"
43 def help(self
, warning
=False):
44 warning
= 'See "ceph-volume --help" for full list of options.' if warning
else ''
45 return self
._help
.format(
47 log_path
=conf
.log_path
,
48 ceph_path
=self
.stat_ceph_conf(),
49 plugins
=self
.plugin_help
,
50 sub_help
=terminal
.subhelp(self
.mapper
),
51 environ_vars
=self
.get_environ_vars()
54 def get_environ_vars(self
):
56 for key
, value
in os
.environ
.items():
57 if key
.startswith('CEPH_'):
58 environ_vars
.append("%s=%s" % (key
, value
))
62 environ_vars
.insert(0, '\nEnviron Variables:')
63 return '\n'.join(environ_vars
)
65 def enable_plugins(self
):
67 Load all plugins available, add them to the mapper and extend the help
68 string with the information from each one
70 plugins
= _load_library_extensions()
71 for plugin
in plugins
:
72 self
.mapper
[plugin
._ceph
_volume
_name
_] = plugin
73 self
.plugin_help
= '\n'.join(['%-19s %s\n' % (
74 plugin
.name
, getattr(plugin
, 'help_menu', ''))
75 for plugin
in plugins
])
77 self
.plugin_help
= '\nPlugins:\n' + self
.plugin_help
79 def load_log_path(self
):
80 conf
.log_path
= os
.getenv('CEPH_VOLUME_LOG_PATH', '/var/log/ceph')
82 def stat_ceph_conf(self
):
84 configuration
.load(conf
.path
)
85 return terminal
.green(conf
.path
)
86 except exceptions
.ConfigurationError
as error
:
87 return terminal
.red(error
)
89 def _get_split_args(self
):
90 subcommands
= self
.mapper
.keys()
91 slice_on_index
= len(self
.argv
) + 1
92 pruned_args
= self
.argv
[1:]
93 for count
, arg
in enumerate(pruned_args
):
94 if arg
in subcommands
:
95 slice_on_index
= count
97 return pruned_args
[:slice_on_index
], pruned_args
[slice_on_index
:]
100 def main(self
, argv
):
101 # these need to be available for the help, which gets parsed super
103 configuration
.load_ceph_conf_path()
105 self
.enable_plugins()
106 main_args
, subcommand_args
= self
._get
_split
_args
()
107 # no flags where passed in, return the help menu instead of waiting for
108 # argparse which will end up complaning that there are no args
110 print(self
.help(warning
=True))
112 parser
= argparse
.ArgumentParser(
114 formatter_class
=argparse
.RawDescriptionHelpFormatter
,
115 description
=self
.help(),
120 help='Cluster name (defaults to "ceph")',
125 choices
=['debug', 'info', 'warning', 'error', 'critical'],
126 help='Change the file log level (defaults to debug)',
130 default
='/var/log/ceph/',
131 help='Change the log path (defaults to /var/log/ceph)',
133 args
= parser
.parse_args(main_args
)
134 conf
.log_path
= args
.log_path
135 if os
.path
.isdir(conf
.log_path
):
136 conf
.log_path
= os
.path
.join(args
.log_path
, 'ceph-volume.log')
137 log
.setup(log_level
=args
.log_level
)
139 logger
= logging
.getLogger(__name__
)
140 logger
.info("Running command: ceph-volume %s %s", " ".join(main_args
), " ".join(subcommand_args
))
141 # set all variables from args and load everything needed according to
143 configuration
.load_ceph_conf_path(cluster_name
=args
.cluster
)
145 conf
.ceph
= configuration
.load(conf
.path
)
146 except exceptions
.ConfigurationError
as error
:
147 # we warn only here, because it is possible that the configuration
148 # file is not needed, or that it will be loaded by some other means
149 # (like reading from lvm tags)
150 logger
.warning('ignoring inability to load ceph.conf', exc_info
=1)
151 terminal
.yellow(error
)
152 # dispatch to sub-commands
153 terminal
.dispatch(self
.mapper
, subcommand_args
)
156 def _load_library_extensions():
158 Locate all setuptools entry points by the name 'ceph_volume_handlers'
160 Any third-party library may register an entry point by adding the
161 following to their setup.py::
164 'ceph_volume_handlers': [
165 'plugin_name = mylib.mymodule:Handler_Class',
169 `plugin_name` will be used to load it as a sub command.
171 logger
= logging
.getLogger('ceph_volume.plugins')
172 group
= 'ceph_volume_handlers'
173 entry_points
= pkg_resources
.iter_entry_points(group
=group
)
175 for ep
in entry_points
:
177 logger
.debug('loading %s' % ep
.name
)
179 plugin
._ceph
_volume
_name
_ = ep
.name
180 plugins
.append(plugin
)
181 except Exception as error
:
182 logger
.exception("Error initializing plugin %s: %s" % (ep
, error
))