def do_force_delete(cs, args): """Attempt forced removal of volume(s), regardless of the state(s).""" failure_count = 0 for volume in args.volume: try: utils.find_volume(cs, volume).force_delete() except Exception as e: failure_count += 1 print("Delete for volume %s failed: %s" % (volume, e)) if failure_count == len(args.volume): raise exceptions.CommandError("Unable to force delete any of the " "specified volumes.")
def do_delete(cs, args): """Remove a volume(s).""" failure_count = 0 for volume in args.volume: try: utils.find_volume(cs, volume).delete() except Exception as e: failure_count += 1 print("Delete for volume %s failed: %s" % (volume, e)) if failure_count == len(args.volume): raise exceptions.CommandError("Unable to delete any of the specified " "volumes.")
def do_delete(cs, args): """Remove volume(s).""" failure_count = 0 for volume in args.volume: try: utils.find_volume(cs, volume).delete() except Exception as e: failure_count += 1 print("Delete for volume %s failed: %s" % (volume, e)) if failure_count == len(args.volume): raise exceptions.CommandError("Unable to delete any of the specified " "volumes.")
def do_export(cs, args): """export a volume(s).""" failure_count = 0 for volume in args.volume: try: utils.find_volume(cs, volume).export() except Exception as e: failure_count += 1 print("export for volume %s failed: %s" % (volume, e)) if failure_count == len(args.volume): raise exceptions.CommandError("Unable to export any of the specified " "volumes.")
def do_rename(cs, args): """Rename a volume.""" kwargs = {} if args.display_name is not None: kwargs['display_name'] = args.display_name if args.display_description is not None: kwargs['display_description'] = args.display_description if not any(kwargs): msg = 'Must supply either display-name or display-description.' raise exceptions.ClientException(code=1, message=msg) utils.find_volume(cs, args.volume).update(**kwargs)
def do_rename(cs, args): """Renames a volume.""" kwargs = {} if args.display_name is not None: kwargs['display_name'] = args.display_name if args.display_description is not None: kwargs['display_description'] = args.display_description if not any(kwargs): msg = 'Must supply either display-name or display-description.' raise exceptions.ClientException(code=1, message=msg) utils.find_volume(cs, args.volume).update(**kwargs)
def do_reset_state(cs, args): """Explicitly updates the volume state.""" failure_flag = False for volume in args.volume: try: utils.find_volume(cs, volume).reset_state(args.state) except Exception as e: failure_flag = True msg = "Reset state for volume %s failed: %s" % (volume, e) print(msg) if failure_flag: msg = "Unable to reset the state for the specified volume(s)." raise exceptions.CommandError(msg)
def do_rename(cs, args): """Rename a volume.""" kwargs = {} if args.name is not None: kwargs["name"] = args.name if args.display_description is not None: kwargs["description"] = args.display_description elif args.description is not None: kwargs["description"] = args.description if not any(kwargs): msg = "Must supply either name or description." raise exceptions.ClientException(code=1, message=msg) utils.find_volume(cs, args.volume).update(**kwargs)
def do_upload_to_image(cs, args): """Uploads volume to Image Service as an image.""" volume = utils.find_volume(cs, args.volume) _print_volume_image(volume.upload_to_image(args.force, args.image_name, args.container_format, args.disk_format))
def do_backup_restore(cs, args): """Restores a backup.""" if args.volume_id: volume_id = utils.find_volume(cs, args.volume_id).id else: volume_id = None cs.restores.restore(args.backup, volume_id)
def do_snapshot_create(cs, args): """Creates a snapshot.""" volume = utils.find_volume(cs, args.volume) snapshot = cs.volume_snapshots.create(volume.id, args.force, args.display_name, args.display_description) _print_volume_snapshot(snapshot)
def do_backup_restore(cs, args): """Restore a backup.""" if args.volume_id: volume_id = utils.find_volume(cs, args.volume_id).id else: volume_id = None cs.restores.restore(args.backup, volume_id)
def do_upload_to_image(cs, args): """Upload volume to image service as image.""" volume = utils.find_volume(cs, args.volume) _print_volume_image(volume.upload_to_image(args.force, args.image_name, args.container_format, args.disk_format))
def do_backup_restore(cs, args): """Restore a backup.""" vol = args.volume or args.volume_id if vol: volume_id = utils.find_volume(cs, vol).id else: volume_id = None cs.restores.restore(args.backup, volume_id)
def do_show(cs, args): """Show details about a volume.""" info = dict() volume = utils.find_volume(cs, args.volume) info.update(volume._info) info.pop('links', None) utils.print_dict(info)
def do_metadata(cs, args): """Set or Delete metadata on a volume.""" volume = utils.find_volume(cs, args.volume) metadata = _extract_metadata(args) if args.action == 'set': cs.volumes.set_metadata(volume, metadata) elif args.action == 'unset': cs.volumes.delete_metadata(volume, list(metadata.keys()))
def do_backup_restore(cs, args): """Restores a backup.""" if args.volume_id: volume_id = utils.find_volume(cs, args.volume_id).id else: volume_id = None cs.restores.restore(args.backup, volume_id, args.availability_zone, args.description)
def do_reset_state(cs, args): """Explicitly update the state of a volume.""" failure_count = 0 single = (len(args.volume) == 1) for volume in args.volume: try: utils.find_volume(cs, volume).reset_state(args.state) except Exception as e: failure_count += 1 msg = "Reset state for volume %s failed: %s" % (volume, e) if not single: print(msg) if failure_count == len(args.volume): if not single: msg = "Unable to reset the state for any of the specified volumes." raise exceptions.CommandError(msg)
def do_metadata(cs, args): """Set or Delete metadata on a volume.""" volume = utils.find_volume(cs, args.volume) metadata = _extract_metadata(args) if args.action == "set": cs.volumes.set_metadata(volume, metadata) elif args.action == "unset": # NOTE(zul): Make sure py2/py3 sorting is the same cs.volumes.delete_metadata(volume, sorted(metadata.keys(), reverse=True))
def do_metadata(cs, args): """Sets or deletes volume metadata.""" volume = utils.find_volume(cs, args.volume) metadata = shell_utils.extract_metadata(args) if args.action == 'set': cs.volumes.set_metadata(volume, metadata) elif args.action == 'unset': # NOTE(zul): Make sure py2/py3 sorting is the same cs.volumes.delete_metadata(volume, sorted(metadata.keys(), reverse=True))
def do_transfer_create(cs, args): """Creates a volume transfer.""" volume = utils.find_volume(cs, args.volume) transfer = cs.transfers.create(volume.id, args.display_name) info = dict() info.update(transfer._info) if 'links' in info: info.pop('links') utils.print_dict(info)
def do_snapshot_create(cs, args): """Add a new snapshot.""" if args.display_name is not None: args.name = args.display_name if args.display_description is not None: args.description = args.display_description volume = utils.find_volume(cs, args.volume) snapshot = cs.volume_snapshots.create(volume.id, args.force, args.name, args.description) _print_volume_snapshot(snapshot)
def do_metadata(cs, args): """Set or Delete metadata on a volume.""" volume = utils.find_volume(cs, args.volume) metadata = _extract_metadata(args) if args.action == 'set': cs.volumes.set_metadata(volume, metadata) elif args.action == 'unset': # NOTE(zul): Make sure py2/py3 sorting is the same cs.volumes.delete_metadata(volume, sorted(metadata.keys(), reverse=True))
def do_transfer_create(cs, args): """Creates a volume transfer.""" volume = utils.find_volume(cs, args.volume) transfer = cs.transfers.create(volume.id, args.display_name) info = dict() info.update(transfer._info) if "links" in info: info.pop("links") utils.print_dict(info)
def do_transfer_create(cs, args): """Creates a volume transfer.""" if args.display_name is not None: args.name = args.display_name volume = utils.find_volume(cs, args.volume) transfer = cs.transfers.create(volume.id, args.name) info = dict() info.update(transfer._info) info.pop('links', None) utils.print_dict(info)
def do_upload_to_image(cs, args): """Uploads volume to Image Service as an image.""" volume = utils.find_volume(cs, args.volume) if cs.api_version >= api_versions.APIVersion("3.1"): shell_utils.print_volume_image( volume.upload_to_image(args.force, args.image_name, args.container_format, args.disk_format, args.visibility, args.protected)) else: shell_utils.print_volume_image( volume.upload_to_image(args.force, args.image_name, args.container_format, args.disk_format))
def do_transfer_create(cs, args): """Creates a volume transfer.""" if args.display_name is not None: args.name = args.display_name volume = utils.find_volume(cs, args.volume) transfer = cs.transfers.create(volume.id, args.name) info = dict() info.update(transfer._info) info.pop("links", None) utils.print_dict(info)
def do_backup_create(cs, args): """Creates a volume backup.""" volume = utils.find_volume(cs, args.volume) backup = cs.backups.create(volume.id, args.container, args.display_name, args.display_description) info = {"volume_id": volume.id} info.update(backup._info) if "links" in info: info.pop("links") utils.print_dict(info)
def do_backup_create(cs, args): """Creates a volume backup.""" volume = utils.find_volume(cs, args.volume) backup = cs.backups.create(volume.id, args.container, args.display_name, args.display_description) info = {"volume_id": volume.id} info.update(backup._info) if 'links' in info: info.pop('links') utils.print_dict(info)
def take_action(self, parsed_args): volume_client = self.app.client_manager.volume # Parse the volume ID from the filename which is in this format: # volume-<id>-<timestamp>.tgz if (parsed_args.file_name.find("volume-") != 0 or parsed_args.file_name.rfind(".tgz") == -1 or len(parsed_args.file_name) < 28): raise exceptions.CommandError( "Invalid filename - volume files must have the following format: " "volume-<id>-<timestamp>.tgz") volume_id = parsed_args.file_name[7:-20] volume = cinder_utils.find_volume(volume_client, volume_id) volume_client.volumes.import_volume(volume, parsed_args.file_name)
def do_import(cs, args): """Import a volume from a file.""" # Parse the volume ID from the filename which is in this format: # volume-<id>-<timestamp>.tgz # For example: # volume-3a2cae29-850d-4445-b9ae-03865080b915-20140821-162819.tgz if (args.file_name.find("volume-") != 0 or args.file_name.rfind(".tgz") == -1 or len(args.file_name) < 28): raise exceptions.CommandError( "Invalid filename - volume files must have the following format: " "volume-<id>-<timestamp>.tgz") volume_id = args.file_name[7:-20] volume = utils.find_volume(cs, volume_id) updated_volume = volume.import_volume(args.file_name) utils.print_dict(updated_volume[1]['wrs-volume:os-volume_import'])
def do_backup_create(cs, args): """Creates a backup.""" if args.display_name is not None: args.name = args.display_name if args.display_description is not None: args.description = args.display_description volume = utils.find_volume(cs, args.volume) backup = cs.backups.create(volume.id, args.container, args.name, args.description) info = {"volume_id": volume.id} info.update(backup._info) if 'links' in info: info.pop('links') utils.print_dict(info)
def do_show(cs, args): """Shows volume details.""" volume = utils.find_volume(cs, args.volume) _print_volume(volume)
def do_metadata_update_all(cs, args): """Updates volume metadata.""" volume = utils.find_volume(cs, args.volume) metadata = _extract_metadata(args) metadata = volume.update_all_metadata(metadata) utils.print_dict(metadata['metadata'], 'Metadata-property')
def do_readonly_mode_update(cs, args): """Updates volume read-only access-mode flag.""" volume = utils.find_volume(cs, args.volume) cs.volumes.update_readonly_flag(volume, strutils.bool_from_string(args.read_only))
def do_set_bootable(cs, args): """Update bootable status of a volume.""" volume = utils.find_volume(cs, args.volume) cs.volumes.set_bootable(volume, strutils.bool_from_string(args.bootable))
def do_metadata_show(cs, args): """Shows volume metadata.""" volume = utils.find_volume(cs, args.volume) utils.print_dict(volume._info['metadata'], 'Metadata-property')
def do_metadata_update_all(cs, args): """Updates volume metadata.""" volume = utils.find_volume(cs, args.volume) metadata = _extract_metadata(args) metadata = volume.update_all_metadata(metadata) utils.print_dict(metadata)
def do_readonly_mode_update(cs, args): """Update volume read-only access mode read_only.""" volume = utils.find_volume(cs, args.volume) cs.volumes.update_readonly_flag(volume, strutils.bool_from_string(args.read_only))
def do_migrate(cs, args): """Migrates volume to a new host.""" volume = utils.find_volume(cs, args.volume) volume.migrate_volume(args.host, args.force_host_copy)
def do_migrate(cs, args): """Migrate the volume to the new host.""" volume = utils.find_volume(cs, args.volume) volume.migrate_volume(args.host, args.force_host_copy)
def do_metadata_update_all(cs, args): """Update all metadata of a volume.""" volume = utils.find_volume(cs, args.volume) metadata = _extract_metadata(args) metadata = volume.update_all_metadata(metadata) utils.print_dict(metadata)
def do_reset_state(cs, args): """Explicitly update the state of a volume.""" volume = utils.find_volume(cs, args.volume) volume.reset_state(args.state)
def do_show(cs, args): """Show details about a volume.""" volume = utils.find_volume(cs, args.volume) _print_volume(volume)
def do_extend(cs, args): """Attempt to extend the size of an existing volume.""" volume = utils.find_volume(cs, args.volume) cs.volumes.extend(volume, args.new_size)
def tidy_storage(result_file): """ Search Glance images DB and rbd images pool for any discrepancy between the two. - If an image is in Glance images DB but not in rbd images pool, list the image and suggested actions to take in a log file. - If an image is in rbd images pool but not in Glance images DB, create a Glance image in Glance images DB to associate with the backend data. List the image and suggested actions to take in a log file. Search Cinder volumes DB and rbd cinder-volumes pool for any discrepancy between the two. - If a volume is in Cinder volumes DB but not in rbd cinder-volumes pool, set the volume state to "error". List the volume and suggested actions to take in a log file. - If a volume is in rbd cinder-volumes pool but not in Cinder volumes DB, remove any snapshot(s) assoicated with this volume in rbd pool and create a volume in Cinder volumes DB to associate with the backend data. List the volume and suggested actions to take in a log file. - If a volume is in both Cinder volumes DB and rbd cinder-volumes pool and it has snapshot(s) in the rbd pool, re-create the snapshot in Cinder if it doesn't exist. Clean up Cinder snapshots DB if the snapshot doesn't have backend data. """ with OpenStack() as client: # Check Glance images print("Scanning Glance images in DB and rbd images pool...\n") try: g_client_v1, g_client_v2 = client.get_glance_client image_l = g_client_v2.images.list() image_id_l = [image['id'].encode('utf-8') for image in image_l] output = subprocess.check_output(["rbd", "ls", "--pool", "images"], stderr=subprocess.STDOUT) except subprocess.CalledProcessError: LOG.error("Failed to access rbd images pool") raise TidyStorageFail("Failed to access rbd images pool") except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to list Glance images") rbd_image_l = [i for i in output.split('\n') if i != ""] print("Images in Glance images DB: %s \n" % image_id_l) print("Images in rbd images pool: %s \n" % rbd_image_l) in_glance_only = np.setdiff1d(image_id_l, rbd_image_l) in_rbd_image_only = np.setdiff1d(rbd_image_l, image_id_l) print("Images in Glance images DB only: %s \n" % in_glance_only) print("Images in rbd images pool only: %s \n" % in_rbd_image_only) if in_rbd_image_only.size != 0: output = subprocess.check_output( ["grep", "fsid", "/etc/ceph/ceph.conf"], stderr=subprocess.STDOUT) ceph_cluster = [ i.strip() for i in output.split('=') if i.find('fsid') == -1 ] fields = dict() for image in in_rbd_image_only: try: img_file = 'rbd:images/{}'.format(image) output = subprocess.check_output( ["qemu-img", "info", img_file], stderr=subprocess.STDOUT) fields['disk_format'] = 'qcow2' for line in output.split('\n'): if 'file format:' in line: fields['disk_format'] = line.split(':')[1].strip() break fields['name'] = 'found-image-%s' % image fields['id'] = image fields['container_format'] = 'bare' fields['location'] = \ 'rbd://{}/images/{}/snap'.format(ceph_cluster[0], image) print("Creating a Glance image %s ...\n " % fields['name']) g_client_v1.images.create(**fields) except subprocess.CalledProcessError: LOG.error("Failed to access rbd image %s" % image) raise TidyStorageFail("Failed to access rbd image") except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to create glance image") # Check cinder volume snapshots. Do it before "cinder manage" # operation as "cinder manage" does not support keeping the same # volume id. print("Scanning Cinder snapshots in DB and rbd cinder-volumes " "pool...\n") try: c_client = client.get_cinder_client snap_l = c_client.volume_snapshots.list(search_opts=search_opts) except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to get Cinder snapshots") snaps_no_backend_vol = [] for snap in snap_l: print("Check if volume snapshot %s has backend " % snap.name) try: output = subprocess.check_output( ["rbd", "ls", "--pool", "cinder-volumes"], stderr=subprocess.STDOUT) except subprocess.CalledProcessError: LOG.error("Failed to access rbd cinder-volumes pool") raise TidyStorageFail( "Failed to access rbd cinder-volumes pool") found_vol = False for line in output.split('\n'): if snap.volume_id in line: found_vol = True break if found_vol: volume = 'cinder-volumes/volume-{}'.format(snap.volume_id) try: output = subprocess.check_output( ["rbd", "snap", "list", volume], stderr=subprocess.STDOUT) keep_snap = False for line in output.split('\n'): if snap.id in line: keep_snap = True break except subprocess.CalledProcessError: LOG.info("Failed to list snapshots for volume %s in " "rbd cinder-volumes pool" % snap.volume_id) raise TidyStorageFail("Failed to list snapshots in rbd.") if not keep_snap: try: print("Volume snapshot %s has no backend data. " "Deleting it from Cinder...\n" % snap.name) c_client.volume_snapshots.delete(c_utils.find_resource( c_client.volume_snapshots, snap.id), force=True) except Exception as e: LOG.exception(e) raise TidyStorageFail( "Failed to delete volume snapshot") else: # Volume snapshot that doesn't have backend volume cannot # be deleted. If the backend volume is restored later, then # the snapshot can be deleted. So for now we will add these # snapshots in the user action log. snaps_no_backend_vol.append(snap) # Check Cinder volumes print("Scanning Cinder volumes in DB and rbd cinder-volumes pool...\n") try: volume_l = c_client.volumes.list(search_opts=search_opts) v_t_d = c_client.volume_types.default() avail_zones = c_client.availability_zones.list() pools = c_client.pools.list() except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to get Cinder volume info") if pools: host = pools[0].name # pylint: disable=no-member if v_t_d is None: v_t_d = 'ceph' else: v_t_d = v_t_d.name cinder_volume_l = [i.id.encode('utf-8') for i in volume_l] if avail_zones: avail_z = avail_zones[0].zoneName # pylint: disable=no-member try: output = subprocess.check_output( ["rbd", "ls", "--pool", "cinder-volumes"], stderr=subprocess.STDOUT) except subprocess.CalledProcessError: LOG.error("Failed to access rbd cinder-volumes pool") raise TidyStorageFail("Failed to access rbd cinder-volumes pool") rbd_volume_l = [i[7:] for i in output.split('\n') if i != ""] print("Volumes in Cinder volumes DB: %s \n" % cinder_volume_l) print("Volumes in rbd pool: %s \n" % rbd_volume_l) in_cinder_only = np.setdiff1d(cinder_volume_l, rbd_volume_l) in_rbd_volume_only = np.setdiff1d(rbd_volume_l, cinder_volume_l) in_cinder_and_rbd = np.intersect1d(cinder_volume_l, rbd_volume_l) print("Volumes in Cinder volumes DB only: %s \n" % in_cinder_only) print("Volumes in rbd pool only: %s \n" % in_rbd_volume_only) print("Volumes in Cinder volumes DB and rbd pool: %s \n" % in_cinder_and_rbd) for vol_id in in_rbd_volume_only: volume = 'cinder-volumes/volume-{}'.format(vol_id) try: # Find out if the volume is a bootable one output = subprocess.check_output(["rbd", "info", volume], stderr=subprocess.STDOUT) bootable = False for line in output.split('\n'): if 'parent: images/' in line: bootable = True break # Find out if the volume has any snapshots. print("Checking if volume %s has snapshots...\n" % vol_id) output = subprocess.check_output( ["rbd", "snap", "list", volume], stderr=subprocess.STDOUT) snap_l = [ item.strip() for item in output.split(' ') if item.find('snapshot-') != -1 ] # Returned volume id (vol.id) will be different from vol_id try: vol = c_client.volumes.manage( host=host, ref={'source-name': 'volume-%s' % vol_id}, name='found-volume-%s' % vol_id, description='manage a volume', volume_type=v_t_d, availability_zone=avail_z, bootable=bootable) print("Creating volume found-volume-%s in Cinder...\n" % vol_id) except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to manage volume") try: for snap in snap_l: # Manage a snapshot for a managed volume is not # supported in rbd. So we just remove the snapshot. # Remove the snapshot print( textwrap.fill( "Removing snapshot %s from volume %s " "in rbd...\n" % (snap, vol_id), 76)) del_snap = '{}@{}'.format(volume, snap) output = subprocess.check_output( ["rbd", "snap", "unprotect", del_snap], stderr=subprocess.STDOUT) output = subprocess.check_output( ["rbd", "snap", "rm", del_snap], stderr=subprocess.STDOUT) except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to manage volume snapshot") except subprocess.CalledProcessError: LOG.error("Failed to access volume %s in cinder-volumes pool" % vol_id) raise TidyStorageFail("Failed to access rbd image") for vol in in_cinder_only: try: c_client.volumes.reset_state(c_utils.find_volume( c_client, vol), state='error') print("Setting state to error for volume %s \n" % vol) except Exception as e: LOG.error("Failed to update volume to error state for %s" % vol) raise TidyStorageFail("Failed to update volume to error state") # For volumes that are in Cinder volumes DB and rbd cinder-volumes # pool, we check if any volume snapshot needs to be re-created try: c_s_l = c_client.volume_snapshots.list(search_opts=search_opts) cinder_snap_l = ['snapshot-{}'.format(snap.id) for snap in c_s_l] except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to get Cinder snapshots") for vol_id in in_cinder_and_rbd: volume = 'cinder-volumes/volume-{}'.format(vol_id) try: # Find out if the volume has any snapshots. print("Checking if volume %s has snapshots...\n" % vol_id) output = subprocess.check_output( ["rbd", "snap", "list", volume], stderr=subprocess.STDOUT) snap_l = [ item.strip() for item in output.split(' ') if item.find('snapshot-') != -1 ] for snap in snap_l: if snap not in cinder_snap_l: print("Creating volume snapshot found-%s " "in Cinder...\n" % snap) c_client.volume_snapshots.manage( volume_id=vol_id, ref={'source-name': snap}, name='found-%s' % snap, description='manage a snapshot') except subprocess.CalledProcessError: LOG.error("Failed to access snapshot for volume %s" % vol_id) raise TidyStorageFail("Failed to access volume snapshot") except Exception as e: LOG.exception(e) raise TidyStorageFail("Failed to manage Cinder snapshot") try: with open(result_file, 'w') as f: f.write('\n%s\n' % ('-' * 80)) f.write( textwrap.fill( "Following images are found in Ceph images pool but " "not in Glance. These images were created after the " "system backup was done. If you do not want to keep " "them, you can delete them by " "\"glance image-delete <id>\" command.", 80)) f.write("\n\n") f.write('{0[0]:<40}{0[1]:<50}\n'.format(['ID', 'NAME'])) image_l = g_client_v2.images.list() for image in image_l: if image['name'].find("found-image") != -1: f.write('{0[0]:<40}{0[1]:<50}\n'.format( [image['id'].encode('utf-8'), image['name']])) f.write("\n") f.write('\n%s\n' % ('-' * 80)) f.write( textwrap.fill( "Following images are found in Glance without backend " "data associated with. These images were deleted after " "the system backup was done. You can delete them by " "\"glance image-delete <id>\" command or follow the B&R " "document to restore the image.", 80)) f.write("\n\n") f.write('{0[0]:<40}{0[1]:<50}\n'.format(['ID', 'NAME'])) image_l = g_client_v2.images.list() for image in image_l: if (in_glance_only.size != 0 and image['id'].encode('utf-8') in in_glance_only): f.write('{0[0]:<40}{0[1]:<50}\n'.format( [image['id'].encode('utf-8'), image['name']])) f.write("\n") f.write('\n%s\n' % ('-' * 80)) f.write( textwrap.fill( "Following volumes are found in Ceph cinder-volumes " "pool but not in Cinder. These volumes were created " "after the system backup was done. If you do not want " "to keep them you can delete them by " "\"cinder delete <id>\" command.", 80)) f.write("\n\n") f.write('{0[0]:<40}{0[1]:<50}\n'.format(['ID', 'NAME'])) volume_l = c_client.volumes.list(search_opts=search_opts) for volume in volume_l: if volume.name.find("found-") != -1: f.write('{0[0]:<40}{0[1]:<50}\n'.format( [volume.id.encode('utf-8'), volume.name])) f.write("\n") f.write('\n%s\n' % ('-' * 80)) f.write( textwrap.fill( "Following volumes are found in Cinder without backend " "data associated with. These volumes were deleted " "after the system backup was done. You can delete them " "by \"cinder delete <id>\" command or follow the B&R " "document to restore the cinder volume.", 80)) f.write("\n\n") f.write('{0[0]:<40}{0[1]:<50}\n'.format(['ID', 'NAME'])) volume_l = c_client.volumes.list(search_opts=search_opts) for volume in volume_l: if (in_cinder_only.size != 0 and volume.id in in_cinder_only): f.write('{0[0]:<40}{0[1]:<50}\n'.format( [volume.id.encode('utf-8'), volume.name])) f.write("\n") f.write('\n%s\n' % ('-' * 80)) f.write( textwrap.fill( "Following volume snapshots are found in Ceph but not in " "Cinder. These volume snapshots were created after the " "system backup was done. If you do not want to keep them " "you can delete them by \"cinder snapshot-delete <id>\" " "command.", 80)) f.write("\n\n") f.write('{0[0]:<40}{0[1]:<50}\n'.format(['ID', 'NAME'])) snap_l = c_client.volume_snapshots.list( search_opts=search_opts) for snap in snap_l: if snap.name.find("found-") != -1: f.write('{0[0]:<40}{0[1]:<50}\n'.format( [snap.id.encode('utf-8'), snap.name])) f.write("\n") f.write('\n%s\n' % ('-' * 80)) f.write( textwrap.fill( "Following volume snapshots are found in Cinder without " "backend volumes. If you want to delete them, you can do " "so by \"cinder snapshot-delete <id>\" after backend " "volumes are restored.", 80)) f.write("\n\n") f.write('{0[0]:<40}{0[1]:<50}\n'.format(['ID', 'NAME'])) for snap in snaps_no_backend_vol: f.write('{0[0]:<40}{0[1]:<50}\n'.format( [snap.id.encode('utf-8'), snap.name])) f.write("\n\n") except IOError: raise TidyStorageFail("Failed to open file: %s" % result_file)
def do_extend(cs, args): """Attempts to extend size of an existing volume.""" volume = utils.find_volume(cs, args.volume) cs.volumes.extend(volume, args.new_size)
def do_metadata_show(cs, args): """Show metadata of given volume.""" volume = utils.find_volume(cs, args.volume) utils.print_dict(volume._info['metadata'], 'Metadata-property')