Skip to content

Commit 97af1b6

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "image: Add 'image task show' commands"
2 parents 00d8d94 + d163a20 commit 97af1b6

6 files changed

Lines changed: 218 additions & 1 deletion

File tree

doc/source/cli/data/glance.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,6 @@ stores-delete,,Delete image from specific store.
5555
stores-info,,Print available backends from Glance.
5656
task-create,,Create a new task.
5757
task-list,,List tasks you can access.
58-
task-show,,Describe a specific task.
58+
task-show,image task show,Describe a specific task.
5959
bash-completion,complete,Prints arguments for bash_completion.
6060
help,help,Display help about this program or one of its subcommands.

openstackclient/image/v2/task.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
from osc_lib.cli import format_columns
14+
from osc_lib.command import command
15+
16+
from openstackclient.i18n import _
17+
18+
19+
def _format_task(task):
20+
"""Format an task to make it more consistent with OSC operations."""
21+
22+
info = {}
23+
properties = {}
24+
25+
# the only fields we're not including is "links", "tags" and the properties
26+
fields_to_show = [
27+
'created_at',
28+
'expires_at',
29+
'id',
30+
'input',
31+
'message',
32+
'owner_id',
33+
'result',
34+
'status',
35+
'type',
36+
'updated_at',
37+
]
38+
39+
# split out the usual key and the properties which are top-level
40+
for field in fields_to_show:
41+
info[field] = task.get(field)
42+
43+
for key in task:
44+
if key in fields_to_show:
45+
continue
46+
47+
if key in {'location', 'name', 'schema'}:
48+
continue
49+
50+
properties[key] = task.get(key)
51+
52+
# add properties back into the dictionary as a top-level key
53+
info['properties'] = format_columns.DictColumn(properties)
54+
55+
return info
56+
57+
58+
class ShowTask(command.ShowOne):
59+
_description = _('Display task details')
60+
61+
def get_parser(self, prog_name):
62+
parser = super(ShowTask, self).get_parser(prog_name)
63+
64+
parser.add_argument(
65+
'task',
66+
metavar='<Task ID>',
67+
help=_('Task to display (ID)'),
68+
)
69+
70+
return parser
71+
72+
def take_action(self, parsed_args):
73+
image_client = self.app.client_manager.image
74+
75+
task = image_client.get_task(parsed_args.task)
76+
info = _format_task(task)
77+
78+
return zip(*sorted(info.items()))

openstackclient/tests/unit/image/v2/fakes.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from openstack.image.v2 import image
2020
from openstack.image.v2 import member
21+
from openstack.image.v2 import task
2122

2223
from openstackclient.tests.unit import fakes
2324
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@@ -44,6 +45,9 @@ def __init__(self, **kwargs):
4445

4546
self.remove_tag = mock.Mock()
4647

48+
self.tasks = mock.Mock()
49+
self.get_task = mock.Mock()
50+
4751
self.auth_token = kwargs['token']
4852
self.management_url = kwargs['endpoint']
4953
self.version = 2.0
@@ -129,3 +133,53 @@ def create_one_image_member(attrs=None):
129133
image_member_info.update(attrs)
130134

131135
return member.Member(**image_member_info)
136+
137+
138+
def create_one_task(attrs=None):
139+
"""Create a fake task.
140+
141+
:param attrs: A dictionary with all attributes of task
142+
:type attrs: dict
143+
:return: A fake Task object.
144+
:rtype: `openstack.image.v2.task.Task`
145+
"""
146+
attrs = attrs or {}
147+
148+
# Set default attribute
149+
task_info = {
150+
'created_at': '2016-06-29T16:13:07Z',
151+
'expires_at': '2016-07-01T16:13:07Z',
152+
'id': str(uuid.uuid4()),
153+
'input': {
154+
'image_properties': {
155+
'container_format': 'ovf',
156+
'disk_format': 'vhd'
157+
},
158+
'import_from': 'https://apps.openstack.org/excellent-image',
159+
'import_from_format': 'qcow2'
160+
},
161+
'message': '',
162+
'owner': str(uuid.uuid4()),
163+
'result': {
164+
'image_id': str(uuid.uuid4()),
165+
},
166+
'schema': '/v2/schemas/task',
167+
'status': random.choice(
168+
[
169+
'pending',
170+
'processing',
171+
'success',
172+
'failure',
173+
]
174+
),
175+
# though not documented, the API only allows 'import'
176+
# https://github.com/openstack/glance/blob/24.0.0/glance/api/v2/tasks.py#L186-L190
177+
'type': 'import',
178+
'updated_at': '2016-06-29T16:13:07Z',
179+
180+
}
181+
182+
# Overwrite default attributes if there are some attributes set
183+
task_info.update(attrs)
184+
185+
return task.Task(**task_info)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
from osc_lib.cli import format_columns
14+
15+
from openstackclient.image.v2 import task
16+
from openstackclient.tests.unit.image.v2 import fakes as image_fakes
17+
18+
19+
class TestTask(image_fakes.TestImagev2):
20+
def setUp(self):
21+
super().setUp()
22+
23+
# Get shortcuts to mocked image client
24+
self.client = self.app.client_manager.image
25+
26+
27+
class TestTaskShow(TestTask):
28+
29+
task = image_fakes.create_one_task()
30+
31+
columns = (
32+
'created_at',
33+
'expires_at',
34+
'id',
35+
'input',
36+
'message',
37+
'owner_id',
38+
'properties',
39+
'result',
40+
'status',
41+
'type',
42+
'updated_at',
43+
)
44+
data = (
45+
task.created_at,
46+
task.expires_at,
47+
task.id,
48+
task.input,
49+
task.message,
50+
task.owner_id,
51+
format_columns.DictColumn({}),
52+
task.result,
53+
task.status,
54+
task.type,
55+
task.updated_at,
56+
)
57+
58+
def setUp(self):
59+
super().setUp()
60+
61+
self.client.get_task.return_value = self.task
62+
63+
# Get the command object to test
64+
self.cmd = task.ShowTask(self.app, None)
65+
66+
def test_task_show(self):
67+
arglist = [self.task.id]
68+
verifylist = [
69+
('task', self.task.id),
70+
]
71+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
72+
73+
# In base command class ShowOne in cliff, abstract method take_action()
74+
# returns a two-part tuple with a tuple of column names and a tuple of
75+
# data to be shown.
76+
columns, data = self.cmd.take_action(parsed_args)
77+
self.client.get_task.assert_called_with(self.task.id)
78+
79+
self.assertEqual(self.columns, columns)
80+
self.assertCountEqual(self.data, data)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- |
4+
Add ``image task show`` command to show a task for the image service.

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ openstack.image.v2 =
382382
image_show = openstackclient.image.v2.image:ShowImage
383383
image_set = openstackclient.image.v2.image:SetImage
384384
image_unset = openstackclient.image.v2.image:UnsetImage
385+
image_task_show = openstackclient.image.v2.task:ShowTask
385386

386387
openstack.network.v2 =
387388
address_group_create = openstackclient.network.v2.address_group:CreateAddressGroup

0 commit comments

Comments
 (0)