Remove deprecated commands from shell
Remove all deprecated commands from the shell since they are no longer used and to keep the command line menu from looking cluttered. Closes-bug: #1314218 Change-Id: I66e82872988e3835e4f290f48dfc80538271426c
This commit is contained in:
@@ -1,515 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
DEPRECATED functions that implement the same command line interface as the
|
||||
legacy glance client.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from six.moves.urllib import parse
|
||||
|
||||
from glanceclient.common import utils
|
||||
from glanceclient.openstack.common import strutils
|
||||
|
||||
|
||||
SUCCESS = 0
|
||||
FAILURE = 1
|
||||
|
||||
|
||||
def get_image_fields_from_args(args):
|
||||
"""
|
||||
Validate the set of arguments passed as field name/value pairs
|
||||
and return them as a mapping.
|
||||
"""
|
||||
fields = {}
|
||||
for arg in args:
|
||||
pieces = arg.strip(',').split('=')
|
||||
if len(pieces) != 2:
|
||||
msg = ("Arguments should be in the form of field=value. "
|
||||
"You specified %s." % arg)
|
||||
raise RuntimeError(msg)
|
||||
fields[pieces[0]] = pieces[1]
|
||||
|
||||
return fields
|
||||
|
||||
|
||||
def get_image_filters_from_args(args):
|
||||
"""Build a dictionary of query filters based on the supplied args."""
|
||||
try:
|
||||
fields = get_image_fields_from_args(args)
|
||||
except RuntimeError as e:
|
||||
print(e)
|
||||
return FAILURE
|
||||
|
||||
SUPPORTED_FILTERS = ['name', 'disk_format', 'container_format', 'status',
|
||||
'min_ram', 'min_disk', 'size_min', 'size_max',
|
||||
'changes-since']
|
||||
filters = {}
|
||||
for (key, value) in fields.items():
|
||||
if key not in SUPPORTED_FILTERS:
|
||||
key = 'property-%s' % (key,)
|
||||
filters[key] = value
|
||||
|
||||
return filters
|
||||
|
||||
|
||||
def print_image_formatted(client, image):
|
||||
"""
|
||||
Formatted print of image metadata.
|
||||
|
||||
:param client: The Glance client object
|
||||
:param image: The image metadata
|
||||
"""
|
||||
uri_parts = parse.urlparse(client.http_client.endpoint)
|
||||
if uri_parts.port:
|
||||
hostbase = "%s:%s" % (uri_parts.hostname, uri_parts.port)
|
||||
else:
|
||||
hostbase = uri_parts.hostname
|
||||
print("URI: %s://%s/v1/images/%s" % (uri_parts.scheme, hostbase, image.id))
|
||||
print("Id: %s" % image.id)
|
||||
print("Public: " + (image.is_public and "Yes" or "No"))
|
||||
print("Protected: " + (image.protected and "Yes" or "No"))
|
||||
print("Name: %s" % getattr(image, 'name', ''))
|
||||
print("Status: %s" % image.status)
|
||||
print("Size: %d" % int(image.size))
|
||||
print("Disk format: %s" % getattr(image, 'disk_format', ''))
|
||||
print("Container format: %s" % getattr(image, 'container_format', ''))
|
||||
print("Minimum Ram Required (MB): %s" % image.min_ram)
|
||||
print("Minimum Disk Required (GB): %s" % image.min_disk)
|
||||
if hasattr(image, 'owner'):
|
||||
print("Owner: %s" % image.owner)
|
||||
if len(image.properties) > 0:
|
||||
for k, v in image.properties.items():
|
||||
print("Property '%s': %s" % (k, v))
|
||||
print("Created at: %s" % image.created_at)
|
||||
if hasattr(image, 'deleted_at'):
|
||||
print("Deleted at: %s" % image.deleted_at)
|
||||
if hasattr(image, 'updated_at'):
|
||||
print("Updated at: %s" % image.updated_at)
|
||||
|
||||
|
||||
@utils.arg('--silent-upload', action="store_true",
|
||||
help="DEPRECATED! Animations are always off.")
|
||||
@utils.arg('fields', default=[], nargs='*', help=argparse.SUPPRESS)
|
||||
def do_add(gc, args):
|
||||
"""DEPRECATED! Use image-create instead."""
|
||||
try:
|
||||
fields = get_image_fields_from_args(args.fields)
|
||||
except RuntimeError as e:
|
||||
print(e)
|
||||
return FAILURE
|
||||
|
||||
image_meta = {
|
||||
'is_public': strutils.bool_from_string(
|
||||
fields.pop('is_public', 'False')),
|
||||
'protected': strutils.bool_from_string(
|
||||
fields.pop('protected', 'False')),
|
||||
'min_disk': fields.pop('min_disk', 0),
|
||||
'min_ram': fields.pop('min_ram', 0),
|
||||
}
|
||||
|
||||
#NOTE(bcwaldon): Use certain properties only if they are explicitly set
|
||||
optional = ['id', 'name', 'disk_format', 'container_format']
|
||||
for field in optional:
|
||||
if field in fields:
|
||||
image_meta[field] = fields.pop(field)
|
||||
|
||||
# Strip any args that are not supported
|
||||
unsupported_fields = ['status', 'size']
|
||||
for field in unsupported_fields:
|
||||
if field in fields.keys():
|
||||
print('Found non-settable field %s. Removing.' % field)
|
||||
fields.pop(field)
|
||||
|
||||
# We need either a location or image data/stream to add...
|
||||
image_data = None
|
||||
if 'location' in fields.keys():
|
||||
image_meta['location'] = fields.pop('location')
|
||||
if 'checksum' in fields.keys():
|
||||
image_meta['checksum'] = fields.pop('checksum')
|
||||
elif 'copy_from' in fields.keys():
|
||||
image_meta['copy_from'] = fields.pop('copy_from')
|
||||
else:
|
||||
# Grab the image data stream from stdin or redirect,
|
||||
# otherwise error out
|
||||
image_data = sys.stdin
|
||||
|
||||
image_meta['data'] = image_data
|
||||
|
||||
# allow owner to be set when image is created
|
||||
if 'owner' in fields.keys():
|
||||
image_meta['owner'] = fields.pop('owner')
|
||||
|
||||
# Add custom attributes, which are all the arguments remaining
|
||||
image_meta['properties'] = fields
|
||||
|
||||
if not args.dry_run:
|
||||
image = gc.images.create(**image_meta)
|
||||
print("Added new image with ID: %s" % image.id)
|
||||
if args.verbose:
|
||||
print("Returned the following metadata for the new image:")
|
||||
for k, v in sorted(image.to_dict().items()):
|
||||
print(" %(k)30s => %(v)s" % {'k': k, 'v': v})
|
||||
else:
|
||||
print("Dry run. We would have done the following:")
|
||||
|
||||
def _dump(dict):
|
||||
for k, v in sorted(dict.items()):
|
||||
print(" %(k)30s => %(v)s" % {'k': k, 'v': v})
|
||||
|
||||
print("Add new image with metadata:")
|
||||
_dump(image_meta)
|
||||
|
||||
return SUCCESS
|
||||
|
||||
|
||||
@utils.arg('id', metavar='<IMAGE_ID>', help='ID of image to describe.')
|
||||
@utils.arg('fields', default=[], nargs='*', help=argparse.SUPPRESS)
|
||||
def do_update(gc, args):
|
||||
"""DEPRECATED! Use image-update instead."""
|
||||
try:
|
||||
fields = get_image_fields_from_args(args.fields)
|
||||
except RuntimeError as e:
|
||||
print(e)
|
||||
return FAILURE
|
||||
|
||||
image_meta = {}
|
||||
|
||||
# Strip any args that are not supported
|
||||
nonmodifiable_fields = ['created_at', 'deleted_at', 'deleted',
|
||||
'updated_at', 'size', 'status']
|
||||
for field in nonmodifiable_fields:
|
||||
if field in fields.keys():
|
||||
print('Found non-modifiable field %s. Removing.' % field)
|
||||
fields.pop(field)
|
||||
|
||||
base_image_fields = ['disk_format', 'container_format', 'name',
|
||||
'min_disk', 'min_ram', 'location', 'owner',
|
||||
'copy_from']
|
||||
for field in base_image_fields:
|
||||
fvalue = fields.pop(field, None)
|
||||
if fvalue is not None:
|
||||
image_meta[field] = fvalue
|
||||
|
||||
# Have to handle "boolean" values specially...
|
||||
if 'is_public' in fields:
|
||||
image_meta['is_public'] = strutils.\
|
||||
bool_from_string(fields.pop('is_public'))
|
||||
if 'protected' in fields:
|
||||
image_meta['protected'] = strutils.\
|
||||
bool_from_string(fields.pop('protected'))
|
||||
|
||||
# Add custom attributes, which are all the arguments remaining
|
||||
image_meta['properties'] = fields
|
||||
|
||||
if not args.dry_run:
|
||||
image = gc.images.update(args.id, **image_meta)
|
||||
print("Updated image %s" % args.id)
|
||||
|
||||
if args.verbose:
|
||||
print("Updated image metadata for image %s:" % args.id)
|
||||
print_image_formatted(gc, image)
|
||||
else:
|
||||
def _dump(dict):
|
||||
for k, v in sorted(dict.items()):
|
||||
print(" %(k)30s => %(v)s" % {'k': k, 'v': v})
|
||||
|
||||
print("Dry run. We would have done the following:")
|
||||
print("Update existing image with metadata:")
|
||||
_dump(image_meta)
|
||||
|
||||
return SUCCESS
|
||||
|
||||
|
||||
@utils.arg('id', metavar='<IMAGE_ID>', help='ID of image to describe.')
|
||||
def do_delete(gc, args):
|
||||
"""DEPRECATED! Use image-delete instead."""
|
||||
if not (args.force or
|
||||
user_confirm("Delete image %s?" % args.id, default=False)):
|
||||
print('Not deleting image %s' % args.id)
|
||||
return FAILURE
|
||||
|
||||
gc.images.get(args.id).delete()
|
||||
|
||||
|
||||
@utils.arg('id', metavar='<IMAGE_ID>', help='ID of image to describe.')
|
||||
def do_show(gc, args):
|
||||
"""DEPRECATED! Use image-show instead."""
|
||||
image = gc.images.get(args.id)
|
||||
print_image_formatted(gc, image)
|
||||
return SUCCESS
|
||||
|
||||
|
||||
def _get_images(gc, args):
|
||||
parameters = {
|
||||
'filters': get_image_filters_from_args(args.filters),
|
||||
'page_size': args.limit,
|
||||
}
|
||||
|
||||
optional_kwargs = ['marker', 'sort_key', 'sort_dir']
|
||||
for kwarg in optional_kwargs:
|
||||
value = getattr(args, kwarg, None)
|
||||
if value is not None:
|
||||
parameters[kwarg] = value
|
||||
|
||||
return gc.images.list(**parameters)
|
||||
|
||||
|
||||
@utils.arg('--limit', dest="limit", metavar="LIMIT", default=10,
|
||||
type=int, help="Page size for image metadata requests.")
|
||||
@utils.arg('--marker', dest="marker", metavar="MARKER",
|
||||
default=None, help="Image index after which to begin pagination.")
|
||||
@utils.arg('--sort_key', dest="sort_key", metavar="KEY",
|
||||
help="Sort results by this image attribute.")
|
||||
@utils.arg('--sort_dir', dest="sort_dir", metavar="[desc|asc]",
|
||||
help="Sort results in this direction.")
|
||||
@utils.arg('filters', default=[], nargs='*', help=argparse.SUPPRESS)
|
||||
def do_index(gc, args):
|
||||
"""DEPRECATED! Use image-list instead."""
|
||||
images = _get_images(gc, args)
|
||||
|
||||
if not images:
|
||||
return SUCCESS
|
||||
|
||||
pretty_table = PrettyTable()
|
||||
pretty_table.add_column(36, label="ID")
|
||||
pretty_table.add_column(30, label="Name")
|
||||
pretty_table.add_column(20, label="Disk Format")
|
||||
pretty_table.add_column(20, label="Container Format")
|
||||
pretty_table.add_column(14, label="Size", just="r")
|
||||
|
||||
print(pretty_table.make_header())
|
||||
|
||||
for image in images:
|
||||
print(pretty_table.make_row(image.id,
|
||||
image.name,
|
||||
image.disk_format,
|
||||
image.container_format,
|
||||
image.size))
|
||||
|
||||
|
||||
@utils.arg('--limit', dest="limit", metavar="LIMIT", default=10,
|
||||
type=int, help="Page size for image metadata requests.")
|
||||
@utils.arg('--marker', dest="marker", metavar="MARKER",
|
||||
default=None, help="Image index after which to begin pagination.")
|
||||
@utils.arg('--sort_key', dest="sort_key", metavar="KEY",
|
||||
help="Sort results by this image attribute.")
|
||||
@utils.arg('--sort_dir', dest="sort_dir", metavar="[desc|asc]",
|
||||
help="Sort results in this direction.")
|
||||
@utils.arg('filters', default='', nargs='*', help=argparse.SUPPRESS)
|
||||
def do_details(gc, args):
|
||||
"""DEPRECATED! Use image-list instead."""
|
||||
images = _get_images(gc, args)
|
||||
for i, image in enumerate(images):
|
||||
if i == 0:
|
||||
print("=" * 80)
|
||||
print_image_formatted(gc, image)
|
||||
print("=" * 80)
|
||||
|
||||
|
||||
def do_clear(gc, args):
|
||||
"""DEPRECATED!"""
|
||||
if not (args.force or
|
||||
user_confirm("Delete all images?", default=False)):
|
||||
print('Not deleting any images')
|
||||
return FAILURE
|
||||
|
||||
images = gc.images.list()
|
||||
for image in images:
|
||||
if args.verbose:
|
||||
print('Deleting image %s "%s" ...' % (image.id, image.name),
|
||||
end=' ')
|
||||
try:
|
||||
image.delete()
|
||||
if args.verbose:
|
||||
print('done')
|
||||
except Exception as e:
|
||||
print('Failed to delete image %s' % image.id)
|
||||
print(e)
|
||||
return FAILURE
|
||||
return SUCCESS
|
||||
|
||||
|
||||
@utils.arg('image_id', help='Image ID to filters members with.')
|
||||
def do_image_members(gc, args):
|
||||
"""DEPRECATED! Use member-list instead."""
|
||||
members = gc.image_members.list(image=args.image_id)
|
||||
sharers = 0
|
||||
# Output the list of members
|
||||
for memb in members:
|
||||
can_share = ''
|
||||
if memb.can_share:
|
||||
can_share = ' *'
|
||||
sharers += 1
|
||||
print("%s%s" % (memb.member_id, can_share))
|
||||
|
||||
# Emit a footnote
|
||||
if sharers > 0:
|
||||
print("\n(*: Can share image)")
|
||||
|
||||
|
||||
@utils.arg('--can-share', default=False, action="store_true",
|
||||
help="Allow member to further share image.")
|
||||
@utils.arg('member_id',
|
||||
help='ID of member (typically tenant) to grant access.')
|
||||
def do_member_images(gc, args):
|
||||
"""DEPRECATED! Use member-list instead."""
|
||||
members = gc.image_members.list(member=args.member_id)
|
||||
|
||||
if not len(members):
|
||||
print("No images shared with member %s" % args.member_id)
|
||||
return SUCCESS
|
||||
|
||||
sharers = 0
|
||||
# Output the list of images
|
||||
for memb in members:
|
||||
can_share = ''
|
||||
if memb.can_share:
|
||||
can_share = ' *'
|
||||
sharers += 1
|
||||
print("%s%s" % (memb.image_id, can_share))
|
||||
|
||||
# Emit a footnote
|
||||
if sharers > 0:
|
||||
print("\n(*: Can share image)")
|
||||
|
||||
|
||||
@utils.arg('--can-share', default=False, action="store_true",
|
||||
help="Allow member to further share image.")
|
||||
@utils.arg('image_id', help='ID of image to describe.')
|
||||
@utils.arg('member_id',
|
||||
help='ID of member (typically tenant) to grant access.')
|
||||
def do_members_replace(gc, args):
|
||||
"""DEPRECATED!"""
|
||||
if not args.dry_run:
|
||||
for member in gc.image_members.list(image=args.image_id):
|
||||
gc.image_members.delete(args.image_id, member.member_id)
|
||||
gc.image_members.create(args.image_id, args.member_id, args.can_share)
|
||||
else:
|
||||
print("Dry run. We would have done the following:")
|
||||
print('Replace members of image %s with "%s"'
|
||||
% (args.image_id, args.member_id))
|
||||
if args.can_share:
|
||||
print("New member would have been able to further share image.")
|
||||
|
||||
|
||||
@utils.arg('--can-share', default=False, action="store_true",
|
||||
help="Allow member to further share image.")
|
||||
@utils.arg('image_id', help='ID of image to describe.')
|
||||
@utils.arg('member_id',
|
||||
help='ID of member (typically tenant) to grant access.')
|
||||
def do_member_add(gc, args):
|
||||
"""DEPRECATED! Use member-create instead."""
|
||||
if not args.dry_run:
|
||||
gc.image_members.create(args.image_id, args.member_id, args.can_share)
|
||||
else:
|
||||
print("Dry run. We would have done the following:")
|
||||
print('Add "%s" to membership of image %s' %
|
||||
(args.member_id, args.image_id))
|
||||
if args.can_share:
|
||||
print("New member would have been able to further share image.")
|
||||
|
||||
|
||||
def user_confirm(prompt, default=False):
|
||||
"""
|
||||
Yes/No question dialog with user.
|
||||
|
||||
:param prompt: question/statement to present to user (string)
|
||||
:param default: boolean value to return if empty string
|
||||
is received as response to prompt
|
||||
|
||||
"""
|
||||
if default:
|
||||
prompt_default = "[Y/n]"
|
||||
else:
|
||||
prompt_default = "[y/N]"
|
||||
|
||||
# for bug 884116, don't issue the prompt if stdin isn't a tty
|
||||
if not (hasattr(sys.stdin, 'isatty') and sys.stdin.isatty()):
|
||||
return default
|
||||
|
||||
answer = raw_input("%s %s " % (prompt, prompt_default))
|
||||
|
||||
if answer == "":
|
||||
return default
|
||||
else:
|
||||
return answer.lower() in ("yes", "y")
|
||||
|
||||
|
||||
class PrettyTable(object):
|
||||
"""Creates an ASCII art table
|
||||
|
||||
Example:
|
||||
|
||||
ID Name Size Hits
|
||||
--- ----------------- ------------ -----
|
||||
122 image 22 0
|
||||
"""
|
||||
def __init__(self):
|
||||
self.columns = []
|
||||
|
||||
def add_column(self, width, label="", just='l'):
|
||||
"""Add a column to the table
|
||||
|
||||
:param width: number of characters wide the column should be
|
||||
:param label: column heading
|
||||
:param just: justification for the column, 'l' for left,
|
||||
'r' for right
|
||||
"""
|
||||
self.columns.append((width, label, just))
|
||||
|
||||
def make_header(self):
|
||||
label_parts = []
|
||||
break_parts = []
|
||||
for width, label, _ in self.columns:
|
||||
# NOTE(sirp): headers are always left justified
|
||||
label_part = self._clip_and_justify(label, width, 'l')
|
||||
label_parts.append(label_part)
|
||||
|
||||
break_part = '-' * width
|
||||
break_parts.append(break_part)
|
||||
|
||||
label_line = ' '.join(label_parts)
|
||||
break_line = ' '.join(break_parts)
|
||||
return '\n'.join([label_line, break_line])
|
||||
|
||||
def make_row(self, *args):
|
||||
row = args
|
||||
row_parts = []
|
||||
for data, (width, _, just) in zip(row, self.columns):
|
||||
row_part = self._clip_and_justify(data, width, just)
|
||||
row_parts.append(row_part)
|
||||
|
||||
row_line = ' '.join(row_parts)
|
||||
return row_line
|
||||
|
||||
@staticmethod
|
||||
def _clip_and_justify(data, width, just):
|
||||
# clip field to column width
|
||||
clipped_data = str(data)[:width]
|
||||
|
||||
if just == 'r':
|
||||
# right justify
|
||||
justified = clipped_data.rjust(width)
|
||||
else:
|
||||
# left justify
|
||||
justified = clipped_data.ljust(width)
|
||||
|
||||
return justified
|
||||
@@ -26,9 +26,6 @@ from glanceclient import exc
|
||||
from glanceclient.openstack.common import strutils
|
||||
import glanceclient.v1.images
|
||||
|
||||
#NOTE(bcwaldon): import deprecated cli functions
|
||||
from glanceclient.v1.legacy_shell import *
|
||||
|
||||
CONTAINER_FORMATS = 'Acceptable formats: ami, ari, aki, bare, and ovf.'
|
||||
DISK_FORMATS = ('Acceptable formats: ami, ari, aki, vhd, vmdk, raw, '
|
||||
'qcow2, vdi, and iso.')
|
||||
@@ -213,7 +210,7 @@ def do_image_create(gc, args):
|
||||
# Filter out None values
|
||||
fields = dict(filter(lambda x: x[1] is not None, vars(args).items()))
|
||||
|
||||
fields['is_public'] = fields.get('is_public') or fields.pop('public')
|
||||
fields['is_public'] = fields.get('is_public')
|
||||
|
||||
if 'is_protected' in fields:
|
||||
fields['protected'] = fields.pop('is_protected')
|
||||
@@ -386,9 +383,4 @@ def do_member_create(gc, args):
|
||||
def do_member_delete(gc, args):
|
||||
"""Remove a shared image from a tenant."""
|
||||
image_id = utils.find_resource(gc.images, args.image).id
|
||||
if not args.dry_run:
|
||||
gc.image_members.delete(image_id, args.tenant_id)
|
||||
else:
|
||||
print("Dry run. We would have done the following:")
|
||||
print('Remove "%s" from the member list of image '
|
||||
'"%s"' % (args.tenant_id, args.image))
|
||||
gc.image_members.delete(image_id, args.tenant_id)
|
||||
|
||||
Reference in New Issue
Block a user