Add image-search support
Change-Id: I7555c05ae7cf2298648d1488efc9e539066a7297 Closes-Bug: #1658365
This commit is contained in:
parent
5ee3b99161
commit
97e976f6d2
@ -62,6 +62,7 @@ openstack.container.v1 =
|
||||
appcontainer_host_show = zunclient.osc.v1.hosts:ShowHost
|
||||
appcontainer_network_detach = zunclient.osc.v1.containers:NetworkDetach
|
||||
appcontainer_network_attach = zunclient.osc.v1.containers:NetworkAttach
|
||||
appcontainer_image_search = zunclient.osc.v1.images:SearchImage
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
|
@ -144,6 +144,17 @@ class Manager(object):
|
||||
url = "%s?%s" % (url, urlparse.urlencode(qparams))
|
||||
self.api.raw_request('DELETE', url)
|
||||
|
||||
def _search(self, url, body=None, response_key=None, obj_class=None,
|
||||
qparams=None):
|
||||
if qparams:
|
||||
url = "%s?%s" % (url, urlparse.urlencode(qparams))
|
||||
|
||||
resp, body = self.api.json_request('SEARCH', url, body=body)
|
||||
data = self._format_body_data(body, response_key)
|
||||
if obj_class is None:
|
||||
obj_class = self.resource_class
|
||||
return [obj_class(self, res, loaded=True) for res in data if res]
|
||||
|
||||
|
||||
class Resource(base.Resource):
|
||||
"""Represents a particular instance of an object (tenant, user, etc).
|
||||
|
@ -90,3 +90,32 @@ class PullImage(command.ShowOne):
|
||||
image = client.images.create(**opts)
|
||||
columns = _image_columns(image)
|
||||
return columns, utils.get_item_properties(image, columns)
|
||||
|
||||
|
||||
class SearchImage(command.Lister):
|
||||
"""Search specified image"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".SearchImage")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SearchImage, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--image-driver',
|
||||
metavar='<image-driver>',
|
||||
help='Name of the image driver')
|
||||
parser.add_argument(
|
||||
'image_name',
|
||||
metavar='<image_name>',
|
||||
help='Name of the image')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = _get_client(self, parsed_args)
|
||||
opts = {}
|
||||
opts['image_driver'] = parsed_args.image_driver
|
||||
opts['image'] = parsed_args.image_name
|
||||
opts = zun_utils.remove_null_parms(**opts)
|
||||
images = client.images.search_image(**opts)
|
||||
columns = ('ID', 'Name', 'Tags', 'Status', 'Size', 'Metadata')
|
||||
return (columns, (utils.get_item_properties(image, columns)
|
||||
for image in images))
|
||||
|
@ -29,6 +29,17 @@ IMAGE2 = {'uuid': '1996ba70-b074-454b-a8fc-0895ae26c7c6',
|
||||
'tag': 'latest',
|
||||
'size': '1024',
|
||||
}
|
||||
IMAGE3 = {'uuid': '1267gf34-34e4-tf4b-b84c-1345avf6c7c6',
|
||||
'image_id': '24r5tt6y87c6',
|
||||
'image': 'fake-name3',
|
||||
'tag': 'latest',
|
||||
'size': '1024',
|
||||
'image_driver': 'fake-driver',
|
||||
}
|
||||
SEARCH_IMAGE = {'image': 'fake-name3',
|
||||
'image_driver': 'fake-driver',
|
||||
}
|
||||
|
||||
|
||||
fake_responses = {
|
||||
'/v1/images/':
|
||||
@ -37,6 +48,10 @@ fake_responses = {
|
||||
{},
|
||||
{'images': [IMAGE1, IMAGE2]},
|
||||
),
|
||||
'SEARCH': (
|
||||
{},
|
||||
{'images': [IMAGE3]},
|
||||
),
|
||||
},
|
||||
'/v1/images/?limit=2':
|
||||
{
|
||||
@ -161,3 +176,13 @@ class ImageManagerTest(testtools.TestCase):
|
||||
self._test_image_list_with_filters(
|
||||
sort_key='image_id', sort_dir='desc',
|
||||
expect=expect)
|
||||
|
||||
def test_image_search(self):
|
||||
images = self.mgr.search_image(**SEARCH_IMAGE)
|
||||
expect = [
|
||||
('SEARCH', '/v1/images/', {},
|
||||
{'image': IMAGE3['image'],
|
||||
'image_driver': IMAGE3['image_driver']}),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertThat(images, matchers.HasLength(1))
|
||||
|
@ -16,6 +16,7 @@ from zunclient import exceptions
|
||||
|
||||
|
||||
PULL_ATTRIBUTES = ['repo']
|
||||
IMAGE_SEARCH_ATTRIBUTES = ['image', 'image_driver']
|
||||
|
||||
|
||||
class Image(base.Resource):
|
||||
@ -94,3 +95,20 @@ class ImageManager(base.Manager):
|
||||
raise exceptions.InvalidAttribute(
|
||||
"Key must be in %s" % ','.join(PULL_ATTRIBUTES))
|
||||
return self._create(self._path(), new)
|
||||
|
||||
def search_image(self, **kwargs):
|
||||
"""Retrieves list of images based on image name and image_driver name
|
||||
|
||||
:returns: A list of images based on the search query
|
||||
i.e., image_name & image_driver
|
||||
|
||||
"""
|
||||
image_query = {}
|
||||
for (key, value) in kwargs.items():
|
||||
if key in IMAGE_SEARCH_ATTRIBUTES:
|
||||
image_query[key] = value
|
||||
else:
|
||||
raise exceptions.InvalidAttribute(
|
||||
"Key must be in %s" % ','.join(IMAGE_SEARCH_ATTRIBUTES))
|
||||
path = ''
|
||||
return self._search(self._path(path), image_query)
|
||||
|
@ -57,3 +57,22 @@ def do_image_list(cs, args):
|
||||
utils.print_list(images, columns,
|
||||
{'versions': zun_utils.print_list_field('versions')},
|
||||
sortby_index=None)
|
||||
|
||||
|
||||
@utils.arg('image',
|
||||
metavar='<image>',
|
||||
help='Name of the image')
|
||||
@utils.arg('image_driver',
|
||||
metavar='<image-driver>',
|
||||
choices=['glance', 'docker'],
|
||||
help='Name of the image driver (glance, docker)')
|
||||
def do_image_search(cs, args):
|
||||
"""Print list of available images from repository based on user query."""
|
||||
opts = {}
|
||||
opts['image'] = args.image
|
||||
opts['image_driver'] = args.image_driver
|
||||
images = cs.images.search_image(**opts)
|
||||
columns = ('ID', 'Name', 'Tags', 'Status', 'Size', 'Metadata')
|
||||
utils.print_list(images, columns,
|
||||
{'versions': zun_utils.print_list_field('versions')},
|
||||
sortby_index=None)
|
||||
|
Loading…
Reference in New Issue
Block a user