summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-09-26 23:09:21 +0000
committerGerrit Code Review <review@openstack.org>2014-09-26 23:09:21 +0000
commit98b9b568fe21f48dde7e48ebfdad4cf89856d767 (patch)
tree9764a89d51e8691f8c78f4f5beaa96714d2b2f92
parent50c9ed8502ce486771ed885043c01227fa62a58a (diff)
parent0655b58eaf9b186b20391cd8cf68b8f97ea0358a (diff)
Merge "Fix creation of share from snapshot"2014.2.rc22014.2
-rw-r--r--manila/share/api.py56
-rw-r--r--manila/tests/share/test_api.py103
2 files changed, 124 insertions, 35 deletions
diff --git a/manila/share/api.py b/manila/share/api.py
index 56809d5..a6322e9 100644
--- a/manila/share/api.py
+++ b/manila/share/api.py
@@ -31,7 +31,17 @@ from manila import quota
31from manila.scheduler import rpcapi as scheduler_rpcapi 31from manila.scheduler import rpcapi as scheduler_rpcapi
32from manila.share import rpcapi as share_rpcapi 32from manila.share import rpcapi as share_rpcapi
33 33
34share_api_opts = [
35 cfg.BoolOpt('use_scheduler_creating_share_from_snapshot',
36 default=False,
37 help='If set to False, then share creation from snapshot will '
38 'be performed on the same host. '
39 'If set to True, then scheduling step will be used.')
40]
41
34CONF = cfg.CONF 42CONF = cfg.CONF
43CONF.register_opts(share_api_opts)
44
35LOG = logging.getLogger(__name__) 45LOG = logging.getLogger(__name__)
36GB = 1048576 * 1024 46GB = 1048576 * 1024
37QUOTAS = quota.QUOTAS 47QUOTAS = quota.QUOTAS
@@ -152,22 +162,40 @@ class API(base.Base):
152 finally: 162 finally:
153 QUOTAS.rollback(context, reservations) 163 QUOTAS.rollback(context, reservations)
154 164
155 request_spec = {'share_properties': options, 165 request_spec = {
156 'share_proto': share_proto, 166 'share_properties': options,
157 'share_id': share['id'], 167 'share_proto': share_proto,
158 'snapshot_id': share['snapshot_id'], 168 'share_id': share['id'],
159 'volume_type': volume_type 169 'snapshot_id': snapshot_id,
160 } 170 'volume_type': volume_type,
161 171 }
162 filter_properties = {} 172 filter_properties = {}
163 173
164 self.scheduler_rpcapi.create_share( 174 if (snapshot and not CONF.use_scheduler_creating_share_from_snapshot):
165 context, 175 # Shares from snapshots with restriction - source host only.
166 CONF.share_topic, 176 # It is common situation for different types of backends.
167 share['id'], 177 host = snapshot['share']['host']
168 snapshot_id, 178 share = self.db.share_update(context, share['id'], {'host': host})
169 request_spec=request_spec, 179 self.share_rpcapi.create_share(
170 filter_properties=filter_properties) 180 context,
181 share,
182 host,
183 request_spec=request_spec,
184 filter_properties=filter_properties,
185 snapshot_id=snapshot_id,
186 )
187 else:
188 # Shares from scratch and from snapshots when source host is not
189 # the only allowed, it is possible, for example, in multibackend
190 # installation with Generic drivers only.
191 self.scheduler_rpcapi.create_share(
192 context,
193 CONF.share_topic,
194 share['id'],
195 snapshot_id,
196 request_spec=request_spec,
197 filter_properties=filter_properties,
198 )
171 199
172 return share 200 return share
173 201
diff --git a/manila/tests/share/test_api.py b/manila/tests/share/test_api.py
index 2fe8816..4980bd5 100644
--- a/manila/tests/share/test_api.py
+++ b/manila/tests/share/test_api.py
@@ -18,6 +18,7 @@ import datetime
18import uuid 18import uuid
19 19
20import mock 20import mock
21from oslo.config import cfg
21 22
22from manila import context 23from manila import context
23from manila import db as db_driver 24from manila import db as db_driver
@@ -30,6 +31,8 @@ from manila import test
30from manila.tests.db import fakes as db_fakes 31from manila.tests.db import fakes as db_fakes
31from manila import utils 32from manila import utils
32 33
34CONF = cfg.CONF
35
33 36
34def fake_share(id, **kwargs): 37def fake_share(id, **kwargs):
35 share = { 38 share = {
@@ -73,7 +76,8 @@ def fake_snapshot(id, **kwargs):
73 'progress': 'fakeprogress99%', 76 'progress': 'fakeprogress99%',
74 'scheduled_at': datetime.datetime(1, 1, 1, 1, 1, 1), 77 'scheduled_at': datetime.datetime(1, 1, 1, 1, 1, 1),
75 'launched_at': datetime.datetime(1, 1, 1, 1, 1, 1), 78 'launched_at': datetime.datetime(1, 1, 1, 1, 1, 1),
76 'terminated_at': datetime.datetime(1, 1, 1, 1, 1, 1) 79 'terminated_at': datetime.datetime(1, 1, 1, 1, 1, 1),
80 'share': {'host': 'fake_source_host'},
77 } 81 }
78 snapshot.update(kwargs) 82 snapshot.update(kwargs)
79 return snapshot 83 return snapshot
@@ -439,6 +443,7 @@ class ShareAPITestCase(test.TestCase):
439 mock.Mock(return_value='reservation')) 443 mock.Mock(return_value='reservation'))
440 @mock.patch.object(quota.QUOTAS, 'commit', mock.Mock()) 444 @mock.patch.object(quota.QUOTAS, 'commit', mock.Mock())
441 def test_create_from_snapshot_available(self): 445 def test_create_from_snapshot_available(self):
446 CONF.set_default("use_scheduler_creating_share_from_snapshot", False)
442 date = datetime.datetime(1, 1, 1, 1, 1, 1) 447 date = datetime.datetime(1, 1, 1, 1, 1, 1)
443 self.mock_utcnow.return_value = date 448 self.mock_utcnow.return_value = date
444 snapshot = fake_snapshot('fakesnapshotid', 449 snapshot = fake_snapshot('fakesnapshotid',
@@ -460,28 +465,80 @@ class ShareAPITestCase(test.TestCase):
460 'volume_type': None, 465 'volume_type': None,
461 'snapshot_id': share['snapshot_id'], 466 'snapshot_id': share['snapshot_id'],
462 } 467 }
463 with mock.patch.object(db_driver, 'share_create', 468 self.stubs.Set(db_driver, 'share_create',
464 mock.Mock(return_value=share)): 469 mock.Mock(return_value=share))
465 self.api.create(self.context, 'nfs', '1', 'fakename', 'fakedesc', 470 self.stubs.Set(db_driver, 'share_update',
466 snapshot=snapshot, availability_zone='fakeaz') 471 mock.Mock(return_value=share))
467 self.scheduler_rpcapi.create_share.assert_called_once_with( 472
468 self.context, 'manila-share', share['id'], 473 self.api.create(self.context, 'nfs', '1', 'fakename', 'fakedesc',
469 share['snapshot_id'], request_spec=request_spec, 474 snapshot=snapshot, availability_zone='fakeaz')
470 filter_properties={}) 475
471 db_driver.share_create.assert_called_once_with( 476 self.share_rpcapi.create_share.assert_called_once_with(
472 self.context, options) 477 self.context, share, snapshot['share']['host'],
473 share_api.policy.check_policy.assert_called_once_with( 478 request_spec=request_spec, filter_properties={},
474 self.context, 'share', 'create') 479 snapshot_id=snapshot['id'])
475 quota.QUOTAS.reserve.assert_called_once_with( 480 db_driver.share_create.assert_called_once_with(
476 self.context, gigabytes=1, shares=1) 481 self.context, options)
477 quota.QUOTAS.commit.assert_called_once_with( 482 share_api.policy.check_policy.assert_called_once_with(
478 self.context, 'reservation') 483 self.context, 'share', 'create')
484 quota.QUOTAS.reserve.assert_called_once_with(
485 self.context, gigabytes=1, shares=1)
486 quota.QUOTAS.commit.assert_called_once_with(
487 self.context, 'reservation')
488
489 @mock.patch.object(quota.QUOTAS, 'reserve',
490 mock.Mock(return_value='reservation'))
491 @mock.patch.object(quota.QUOTAS, 'commit', mock.Mock())
492 def test_create_from_snapshot_without_host_restriction(self):
493 CONF.set_default("use_scheduler_creating_share_from_snapshot", True)
494 date = datetime.datetime(1, 1, 1, 1, 1, 1)
495 self.mock_utcnow.return_value = date
496 snapshot = fake_snapshot('fakesnapshotid',
497 share_id='fakeshare_id',
498 status='available')
499 share = fake_share('fakeid',
500 user_id=self.context.user_id,
501 project_id=self.context.project_id,
502 snapshot_id=snapshot['id'],
503 status='creating')
504 options = share.copy()
505 for name in ('id', 'export_location', 'host', 'launched_at',
506 'terminated_at'):
507 options.pop(name, None)
508 request_spec = {
509 'share_properties': options,
510 'share_proto': share['share_proto'],
511 'share_id': share['id'],
512 'volume_type': None,
513 'snapshot_id': share['snapshot_id'],
514 }
515 self.stubs.Set(db_driver, 'share_create',
516 mock.Mock(return_value=share))
517 self.stubs.Set(db_driver, 'share_update',
518 mock.Mock(return_value=share))
519
520 self.api.create(self.context, 'nfs', '1', 'fakename', 'fakedesc',
521 snapshot=snapshot, availability_zone='fakeaz')
522
523 self.scheduler_rpcapi.create_share.assert_called_once_with(
524 self.context, 'manila-share', share['id'],
525 share['snapshot_id'], request_spec=request_spec,
526 filter_properties={})
527 db_driver.share_create.assert_called_once_with(
528 self.context, options)
529 share_api.policy.check_policy.assert_called_once_with(
530 self.context, 'share', 'create')
531 quota.QUOTAS.reserve.assert_called_once_with(
532 self.context, gigabytes=1, shares=1)
533 quota.QUOTAS.commit.assert_called_once_with(
534 self.context, 'reservation')
479 535
480 @mock.patch.object(quota.QUOTAS, 'reserve', 536 @mock.patch.object(quota.QUOTAS, 'reserve',
481 mock.Mock(return_value='reservation')) 537 mock.Mock(return_value='reservation'))
482 @mock.patch.object(quota.QUOTAS, 'commit', mock.Mock()) 538 @mock.patch.object(quota.QUOTAS, 'commit', mock.Mock())
483 def test_create_from_snapshot_with_volume_type_same(self): 539 def test_create_from_snapshot_with_volume_type_same(self):
484 # Prepare data for test 540 # Prepare data for test
541 CONF.set_default("use_scheduler_creating_share_from_snapshot", False)
485 date = datetime.datetime(1, 1, 1, 1, 1, 1) 542 date = datetime.datetime(1, 1, 1, 1, 1, 1)
486 self.mock_utcnow.return_value = date 543 self.mock_utcnow.return_value = date
487 share_id = 'fake_share_id' 544 share_id = 'fake_share_id'
@@ -506,6 +563,8 @@ class ShareAPITestCase(test.TestCase):
506 } 563 }
507 self.stubs.Set(db_driver, 'share_create', 564 self.stubs.Set(db_driver, 'share_create',
508 mock.Mock(return_value=share)) 565 mock.Mock(return_value=share))
566 self.stubs.Set(db_driver, 'share_update',
567 mock.Mock(return_value=share))
509 self.stubs.Set(db_driver, 'share_get', mock.Mock(return_value=share)) 568 self.stubs.Set(db_driver, 'share_get', mock.Mock(return_value=share))
510 569
511 # Call tested method 570 # Call tested method
@@ -514,10 +573,10 @@ class ShareAPITestCase(test.TestCase):
514 volume_type=volume_type) 573 volume_type=volume_type)
515 574
516 # Verify results 575 # Verify results
517 self.scheduler_rpcapi.create_share.assert_called_once_with( 576 self.share_rpcapi.create_share.assert_called_once_with(
518 self.context, 'manila-share', share_id, 577 self.context, share, snapshot['share']['host'],
519 share['snapshot_id'], request_spec=request_spec, 578 request_spec=request_spec, filter_properties={},
520 filter_properties={}) 579 snapshot_id=snapshot['id'])
521 db_driver.share_create.assert_called_once_with( 580 db_driver.share_create.assert_called_once_with(
522 self.context, options) 581 self.context, options)
523 share_api.policy.check_policy.assert_called_once_with( 582 share_api.policy.check_policy.assert_called_once_with(
@@ -528,6 +587,8 @@ class ShareAPITestCase(test.TestCase):
528 self.context, 'reservation') 587 self.context, 'reservation')
529 db_driver.share_get.assert_called_once_with( 588 db_driver.share_get.assert_called_once_with(
530 self.context, share_id) 589 self.context, share_id)
590 db_driver.share_update.assert_called_once_with(
591 self.context, share_id, {'host': snapshot['share']['host']})
531 592
532 @mock.patch.object(quota.QUOTAS, 'reserve', 593 @mock.patch.object(quota.QUOTAS, 'reserve',
533 mock.Mock(return_value='reservation')) 594 mock.Mock(return_value='reservation'))