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
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 'inventory': inventory
.Inventory
,
32 self
.plugin_help
= "No plugins found/loaded"
40 def help(self
, warning
=False):
41 warning
= 'See "ceph-volume --help" for full list of options.' if warning
else ''
42 return self
._help
.format(
44 log_path
=conf
.log_path
,
45 ceph_path
=self
.stat_ceph_conf(),
46 plugins
=self
.plugin_help
,
47 sub_help
=terminal
.subhelp(self
.mapper
),
48 environ_vars
=self
.get_environ_vars()
51 def get_environ_vars(self
):
53 for key
, value
in os
.environ
.items():
54 if key
.startswith('CEPH_'):
55 environ_vars
.append("%s=%s" % (key
, value
))
59 environ_vars
.insert(0, '\nEnviron Variables:')
60 return '\n'.join(environ_vars
)
62 def enable_plugins(self
):
64 Load all plugins available, add them to the mapper and extend the help
65 string with the information from each one
67 plugins
= _load_library_extensions()
68 for plugin
in plugins
:
69 self
.mapper
[plugin
._ceph
_volume
_name
_] = plugin
70 self
.plugin_help
= '\n'.join(['%-19s %s\n' % (
71 plugin
.name
, getattr(plugin
, 'help_menu', ''))
72 for plugin
in plugins
])
74 self
.plugin_help
= '\nPlugins:\n' + self
.plugin_help
76 def load_log_path(self
):
77 conf
.log_path
= os
.getenv('CEPH_VOLUME_LOG_PATH', '/var/log/ceph')
79 def stat_ceph_conf(self
):
81 configuration
.load(conf
.path
)
82 return terminal
.green(conf
.path
)
83 except exceptions
.ConfigurationError
as error
:
84 return terminal
.red(error
)
86 def _get_split_args(self
):
87 subcommands
= self
.mapper
.keys()
88 slice_on_index
= len(self
.argv
) + 1
89 pruned_args
= self
.argv
[1:]
90 for count
, arg
in enumerate(pruned_args
):
91 if arg
in subcommands
:
92 slice_on_index
= count
94 return pruned_args
[:slice_on_index
], pruned_args
[slice_on_index
:]
98 # these need to be available for the help, which gets parsed super
100 configuration
.load_ceph_conf_path()
102 self
.enable_plugins()
103 main_args
, subcommand_args
= self
._get
_split
_args
()
104 # no flags where passed in, return the help menu instead of waiting for
105 # argparse which will end up complaning that there are no args
107 print(self
.help(warning
=True))
109 parser
= argparse
.ArgumentParser(
111 formatter_class
=argparse
.RawDescriptionHelpFormatter
,
112 description
=self
.help(),
117 help='Cluster name (defaults to "ceph")',
122 help='Change the file log level (defaults to debug)',
126 default
='/var/log/ceph/',
127 help='Change the log path (defaults to /var/log/ceph)',
129 args
= parser
.parse_args(main_args
)
130 conf
.log_path
= args
.log_path
131 if os
.path
.isdir(conf
.log_path
):
132 conf
.log_path
= os
.path
.join(args
.log_path
, 'ceph-volume.log')
135 logger
= logging
.getLogger(__name__
)
136 logger
.info("Running command: ceph-volume %s %s", " ".join(main_args
), " ".join(subcommand_args
))
137 # set all variables from args and load everything needed according to
139 configuration
.load_ceph_conf_path(cluster_name
=args
.cluster
)
141 conf
.ceph
= configuration
.load(conf
.path
)
142 except exceptions
.ConfigurationError
as error
:
143 # we warn only here, because it is possible that the configuration
144 # file is not needed, or that it will be loaded by some other means
145 # (like reading from lvm tags)
146 logger
.exception('ignoring inability to load ceph.conf')
148 # dispatch to sub-commands
149 terminal
.dispatch(self
.mapper
, subcommand_args
)
152 def _load_library_extensions():
154 Locate all setuptools entry points by the name 'ceph_volume_handlers'
156 Any third-party library may register an entry point by adding the
157 following to their setup.py::
160 'ceph_volume_handlers': [
161 'plugin_name = mylib.mymodule:Handler_Class',
165 `plugin_name` will be used to load it as a sub command.
167 logger
= logging
.getLogger('ceph_volume.plugins')
168 group
= 'ceph_volume_handlers'
169 entry_points
= pkg_resources
.iter_entry_points(group
=group
)
171 for ep
in entry_points
:
173 logger
.debug('loading %s' % ep
.name
)
175 plugin
._ceph
_volume
_name
_ = ep
.name
176 plugins
.append(plugin
)
177 except Exception as error
:
178 logger
.exception("Error initializing plugin %s: %s" % (ep
, error
))