Merge "Fix handle_restore for server and volume resources" into stable/ocata

This commit is contained in:
Jenkins 2017-06-09 08:03:48 +00:00 committed by Gerrit Code Review
commit c6403967b9
5 changed files with 91 additions and 5 deletions

View File

@ -647,7 +647,7 @@ class CinderVolume(vb.BaseVolume, sh.SchedulerHintsMixin):
self.IMAGE_REF, self.IMAGE, self.SOURCE_VOLID) self.IMAGE_REF, self.IMAGE, self.SOURCE_VOLID)
props = dict( props = dict(
(key, value) for (key, value) in (key, value) for (key, value) in
six.iteritems(defn.properties(self.properties_schema)) self.properties.data.items()
if key not in ignore_props and value is not None) if key not in ignore_props and value is not None)
props[self.BACKUP_ID] = backup_id props[self.BACKUP_ID] = backup_id
return defn.freeze(properties=props) return defn.freeze(properties=props)

View File

@ -23,7 +23,6 @@ from heat.common.i18n import _
from heat.engine import attributes from heat.engine import attributes
from heat.engine.clients import progress from heat.engine.clients import progress
from heat.engine import constraints from heat.engine import constraints
from heat.engine import function
from heat.engine import properties from heat.engine import properties
from heat.engine.resources.openstack.neutron import port as neutron_port from heat.engine.resources.openstack.neutron import port as neutron_port
from heat.engine.resources.openstack.neutron import subnet from heat.engine.resources.openstack.neutron import subnet
@ -1577,7 +1576,8 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
def handle_restore(self, defn, restore_data): def handle_restore(self, defn, restore_data):
image_id = restore_data['resource_data']['snapshot_image_id'] image_id = restore_data['resource_data']['snapshot_image_id']
props = function.resolve(self.properties.data) props = dict((k, v) for k, v in self.properties.data.items()
if v is not None)
props[self.IMAGE] = image_id props[self.IMAGE] = image_id
return defn.freeze(properties=props) return defn.freeze(properties=props)

View File

@ -13,7 +13,6 @@
import collections import collections
from oslo_log import log as logging from oslo_log import log as logging
import six
from heat.common.i18n import _LW from heat.common.i18n import _LW
from heat.engine import attributes from heat.engine import attributes
@ -373,7 +372,7 @@ class ResourceWithRestoreType(ResWithComplexPropsAndAttrs):
def handle_restore(self, defn, data): def handle_restore(self, defn, data):
props = dict( props = dict(
(key, value) for (key, value) in (key, value) for (key, value) in
six.iteritems(defn.properties(self.properties_schema)) self.properties.data.items()
if value is not None) if value is not None)
value = data['resource_data']['a_string'] value = data['resource_data']['a_string']
props['a_string'] = value props['a_string'] = value

View File

@ -604,6 +604,17 @@ class HeatIntegrationTest(testscenarios.WithScenarios,
info = self.client.stacks.abandon(stack_id=stack_id) info = self.client.stacks.abandon(stack_id=stack_id)
return info return info
def stack_snapshot(self, stack_id,
wait_for_status='SNAPSHOT_COMPLETE'):
snapshot = self.client.stacks.snapshot(stack_id=stack_id)
self._wait_for_stack_status(stack_id, wait_for_status)
return snapshot['id']
def stack_restore(self, stack_id, snapshot_id,
wait_for_status='RESTORE_COMPLETE'):
self.client.stacks.restore(stack_id, snapshot_id)
self._wait_for_stack_status(stack_id, wait_for_status)
def stack_suspend(self, stack_identifier): def stack_suspend(self, stack_identifier):
if (self.conf.skip_test_stack_action_list and if (self.conf.skip_test_stack_action_list and
'SUSPEND' in self.conf.skip_test_stack_action_list): 'SUSPEND' in self.conf.skip_test_stack_action_list):

View File

@ -0,0 +1,76 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from heat_integrationtests.functional import functional_base
class StackSnapshotRestoreTest(functional_base.FunctionalTestsBase):
def setUp(self):
super(StackSnapshotRestoreTest, self).setUp()
if not self.conf.minimal_image_ref:
raise self.skipException("No image configured to test")
if not self.conf.minimal_instance_type:
raise self.skipException(
"No minimal_instance_type configured to test")
self.assign_keypair()
def test_stack_snapshot_restore(self):
template = '''
heat_template_version: ocata
parameters:
keyname:
type: string
flavor:
type: string
image:
type: string
network:
type: string
resources:
my_port:
type: OS::Neutron::Port
properties:
network: {get_param: network}
my_server:
type: OS::Nova::Server
properties:
image: {get_param: image}
flavor: {get_param: flavor}
key_name: {get_param: keyname}
networks: [{port: {get_resource: my_port} }]
'''
def get_server_image(server_id):
server = self.compute_client.servers.get(server_id)
return server.image['id']
parameters = {'keyname': self.keypair_name,
'flavor': self.conf.minimal_instance_type,
'image': self.conf.minimal_image_ref,
'network': self.conf.fixed_network_name}
stack_identifier = self.stack_create(template=template,
parameters=parameters)
server_resource = self.client.resources.get(
stack_identifier, 'my_server')
server_id = server_resource.physical_resource_id
prev_image_id = get_server_image(server_id)
# Do snapshot and restore
snapshot_id = self.stack_snapshot(stack_identifier)
self.stack_restore(stack_identifier, snapshot_id)
self.assertNotEqual(prev_image_id, get_server_image(server_id))