summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-06-09 08:03:48 +0000
committerGerrit Code Review <review@openstack.org>2017-06-09 08:03:48 +0000
commitc6403967b9e253571bfaee6ba0b450d296329295 (patch)
tree7078c0feb32b448030e5dcb6f657f9db8c591c00
parentb98af9d4646ecae2269ec9459a824d2c733a1e75 (diff)
parent437c5e7c4fe2f0fc3eaa034348384e7cd7cc81a6 (diff)
Merge "Fix handle_restore for server and volume resources" into stable/ocata
-rw-r--r--heat/engine/resources/openstack/cinder/volume.py2
-rw-r--r--heat/engine/resources/openstack/nova/server.py4
-rw-r--r--heat/tests/generic_resource.py3
-rw-r--r--heat_integrationtests/common/test.py11
-rw-r--r--heat_integrationtests/functional/test_snapshot_restore.py76
5 files changed, 91 insertions, 5 deletions
diff --git a/heat/engine/resources/openstack/cinder/volume.py b/heat/engine/resources/openstack/cinder/volume.py
index b6d0a05..e76d17e 100644
--- a/heat/engine/resources/openstack/cinder/volume.py
+++ b/heat/engine/resources/openstack/cinder/volume.py
@@ -647,7 +647,7 @@ class CinderVolume(vb.BaseVolume, sh.SchedulerHintsMixin):
647 self.IMAGE_REF, self.IMAGE, self.SOURCE_VOLID) 647 self.IMAGE_REF, self.IMAGE, self.SOURCE_VOLID)
648 props = dict( 648 props = dict(
649 (key, value) for (key, value) in 649 (key, value) for (key, value) in
650 six.iteritems(defn.properties(self.properties_schema)) 650 self.properties.data.items()
651 if key not in ignore_props and value is not None) 651 if key not in ignore_props and value is not None)
652 props[self.BACKUP_ID] = backup_id 652 props[self.BACKUP_ID] = backup_id
653 return defn.freeze(properties=props) 653 return defn.freeze(properties=props)
diff --git a/heat/engine/resources/openstack/nova/server.py b/heat/engine/resources/openstack/nova/server.py
index fb10ac4..eb0baa4 100644
--- a/heat/engine/resources/openstack/nova/server.py
+++ b/heat/engine/resources/openstack/nova/server.py
@@ -23,7 +23,6 @@ from heat.common.i18n import _
23from heat.engine import attributes 23from heat.engine import attributes
24from heat.engine.clients import progress 24from heat.engine.clients import progress
25from heat.engine import constraints 25from heat.engine import constraints
26from heat.engine import function
27from heat.engine import properties 26from heat.engine import properties
28from heat.engine.resources.openstack.neutron import port as neutron_port 27from heat.engine.resources.openstack.neutron import port as neutron_port
29from heat.engine.resources.openstack.neutron import subnet 28from heat.engine.resources.openstack.neutron import subnet
@@ -1577,7 +1576,8 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
1577 1576
1578 def handle_restore(self, defn, restore_data): 1577 def handle_restore(self, defn, restore_data):
1579 image_id = restore_data['resource_data']['snapshot_image_id'] 1578 image_id = restore_data['resource_data']['snapshot_image_id']
1580 props = function.resolve(self.properties.data) 1579 props = dict((k, v) for k, v in self.properties.data.items()
1580 if v is not None)
1581 props[self.IMAGE] = image_id 1581 props[self.IMAGE] = image_id
1582 return defn.freeze(properties=props) 1582 return defn.freeze(properties=props)
1583 1583
diff --git a/heat/tests/generic_resource.py b/heat/tests/generic_resource.py
index 9032d5c..bbe17a2 100644
--- a/heat/tests/generic_resource.py
+++ b/heat/tests/generic_resource.py
@@ -13,7 +13,6 @@
13 13
14import collections 14import collections
15from oslo_log import log as logging 15from oslo_log import log as logging
16import six
17 16
18from heat.common.i18n import _LW 17from heat.common.i18n import _LW
19from heat.engine import attributes 18from heat.engine import attributes
@@ -373,7 +372,7 @@ class ResourceWithRestoreType(ResWithComplexPropsAndAttrs):
373 def handle_restore(self, defn, data): 372 def handle_restore(self, defn, data):
374 props = dict( 373 props = dict(
375 (key, value) for (key, value) in 374 (key, value) for (key, value) in
376 six.iteritems(defn.properties(self.properties_schema)) 375 self.properties.data.items()
377 if value is not None) 376 if value is not None)
378 value = data['resource_data']['a_string'] 377 value = data['resource_data']['a_string']
379 props['a_string'] = value 378 props['a_string'] = value
diff --git a/heat_integrationtests/common/test.py b/heat_integrationtests/common/test.py
index b422012..7f024d7 100644
--- a/heat_integrationtests/common/test.py
+++ b/heat_integrationtests/common/test.py
@@ -604,6 +604,17 @@ class HeatIntegrationTest(testscenarios.WithScenarios,
604 info = self.client.stacks.abandon(stack_id=stack_id) 604 info = self.client.stacks.abandon(stack_id=stack_id)
605 return info 605 return info
606 606
607 def stack_snapshot(self, stack_id,
608 wait_for_status='SNAPSHOT_COMPLETE'):
609 snapshot = self.client.stacks.snapshot(stack_id=stack_id)
610 self._wait_for_stack_status(stack_id, wait_for_status)
611 return snapshot['id']
612
613 def stack_restore(self, stack_id, snapshot_id,
614 wait_for_status='RESTORE_COMPLETE'):
615 self.client.stacks.restore(stack_id, snapshot_id)
616 self._wait_for_stack_status(stack_id, wait_for_status)
617
607 def stack_suspend(self, stack_identifier): 618 def stack_suspend(self, stack_identifier):
608 if (self.conf.skip_test_stack_action_list and 619 if (self.conf.skip_test_stack_action_list and
609 'SUSPEND' in self.conf.skip_test_stack_action_list): 620 'SUSPEND' in self.conf.skip_test_stack_action_list):
diff --git a/heat_integrationtests/functional/test_snapshot_restore.py b/heat_integrationtests/functional/test_snapshot_restore.py
new file mode 100644
index 0000000..f63a360
--- /dev/null
+++ b/heat_integrationtests/functional/test_snapshot_restore.py
@@ -0,0 +1,76 @@
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
14from heat_integrationtests.functional import functional_base
15
16
17class StackSnapshotRestoreTest(functional_base.FunctionalTestsBase):
18
19 def setUp(self):
20 super(StackSnapshotRestoreTest, self).setUp()
21 if not self.conf.minimal_image_ref:
22 raise self.skipException("No image configured to test")
23
24 if not self.conf.minimal_instance_type:
25 raise self.skipException(
26 "No minimal_instance_type configured to test")
27
28 self.assign_keypair()
29
30 def test_stack_snapshot_restore(self):
31 template = '''
32heat_template_version: ocata
33parameters:
34 keyname:
35 type: string
36 flavor:
37 type: string
38 image:
39 type: string
40 network:
41 type: string
42resources:
43 my_port:
44 type: OS::Neutron::Port
45 properties:
46 network: {get_param: network}
47 my_server:
48 type: OS::Nova::Server
49 properties:
50 image: {get_param: image}
51 flavor: {get_param: flavor}
52 key_name: {get_param: keyname}
53 networks: [{port: {get_resource: my_port} }]
54
55'''
56
57 def get_server_image(server_id):
58 server = self.compute_client.servers.get(server_id)
59 return server.image['id']
60
61 parameters = {'keyname': self.keypair_name,
62 'flavor': self.conf.minimal_instance_type,
63 'image': self.conf.minimal_image_ref,
64 'network': self.conf.fixed_network_name}
65 stack_identifier = self.stack_create(template=template,
66 parameters=parameters)
67 server_resource = self.client.resources.get(
68 stack_identifier, 'my_server')
69 server_id = server_resource.physical_resource_id
70 prev_image_id = get_server_image(server_id)
71
72 # Do snapshot and restore
73 snapshot_id = self.stack_snapshot(stack_identifier)
74 self.stack_restore(stack_identifier, snapshot_id)
75
76 self.assertNotEqual(prev_image_id, get_server_image(server_id))