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_host_show = zunclient.osc.v1.hosts:ShowHost
|
||||||
appcontainer_network_detach = zunclient.osc.v1.containers:NetworkDetach
|
appcontainer_network_detach = zunclient.osc.v1.containers:NetworkDetach
|
||||||
appcontainer_network_attach = zunclient.osc.v1.containers:NetworkAttach
|
appcontainer_network_attach = zunclient.osc.v1.containers:NetworkAttach
|
||||||
|
appcontainer_image_search = zunclient.osc.v1.images:SearchImage
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
source-dir = doc/source
|
source-dir = doc/source
|
||||||
|
@ -144,6 +144,17 @@ class Manager(object):
|
|||||||
url = "%s?%s" % (url, urlparse.urlencode(qparams))
|
url = "%s?%s" % (url, urlparse.urlencode(qparams))
|
||||||
self.api.raw_request('DELETE', url)
|
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):
|
class Resource(base.Resource):
|
||||||
"""Represents a particular instance of an object (tenant, user, etc).
|
"""Represents a particular instance of an object (tenant, user, etc).
|
||||||
|
@ -90,3 +90,32 @@ class PullImage(command.ShowOne):
|
|||||||
image = client.images.create(**opts)
|
image = client.images.create(**opts)
|
||||||
columns = _image_columns(image)
|
columns = _image_columns(image)
|
||||||
return columns, utils.get_item_properties(image, columns)
|
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',
|
'tag': 'latest',
|
||||||
'size': '1024',
|
'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 = {
|
fake_responses = {
|
||||||
'/v1/images/':
|
'/v1/images/':
|
||||||
@ -37,6 +48,10 @@ fake_responses = {
|
|||||||
{},
|
{},
|
||||||
{'images': [IMAGE1, IMAGE2]},
|
{'images': [IMAGE1, IMAGE2]},
|
||||||
),
|
),
|
||||||
|
'SEARCH': (
|
||||||
|
{},
|
||||||
|
{'images': [IMAGE3]},
|
||||||
|
),
|
||||||
},
|
},
|
||||||
'/v1/images/?limit=2':
|
'/v1/images/?limit=2':
|
||||||
{
|
{
|
||||||
@ -161,3 +176,13 @@ class ImageManagerTest(testtools.TestCase):
|
|||||||
self._test_image_list_with_filters(
|
self._test_image_list_with_filters(
|
||||||
sort_key='image_id', sort_dir='desc',
|
sort_key='image_id', sort_dir='desc',
|
||||||
expect=expect)
|
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']
|
PULL_ATTRIBUTES = ['repo']
|
||||||
|
IMAGE_SEARCH_ATTRIBUTES = ['image', 'image_driver']
|
||||||
|
|
||||||
|
|
||||||
class Image(base.Resource):
|
class Image(base.Resource):
|
||||||
@ -94,3 +95,20 @@ class ImageManager(base.Manager):
|
|||||||
raise exceptions.InvalidAttribute(
|
raise exceptions.InvalidAttribute(
|
||||||
"Key must be in %s" % ','.join(PULL_ATTRIBUTES))
|
"Key must be in %s" % ','.join(PULL_ATTRIBUTES))
|
||||||
return self._create(self._path(), new)
|
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,
|
utils.print_list(images, columns,
|
||||||
{'versions': zun_utils.print_list_field('versions')},
|
{'versions': zun_utils.print_list_field('versions')},
|
||||||
sortby_index=None)
|
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