Skip to content

Commit ce4fcd3

Browse files
ugglagouthampacha
andcommitted
Add share commands to compute
Manila is a service in OpenStack that enables shared filesystems. The modifications made in this patch update the openstack client so that Nova can now link the shared resources provided by Manila to instances using virtiofs. Co-Authored-By: Goutham Pacha Ravi <gouthampravi@gmail.com> Implements: blueprint libvirt-virtiofs-attach-manila-shares Change-Id: Ibb0c41f76c081909c160e4955c7d93c142eeedb2 Signed-off-by: Goutham Pacha Ravi <gouthampravi@gmail.com>
1 parent 177a6b3 commit ce4fcd3

6 files changed

Lines changed: 587 additions & 1 deletion

File tree

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
# Copyright 2020, Red Hat Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
"""Compute v2 Server action implementations"""
16+
17+
from openstack import utils as sdk_utils
18+
from osc_lib import exceptions
19+
from osc_lib import utils
20+
21+
from openstackclient import command
22+
from openstackclient.i18n import _
23+
24+
25+
def _get_server_share_columns(item):
26+
# Non admin cannot see uuid and export location, so hide them
27+
if item.uuid is None:
28+
column_map = {
29+
'share_id': 'Share ID',
30+
'status': 'Status',
31+
'tag': 'Tag',
32+
}
33+
hidden_columns = [
34+
'id',
35+
'location',
36+
'name',
37+
'uuid',
38+
'export_location',
39+
'share_proto',
40+
]
41+
else:
42+
column_map = {
43+
'uuid': 'UUID',
44+
'share_id': 'Share ID',
45+
'status': 'Status',
46+
'tag': 'Tag',
47+
'export_location': 'Export Location',
48+
}
49+
hidden_columns = ['id', 'location', 'name', 'share_proto']
50+
51+
return utils.get_osc_show_columns_for_sdk_resource(
52+
item, column_map, hidden_columns
53+
)
54+
55+
56+
class ListServerShare(command.Lister):
57+
"""List all the shares attached to a server.
58+
59+
Requires ``--os-compute-api-version 2.97`` or later.
60+
"""
61+
62+
def get_parser(self, prog_name):
63+
parser = super().get_parser(prog_name)
64+
parser.add_argument(
65+
'server',
66+
metavar='<server>',
67+
help=_('Server to list share mapping for (name or ID)'),
68+
)
69+
return parser
70+
71+
def take_action(self, parsed_args):
72+
compute_client = self.app.client_manager.compute
73+
74+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
75+
msg = _(
76+
'--os-compute-api-version 2.97 or greater is required '
77+
'to support share attachments'
78+
)
79+
raise exceptions.CommandError(msg)
80+
81+
server = compute_client.find_server(
82+
parsed_args.server,
83+
ignore_missing=False,
84+
)
85+
shares = compute_client.share_attachments(server)
86+
87+
columns = (
88+
'share_id',
89+
'status',
90+
'tag',
91+
)
92+
column_headers = (
93+
'Share ID',
94+
'Status',
95+
'Tag',
96+
)
97+
98+
return (
99+
column_headers,
100+
(utils.get_item_properties(s, columns) for s in shares),
101+
)
102+
103+
104+
class ShowServerShare(command.ShowOne):
105+
"""Show detail of a share attachment to a server.
106+
107+
Requires ``--os-compute-api-version 2.97`` or later.
108+
"""
109+
110+
def get_parser(self, prog_name):
111+
parser = super().get_parser(prog_name)
112+
parser.add_argument(
113+
'server',
114+
metavar='<server>',
115+
help=_('Server to show share mapping for (name or ID)'),
116+
)
117+
parser.add_argument(
118+
'share',
119+
metavar='<share>',
120+
help=_('Share to show details for (name or ID)'),
121+
)
122+
return parser
123+
124+
def take_action(self, parsed_args):
125+
compute_client = self.app.client_manager.compute
126+
shared_file_system_client = (
127+
self.app.client_manager.sdk_connection.shared_file_system
128+
)
129+
130+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
131+
msg = _(
132+
'--os-compute-api-version 2.97 or greater is required '
133+
'to support share attachments'
134+
)
135+
raise exceptions.CommandError(msg)
136+
137+
server = compute_client.find_server(
138+
parsed_args.server,
139+
ignore_missing=False,
140+
)
141+
share = shared_file_system_client.find_share(
142+
parsed_args.share,
143+
ignore_missing=False,
144+
)
145+
share_attachment = compute_client.get_share_attachment(
146+
server, share.id
147+
)
148+
149+
display_columns, columns = _get_server_share_columns(
150+
share_attachment,
151+
)
152+
data = utils.get_item_properties(share_attachment, columns)
153+
return display_columns, data
154+
155+
156+
class AddServerShare(command.ShowOne):
157+
"""Add a share to a server.
158+
159+
Requires ``--os-compute-api-version 2.97`` or later.
160+
"""
161+
162+
def get_parser(self, prog_name):
163+
parser = super().get_parser(prog_name)
164+
parser.add_argument(
165+
'server',
166+
metavar='<server>',
167+
help=_('Server to add share to (name or ID)'),
168+
)
169+
parser.add_argument(
170+
'share',
171+
metavar='<share>',
172+
help=_('Share to add (name or ID)'),
173+
)
174+
parser.add_argument(
175+
'--tag',
176+
metavar='<tag>',
177+
help=_(
178+
'Optional tag used to mount the share, '
179+
'if not provided the share uuid is used as tag by default'
180+
),
181+
)
182+
return parser
183+
184+
def take_action(self, parsed_args):
185+
compute_client = self.app.client_manager.compute
186+
shared_file_system_client = (
187+
self.app.client_manager.sdk_connection.shared_file_system
188+
)
189+
190+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
191+
msg = _(
192+
'--os-compute-api-version 2.97 or greater is required '
193+
'to support share attachments'
194+
)
195+
raise exceptions.CommandError(msg)
196+
197+
server = compute_client.find_server(
198+
parsed_args.server,
199+
ignore_missing=False,
200+
)
201+
share = shared_file_system_client.find_share(
202+
parsed_args.share,
203+
ignore_missing=False,
204+
)
205+
206+
kwargs = {}
207+
if parsed_args.tag:
208+
kwargs['tag'] = parsed_args.tag
209+
210+
share_attachment = compute_client.create_share_attachment(
211+
server, share.id, **kwargs
212+
)
213+
214+
display_columns, columns = _get_server_share_columns(
215+
share_attachment,
216+
)
217+
data = utils.get_item_properties(share_attachment, columns)
218+
return display_columns, data
219+
220+
221+
class RemoveServerShare(command.Command):
222+
"""Remove a share from a server.
223+
224+
Requires ``--os-compute-api-version 2.97`` or later.
225+
"""
226+
227+
def get_parser(self, prog_name):
228+
parser = super().get_parser(prog_name)
229+
parser.add_argument(
230+
'server',
231+
metavar='<server>',
232+
help=_('Server to remove share from (name or ID)'),
233+
)
234+
parser.add_argument(
235+
'share',
236+
metavar='<share>',
237+
help=_('Share to remove (name or ID)'),
238+
)
239+
return parser
240+
241+
def take_action(self, parsed_args):
242+
compute_client = self.app.client_manager.compute
243+
shared_file_system_client = (
244+
self.app.client_manager.sdk_connection.shared_file_system
245+
)
246+
247+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
248+
msg = _(
249+
'--os-compute-api-version 2.97 or greater is required '
250+
'to support share attachments'
251+
)
252+
raise exceptions.CommandError(msg)
253+
254+
server = compute_client.find_server(
255+
parsed_args.server,
256+
ignore_missing=False,
257+
)
258+
share = shared_file_system_client.find_share(
259+
parsed_args.share,
260+
ignore_missing=False,
261+
)
262+
compute_client.delete_share_attachment(server, share.id)

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
from openstack.compute.v2 import server_action as _server_action
3030
from openstack.compute.v2 import server_interface as _server_interface
3131
from openstack.compute.v2 import server_migration as _server_migration
32+
from openstack.compute.v2 import server_share as _server_share
3233
from openstack.compute.v2 import volume_attachment as _volume_attachment
34+
from openstack.test import fakes as sdk_fakes
3335

3436
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
3537
from openstackclient.tests.unit.image.v2 import fakes as image_fakes
@@ -788,6 +790,29 @@ def create_volume_attachments(attrs=None, count=2):
788790
return volume_attachments
789791

790792

793+
def create_one_share(attrs=None):
794+
"""Create a fake share attachment.
795+
796+
:param dict attrs: A dictionary with all attributes
797+
:return: A fake openstack.compute.v2.server_share.ShareMapping
798+
object
799+
"""
800+
return sdk_fakes.generate_fake_resource(
801+
_server_share.ShareMapping, **(attrs or {})
802+
)
803+
804+
805+
def create_shares(attrs=None, count=2):
806+
"""Create multiple fake share attachments.
807+
808+
:param dict attrs: A dictionary with all attributes
809+
:param int count: The number of share attachments to fake
810+
:return: A list of fake
811+
openstack.compute.v2.server_share.ShareMapping objects
812+
"""
813+
return [create_one_share(attrs) for _ in range(count)]
814+
815+
791816
def create_one_server_interface(attrs=None):
792817
"""Create a fake ServerInterface.
793818

0 commit comments

Comments
 (0)