1 from __future__
import print_function
9 from ceph_volume
.decorators
import catches
10 from ceph_volume
import log
, devices
, configuration
, conf
, exceptions
, terminal
15 ceph-volume: Deploy Ceph OSDs using different device technologies like lvm or
21 Ceph Conf: {ceph_path}
29 def __init__(self
, argv
=None, parse
=True):
30 self
.mapper
= {'lvm': devices
.lvm
.LVM
, 'simple': devices
.simple
.Simple
}
31 self
.plugin_help
= "No plugins found/loaded"
39 def help(self
, warning
=False):
40 warning
= 'See "ceph-volume --help" for full list of options.' if warning
else ''
41 return self
._help
.format(
43 version
=ceph_volume
.__version
__,
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_ceph_conf_path(self
, cluster_name
='ceph'):
77 abspath
= '/etc/ceph/%s.conf' % cluster_name
78 conf
.path
= os
.getenv('CEPH_CONF', abspath
)
79 conf
.cluster
= cluster_name
81 def load_log_path(self
):
82 conf
.log_path
= os
.getenv('CEPH_VOLUME_LOG_PATH', '/var/log/ceph')
84 def stat_ceph_conf(self
):
86 configuration
.load(conf
.path
)
87 return terminal
.green(conf
.path
)
88 except exceptions
.ConfigurationError
as error
:
89 return terminal
.red(error
)
91 def _get_split_args(self
):
92 subcommands
= self
.mapper
.keys()
93 slice_on_index
= len(self
.argv
) + 1
94 pruned_args
= self
.argv
[1:]
95 for count
, arg
in enumerate(pruned_args
):
96 if arg
in subcommands
:
97 slice_on_index
= count
99 return pruned_args
[:slice_on_index
], pruned_args
[slice_on_index
:]
102 def main(self
, argv
):
103 # these need to be available for the help, which gets parsed super
105 self
.load_ceph_conf_path()
107 self
.enable_plugins()
108 main_args
, subcommand_args
= self
._get
_split
_args
()
109 # no flags where passed in, return the help menu instead of waiting for
110 # argparse which will end up complaning that there are no args
112 print(self
.help(warning
=True))
114 parser
= argparse
.ArgumentParser(
116 formatter_class
=argparse
.RawDescriptionHelpFormatter
,
117 description
=self
.help(),
122 help='Cluster name (defaults to "ceph")',
127 help='Change the file log level (defaults to debug)',
131 default
='/var/log/ceph/',
132 help='Change the log path (defaults to /var/log/ceph)',
134 args
= parser
.parse_args(main_args
)
135 conf
.log_path
= args
.log_path
136 if os
.path
.isdir(conf
.log_path
):
137 conf
.log_path
= os
.path
.join(args
.log_path
, 'ceph-volume.log')
139 logger
= logging
.getLogger(__name__
)
140 # set all variables from args and load everything needed according to
142 self
.load_ceph_conf_path(cluster_name
=args
.cluster
)
144 conf
.ceph
= configuration
.load(conf
.path
)
145 except exceptions
.ConfigurationError
as error
:
146 # we warn only here, because it is possible that the configuration
147 # file is not needed, or that it will be loaded by some other means
148 # (like reading from lvm tags)
149 logger
.exception('ignoring inability to load ceph.conf')
151 # dispatch to sub-commands
152 terminal
.dispatch(self
.mapper
, subcommand_args
)
155 def _load_library_extensions():
157 Locate all setuptools entry points by the name 'ceph_volume_handlers'
159 Any third-party library may register an entry point by adding the
160 following to their setup.py::
163 'ceph_volume_handlers': [
164 'plugin_name = mylib.mymodule:Handler_Class',
168 `plugin_name` will be used to load it as a sub command.
170 logger
= logging
.getLogger('ceph_volume.plugins')
171 group
= 'ceph_volume_handlers'
172 entry_points
= pkg_resources
.iter_entry_points(group
=group
)
174 for ep
in entry_points
:
176 logger
.debug('loading %s' % ep
.name
)
178 plugin
._ceph
_volume
_name
_ = ep
.name
179 plugins
.append(plugin
)
180 except Exception as error
:
181 logger
.exception("Error initializing plugin %s: %s" % (ep
, error
))