X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fceph-volume%2Fceph_volume%2Fdevices%2Flvm%2Flisting.py;fp=src%2Fceph%2Fsrc%2Fceph-volume%2Fceph_volume%2Fdevices%2Flvm%2Flisting.py;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=6982f91bcdae298a84af18c6aa6f6769226c8bac;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/ceph-volume/ceph_volume/devices/lvm/listing.py b/src/ceph/src/ceph-volume/ceph_volume/devices/lvm/listing.py deleted file mode 100644 index 6982f91..0000000 --- a/src/ceph/src/ceph-volume/ceph_volume/devices/lvm/listing.py +++ /dev/null @@ -1,244 +0,0 @@ -from __future__ import print_function -import argparse -import json -import logging -from textwrap import dedent -from ceph_volume import decorators -from ceph_volume.util import disk -from ceph_volume.api import lvm as api - -logger = logging.getLogger(__name__) - - -osd_list_header_template = """\n -{osd_id:=^20}""" - - -osd_device_header_template = """ - - [{type: >4}] {path} -""" - -device_metadata_item_template = """ - {tag_name: <25} {value}""" - - -def readable_tag(tag): - actual_name = tag.split('.')[-1] - return actual_name.replace('_', ' ') - - -def pretty_report(report): - output = [] - for _id, devices in report.items(): - output.append( - osd_list_header_template.format(osd_id=" osd.%s " % _id) - ) - for device in devices: - output.append( - osd_device_header_template.format( - type=device['type'], - path=device['path'] - ) - ) - for tag_name, value in device.get('tags', {}).items(): - output.append( - device_metadata_item_template.format( - tag_name=readable_tag(tag_name), - value=value - ) - ) - print(''.join(output)) - - -class List(object): - - help = 'list logical volumes and devices associated with Ceph' - - def __init__(self, argv): - self.argv = argv - - @decorators.needs_root - def list(self, args): - # ensure everything is up to date before calling out - # to list lv's - self.update() - report = self.generate(args) - if args.format == 'json': - # If the report is empty, we don't return a non-zero exit status - # because it is assumed this is going to be consumed by automated - # systems like ceph-ansible which would be forced to ignore the - # non-zero exit status if all they need is the information in the - # JSON object - print(json.dumps(report, indent=4, sort_keys=True)) - else: - if not report: - raise SystemExit('No valid Ceph devices found') - pretty_report(report) - - def update(self): - """ - Ensure all journal devices are up to date if they aren't a logical - volume - """ - lvs = api.Volumes() - for lv in lvs: - try: - lv.tags['ceph.osd_id'] - except KeyError: - # only consider ceph-based logical volumes, everything else - # will get ignored - continue - - for device_type in ['journal', 'block', 'wal', 'db']: - device_name = 'ceph.%s_device' % device_type - device_uuid = lv.tags.get('ceph.%s_uuid' % device_type) - if not device_uuid: - # bluestore will not have a journal, filestore will not have - # a block/wal/db, so we must skip if not present - continue - disk_device = disk.get_device_from_partuuid(device_uuid) - if disk_device: - if lv.tags[device_name] != disk_device: - # this means that the device has changed, so it must be updated - # on the API to reflect this - lv.set_tags({device_name: disk_device}) - - def generate(self, args): - """ - Generate reports for an individual device or for all Ceph-related - devices, logical or physical, as long as they have been prepared by - this tool before and contain enough metadata. - """ - if args.device: - return self.single_report(args.device) - else: - return self.full_report() - - def single_report(self, device): - """ - Generate a report for a single device. This can be either a logical - volume in the form of vg/lv or a device with an absolute path like - /dev/sda1 - """ - lvs = api.Volumes() - report = {} - lv = api.get_lv_from_argument(device) - if lv: - try: - _id = lv.tags['ceph.osd_id'] - except KeyError: - logger.warning('device is not part of ceph: %s', device) - return report - - report.setdefault(_id, []) - report[_id].append( - lv.as_dict() - ) - - else: - # this has to be a journal/wal/db device (not a logical volume) so try - # to find the PARTUUID that should be stored in the OSD logical - # volume - for device_type in ['journal', 'block', 'wal', 'db']: - device_tag_name = 'ceph.%s_device' % device_type - device_tag_uuid = 'ceph.%s_uuid' % device_type - associated_lv = lvs.get(lv_tags={device_tag_name: device}) - if associated_lv: - _id = associated_lv.tags['ceph.osd_id'] - uuid = associated_lv.tags[device_tag_uuid] - - report.setdefault(_id, []) - report[_id].append( - { - 'tags': {'PARTUUID': uuid}, - 'type': device_type, - 'path': device, - } - ) - return report - - def full_report(self): - """ - Generate a report for all the logical volumes and associated devices - that have been previously prepared by Ceph - """ - lvs = api.Volumes() - report = {} - for lv in lvs: - try: - _id = lv.tags['ceph.osd_id'] - except KeyError: - # only consider ceph-based logical volumes, everything else - # will get ignored - continue - - report.setdefault(_id, []) - report[_id].append( - lv.as_dict() - ) - - for device_type in ['journal', 'block', 'wal', 'db']: - device_uuid = lv.tags.get('ceph.%s_uuid' % device_type) - if not device_uuid: - # bluestore will not have a journal, filestore will not have - # a block/wal/db, so we must skip if not present - continue - if not api.get_lv(lv_uuid=device_uuid): - # means we have a regular device, so query blkid - disk_device = disk.get_device_from_partuuid(device_uuid) - if disk_device: - report[_id].append( - { - 'tags': {'PARTUUID': device_uuid}, - 'type': device_type, - 'path': disk_device, - } - ) - - return report - - def main(self): - sub_command_help = dedent(""" - List devices or logical volumes associated with Ceph. An association is - determined if a device has information relating to an OSD. This is - verified by querying LVM's metadata and correlating it with devices. - - The lvs associated with the OSD need to have been prepared previously, - so that all needed tags and metadata exist. - - Full listing of all system devices associated with a cluster:: - - ceph-volume lvm list - - List a particular device, reporting all metadata about it:: - - ceph-volume lvm list /dev/sda1 - - List a logical volume, along with all its metadata (vg is a volume - group, and lv the logical volume name):: - - ceph-volume lvm list {vg/lv} - """) - parser = argparse.ArgumentParser( - prog='ceph-volume lvm list', - formatter_class=argparse.RawDescriptionHelpFormatter, - description=sub_command_help, - ) - - parser.add_argument( - 'device', - metavar='DEVICE', - nargs='?', - help='Path to an lv (as vg/lv) or to a device like /dev/sda1' - ) - - parser.add_argument( - '--format', - help='output format, defaults to "pretty"', - default='pretty', - choices=['json', 'pretty'], - ) - - args = parser.parse_args(self.argv) - self.list(args)