Change Resource timestamps to save correct info
Resource.updated_time is currently being treated as modification time of the object in the database. Since it's not a very useful thing to have and the CFN API treats this value as "the last time an update call was issued", it makes sense to have the same behavior here as well. This changes the current real-time retrieval of created_time and updated_time in favor of the attributes already present in the resource and changes the information stored in these two fields to be the time the resource was created and the time the resource was last updated by the user, respectively. Co-Authored-By: Richard Lee <rblee88@gmail.com> Related-Bug: #1193269 Change-Id: Iad689b97d237fa63856b878827a1fcb1676c991c
This commit is contained in:
parent
ce690963e7
commit
cc1d2dddfb
|
@ -222,6 +222,11 @@ class Resource(BASE, HeatBase):
|
|||
cascade="all,delete",
|
||||
backref=backref('resource'))
|
||||
|
||||
# Override timestamp column to store the correct value: it should be the
|
||||
# time the create/update call was issued, not the time the DB entry is
|
||||
# created/modified. (bug #1193269)
|
||||
updated_at = sqlalchemy.Column(sqlalchemy.DateTime)
|
||||
|
||||
|
||||
class WatchRule(BASE, HeatBase):
|
||||
"""Represents a watch_rule created by the heat engine."""
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import base64
|
||||
import copy
|
||||
from datetime import datetime
|
||||
|
||||
from heat.engine import event
|
||||
from heat.common import exception
|
||||
|
@ -25,7 +26,6 @@ from heat.common import short_id
|
|||
from heat.engine import scheduler
|
||||
from heat.engine import resources
|
||||
from heat.engine import support
|
||||
from heat.engine import timestamp
|
||||
# import class to avoid name collisions and ugly aliasing
|
||||
from heat.engine.attributes import Attributes
|
||||
from heat.engine.properties import Properties
|
||||
|
@ -102,9 +102,6 @@ class Resource(object):
|
|||
# If True, this resource must be created before it can be referenced.
|
||||
strict_dependency = True
|
||||
|
||||
created_time = timestamp.Timestamp(db_api.resource_get, 'created_at')
|
||||
updated_time = timestamp.Timestamp(db_api.resource_get, 'updated_at')
|
||||
|
||||
_metadata = Metadata()
|
||||
|
||||
# Resource implementation set this to the subset of template keys
|
||||
|
@ -167,6 +164,8 @@ class Resource(object):
|
|||
self.status_reason = resource.status_reason
|
||||
self.id = resource.id
|
||||
self.data = resource.data
|
||||
self.created_time = resource.created_at
|
||||
self.updated_time = resource.updated_at
|
||||
else:
|
||||
self.resource_id = None
|
||||
# if the stack is being deleted, assume we've already been deleted
|
||||
|
@ -178,6 +177,8 @@ class Resource(object):
|
|||
self.status_reason = ''
|
||||
self.id = None
|
||||
self.data = []
|
||||
self.created_time = None
|
||||
self.updated_time = None
|
||||
|
||||
def reparse(self):
|
||||
self.t = self.stack.resolve_static_data(self.json_snippet)
|
||||
|
@ -539,6 +540,7 @@ class Resource(object):
|
|||
logger.info('updating %s' % str(self))
|
||||
|
||||
try:
|
||||
self.updated_time = datetime.utcnow()
|
||||
self.state_set(action, self.IN_PROGRESS)
|
||||
properties = Properties(self.properties_schema,
|
||||
after.get('Properties', {}),
|
||||
|
@ -750,6 +752,7 @@ class Resource(object):
|
|||
|
||||
new_rs = db_api.resource_create(self.context, rs)
|
||||
self.id = new_rs.id
|
||||
self.created_time = new_rs.created_at
|
||||
except Exception as ex:
|
||||
logger.error(_('DB error %s') % str(ex))
|
||||
|
||||
|
@ -776,6 +779,7 @@ class Resource(object):
|
|||
'status': self.status,
|
||||
'status_reason': reason,
|
||||
'stack_id': self.stack.id,
|
||||
'updated_at': self.updated_time,
|
||||
'nova_instance': self.resource_id})
|
||||
except Exception as ex:
|
||||
logger.error(_('DB error %s') % str(ex))
|
||||
|
|
|
@ -226,14 +226,27 @@ class ResourceTest(HeatTestCase):
|
|||
self.assertIsNotNone(res.created_time)
|
||||
|
||||
def test_updated_time(self):
|
||||
tmpl = {'Type': 'Foo'}
|
||||
res = generic_rsrc.GenericResource('test_res_upd', tmpl, self.stack)
|
||||
tmpl = {'Type': 'GenericResourceType'}
|
||||
res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
|
||||
res.update_allowed_keys = ('Type',)
|
||||
res._store()
|
||||
stored_time = res.updated_time
|
||||
res.state_set(res.CREATE, res.IN_PROGRESS, 'testing')
|
||||
|
||||
utmpl = {'Type': 'Foo'}
|
||||
scheduler.TaskRunner(res.update, utmpl)()
|
||||
self.assertIsNotNone(res.updated_time)
|
||||
self.assertNotEqual(res.updated_time, stored_time)
|
||||
|
||||
def test_updated_time_changes_only_on_update_calls(self):
|
||||
tmpl = {'Type': 'GenericResourceType'}
|
||||
res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
|
||||
res.update_allowed_keys = ('Type',)
|
||||
res._store()
|
||||
self.assertIsNone(res.updated_time)
|
||||
|
||||
res._store_or_update(res.UPDATE, res.COMPLETE, 'should not change')
|
||||
self.assertIsNone(res.updated_time)
|
||||
|
||||
def test_store_or_update(self):
|
||||
tmpl = {'Type': 'Foo'}
|
||||
res = generic_rsrc.GenericResource('test_res_upd', tmpl, self.stack)
|
||||
|
|
Loading…
Reference in New Issue