from ceph_volume.util import arg_validators
from . import strategies
+mlogger = terminal.MultiLogger(__name__)
+
device_list_template = """
* {path: <25} {size: <10} {state}"""
return strategies.filestore.MixedType
-def get_strategy(args):
+def get_strategy(args, devices):
"""
Given a set of devices as input, go through the different detection
mechanisms to narrow down on a strategy to use. The strategies are 4 in
strategies = filestore_strategies
for strategy in strategies:
- backend = strategy(args.devices)
+ backend = strategy(devices)
if backend:
- return backend(args.devices, args)
+ return backend
class Batch(object):
)
def report(self, args):
- strategy = get_strategy(args)
+ strategy = self._get_strategy(args)
if args.format == 'pretty':
strategy.report_pretty()
elif args.format == 'json':
raise RuntimeError('report format must be "pretty" or "json"')
def execute(self, args):
- strategy = get_strategy(args)
+ strategy = self._get_strategy(args)
if not args.yes:
strategy.report_pretty()
terminal.info('The above OSDs would be created if the operation continues')
strategy.execute()
+ def _get_strategy(self, args):
+ strategy = get_strategy(args, args.devices)
+ unused_devices = [device for device in args.devices if not device.used_by_ceph]
+ # only data devices, journals can be reused
+ used_devices = [device.abspath for device in args.devices if device.used_by_ceph]
+ args.filtered_devices = {}
+ if used_devices:
+ for device in used_devices:
+ args.filtered_devices[device] = {"reasons": ["Used by ceph as a data device already"]}
+ if not args.report:
+ mlogger.info("Ignoring devices already used by ceph: %s" % ",".join(used_devices))
+ if not unused_devices and not args.report:
+ # report nothing changed
+ mlogger.info("All devices are already used by ceph. No OSDs will be created.")
+ raise SystemExit(0)
+ else:
+ new_strategy = get_strategy(args, unused_devices)
+ if type(strategy) != type(new_strategy):
+ if not args.report:
+ mlogger.error("aborting because strategy changed from %s to %s after filtering" % (strategy, new_strategy))
+ raise SystemExit(0)
+ else:
+ strategy = new_strategy
+ return strategy(unused_devices, args)
+
@decorators.needs_root
def main(self):
parser = argparse.ArgumentParser(
self.devices = devices
self.hdds = [device for device in devices if device.sys_api['rotational'] == '1']
self.ssds = [device for device in devices if device.sys_api['rotational'] == '0']
- self.computed = {'osds': [], 'vgs': []}
+ self.computed = {'osds': [], 'vgs': [], 'filtered_devices': args.filtered_devices}
self.journal_size = get_journal_size(args)
self.validate()
self.compute()
# chose whichever is the one group we have to compute against
devices = self.hdds or self.ssds
osds = self.computed['osds']
- used_osds = []
for device in devices:
for osd in range(self.osds_per_device):
device_size = disk.Size(b=device.sys_api['size'])
journal_size = self.journal_size
data_size = osd_size - journal_size
data_percentage = data_size * 100 / device_size
- used_osds.append(device.used_by_ceph)
osd = {'data': {}, 'journal': {}, 'used_by_ceph': device.used_by_ceph}
osd['data']['path'] = device.abspath
osd['data']['size'] = data_size.b.as_int()
osd['journal']['human_readable_size'] = str(journal_size)
osds.append(osd)
- self.computed['changed'] = not any(used_osds)
+ self.computed['changed'] = len(osds) > 0
def execute(self):
"""