Support manage/unmanage shares with manila
Change-Id: I95b72434a8a44f737f5ee9a44b6ecbf8f4162a7a
This commit is contained in:
parent
8742c06490
commit
7b5356f32d
@ -180,3 +180,21 @@ specify multiple keys to be deleted.
|
|||||||
|
|
||||||
.. literalinclude:: ../examples/shared_file_system/share_metadata.py
|
.. literalinclude:: ../examples/shared_file_system/share_metadata.py
|
||||||
:pyobject: delete_share_metadata
|
:pyobject: delete_share_metadata
|
||||||
|
|
||||||
|
|
||||||
|
Manage Share
|
||||||
|
------------
|
||||||
|
|
||||||
|
Manage a share with Manila.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/shared_file_system/shares.py
|
||||||
|
:pyobject: manage_share
|
||||||
|
|
||||||
|
|
||||||
|
Unmanage Share
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Unmanage a share from Manila.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/shared_file_system/shares.py
|
||||||
|
:pyobject: unmanage_share
|
||||||
|
@ -33,7 +33,8 @@ service.
|
|||||||
.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy
|
.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy
|
||||||
:noindex:
|
:noindex:
|
||||||
:members: shares, get_share, delete_share, update_share, create_share,
|
:members: shares, get_share, delete_share, update_share, create_share,
|
||||||
revert_share_to_snapshot, resize_share, find_share
|
revert_share_to_snapshot, resize_share, find_share, manage_share,
|
||||||
|
unmanage_share
|
||||||
|
|
||||||
|
|
||||||
Shared File System Storage Pools
|
Shared File System Storage Pools
|
||||||
|
@ -31,3 +31,26 @@ def resize_shares_without_shrink(conn, min_size):
|
|||||||
# Extend shares smaller than min_size to min_size,
|
# Extend shares smaller than min_size to min_size,
|
||||||
# but don't shrink shares larger than min_size.
|
# but don't shrink shares larger than min_size.
|
||||||
conn.share.resize_share(share.id, min_size, no_shrink=True)
|
conn.share.resize_share(share.id, min_size, no_shrink=True)
|
||||||
|
|
||||||
|
|
||||||
|
def manage_share(conn, protocol, export_path, service_host, **params):
|
||||||
|
# Manage a share with the given protocol, export path, service host, and
|
||||||
|
# optional additional parameters
|
||||||
|
managed_share = conn.share.manage_share(
|
||||||
|
protocol, export_path, service_host, **params
|
||||||
|
)
|
||||||
|
|
||||||
|
# Can get the ID of the share, which is now being managed with Manila
|
||||||
|
managed_share_id = managed_share.id
|
||||||
|
print("The ID of the share which was managed: %s", managed_share_id)
|
||||||
|
|
||||||
|
|
||||||
|
def unmanage_share(conn, share_id):
|
||||||
|
# Unmanage the share with the given share ID
|
||||||
|
conn.share.unmanage_share(share_id)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Getting the share will raise an exception as it has been unmanaged
|
||||||
|
conn.share.get_share(share_id)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
@ -187,6 +187,42 @@ class Proxy(proxy.Proxy):
|
|||||||
res = self._get(_share.Share, share_id)
|
res = self._get(_share.Share, share_id)
|
||||||
res.revert_to_snapshot(self, snapshot_id)
|
res.revert_to_snapshot(self, snapshot_id)
|
||||||
|
|
||||||
|
def manage_share(self, protocol, export_path, service_host, **params):
|
||||||
|
"""Manage a share.
|
||||||
|
|
||||||
|
:param str protocol: The shared file systems protocol of this share.
|
||||||
|
:param str export_path: The export path formatted according to the
|
||||||
|
protocol.
|
||||||
|
:param str service_host: The manage-share service host.
|
||||||
|
:param kwargs params: Optional parameters to be sent. Available
|
||||||
|
parameters include:
|
||||||
|
* name: The user defined name of the resource.
|
||||||
|
* share_type: The name or ID of the share type to be used to create
|
||||||
|
the resource.
|
||||||
|
* driver_options: A set of one or more key and value pairs, as a
|
||||||
|
dictionary of strings, that describe driver options.
|
||||||
|
* is_public: The level of visibility for the share.
|
||||||
|
* description: The user defiend description of the resource.
|
||||||
|
* share_server_id: The UUID of the share server.
|
||||||
|
|
||||||
|
:returns: The share that was managed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
share = _share.Share()
|
||||||
|
return share.manage(
|
||||||
|
self, protocol, export_path, service_host, **params
|
||||||
|
)
|
||||||
|
|
||||||
|
def unmanage_share(self, share_id):
|
||||||
|
"""Unmanage the share with the given share ID.
|
||||||
|
|
||||||
|
:param share_id: The ID of the share to unmanage.
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
|
||||||
|
share_to_unmanage = self._get(_share.Share, share_id)
|
||||||
|
share_to_unmanage.unmanage(self)
|
||||||
|
|
||||||
def resize_share(
|
def resize_share(
|
||||||
self, share_id, new_size, no_shrink=False, no_extend=False, force=False
|
self, share_id, new_size, no_shrink=False, no_extend=False, force=False
|
||||||
):
|
):
|
||||||
|
@ -160,3 +160,54 @@ class Share(resource.Resource, metadata.MetadataMixin):
|
|||||||
"""
|
"""
|
||||||
body = {"revert": {"snapshot_id": snapshot_id}}
|
body = {"revert": {"snapshot_id": snapshot_id}}
|
||||||
self._action(session, body)
|
self._action(session, body)
|
||||||
|
|
||||||
|
def manage(self, session, protocol, export_path, service_host, **params):
|
||||||
|
"""Manage a share.
|
||||||
|
|
||||||
|
:param session: A session object used for sending request.
|
||||||
|
:param str protocol: The shared file systems protocol of this share.
|
||||||
|
:param str export_path: The export path formatted according to the
|
||||||
|
protocol.
|
||||||
|
:param str service_host: The manage-share service host.
|
||||||
|
:param kwargs params: Optional parameters to be sent. Available
|
||||||
|
parameters include:
|
||||||
|
|
||||||
|
* name: The user defined name of the resource.
|
||||||
|
* share_type: The name or ID of the share type to be used to create
|
||||||
|
the resource.
|
||||||
|
* driver_options: A set of one or more key and value pairs, as a
|
||||||
|
dictionary of strings, that describe driver options.
|
||||||
|
* is_public: The level of visibility for the share.
|
||||||
|
* description: The user defiend description of the resource.
|
||||||
|
* share_server_id: The UUID of the share server.
|
||||||
|
|
||||||
|
:returns: The share that was managed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
path = 'manage'
|
||||||
|
attrs = {
|
||||||
|
'share': {
|
||||||
|
'protocol': protocol,
|
||||||
|
'export_path': export_path,
|
||||||
|
'service_host': service_host,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs['share'].update(params)
|
||||||
|
|
||||||
|
url = utils.urljoin(self.base_path, path)
|
||||||
|
resp = session.post(url, json=attrs)
|
||||||
|
|
||||||
|
self._translate_response(resp)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def unmanage(self, session):
|
||||||
|
"""Unmanage a share.
|
||||||
|
|
||||||
|
:param session: A session object used for sending request.
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
|
||||||
|
body = {'unmanage': None}
|
||||||
|
|
||||||
|
self._action(session, body)
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from openstack import exceptions
|
||||||
from openstack.shared_file_system.v2 import share as _share
|
from openstack.shared_file_system.v2 import share as _share
|
||||||
from openstack.tests.functional.shared_file_system import base
|
from openstack.tests.functional.shared_file_system import base
|
||||||
|
|
||||||
@ -158,3 +159,59 @@ class ShareTest(base.BaseSharedFileSystemTest):
|
|||||||
wait=self._wait_for_timeout,
|
wait=self._wait_for_timeout,
|
||||||
)
|
)
|
||||||
self.assertEqual(larger_size, get_resized_share.size)
|
self.assertEqual(larger_size, get_resized_share.size)
|
||||||
|
|
||||||
|
|
||||||
|
class ManageUnmanageShareTest(base.BaseSharedFileSystemTest):
|
||||||
|
def setUp(self):
|
||||||
|
super(ManageUnmanageShareTest, self).setUp()
|
||||||
|
|
||||||
|
self.NEW_SHARE = self.create_share(
|
||||||
|
share_proto="NFS",
|
||||||
|
name="accounting_p8787",
|
||||||
|
size=2,
|
||||||
|
)
|
||||||
|
self.SHARE_ID = self.NEW_SHARE.id
|
||||||
|
|
||||||
|
self.export_locations = self.operator_cloud.share.export_locations(
|
||||||
|
self.SHARE_ID
|
||||||
|
)
|
||||||
|
export_paths = [export['path'] for export in self.export_locations]
|
||||||
|
self.export_path = export_paths[0]
|
||||||
|
|
||||||
|
self.share_host = self.operator_cloud.share.get_share(self.SHARE_ID)[
|
||||||
|
'host'
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_manage_and_unmanage_share(self):
|
||||||
|
self.operator_cloud.share.unmanage_share(self.SHARE_ID)
|
||||||
|
|
||||||
|
self.operator_cloud.shared_file_system.wait_for_delete(
|
||||||
|
self.NEW_SHARE, interval=2, wait=self._wait_for_timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.operator_cloud.share.get_share(self.SHARE_ID)
|
||||||
|
except exceptions.ResourceNotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
managed_share = self.operator_cloud.share.manage_share(
|
||||||
|
self.NEW_SHARE.share_protocol, self.export_path, self.share_host
|
||||||
|
)
|
||||||
|
|
||||||
|
self.operator_cloud.share.wait_for_status(
|
||||||
|
managed_share,
|
||||||
|
status='available',
|
||||||
|
failures=['error'],
|
||||||
|
interval=5,
|
||||||
|
wait=self._wait_for_timeout,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.NEW_SHARE.share_protocol, managed_share.share_protocol
|
||||||
|
)
|
||||||
|
|
||||||
|
managed_host = self.operator_cloud.share.get_share(managed_share.id)[
|
||||||
|
'host'
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(self.share_host, managed_host)
|
||||||
|
@ -183,3 +183,50 @@ class TestShareActions(TestShares):
|
|||||||
self.sess.post.assert_called_with(
|
self.sess.post.assert_called_with(
|
||||||
url, json=body, headers=headers, microversion=microversion
|
url, json=body, headers=headers, microversion=microversion
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_manage_share(self):
|
||||||
|
sot = share.Share()
|
||||||
|
|
||||||
|
self.resp.headers = {}
|
||||||
|
self.resp.json = mock.Mock(
|
||||||
|
return_value={"share": {"name": "test_share", "size": 1}}
|
||||||
|
)
|
||||||
|
|
||||||
|
export_path = (
|
||||||
|
"10.254.0 .5:/shares/share-42033c24-0261-424f-abda-4fef2f6dbfd5."
|
||||||
|
)
|
||||||
|
params = {"name": "test_share"}
|
||||||
|
res = sot.manage(
|
||||||
|
self.sess,
|
||||||
|
sot["share_protocol"],
|
||||||
|
export_path,
|
||||||
|
sot["host"],
|
||||||
|
**params,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(res.name, "test_share")
|
||||||
|
self.assertEqual(res.size, 1)
|
||||||
|
|
||||||
|
jsonDict = {
|
||||||
|
"share": {
|
||||||
|
"protocol": sot["share_protocol"],
|
||||||
|
"export_path": export_path,
|
||||||
|
"service_host": sot["host"],
|
||||||
|
"name": "test_share",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.sess.post.assert_called_once_with("shares/manage", json=jsonDict)
|
||||||
|
|
||||||
|
def test_unmanage_share(self):
|
||||||
|
sot = share.Share(**EXAMPLE)
|
||||||
|
microversion = sot._get_microversion(self.sess, action='patch')
|
||||||
|
|
||||||
|
self.assertIsNone(sot.unmanage(self.sess))
|
||||||
|
|
||||||
|
url = 'shares/%s/action' % IDENTIFIER
|
||||||
|
body = {'unmanage': None}
|
||||||
|
|
||||||
|
self.sess.post.assert_called_with(
|
||||||
|
url, json=body, headers={'Accept': ''}, microversion=microversion
|
||||||
|
)
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support to manage and unmanage shares
|
||||||
|
from the shared file system service.
|
Loading…
Reference in New Issue
Block a user