)]}'
{"heat/engine/resources/swift_utils.py":[{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"a8f7d49c7c252028a1f882d763ec5278ba7f1603","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"dab895d6_5b87ae61","updated":"2014-06-30 21:50:24.000000000","message":"Could this file (and tests) be broken out into the first change in this series?","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"38208cd0a4e0c0e3cec15ad7aa176ac4792e5db8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"baada198_a665ece2","in_reply_to":"dab895d6_5b87ae61","updated":"2014-07-01 18:57:07.000000000","message":"Will do.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"a8f7d49c7c252028a1f882d763ec5278ba7f1603","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    return bool(len(parts) \u003d\u003d 5 and"},{"line_number":33,"context_line":"                not parts[0] and"},{"line_number":34,"context_line":"                parts[1] \u003d\u003d \u0027v1\u0027 and"},{"line_number":35,"context_line":"                parts[2].startswith(\u0027AUTH_\u0027) and"},{"line_number":36,"context_line":"                parts[3] and"},{"line_number":37,"context_line":"                parts[4].strip(\u0027/\u0027))"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"dab895d6_9b81464d","line":35,"updated":"2014-06-30 21:50:24.000000000","message":"Is the v1 and AUTH_ check being a little too strict? How about the validation assumes the last 3 parts are account, container, object. So the validation is just checking for a path for at least 3 paths.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"38208cd0a4e0c0e3cec15ad7aa176ac4792e5db8","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    return bool(len(parts) \u003d\u003d 5 and"},{"line_number":33,"context_line":"                not parts[0] and"},{"line_number":34,"context_line":"                parts[1] \u003d\u003d \u0027v1\u0027 and"},{"line_number":35,"context_line":"                parts[2].startswith(\u0027AUTH_\u0027) and"},{"line_number":36,"context_line":"                parts[3] and"},{"line_number":37,"context_line":"                parts[4].strip(\u0027/\u0027))"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_26539c18","line":35,"in_reply_to":"dab895d6_9b81464d","updated":"2014-07-01 18:57:07.000000000","message":"The v1 check seems to be important:\nhttps://github.com/openstack/swift/blob/master/bin/swift-temp-url#L61\n\nIt seems like \"AUTH_\" can be something else.  I\u0027ll remove that check.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d7a554d24332c2379e3f5e3748c6921f94033386","unresolved":false,"context_lines":[{"line_number":40,"context_line":"def generate_temp_url(method, seconds, path, key):"},{"line_number":41,"context_line":"    \u0027\u0027\u0027Generate a Swift TempURL\u0027\u0027\u0027"},{"line_number":42,"context_line":"    try:"},{"line_number":43,"context_line":"        expires \u003d int(time.time() + int(seconds))"},{"line_number":44,"context_line":"    except ValueError:"},{"line_number":45,"context_line":"        expires \u003d 0"},{"line_number":46,"context_line":"    if expires \u003c 1:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_3e63f3dd","line":43,"updated":"2014-06-27 21:09:56.000000000","message":"Since it takes some time to process this request, do we want to add some fudge factor here, say +2 seconds?","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d300524d438d863279406ddaf0f200816c044c54","unresolved":false,"context_lines":[{"line_number":40,"context_line":"def generate_temp_url(method, seconds, path, key):"},{"line_number":41,"context_line":"    \u0027\u0027\u0027Generate a Swift TempURL\u0027\u0027\u0027"},{"line_number":42,"context_line":"    try:"},{"line_number":43,"context_line":"        expires \u003d int(time.time() + int(seconds))"},{"line_number":44,"context_line":"    except ValueError:"},{"line_number":45,"context_line":"        expires \u003d 0"},{"line_number":46,"context_line":"    if expires \u003c 1:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_aff18f6b","line":43,"in_reply_to":"1ae5cdf2_09ce0383","updated":"2014-06-27 22:47:44.000000000","message":"Agreed, not sure myself the better way to handle this. It may in fact be best to have the user take that into account when they set their timeout.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"d03d6fcf681946bd3020f19771687fa23281d6cd","unresolved":false,"context_lines":[{"line_number":40,"context_line":"def generate_temp_url(method, seconds, path, key):"},{"line_number":41,"context_line":"    \u0027\u0027\u0027Generate a Swift TempURL\u0027\u0027\u0027"},{"line_number":42,"context_line":"    try:"},{"line_number":43,"context_line":"        expires \u003d int(time.time() + int(seconds))"},{"line_number":44,"context_line":"    except ValueError:"},{"line_number":45,"context_line":"        expires \u003d 0"},{"line_number":46,"context_line":"    if expires \u003c 1:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_09ce0383","line":43,"in_reply_to":"1ae5cdf2_3e63f3dd","updated":"2014-06-27 21:30:38.000000000","message":"I see your point, but I can\u0027t decide if that belongs in this function.  Will wait to see if others have an opinion.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"a8f7d49c7c252028a1f882d763ec5278ba7f1603","unresolved":false,"context_lines":[{"line_number":40,"context_line":"def generate_temp_url(method, seconds, path, key):"},{"line_number":41,"context_line":"    \u0027\u0027\u0027Generate a Swift TempURL\u0027\u0027\u0027"},{"line_number":42,"context_line":"    try:"},{"line_number":43,"context_line":"        expires \u003d int(time.time() + int(seconds))"},{"line_number":44,"context_line":"    except ValueError:"},{"line_number":45,"context_line":"        expires \u003d 0"},{"line_number":46,"context_line":"    if expires \u003c 1:"}],"source_content_type":"text/x-python","patch_set":2,"id":"dab895d6_fbe6c243","line":43,"in_reply_to":"1ae5cdf2_aff18f6b","updated":"2014-06-30 21:50:24.000000000","message":"Actually I\u0027d prefer that the expires was calculated outside this function too (so replace the seconds arg with an expires arg).\n\nI see some need for \"temp\" URLs which never expire, so maybe if \"expire\" is not supplied it defaults to the max unix timestamp.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"38208cd0a4e0c0e3cec15ad7aa176ac4792e5db8","unresolved":false,"context_lines":[{"line_number":40,"context_line":"def generate_temp_url(method, seconds, path, key):"},{"line_number":41,"context_line":"    \u0027\u0027\u0027Generate a Swift TempURL\u0027\u0027\u0027"},{"line_number":42,"context_line":"    try:"},{"line_number":43,"context_line":"        expires \u003d int(time.time() + int(seconds))"},{"line_number":44,"context_line":"    except ValueError:"},{"line_number":45,"context_line":"        expires \u003d 0"},{"line_number":46,"context_line":"    if expires \u003c 1:"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_db7e31ae","line":43,"in_reply_to":"dab895d6_fbe6c243","updated":"2014-07-01 18:57:07.000000000","message":"Done","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"}],"heat/engine/resources/swiftsignal.py":[{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"89872a69f4387ad02e6be1784c35f66782dc4cbe","unresolved":false,"context_lines":[{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def resource_mapping():"},{"line_number":113,"context_line":"    return {\u0027OS::Heat::SwiftSignal\u0027: SwiftSignal,"},{"line_number":114,"context_line":"            \u0027OS::Heat::SwiftSignalHandle\u0027: SwiftSignalHandle}"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"1ae5cdf2_f84756ba","line":113,"updated":"2014-06-17 21:07:43.000000000","message":"I\u0027d prefer OS::Heat::WaitCondition or OS::Heat::Signal. The fact that it uses Swift is (or should be) an implementation detail. It\u0027s quite possible that different operators would like to provide different ways of accessing this.","commit_id":"6f1f74c9eb6d59bd75a473ab4cec53acddee1b7a"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"8f5731f07eb089eb2d77146446c701d3331c954f","unresolved":false,"context_lines":[{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def resource_mapping():"},{"line_number":113,"context_line":"    return {\u0027OS::Heat::SwiftSignal\u0027: SwiftSignal,"},{"line_number":114,"context_line":"            \u0027OS::Heat::SwiftSignalHandle\u0027: SwiftSignalHandle}"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"1ae5cdf2_bcaeb87f","line":113,"in_reply_to":"1ae5cdf2_f84756ba","updated":"2014-06-24 17:06:40.000000000","message":"Isn\u0027t that what environments are for?","commit_id":"6f1f74c9eb6d59bd75a473ab4cec53acddee1b7a"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"a8f7d49c7c252028a1f882d763ec5278ba7f1603","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        sw_url \u003d urlparse.urlparse(self.swift().url)"},{"line_number":70,"context_line":"        tempurl \u003d \u0027%s://%s%s\u0027 % (sw_url.scheme, sw_url.netloc, path)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        self.resource_id_set(tempurl)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def FnGetRefId(self):"},{"line_number":75,"context_line":"        return self.resource_id if self.resource_id else self.name"}],"source_content_type":"text/x-python","patch_set":2,"id":"dab895d6_7b41d20a","line":72,"updated":"2014-06-30 21:50:24.000000000","message":"I think we need to support the use-case which led to UpdateWaitConditionHandle, which might just need an update method which raises UpdateReplace","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"38208cd0a4e0c0e3cec15ad7aa176ac4792e5db8","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        sw_url \u003d urlparse.urlparse(self.swift().url)"},{"line_number":70,"context_line":"        tempurl \u003d \u0027%s://%s%s\u0027 % (sw_url.scheme, sw_url.netloc, path)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        self.resource_id_set(tempurl)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def FnGetRefId(self):"},{"line_number":75,"context_line":"        return self.resource_id if self.resource_id else self.name"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_cd9038ef","line":72,"in_reply_to":"dab895d6_7b41d20a","updated":"2014-07-01 18:57:07.000000000","message":"Done","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"f97adae0336f0c6f251d1e03cd4ac6a419c64a16","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.resource_id_set(tempurl)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def FnGetRefId(self):"},{"line_number":75,"context_line":"        return self.resource_id if self.resource_id else self.name"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"class SwiftSignal(resource.Resource):"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_0d99a66c","line":75,"updated":"2014-06-28 09:23:35.000000000","message":"I don\u0027t think this is needed, as it\u0027s what the Resource base class does anyway:\n\nhttps://github.com/openstack/heat/blob/master/heat/engine/resource.py#L817","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"ba4471f38f98231d5f3bf383f80d96afa95b621a","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.resource_id_set(tempurl)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def FnGetRefId(self):"},{"line_number":75,"context_line":"        return self.resource_id if self.resource_id else self.name"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"class SwiftSignal(resource.Resource):"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_a9e24201","line":75,"in_reply_to":"1ae5cdf2_0d99a66c","updated":"2014-06-30 21:36:33.000000000","message":"Done","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"f97adae0336f0c6f251d1e03cd4ac6a419c64a16","unresolved":false,"context_lines":[{"line_number":85,"context_line":"            required\u003dTrue,"},{"line_number":86,"context_line":"            description\u003d_(\u0027URL of TempURL where resource will signal \u0027"},{"line_number":87,"context_line":"                          \u0027completion and optionally upload data.\u0027)"},{"line_number":88,"context_line":"        ),"},{"line_number":89,"context_line":"        TIMEOUT: properties.Schema("},{"line_number":90,"context_line":"            properties.Schema.NUMBER,"},{"line_number":91,"context_line":"            description\u003d_(\u0027The maximum number of seconds to wait for the \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_ad8fd221","line":88,"updated":"2014-06-28 09:23:35.000000000","message":"Don\u0027t we also want some way to handle multiple signals (e.g a count property like with the existing WaitCondition resources?).  \n\nI\u0027m not quite sure how that would be implemented on the swift side, but it seems like it\u0027s a prerequisite if this is going to be a pluggable alternative implementation to the AWS WaitCondition resource.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"ba4471f38f98231d5f3bf383f80d96afa95b621a","unresolved":false,"context_lines":[{"line_number":85,"context_line":"            required\u003dTrue,"},{"line_number":86,"context_line":"            description\u003d_(\u0027URL of TempURL where resource will signal \u0027"},{"line_number":87,"context_line":"                          \u0027completion and optionally upload data.\u0027)"},{"line_number":88,"context_line":"        ),"},{"line_number":89,"context_line":"        TIMEOUT: properties.Schema("},{"line_number":90,"context_line":"            properties.Schema.NUMBER,"},{"line_number":91,"context_line":"            description\u003d_(\u0027The maximum number of seconds to wait for the \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_247497fc","line":88,"in_reply_to":"1ae5cdf2_ad8fd221","updated":"2014-06-30 21:36:33.000000000","message":"With the current design, there would be a race-condition between the check_create_complete code, which polls every second and the curl command that could possibly send more than one signal in a second.  I\u0027ll have to think about this.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"38208cd0a4e0c0e3cec15ad7aa176ac4792e5db8","unresolved":false,"context_lines":[{"line_number":85,"context_line":"            required\u003dTrue,"},{"line_number":86,"context_line":"            description\u003d_(\u0027URL of TempURL where resource will signal \u0027"},{"line_number":87,"context_line":"                          \u0027completion and optionally upload data.\u0027)"},{"line_number":88,"context_line":"        ),"},{"line_number":89,"context_line":"        TIMEOUT: properties.Schema("},{"line_number":90,"context_line":"            properties.Schema.NUMBER,"},{"line_number":91,"context_line":"            description\u003d_(\u0027The maximum number of seconds to wait for the \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_db03910d","line":88,"in_reply_to":"baada198_247497fc","updated":"2014-07-01 18:57:07.000000000","message":"I spoke with Randall about this and he mentioned the swift \"Object Versioning\" feature might be useful.  I\u0027ll try implementing the support for multiple signals using that.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d7a554d24332c2379e3f5e3748c6921f94033386","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        url \u003d urlparse.urlparse(handle)"},{"line_number":129,"context_line":"        self._validate_handle_url(url)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"        self.container_name, self.obj_name \u003d url.path.split(\u0027/\u0027)[3:]"},{"line_number":132,"context_line":"        seconds \u003d self.properties.get(self.TIMEOUT)"},{"line_number":133,"context_line":"        self.timeout_time \u003d time.time() + seconds"},{"line_number":134,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_3ee21301","line":131,"updated":"2014-06-27 21:09:56.000000000","message":"Instead of setting instance properties here, I would just return a tuple of (container_name, object_name, timeout) and process that tuple in check_create_complete:\n\n  container_name, object_name \u003d url.path.split(\u0027/\u0027)[3:]\n  seconds \u003d time.time() + self.properties[self.TIMEOUT]\n  return (container_name, object_name, seconds)","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"d03d6fcf681946bd3020f19771687fa23281d6cd","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        url \u003d urlparse.urlparse(handle)"},{"line_number":129,"context_line":"        self._validate_handle_url(url)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"        self.container_name, self.obj_name \u003d url.path.split(\u0027/\u0027)[3:]"},{"line_number":132,"context_line":"        seconds \u003d self.properties.get(self.TIMEOUT)"},{"line_number":133,"context_line":"        self.timeout_time \u003d time.time() + seconds"},{"line_number":134,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_e9dc7747","line":131,"in_reply_to":"1ae5cdf2_3ee21301","updated":"2014-06-27 21:30:38.000000000","message":"Will do.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"ba4471f38f98231d5f3bf383f80d96afa95b621a","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        url \u003d urlparse.urlparse(handle)"},{"line_number":129,"context_line":"        self._validate_handle_url(url)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"        self.container_name, self.obj_name \u003d url.path.split(\u0027/\u0027)[3:]"},{"line_number":132,"context_line":"        seconds \u003d self.properties.get(self.TIMEOUT)"},{"line_number":133,"context_line":"        self.timeout_time \u003d time.time() + seconds"},{"line_number":134,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_eed7e0bd","line":131,"in_reply_to":"1ae5cdf2_e9dc7747","updated":"2014-06-30 21:36:33.000000000","message":"Done","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d7a554d24332c2379e3f5e3748c6921f94033386","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        seconds \u003d self.properties.get(self.TIMEOUT)"},{"line_number":133,"context_line":"        self.timeout_time \u003d time.time() + seconds"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def check_create_complete(self, signal):"},{"line_number":136,"context_line":"        obj_head, obj_body \u003d self.swift().get_object(self.container_name,"},{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_bebd43d9","line":135,"updated":"2014-06-27 21:09:56.000000000","message":"per the above, I\u0027d start with:\n\n  container_name, object_name, timeout \u003d signal\n\nand remove all the \"self.\" for these variables.\n\nThe reasoning behind this is that while its certainly aligns with the current way we handle the resource lifecycle, once we start work on convergence, there won\u0027t be any guarantee that the instance that ran handle_create is the same instance that runs check_create_complete.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"d03d6fcf681946bd3020f19771687fa23281d6cd","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        seconds \u003d self.properties.get(self.TIMEOUT)"},{"line_number":133,"context_line":"        self.timeout_time \u003d time.time() + seconds"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def check_create_complete(self, signal):"},{"line_number":136,"context_line":"        obj_head, obj_body \u003d self.swift().get_object(self.container_name,"},{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_c9d97b57","line":135,"in_reply_to":"1ae5cdf2_bebd43d9","updated":"2014-06-27 21:30:38.000000000","message":"Will do.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"ba4471f38f98231d5f3bf383f80d96afa95b621a","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        seconds \u003d self.properties.get(self.TIMEOUT)"},{"line_number":133,"context_line":"        self.timeout_time \u003d time.time() + seconds"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def check_create_complete(self, signal):"},{"line_number":136,"context_line":"        obj_head, obj_body \u003d self.swift().get_object(self.container_name,"},{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_2ee2b89f","line":135,"in_reply_to":"1ae5cdf2_c9d97b57","updated":"2014-06-30 21:36:33.000000000","message":"Done","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d7a554d24332c2379e3f5e3748c6921f94033386","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    def check_create_complete(self, signal):"},{"line_number":136,"context_line":"        obj_head, obj_body \u003d self.swift().get_object(self.container_name,"},{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        if obj_body \u003d\u003d IN_PROGRESS and not timed_out:"},{"line_number":141,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_fefd0b6e","line":138,"updated":"2014-06-27 21:09:56.000000000","message":"I think you need to fail fast and move lines 146-148 here.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"ba4471f38f98231d5f3bf383f80d96afa95b621a","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    def check_create_complete(self, signal):"},{"line_number":136,"context_line":"        obj_head, obj_body \u003d self.swift().get_object(self.container_name,"},{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        if obj_body \u003d\u003d IN_PROGRESS and not timed_out:"},{"line_number":141,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_c9713679","line":138,"in_reply_to":"1ae5cdf2_6f45c799","updated":"2014-06-30 21:36:33.000000000","message":"The AWS resource doesn\u0027t support updates, so I don\u0027t think we should either (would get really complicated).\nhttp://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-waitcondition.html","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"25d211c60ef28a7794b4ee21b6264e26da511e9b","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    def check_create_complete(self, signal):"},{"line_number":136,"context_line":"        obj_head, obj_body \u003d self.swift().get_object(self.container_name,"},{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        if obj_body \u003d\u003d IN_PROGRESS and not timed_out:"},{"line_number":141,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_6f45c799","line":138,"in_reply_to":"1ae5cdf2_a92fcf3c","updated":"2014-06-27 22:46:31.000000000","message":"Hrm. I see what you mean since the container stuff would stay around on a timeout if you made my change. Actually, maybe the container and its artifacts should stick around since the user should be able to do a stack-update (soon) to fix a failed stack and the container would already have been created.\n\nFor those reasons, maybe a handle_delete and/or handle_update would be in order in the signal handle?\n\nSorry for the ramble. Now that you\u0027ve explaned it, I\u0027ll remove my -1 and see how this shakes out as it develops.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"d03d6fcf681946bd3020f19771687fa23281d6cd","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    def check_create_complete(self, signal):"},{"line_number":136,"context_line":"        obj_head, obj_body \u003d self.swift().get_object(self.container_name,"},{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        if obj_body \u003d\u003d IN_PROGRESS and not timed_out:"},{"line_number":141,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_a92fcf3c","line":138,"in_reply_to":"1ae5cdf2_fefd0b6e","updated":"2014-06-27 21:30:38.000000000","message":"I originally had it that way, but I also had a cleanup sub-function (consisted of lines 143-144) that I was calling in 2 or 3 different places.  This way seemed cleaner.  Do you think I should put it back?","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d7a554d24332c2379e3f5e3748c6921f94033386","unresolved":false,"context_lines":[{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        if obj_body \u003d\u003d IN_PROGRESS and not timed_out:"},{"line_number":141,"context_line":"            return False"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        self.swift().delete_object(self.container_name, self.obj_name)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_be2e23f8","line":140,"updated":"2014-06-27 21:09:56.000000000","message":"if you make the above change, you can remove \"and...\" from this condition.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"d03d6fcf681946bd3020f19771687fa23281d6cd","unresolved":false,"context_lines":[{"line_number":137,"context_line":"                                                     self.obj_name)"},{"line_number":138,"context_line":"        timed_out \u003d time.time() \u003e self.timeout_time"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        if obj_body \u003d\u003d IN_PROGRESS and not timed_out:"},{"line_number":141,"context_line":"            return False"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        self.swift().delete_object(self.container_name, self.obj_name)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_a9618fa9","line":140,"in_reply_to":"1ae5cdf2_be2e23f8","updated":"2014-06-27 21:30:38.000000000","message":"See above.","commit_id":"a1601931e3a78059fc49df48f28a43e20cdf5a94"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"63718e3bbdd10609bf440270320abc2c6509a9f0","unresolved":false,"context_lines":[{"line_number":178,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":179,"context_line":"            obj_container_name)[1][0]"},{"line_number":180,"context_line":"        metadata \u003d {}"},{"line_number":181,"context_line":"        for signal_num in xrange(count-1):"},{"line_number":182,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"},{"line_number":183,"context_line":"            signal_data \u003d self.swift().get_object("},{"line_number":184,"context_line":"                ver_container_name,"}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_9640e0a6","line":181,"updated":"2014-07-02 18:31:44.000000000","message":"Doesn\u0027t this inadvertently capture the original \"in progress\" version and possibly skip the \"n-1\" data?","commit_id":"546b3225539acecbc2fa12e8fbf616d4055bebd0"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"e02566f72025257d95facd3c8bd0ad1f98762179","unresolved":false,"context_lines":[{"line_number":178,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":179,"context_line":"            obj_container_name)[1][0]"},{"line_number":180,"context_line":"        metadata \u003d {}"},{"line_number":181,"context_line":"        for signal_num in xrange(count-1):"},{"line_number":182,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"},{"line_number":183,"context_line":"            signal_data \u003d self.swift().get_object("},{"line_number":184,"context_line":"                ver_container_name,"}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_d1f262d1","line":181,"in_reply_to":"baada198_9640e0a6","updated":"2014-07-02 18:57:02.000000000","message":"Hm, it works in my tests.  Check where the ver_container_objects variable is defined above on line 157.  It skips the \"in progress\" version.","commit_id":"546b3225539acecbc2fa12e8fbf616d4055bebd0"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"c8fd4782d1d5b1e17bf8a8a219901f75b8f53700","unresolved":false,"context_lines":[{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def handle_create(self):"},{"line_number":40,"context_line":"        method \u003d \u0027PUT\u0027"},{"line_number":41,"context_line":"        expires \u003d 2147483647  # Maximum Unix timestamp (January 19, 2038)"},{"line_number":42,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":43,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":44,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_a34a05c3","line":41,"updated":"2014-07-02 19:54:07.000000000","message":"IMO, this should be the timeout value of the stack operation. Having this basically never expire seems to lose part of the advantages of the temp urls.","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"5f08b27b79c8c718dd824b86b4bafddaaba6bddc","unresolved":false,"context_lines":[{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def handle_create(self):"},{"line_number":40,"context_line":"        method \u003d \u0027PUT\u0027"},{"line_number":41,"context_line":"        expires \u003d 2147483647  # Maximum Unix timestamp (January 19, 2038)"},{"line_number":42,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":43,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":44,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_f962ecab","line":41,"in_reply_to":"baada198_a34a05c3","updated":"2014-07-02 20:20:33.000000000","message":"Done","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"c8fd4782d1d5b1e17bf8a8a219901f75b8f53700","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            # object version history stack.  Delete the current object"},{"line_number":156,"context_line":"            # along with all object versions, and then delete the"},{"line_number":157,"context_line":"            # containers."},{"line_number":158,"context_line":"            for _ in xrange(signals_received+1):"},{"line_number":159,"context_line":"                self.swift().delete_object(obj_container_name, obj_name)"},{"line_number":160,"context_line":"            self.swift().delete_container(obj_container_name)"},{"line_number":161,"context_line":"            self.swift().delete_container(ver_container_name)"}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_43d689c6","line":158,"updated":"2014-07-02 19:54:07.000000000","message":"The \"_\" gets confused with the i18n operator, so may want to just use a variable here or refactor the loop to just iterate over ver_container_objects.","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"5f08b27b79c8c718dd824b86b4bafddaaba6bddc","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            # object version history stack.  Delete the current object"},{"line_number":156,"context_line":"            # along with all object versions, and then delete the"},{"line_number":157,"context_line":"            # containers."},{"line_number":158,"context_line":"            for _ in xrange(signals_received+1):"},{"line_number":159,"context_line":"                self.swift().delete_object(obj_container_name, obj_name)"},{"line_number":160,"context_line":"            self.swift().delete_container(obj_container_name)"},{"line_number":161,"context_line":"            self.swift().delete_container(ver_container_name)"}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_c61c67c4","line":158,"in_reply_to":"baada198_43d689c6","updated":"2014-07-02 20:20:33.000000000","message":"Done","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"c8fd4782d1d5b1e17bf8a8a219901f75b8f53700","unresolved":false,"context_lines":[{"line_number":156,"context_line":"            # along with all object versions, and then delete the"},{"line_number":157,"context_line":"            # containers."},{"line_number":158,"context_line":"            for _ in xrange(signals_received+1):"},{"line_number":159,"context_line":"                self.swift().delete_object(obj_container_name, obj_name)"},{"line_number":160,"context_line":"            self.swift().delete_container(obj_container_name)"},{"line_number":161,"context_line":"            self.swift().delete_container(ver_container_name)"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_c38ff9ca","line":159,"updated":"2014-07-02 19:54:07.000000000","message":"This looks like a bug in that I think you should be deleting from ver_container_name since obj_container_name should only ever have one object in it. If you refactor the loop as per above, the the loop looks like:\n\n  for obj in all_ver_container_objects:\n     self.swift().delet_object(ver_conatiner_name, obj)","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"52deab2f22a5102d4fd57be8cd0a253298088391","unresolved":false,"context_lines":[{"line_number":156,"context_line":"            # along with all object versions, and then delete the"},{"line_number":157,"context_line":"            # containers."},{"line_number":158,"context_line":"            for _ in xrange(signals_received+1):"},{"line_number":159,"context_line":"                self.swift().delete_object(obj_container_name, obj_name)"},{"line_number":160,"context_line":"            self.swift().delete_container(obj_container_name)"},{"line_number":161,"context_line":"            self.swift().delete_container(ver_container_name)"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_17a687c1","line":159,"in_reply_to":"baada198_9991f09b","updated":"2014-07-02 21:24:54.000000000","message":"Oh. Very wierd.","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"5f08b27b79c8c718dd824b86b4bafddaaba6bddc","unresolved":false,"context_lines":[{"line_number":156,"context_line":"            # along with all object versions, and then delete the"},{"line_number":157,"context_line":"            # containers."},{"line_number":158,"context_line":"            for _ in xrange(signals_received+1):"},{"line_number":159,"context_line":"                self.swift().delete_object(obj_container_name, obj_name)"},{"line_number":160,"context_line":"            self.swift().delete_container(obj_container_name)"},{"line_number":161,"context_line":"            self.swift().delete_container(ver_container_name)"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_9991f09b","line":159,"in_reply_to":"baada198_c38ff9ca","updated":"2014-07-02 20:20:33.000000000","message":"The way it works is counter-intuitive.  See my comment on line 158.  Deleting the original object multiple times actually deletes past versions and, finally, the original object.","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"c8fd4782d1d5b1e17bf8a8a219901f75b8f53700","unresolved":false,"context_lines":[{"line_number":193,"context_line":"    def _resolve_attribute(self, key):"},{"line_number":194,"context_line":"        if key \u003d\u003d self.DATA:"},{"line_number":195,"context_line":"            rsrc_metadata \u003d self.metadata_get(refresh\u003dTrue)"},{"line_number":196,"context_line":"            return rsrc_metadata[\u0027swiftsignal_data\u0027]"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"def resource_mapping():"}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_06a01ff3","line":196,"updated":"2014-07-02 19:54:07.000000000","message":"since this can get resolved prior to create or possibly even during check_create_complete, I suggest you change this to something like:\n\n  if rsrc_metadata:\n     return rsrc_metadata.get(\"swiftsignal_data\", \"\")","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"5f08b27b79c8c718dd824b86b4bafddaaba6bddc","unresolved":false,"context_lines":[{"line_number":193,"context_line":"    def _resolve_attribute(self, key):"},{"line_number":194,"context_line":"        if key \u003d\u003d self.DATA:"},{"line_number":195,"context_line":"            rsrc_metadata \u003d self.metadata_get(refresh\u003dTrue)"},{"line_number":196,"context_line":"            return rsrc_metadata[\u0027swiftsignal_data\u0027]"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"def resource_mapping():"}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_66f9db7f","line":196,"in_reply_to":"baada198_06a01ff3","updated":"2014-07-02 20:20:33.000000000","message":"Done","commit_id":"6bf8dce1f3ba87aef60a3103fc2d7777708f8ccc"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"5c62c0118c3aaef281e541d395339d030ade6258","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    def handle_create(self):"},{"line_number":41,"context_line":"        method \u003d \u0027PUT\u0027"},{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_66182285","line":43,"updated":"2014-07-09 22:48:32.000000000","message":"Why not use the UUID of this resource object in the database? Or just use self.physical_resource_name(), which generates a randomised-but-stable resource name based on that UUID. That how we normally generate resource names.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"bfe8b6d590880bae06dd2bf1d7c4d17516dc5fac","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    def handle_create(self):"},{"line_number":41,"context_line":"        method \u003d \u0027PUT\u0027"},{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_1ae68bb0","line":43,"in_reply_to":"baada198_66182285","updated":"2014-07-11 17:02:04.000000000","message":"Done","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":866,"name":"Chmouel Boudjnah","email":"chmouel@chmouel.com","username":"chmouel"},"change_message_id":"c3890d3dd2a0ff31a33381b135e0bd2513926706","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"},{"line_number":47,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id,"},{"line_number":48,"context_line":"                                      obj_container_name,"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_43c96c59","line":45,"updated":"2014-07-09 07:47:27.000000000","message":"is there a need for versioned objects here? ( I could not find a reasoning in the BP)","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"a2a3919e2f70710027ef6fad2e94d88c1a0ef17e","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"},{"line_number":47,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id,"},{"line_number":48,"context_line":"                                      obj_container_name,"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_5a9a0d6f","line":45,"in_reply_to":"baada198_0ffdb93b","updated":"2014-07-09 23:01:00.000000000","message":"(replying to myself)\n\nActually Swift does allow that, but only using POST so we can\u0027t include all the data in the URL so it won\u0027t work for us:\nhttp://docs.openstack.org/api/openstack-object-storage/1.0/content/form-post.html\n\nI guess it follows that CloudFormation is doing something similar to you here also, because the unique ID is only included in the body of the request:\nhttp://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-waitcondition.html","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"90632726339b2ccbd0c88d9565dbed2b6ba5d8b9","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"},{"line_number":47,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id,"},{"line_number":48,"context_line":"                                      obj_container_name,"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_fc03e80a","line":45,"in_reply_to":"baada198_43c96c59","updated":"2014-07-09 18:50:43.000000000","message":"Since this need to match the contract of the \"native\" api-based resource, it has to support multiple signals and the only way to do that via Swift is to keep track of how many times the object changed and to do that, you need to give swift a separate container to hold the versions.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"a512ac380741bd859f085c6a8f8e0bda037b8193","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"},{"line_number":47,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id,"},{"line_number":48,"context_line":"                                      obj_container_name,"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_461165ab","line":45,"in_reply_to":"baada198_43c96c59","updated":"2014-07-09 19:17:03.000000000","message":"That\u0027s so we can keep track of how many signals were sent.  I\u0027ll add a comment to that effect.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"5c62c0118c3aaef281e541d395339d030ade6258","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"},{"line_number":47,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id,"},{"line_number":48,"context_line":"                                      obj_container_name,"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_0ffdb93b","line":45,"in_reply_to":"baada198_461165ab","updated":"2014-07-09 22:48:32.000000000","message":"It\u0027s unfortunate that Swift doesn\u0027t allow us to create a signed URL for a container into which we can put multiple objects.\n\nThe way WaitConditions are supposed to work is that each time they\u0027re called with a key unique to a particular server. The count is the count of the unique keys (multiple results with the same key are ignored).\n\nI always assumed the way AWS implement this is to create a an object for each key, although now I\u0027m not so sure. Either way, this looks like a nice hack to get around the fact that signed URL are coupled to a particular object in Swift, but at present it doesn\u0027t preserve the behaviour described above. Is that possible? Can we look at old versions of the data?","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"1c377982469059ba9687775161174a437a610df8","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"},{"line_number":47,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id,"},{"line_number":48,"context_line":"                                      obj_container_name,"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_e246be4e","line":45,"in_reply_to":"baada198_5a9a0d6f","updated":"2014-07-10 15:29:12.000000000","message":"Why does it all have to be in the URL?\n\nIn my native WaitConditionHandle resource, headers are required to contain the token, I don\u0027t see why you couldn\u0027t have attributes which provide a pre-canned curl POST command and/or contain the required POST headers and body?","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"bfe8b6d590880bae06dd2bf1d7c4d17516dc5fac","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        expires \u003d int(time.time() + self.stack.timeout_secs())"},{"line_number":43,"context_line":"        obj_container_name \u003d \u0027heat-%s\u0027 % uuidutils.uuid.uuid4()"},{"line_number":44,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":45,"context_line":"        obj_container_headers \u003d {\u0027x-versions-location\u0027: ver_container_name}"},{"line_number":46,"context_line":"        obj_name \u003d \u0027signal\u0027"},{"line_number":47,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id,"},{"line_number":48,"context_line":"                                      obj_container_name,"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_da96d3ef","line":45,"in_reply_to":"baada198_e246be4e","updated":"2014-07-11 17:02:04.000000000","message":"I added those attributes.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"a2a3919e2f70710027ef6fad2e94d88c1a0ef17e","unresolved":false,"context_lines":[{"line_number":49,"context_line":"                                      obj_name)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"        self.swift().put_container(ver_container_name)"},{"line_number":52,"context_line":"        self.swift().put_container(obj_container_name,"},{"line_number":53,"context_line":"                                   headers\u003dobj_container_headers)"},{"line_number":54,"context_line":"        self.swift().put_object(obj_container_name, obj_name, IN_PROGRESS)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_da9c5d60","line":52,"updated":"2014-07-09 23:01:00.000000000","message":"It would be nice if we could get away with e.g. only one container per stack (and each WaitConditionHandle is an object). Maybe use the stack uuid as the container name (created on demand iff it doesn\u0027t already exist) and the resource uuid as the object name.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"bfe8b6d590880bae06dd2bf1d7c4d17516dc5fac","unresolved":false,"context_lines":[{"line_number":49,"context_line":"                                      obj_name)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"        self.swift().put_container(ver_container_name)"},{"line_number":52,"context_line":"        self.swift().put_container(obj_container_name,"},{"line_number":53,"context_line":"                                   headers\u003dobj_container_headers)"},{"line_number":54,"context_line":"        self.swift().put_object(obj_container_name, obj_name, IN_PROGRESS)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_7a8787b5","line":52,"in_reply_to":"baada198_da9c5d60","updated":"2014-07-11 17:02:04.000000000","message":"Good idea!  Done.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"99267b5bd211a45405de1c65cc7831df54e69cbc","unresolved":false,"context_lines":[{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        path \u003d swift_utils.generate_temp_url(method, expires, path, key)"},{"line_number":63,"context_line":"        sw_url \u003d urlparse.urlparse(self.swift().url)"},{"line_number":64,"context_line":"        tempurl \u003d \u0027%s://%s%s\u0027 % (sw_url.scheme, sw_url.netloc, path)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"        self.resource_id_set(tempurl)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_914cb978","line":64,"updated":"2014-07-08 20:49:07.000000000","message":"Ref Zane\u0027s email to the list, I guess this needs refactoring so the URL creation part is in a SwiftSignalResponder class, similar to the engine/signal_responder.py code (e.g in a _get_signed_url function).\n\nI propose that we modify that so it\u0027s \"_get_signal_url\" instead, and probably also add a \"_get_signal_headers\" to support my API signal based implementation.\n\nI guess we\u0027ll also need a _get_signal_method so we can specify PUT/POST for the request.\n\nI\u0027ll work on rebasing my patches in a similar fashion \u0026 hopefully we can discuss and get feedback from others - hopefully it should mean we can converge on a common resource type/interface with configurable transports (just via a slightly different method as I was thinking we\u0027d map them via provider resources, which Zane is not in favour of).","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"a512ac380741bd859f085c6a8f8e0bda037b8193","unresolved":false,"context_lines":[{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        path \u003d swift_utils.generate_temp_url(method, expires, path, key)"},{"line_number":63,"context_line":"        sw_url \u003d urlparse.urlparse(self.swift().url)"},{"line_number":64,"context_line":"        tempurl \u003d \u0027%s://%s%s\u0027 % (sw_url.scheme, sw_url.netloc, path)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"        self.resource_id_set(tempurl)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_9761e5d5","line":64,"in_reply_to":"baada198_914cb978","updated":"2014-07-09 19:17:03.000000000","message":"That sounds good.  Will keep an eye out for your next set of patchsets.  Thanks.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"5c62c0118c3aaef281e541d395339d030ade6258","unresolved":false,"context_lines":[{"line_number":138,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":139,"context_line":"        all_ver_container_objects \u003d self.swift().get_container("},{"line_number":140,"context_line":"            ver_container_name)[1]"},{"line_number":141,"context_line":"        signals_received \u003d len(all_ver_container_objects)"},{"line_number":142,"context_line":"        # Create another list of version objects without the original,"},{"line_number":143,"context_line":"        # \"in progress\", object.  Each object\u0027s \u0027name\u0027 value contains"},{"line_number":144,"context_line":"        # a unix timestamp, which can be used for sorting."}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_6f18f584","line":141,"updated":"2014-07-09 22:48:32.000000000","message":"As noted above, this is insufficient to determine how many signals have been received, as we are supposed to be able to ignore multiple signals from a single server.\n\nAlso, the signal can indicate _either_ success or failure (in which case we should fail immediately rather than wait for a timeout), but here we treat them all as success.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"bfe8b6d590880bae06dd2bf1d7c4d17516dc5fac","unresolved":false,"context_lines":[{"line_number":138,"context_line":"        ver_container_name \u003d obj_container_name + \"-versions\""},{"line_number":139,"context_line":"        all_ver_container_objects \u003d self.swift().get_container("},{"line_number":140,"context_line":"            ver_container_name)[1]"},{"line_number":141,"context_line":"        signals_received \u003d len(all_ver_container_objects)"},{"line_number":142,"context_line":"        # Create another list of version objects without the original,"},{"line_number":143,"context_line":"        # \"in progress\", object.  Each object\u0027s \u0027name\u0027 value contains"},{"line_number":144,"context_line":"        # a unix timestamp, which can be used for sorting."}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_fa50f733","line":141,"in_reply_to":"baada198_6f18f584","updated":"2014-07-11 17:02:04.000000000","message":"Done","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"99267b5bd211a45405de1c65cc7831df54e69cbc","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        if time.time() \u003e timeout_time:"},{"line_number":161,"context_line":"            clean_up()"},{"line_number":162,"context_line":"            raise exception.Error(_(\u0027SwiftSignal wait condition timed out \u0027"},{"line_number":163,"context_line":"                                    \u0027while waiting for a completion signal\u0027))"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"        if signals_received \u003c count:"},{"line_number":166,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_1ffb5548","line":163,"updated":"2014-07-08 20:49:07.000000000","message":"Wondering why do the time comparison here vs doing a wait via a task runnier with a timeout like in the current WaitCondition resource?\n\nSeems like adopting something similar might allow this large check_create_complete to be a bit cleaner?","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d0aefa8cb71a3926755b2d9ffde456d9adfa7bed","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        if time.time() \u003e timeout_time:"},{"line_number":161,"context_line":"            clean_up()"},{"line_number":162,"context_line":"            raise exception.Error(_(\u0027SwiftSignal wait condition timed out \u0027"},{"line_number":163,"context_line":"                                    \u0027while waiting for a completion signal\u0027))"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"        if signals_received \u003c count:"},{"line_number":166,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_e19423ea","line":163,"in_reply_to":"baada198_1ffb5548","updated":"2014-07-09 18:48:54.000000000","message":"Don\u0027t we need to be aware of the timeout so we can clean up the containers when we\u0027re done?","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"99267b5bd211a45405de1c65cc7831df54e69cbc","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        # Save signal data to database"},{"line_number":169,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":170,"context_line":"            obj_container_name)[1][0]"},{"line_number":171,"context_line":"        metadata \u003d {}"},{"line_number":172,"context_line":"        for signal_num in xrange(count - 1):"},{"line_number":173,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_df5c7d4f","line":170,"updated":"2014-07-08 20:49:07.000000000","message":"I\u0027m wondering why we do this - would it not be better to leave the data in swift?\n\nOne of the nice things about having a swift backed signal resource seems to be that you could potentially pass relatively larger payload back as part of the signal data if needed?\n\nSo I\u0027m not sure if (given that it\u0027s already stored in swift) we really gain much by copying it to the DB then deleting it?","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"1c377982469059ba9687775161174a437a610df8","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        # Save signal data to database"},{"line_number":169,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":170,"context_line":"            obj_container_name)[1][0]"},{"line_number":171,"context_line":"        metadata \u003d {}"},{"line_number":172,"context_line":"        for signal_num in xrange(count - 1):"},{"line_number":173,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_42accaa0","line":170,"in_reply_to":"baada198_1535c6da","updated":"2014-07-10 15:29:12.000000000","message":"Well the dollar cost is a valid point (ref my ML comments on the same topic..), but I still think it\u0027s a logical oddity that we put the data in Swift, then take it back out again.  \n\nIMO that\u0027s inconsistent with all other resources, and is counterintuitive - I mean if you use a resource called SwiftSignal, as a user, where do you expect the data to end up?\n\nIf all we actually care about is the tempurl aspect of the transport, I\u0027m almost tempted to say lets allow heat to support signals via tempurl middleware.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"bfe8b6d590880bae06dd2bf1d7c4d17516dc5fac","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        # Save signal data to database"},{"line_number":169,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":170,"context_line":"            obj_container_name)[1][0]"},{"line_number":171,"context_line":"        metadata \u003d {}"},{"line_number":172,"context_line":"        for signal_num in xrange(count - 1):"},{"line_number":173,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_b4be8eac","line":170,"in_reply_to":"baada198_29e7dd41","updated":"2014-07-11 17:02:04.000000000","message":"Good point Zane.  This seems to be a good reason to leave the objects in Swift.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"b37ad32e540b1cbc6f5314d3b368b3b60984d97b","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        # Save signal data to database"},{"line_number":169,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":170,"context_line":"            obj_container_name)[1][0]"},{"line_number":171,"context_line":"        metadata \u003d {}"},{"line_number":172,"context_line":"        for signal_num in xrange(count - 1):"},{"line_number":173,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_1535c6da","line":170,"in_reply_to":"baada198_29e7dd41","updated":"2014-07-09 23:15:50.000000000","message":"The first point is a tricky one (having multiple conditions use the same handle), and may not work for the native one either (I haven\u0027t poked around enough to know for sure, though).\n\nAs for the second point, isn\u0027t that why we save the metadata? Can\u0027t the user always see that? In the end, I think its better to get rid of the containers once we\u0027re done with them rather than keep them around. Alternatively, if these containers were owned by Heat, that may be less of an issue, but would still prevent the user from looking at the data in Swift.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"d0aefa8cb71a3926755b2d9ffde456d9adfa7bed","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        # Save signal data to database"},{"line_number":169,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":170,"context_line":"            obj_container_name)[1][0]"},{"line_number":171,"context_line":"        metadata \u003d {}"},{"line_number":172,"context_line":"        for signal_num in xrange(count - 1):"},{"line_number":173,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_e1c6e315","line":170,"in_reply_to":"baada198_df5c7d4f","updated":"2014-07-09 18:48:54.000000000","message":"There may be a real dollar cost to the user in keeping this data in swift permanently. IMO, we should clean the data out when we\u0027re done. Its just a transport and means to an end, not intended as an actual artifact of the stack.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"a512ac380741bd859f085c6a8f8e0bda037b8193","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        # Save signal data to database"},{"line_number":169,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":170,"context_line":"            obj_container_name)[1][0]"},{"line_number":171,"context_line":"        metadata \u003d {}"},{"line_number":172,"context_line":"        for signal_num in xrange(count - 1):"},{"line_number":173,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_17ca35a1","line":170,"in_reply_to":"baada198_e1c6e315","updated":"2014-07-09 19:17:03.000000000","message":"+1","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"5c62c0118c3aaef281e541d395339d030ade6258","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        # Save signal data to database"},{"line_number":169,"context_line":"        obj_container_object \u003d self.swift().get_container("},{"line_number":170,"context_line":"            obj_container_name)[1][0]"},{"line_number":171,"context_line":"        metadata \u003d {}"},{"line_number":172,"context_line":"        for signal_num in xrange(count - 1):"},{"line_number":173,"context_line":"            key \u003d \"signal_%s\" % (signal_num + 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_29e7dd41","line":170,"in_reply_to":"baada198_e1c6e315","updated":"2014-07-09 22:48:32.000000000","message":"That is a good argument; the problem I see here is that in theory you can have multiple WaitConditions (typically with different counts) referencing the same handle.  For example, you have a cluster and one thing is waiting on a quorum to come up but something else is waiting on the whole thing being ready. By going outside the Heat execution model and effectively deleting another resource, this breaks that use case.\n\nThere are also good reasons the user might want to look at the values after the stack is finished, e.g. for debugging.","commit_id":"dc39688ab2016af803bb1cebd5bf0f6a348a46c3"},{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from heat.engine.resources import swift_utils"},{"line_number":28,"context_line":"from heat.engine.resources import wait_condition"},{"line_number":29,"context_line":"from heat.engine import scheduler"},{"line_number":30,"context_line":"from heat.openstack.common.gettextutils import _"},{"line_number":31,"context_line":"from heat.openstack.common import log as logging"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_84720ee1","line":30,"updated":"2014-07-26 17:57:47.000000000","message":"Can you please use oslo.i18n lib\n\nThere is an effort to move to oslo.i18n. Here is the reference https://review.openstack.org/#/c/109510/","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from heat.engine.resources import swift_utils"},{"line_number":28,"context_line":"from heat.engine.resources import wait_condition"},{"line_number":29,"context_line":"from heat.engine import scheduler"},{"line_number":30,"context_line":"from heat.openstack.common.gettextutils import _"},{"line_number":31,"context_line":"from heat.openstack.common import log as logging"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_f690b997","line":30,"in_reply_to":"baada198_84720ee1","updated":"2014-07-28 17:54:49.000000000","message":"That change is dependent on a patch that hasn\u0027t merged yet https://review.openstack.org/#/c/108924","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"IN_PROGRESS \u003d \u0027in progress\u0027"},{"line_number":36,"context_line":"SWIFTSIGNAL_OBJ_NAME \u003d \u0027swiftsignalhandle_obj_name\u0027"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"class SwiftSignalFailure(wait_condition.WaitConditionFailure):"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_a47d52b4","line":36,"updated":"2014-07-26 17:57:47.000000000","message":"should this be defined as SWIFTSIGNALHANDLE_OBJ_NAME","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"IN_PROGRESS \u003d \u0027in progress\u0027"},{"line_number":36,"context_line":"SWIFTSIGNAL_OBJ_NAME \u003d \u0027swiftsignalhandle_obj_name\u0027"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"class SwiftSignalFailure(wait_condition.WaitConditionFailure):"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_76eca929","line":36,"in_reply_to":"baada198_a47d52b4","updated":"2014-07-28 17:54:49.000000000","message":"Actually, that is no longer being used.  I\u0027ll remove it.","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    )"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _get_signal_url(self):"},{"line_number":93,"context_line":"        # Turn on object versioning so we can use a single TempURL for"},{"line_number":94,"context_line":"        # multiple signals"},{"line_number":95,"context_line":"        headers \u003d {\u0027x-versions-location\u0027: self.stack.id}"},{"line_number":96,"context_line":"        obj_name \u003d \"%s-%s\" % (self.stack.name, self.name)"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_44447672","line":93,"updated":"2014-07-26 17:57:47.000000000","message":"Can you use the doc string format","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    )"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _get_signal_url(self):"},{"line_number":93,"context_line":"        # Turn on object versioning so we can use a single TempURL for"},{"line_number":94,"context_line":"        # multiple signals"},{"line_number":95,"context_line":"        headers \u003d {\u0027x-versions-location\u0027: self.stack.id}"},{"line_number":96,"context_line":"        obj_name \u003d \"%s-%s\" % (self.stack.name, self.name)"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_96d93d58","line":93,"in_reply_to":"baada198_44447672","updated":"2014-07-28 17:54:49.000000000","message":"Done","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":272,"context_line":"            self._obj_name \u003d self.url.path.split(\u0027/\u0027)[4]"},{"line_number":273,"context_line":"        return self._obj_name"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def _validate_handle_url(self):"},{"line_number":276,"context_line":"        parts \u003d self.url.path.split(\u0027/\u0027)"},{"line_number":277,"context_line":"        if (not swift_utils.valid_temp_url_path(self.url.path) or"},{"line_number":278,"context_line":"                not parts[2].endswith(self.context.tenant_id) or"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_17862b65","line":275,"updated":"2014-07-26 17:57:47.000000000","message":"you may want to just keep this method inside handle_create() method.","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":272,"context_line":"            self._obj_name \u003d self.url.path.split(\u0027/\u0027)[4]"},{"line_number":273,"context_line":"        return self._obj_name"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def _validate_handle_url(self):"},{"line_number":276,"context_line":"        parts \u003d self.url.path.split(\u0027/\u0027)"},{"line_number":277,"context_line":"        if (not swift_utils.valid_temp_url_path(self.url.path) or"},{"line_number":278,"context_line":"                not parts[2].endswith(self.context.tenant_id) or"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_96313d5b","line":275,"in_reply_to":"baada198_17862b65","updated":"2014-07-28 17:54:49.000000000","message":"I was trying to keep the method names consistent with those in wait_condition.py where possible to improve readability.","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":273,"context_line":"        return self._obj_name"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def _validate_handle_url(self):"},{"line_number":276,"context_line":"        parts \u003d self.url.path.split(\u0027/\u0027)"},{"line_number":277,"context_line":"        if (not swift_utils.valid_temp_url_path(self.url.path) or"},{"line_number":278,"context_line":"                not parts[2].endswith(self.context.tenant_id) or"},{"line_number":279,"context_line":"                not parts[3] \u003d\u003d self.stack.id or"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_577c2371","line":276,"updated":"2014-07-26 17:57:47.000000000","message":"Adding comment on the url format helps in understanding the url validation logic","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":273,"context_line":"        return self._obj_name"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def _validate_handle_url(self):"},{"line_number":276,"context_line":"        parts \u003d self.url.path.split(\u0027/\u0027)"},{"line_number":277,"context_line":"        if (not swift_utils.valid_temp_url_path(self.url.path) or"},{"line_number":278,"context_line":"                not parts[2].endswith(self.context.tenant_id) or"},{"line_number":279,"context_line":"                not parts[3] \u003d\u003d self.stack.id or"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_29dc96e0","line":276,"in_reply_to":"baada198_577c2371","updated":"2014-07-28 17:54:49.000000000","message":"I added an exception for each part.  Hopefully that will make the code a little clearer.","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":284,"context_line":"    def handle_create(self):"},{"line_number":285,"context_line":"        self._validate_handle_url()"},{"line_number":286,"context_line":"        handle \u003d self._get_handle_resource()"},{"line_number":287,"context_line":"        runner \u003d scheduler.TaskRunner(self._wait, handle)"},{"line_number":288,"context_line":"        runner.start(timeout\u003dfloat(self.properties.get(self.TIMEOUT)))"},{"line_number":289,"context_line":"        return runner"},{"line_number":290,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_f7e9b71a","line":287,"updated":"2014-07-26 17:57:47.000000000","message":"#286 and #287 you can collapse into one as \"handle\" is not used further in the method","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":284,"context_line":"    def handle_create(self):"},{"line_number":285,"context_line":"        self._validate_handle_url()"},{"line_number":286,"context_line":"        handle \u003d self._get_handle_resource()"},{"line_number":287,"context_line":"        runner \u003d scheduler.TaskRunner(self._wait, handle)"},{"line_number":288,"context_line":"        runner.start(timeout\u003dfloat(self.properties.get(self.TIMEOUT)))"},{"line_number":289,"context_line":"        return runner"},{"line_number":290,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_3617919e","line":287,"in_reply_to":"baada198_f7e9b71a","updated":"2014-07-28 17:54:49.000000000","message":"Done","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_handle_resource(self):"},{"line_number":318,"context_line":"        resource_name \u003d self.obj_name.split(\u0027-\u0027)[1]"},{"line_number":319,"context_line":"        return self.stack[resource_name]"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def check_create_complete(self, runner):"},{"line_number":322,"context_line":"        return runner.step()"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_b7e3bf32","line":319,"updated":"2014-07-26 17:57:47.000000000","message":"why not just self.stack(self.obj_name.split(\u0027-\u0027)[1])","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_handle_resource(self):"},{"line_number":318,"context_line":"        resource_name \u003d self.obj_name.split(\u0027-\u0027)[1]"},{"line_number":319,"context_line":"        return self.stack[resource_name]"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def check_create_complete(self, runner):"},{"line_number":322,"context_line":"        return runner.step()"}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_331163f8","line":319,"in_reply_to":"baada198_b7e3bf32","updated":"2014-07-28 17:54:49.000000000","message":"I think that would be more difficult to read.","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"b7baad3aab730ec1300a772ef68fb4e39f1828be","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        \u0027data\u0027, \u0027reason\u0027, \u0027status\u0027, \u0027id\u0027"},{"line_number":90,"context_line":"    )"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _get_signal_url(self):"},{"line_number":93,"context_line":"        \u0027\u0027\u0027"},{"line_number":94,"context_line":"        Turn on object versioning so we can use a single TempURL for"},{"line_number":95,"context_line":"        multiple signals"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_7724b8c2","line":92,"updated":"2014-08-11 23:01:16.000000000","message":"This method is of general use so it would be good to have something in SwiftClientPlugin like:\n\n    def create_temp_url(self, obj_name, container_name, timeout_secs\u003dNone, enable_versions\u003dTrue):\n\nThis can be implemented in the previous change.\n\nWhich is called from here with:\n\n    def _get_signal_url(self):\n        obj_name \u003d \"%s-%s\" % (self.stack.name, self.name)\n        return self.client_plugin().create_temp_url(\n            obj_name,\n            self.stack.id)","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"168712a6d1ba30d5e62ae6e807687dd493d2404a","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        \u0027data\u0027, \u0027reason\u0027, \u0027status\u0027, \u0027id\u0027"},{"line_number":90,"context_line":"    )"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _get_signal_url(self):"},{"line_number":93,"context_line":"        \u0027\u0027\u0027"},{"line_number":94,"context_line":"        Turn on object versioning so we can use a single TempURL for"},{"line_number":95,"context_line":"        multiple signals"}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_36a698c2","line":92,"in_reply_to":"baada198_7724b8c2","updated":"2014-08-13 21:35:13.000000000","message":"Done","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"b7baad3aab730ec1300a772ef68fb4e39f1828be","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        method \u003d \u0027PUT\u0027"},{"line_number":109,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id, self.stack.id,"},{"line_number":110,"context_line":"                                      obj_name)"},{"line_number":111,"context_line":"        secs \u003d self.stack.timeout_secs()"},{"line_number":112,"context_line":"        tempurl \u003d swiftclient_utils.generate_temp_url(path, secs, key, method)"},{"line_number":113,"context_line":"        sw_url \u003d urlparse.urlparse(self.swift().url)"},{"line_number":114,"context_line":"        signal_url \u003d \u0027%s://%s%s\u0027 % (sw_url.scheme, sw_url.netloc, tempurl)"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_8c14e2ea","line":111,"updated":"2014-08-11 23:01:16.000000000","message":"Setting the timeout to the stack timeout may not be practical, see below.","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"168712a6d1ba30d5e62ae6e807687dd493d2404a","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        method \u003d \u0027PUT\u0027"},{"line_number":109,"context_line":"        path \u003d \u0027/v1/AUTH_%s/%s/%s\u0027 % (self.context.tenant_id, self.stack.id,"},{"line_number":110,"context_line":"                                      obj_name)"},{"line_number":111,"context_line":"        secs \u003d self.stack.timeout_secs()"},{"line_number":112,"context_line":"        tempurl \u003d swiftclient_utils.generate_temp_url(path, secs, key, method)"},{"line_number":113,"context_line":"        sw_url \u003d urlparse.urlparse(self.swift().url)"},{"line_number":114,"context_line":"        signal_url \u003d \u0027%s://%s%s\u0027 % (sw_url.scheme, sw_url.netloc, tempurl)"}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_16a19ca9","line":111,"in_reply_to":"baada198_8c14e2ea","updated":"2014-08-13 21:35:13.000000000","message":"Done","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"b7baad3aab730ec1300a772ef68fb4e39f1828be","unresolved":false,"context_lines":[{"line_number":200,"context_line":"        return data"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    def update(self, after, before\u003dNone, prev_resource\u003dNone):"},{"line_number":203,"context_line":"        raise resource.UpdateReplace(self.name)"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"    def _resolve_attribute(self, key):"},{"line_number":206,"context_line":"        if self.resource_id:"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_89c21452","line":203,"updated":"2014-08-11 23:01:16.000000000","message":"If the handle changes on every update then we can\u0027t use it in Server user_data without triggering a replace of the server on every update; that would be bad.\n\nIt looks like the handle URL will need to be stable for the lifetime of the stack, which means that the temp URL timeout needs to be $maxnum instead of stack.timeout_secs","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"168712a6d1ba30d5e62ae6e807687dd493d2404a","unresolved":false,"context_lines":[{"line_number":200,"context_line":"        return data"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    def update(self, after, before\u003dNone, prev_resource\u003dNone):"},{"line_number":203,"context_line":"        raise resource.UpdateReplace(self.name)"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"    def _resolve_attribute(self, key):"},{"line_number":206,"context_line":"        if self.resource_id:"}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_f6c42061","line":203,"in_reply_to":"baada198_89c21452","updated":"2014-08-13 21:35:13.000000000","message":"Done","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"b7baad3aab730ec1300a772ef68fb4e39f1828be","unresolved":false,"context_lines":[{"line_number":320,"context_line":"    def _get_handle_resource(self):"},{"line_number":321,"context_line":"        resource_name \u003d self.obj_name.split(\u0027-\u0027)[1]"},{"line_number":322,"context_line":"        if resource_name in self.stack.resources:"},{"line_number":323,"context_line":"            return self.stack.resources[resource_name]"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"    def check_create_complete(self, runner):"},{"line_number":326,"context_line":"        return runner.step()"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_c9e7ac44","line":323,"updated":"2014-08-11 23:01:16.000000000","message":"We should move heaven and earth to avoid ever accessing self.stack.resources from a resource, and we should only ever be doing this as a workaround to implementing the AWS resource model. Avoiding accessing other resources will make the convergence implementation much easier.\n\nIt looks like the thing to do here is move the methods get_signals, get_status*, get_data out of the handle class and into this class","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"d21ba6f9d7e93a4a58ba1763c91df5f69e52124d","unresolved":false,"context_lines":[{"line_number":320,"context_line":"    def _get_handle_resource(self):"},{"line_number":321,"context_line":"        resource_name \u003d self.obj_name.split(\u0027-\u0027)[1]"},{"line_number":322,"context_line":"        if resource_name in self.stack.resources:"},{"line_number":323,"context_line":"            return self.stack.resources[resource_name]"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"    def check_create_complete(self, runner):"},{"line_number":326,"context_line":"        return runner.step()"}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_ddef0daf","line":323,"in_reply_to":"7ac7a964_560cf494","updated":"2014-08-14 22:29:35.000000000","message":"The handle is literally just a URL, and all interaction with it should be via the swift API.\n\nPart of the motivation for OS::Heat::SwiftSignalHandle was to have a handle which is not implemented internally in heat so that we don\u0027t need to do the resource traversal to interact with it, so I\u0027m quite keen for this to happen in the initial implementation.\n\nThankfully it looks basically as easy as moving the methods here and deleting _get_handle_resource","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"dc77a29445aafff0cbb111f5c083919bba63a80d","unresolved":false,"context_lines":[{"line_number":320,"context_line":"    def _get_handle_resource(self):"},{"line_number":321,"context_line":"        resource_name \u003d self.obj_name.split(\u0027-\u0027)[1]"},{"line_number":322,"context_line":"        if resource_name in self.stack.resources:"},{"line_number":323,"context_line":"            return self.stack.resources[resource_name]"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"    def check_create_complete(self, runner):"},{"line_number":326,"context_line":"        return runner.step()"}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_d246fe20","line":323,"in_reply_to":"7ac7a964_ddef0daf","updated":"2014-08-15 14:48:24.000000000","message":"Totally agree with Steve here. This is exactly the kind of hack that SwiftSignal is supposed to save us from - existing code isn\u0027t a barometer of good design here, it\u0027s an example of what we want to get away from.","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"168712a6d1ba30d5e62ae6e807687dd493d2404a","unresolved":false,"context_lines":[{"line_number":320,"context_line":"    def _get_handle_resource(self):"},{"line_number":321,"context_line":"        resource_name \u003d self.obj_name.split(\u0027-\u0027)[1]"},{"line_number":322,"context_line":"        if resource_name in self.stack.resources:"},{"line_number":323,"context_line":"            return self.stack.resources[resource_name]"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"    def check_create_complete(self, runner):"},{"line_number":326,"context_line":"        return runner.step()"}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_560cf494","line":323,"in_reply_to":"baada198_c9e7ac44","updated":"2014-08-13 21:35:13.000000000","message":"Can\u0027t we solve this as a follow-up?  It\u0027s a problem in other resources, including the recently-merged OS::Heat::WaitCondition resource (although it\u0027s being done indirectly there).\n\nI don\u0027t think those methods should be moved.  They belong in the handle class.  We would have the same problem if they were moved.  The swiftsignal resource would still have to obtain the swiftsignalhandle resource object somehow.","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"f1183d65dfd4c7f8b7cdced7baa64ba5bb91e1bf","unresolved":false,"context_lines":[{"line_number":320,"context_line":"    def _get_handle_resource(self):"},{"line_number":321,"context_line":"        resource_name \u003d self.obj_name.split(\u0027-\u0027)[1]"},{"line_number":322,"context_line":"        if resource_name in self.stack.resources:"},{"line_number":323,"context_line":"            return self.stack.resources[resource_name]"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"    def check_create_complete(self, runner):"},{"line_number":326,"context_line":"        return runner.step()"}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_f84bd056","line":323,"in_reply_to":"baada198_c9e7ac44","updated":"2014-08-15 20:17:29.000000000","message":"Done","commit_id":"11ef76ff5451d2acf82976e89ca1f75c4b1b1dca"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"cc3dd5ff897cd1e72d2c59e3a8f806419b0f5af1","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            properties.Schema.NUMBER,"},{"line_number":119,"context_line":"            description\u003d_(\u0027The maximum number of seconds to wait for the \u0027"},{"line_number":120,"context_line":"                          \u0027resource to signal completion.  Once the timeout \u0027"},{"line_number":121,"context_line":"                          \u0027is reached, creation of the wait condition \u0027"},{"line_number":122,"context_line":"                          \u0027resource will fail.\u0027),"},{"line_number":123,"context_line":"            required\u003dTrue,"},{"line_number":124,"context_line":"            constraints\u003d["}],"source_content_type":"text/x-python","patch_set":20,"id":"7ac7a964_a5e3ec03","line":121,"updated":"2014-08-15 21:21:57.000000000","message":"\"creation of the signal resource\"","commit_id":"8cbe9bcdd15a300f09eeb543a79a8a3b923b83c7"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"4b466deb22b43a804d61215bf2cb0cad59963f98","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            properties.Schema.NUMBER,"},{"line_number":119,"context_line":"            description\u003d_(\u0027The maximum number of seconds to wait for the \u0027"},{"line_number":120,"context_line":"                          \u0027resource to signal completion.  Once the timeout \u0027"},{"line_number":121,"context_line":"                          \u0027is reached, creation of the wait condition \u0027"},{"line_number":122,"context_line":"                          \u0027resource will fail.\u0027),"},{"line_number":123,"context_line":"            required\u003dTrue,"},{"line_number":124,"context_line":"            constraints\u003d["}],"source_content_type":"text/x-python","patch_set":20,"id":"1abeadc6_314afc80","line":121,"in_reply_to":"7ac7a964_a5e3ec03","updated":"2014-08-18 16:06:56.000000000","message":"Done","commit_id":"8cbe9bcdd15a300f09eeb543a79a8a3b923b83c7"},{"author":{"_account_id":4328,"name":"Steven Hardy","email":"steven.hardy@suse.com","username":"shardy"},"change_message_id":"3c5fb2084c0b3ece93acb81f42b76276fb5fce38","unresolved":false,"context_lines":[{"line_number":85,"context_line":"    }"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def handle_create(self):"},{"line_number":88,"context_line":"        obj_name \u003d \"%s-%s\" % (self.stack.name, self.name)"},{"line_number":89,"context_line":"        sc \u003d self.client_plugin(\u0027swift\u0027)"},{"line_number":90,"context_line":"        url \u003d sc.get_signal_url(self.stack.id, obj_name)"},{"line_number":91,"context_line":"        self.data_set(\u0027endpoint\u0027, url)"}],"source_content_type":"text/x-python","patch_set":21,"id":"1abeadc6_cfee7c22","line":88,"updated":"2014-08-18 18:48:58.000000000","message":"Just wondering, is there a reason that you\u0027re doing this, instead of using self.physical_resource_name, which is basically the same other than the additional random suffix?","commit_id":"8ef37a6bee43b847da345940fa59e21d20995701"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"fd8bf5ae7937018dca6e8984e997f27c7516caa6","unresolved":false,"context_lines":[{"line_number":85,"context_line":"    }"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def handle_create(self):"},{"line_number":88,"context_line":"        obj_name \u003d \"%s-%s\" % (self.stack.name, self.name)"},{"line_number":89,"context_line":"        sc \u003d self.client_plugin(\u0027swift\u0027)"},{"line_number":90,"context_line":"        url \u003d sc.get_signal_url(self.stack.id, obj_name)"},{"line_number":91,"context_line":"        self.data_set(\u0027endpoint\u0027, url)"}],"source_content_type":"text/x-python","patch_set":21,"id":"1abeadc6_a9869bb7","line":88,"in_reply_to":"1abeadc6_cfee7c22","updated":"2014-08-18 20:21:53.000000000","message":"I thought there was a reason, but I can\u0027t remember it.  I put it back.","commit_id":"8ef37a6bee43b847da345940fa59e21d20995701"}],"heat/tests/test_swiftsignal.py":[{"author":{"_account_id":6498,"name":"Divakar Padiyar Nandavar","email":"divakar.padiyar-nandavar@hpe.com","username":"divakar-padiyar-nandavar"},"change_message_id":"bddd705aba68a8854144ec0be09ae8090a67b2b5","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from heat.engine import resource"},{"line_number":28,"context_line":"from heat.engine import rsrc_defn"},{"line_number":29,"context_line":"from heat.engine import scheduler"},{"line_number":30,"context_line":"from heat.engine import stack as parser"},{"line_number":31,"context_line":"from heat.tests.common import HeatTestCase"},{"line_number":32,"context_line":"from heat.tests import utils"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_173b8b9c","line":30,"updated":"2014-07-26 17:57:47.000000000","message":"can we avoid import stack as parser?","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"9893309bf27eb041ad60482cdaaec624394db104","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from heat.engine import resource"},{"line_number":28,"context_line":"from heat.engine import rsrc_defn"},{"line_number":29,"context_line":"from heat.engine import scheduler"},{"line_number":30,"context_line":"from heat.engine import stack as parser"},{"line_number":31,"context_line":"from heat.tests.common import HeatTestCase"},{"line_number":32,"context_line":"from heat.tests import utils"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"baada198_386e9a2c","line":30,"in_reply_to":"baada198_173b8b9c","updated":"2014-07-28 17:54:49.000000000","message":"Done","commit_id":"657d7d44f63e129db71e920cf6f2f80f409f03cc"}]}
