)]}'
{"ironic/api/controllers/v1/node.py":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    def put(self, node_id, target):"},{"line_number":80,"context_line":"        \"\"\"Set the power state of the machine.\"\"\""},{"line_number":81,"context_line":"        node \u003d objects.Node.get_by_uuid(pecan.request.context, node_id)"},{"line_number":82,"context_line":"        if node.target_power_state is not None:"},{"line_number":83,"context_line":"            raise wsme.exc.ClientSideError(_(\"Power operation for node %s is \""},{"line_number":84,"context_line":"                                             \"already in progress.\") %"},{"line_number":85,"context_line":"                                              node[\u0027uuid\u0027], status_code\u003d409)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2Fcr4%3D","side":"PARENT","line":82,"updated":"2013-11-06 01:57:38.000000000","message":"Small race condition here. Let\u0027s move this check into the manager, inside the task_manager context","commit_id":"f354d93d84b3ff933a074b2209c43732f257c90c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"560f29348330e71d67df3004c4de59c381adec92","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    def put(self, node_id, target):"},{"line_number":80,"context_line":"        \"\"\"Set the power state of the machine.\"\"\""},{"line_number":81,"context_line":"        node \u003d objects.Node.get_by_uuid(pecan.request.context, node_id)"},{"line_number":82,"context_line":"        if node.target_power_state is not None:"},{"line_number":83,"context_line":"            raise wsme.exc.ClientSideError(_(\"Power operation for node %s is \""},{"line_number":84,"context_line":"                                             \"already in progress.\") %"},{"line_number":85,"context_line":"                                              node[\u0027uuid\u0027], status_code\u003d409)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FOFo%3D","side":"PARENT","line":82,"in_reply_to":"AAAATn%2F%2Fbrk%3D","updated":"2013-11-12 17:52:16.000000000","message":"Yes, I agree with Yuriy; this check should remain here.","commit_id":"f354d93d84b3ff933a074b2209c43732f257c90c"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"e2e8115bcb28bef789ba6a2b23b9c6ddf9d12c51","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    def put(self, node_id, target):"},{"line_number":80,"context_line":"        \"\"\"Set the power state of the machine.\"\"\""},{"line_number":81,"context_line":"        node \u003d objects.Node.get_by_uuid(pecan.request.context, node_id)"},{"line_number":82,"context_line":"        if node.target_power_state is not None:"},{"line_number":83,"context_line":"            raise wsme.exc.ClientSideError(_(\"Power operation for node %s is \""},{"line_number":84,"context_line":"                                             \"already in progress.\") %"},{"line_number":85,"context_line":"                                              node[\u0027uuid\u0027], status_code\u003d409)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2Fbrk%3D","side":"PARENT","line":82,"in_reply_to":"AAAATn%2F%2Fcr4%3D","updated":"2013-11-06 09:26:19.000000000","message":"Devananda, IMO we should move set the target_power_state into manager but not this check. We always will get NodeLocked exception in this case for concurrent operations.","commit_id":"f354d93d84b3ff933a074b2209c43732f257c90c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4acbda34201cad2e314c9864257fb0c24f3a1293","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        #TODO(lucasagomes): Test if target is a valid state and if it\u0027s able"},{"line_number":87,"context_line":"        # to transition to the target state from the current one"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        node[\u0027target_power_state\u0027] \u003d target"},{"line_number":90,"context_line":"        updated_node \u003d pecan.request.rpcapi.update_node(pecan.request.context,"},{"line_number":91,"context_line":"                                                        node)"},{"line_number":92,"context_line":"        pecan.request.rpcapi.change_node_power_state(pecan.request.context,"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FiHI%3D","side":"PARENT","line":89,"updated":"2013-11-01 21:23:53.000000000","message":"I\u0027m still not familiar with the code. Do we need to set the target_power_state here AND in conductor/manager.py?","commit_id":"f354d93d84b3ff933a074b2209c43732f257c90c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"560f29348330e71d67df3004c4de59c381adec92","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        #TODO(lucasagomes): Test if target is a valid state and if it\u0027s able"},{"line_number":87,"context_line":"        # to transition to the target state from the current one"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        node[\u0027target_power_state\u0027] \u003d target"},{"line_number":90,"context_line":"        updated_node \u003d pecan.request.rpcapi.update_node(pecan.request.context,"},{"line_number":91,"context_line":"                                                        node)"},{"line_number":92,"context_line":"        pecan.request.rpcapi.change_node_power_state(pecan.request.context,"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FOFg%3D","side":"PARENT","line":89,"in_reply_to":"AAAATn%2F%2FcsI%3D","updated":"2013-11-12 17:52:16.000000000","message":"Yuppers.","commit_id":"f354d93d84b3ff933a074b2209c43732f257c90c"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        #TODO(lucasagomes): Test if target is a valid state and if it\u0027s able"},{"line_number":87,"context_line":"        # to transition to the target state from the current one"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        node[\u0027target_power_state\u0027] \u003d target"},{"line_number":90,"context_line":"        updated_node \u003d pecan.request.rpcapi.update_node(pecan.request.context,"},{"line_number":91,"context_line":"                                                        node)"},{"line_number":92,"context_line":"        pecan.request.rpcapi.change_node_power_state(pecan.request.context,"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FcsI%3D","side":"PARENT","line":89,"in_reply_to":"AAAATn%2F%2FiHI%3D","updated":"2013-11-06 01:57:38.000000000","message":"No. I think this can cause a race condition if\u003e1 request comes in, and both update node outside change-node-power-state method.","commit_id":"f354d93d84b3ff933a074b2209c43732f257c90c"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":230,"context_line":"    @classmethod"},{"line_number":231,"context_line":"    def convert_with_links(cls, rpc_node, expand\u003dTrue):"},{"line_number":232,"context_line":"        minimum_fields \u003d [\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027,"},{"line_number":233,"context_line":"                          \u0027last_error\u0027,  # RLOO Should this be here?"},{"line_number":234,"context_line":"                          \u0027provision_state\u0027, \u0027target_provision_state\u0027,"},{"line_number":235,"context_line":"                          \u0027instance_uuid\u0027]"},{"line_number":236,"context_line":"        fields \u003d minimum_fields if not expand else None"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FctM%3D","line":233,"updated":"2013-11-06 01:57:38.000000000","message":"Yes, but remove the comment :-)","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"}],"ironic/conductor/manager.py":[{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"4f23209cda963a1c96b538725a1825281e8572e6","unresolved":false,"context_lines":[{"line_number":187,"context_line":"            # take power action"},{"line_number":188,"context_line":"            try:"},{"line_number":189,"context_line":"                task.driver.power.set_power_state(task, node_obj, new_state)"},{"line_number":190,"context_line":"            except exception.IronicException, e:"},{"line_number":191,"context_line":"                node_obj[\u0027last_error\u0027] \u003d str(e)"},{"line_number":192,"context_line":"                node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":193,"context_line":"                node_obj.save(context)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FqsI%3D","line":190,"updated":"2013-10-30 16:51:05.000000000","message":"This syntax deprecated, use\n\nexcept exception.IronicException as e:","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1ae95471fbbeabf91f826ff4001592782e3f8b75","unresolved":false,"context_lines":[{"line_number":187,"context_line":"            # take power action"},{"line_number":188,"context_line":"            try:"},{"line_number":189,"context_line":"                task.driver.power.set_power_state(task, node_obj, new_state)"},{"line_number":190,"context_line":"            except exception.IronicException, e:"},{"line_number":191,"context_line":"                node_obj[\u0027last_error\u0027] \u003d str(e)"},{"line_number":192,"context_line":"                node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":193,"context_line":"                node_obj.save(context)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2Fp7M%3D","line":190,"in_reply_to":"AAAATn%2F%2FqsI%3D","updated":"2013-10-30 19:40:45.000000000","message":"thx!","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"434300221b2196e8ac751f77b79e97661ce9f0ae","unresolved":false,"context_lines":[{"line_number":191,"context_line":"                node_obj[\u0027last_error\u0027] \u003d str(e)"},{"line_number":192,"context_line":"                node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":193,"context_line":"                node_obj.save(context)"},{"line_number":194,"context_line":"                raise"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"            # update the node power states"},{"line_number":197,"context_line":"            node_obj[\u0027power_state\u0027] \u003d new_state"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2Fqt8%3D","line":194,"updated":"2013-10-30 16:46:16.000000000","message":"IMO excutils.save_and_reraise_exception() needed","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1ae95471fbbeabf91f826ff4001592782e3f8b75","unresolved":false,"context_lines":[{"line_number":191,"context_line":"                node_obj[\u0027last_error\u0027] \u003d str(e)"},{"line_number":192,"context_line":"                node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":193,"context_line":"                node_obj.save(context)"},{"line_number":194,"context_line":"                raise"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"            # update the node power states"},{"line_number":197,"context_line":"            node_obj[\u0027power_state\u0027] \u003d new_state"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2Fp7Y%3D","line":194,"in_reply_to":"AAAATn%2F%2Fqt8%3D","updated":"2013-10-30 19:40:45.000000000","message":"Yes, thanks for noticing.","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":167,"context_line":"                    % {\u0027node\u0027: node_id, \u0027state\u0027: new_state})"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dFalse) as task:"},{"line_number":170,"context_line":"            # an exception will be raised if validate or get_power_state fails."},{"line_number":171,"context_line":"            try:"},{"line_number":172,"context_line":"                task.driver.power.validate(node_obj)"},{"line_number":173,"context_line":"                curr_state \u003d task.driver.power.get_power_state(task, node_obj)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2Fcqs%3D","line":170,"updated":"2013-11-06 01:57:38.000000000","message":"Let\u0027s check that target state is null here.","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"560f29348330e71d67df3004c4de59c381adec92","unresolved":false,"context_lines":[{"line_number":167,"context_line":"                    % {\u0027node\u0027: node_id, \u0027state\u0027: new_state})"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dFalse) as task:"},{"line_number":170,"context_line":"            # an exception will be raised if validate or get_power_state fails."},{"line_number":171,"context_line":"            try:"},{"line_number":172,"context_line":"                task.driver.power.validate(node_obj)"},{"line_number":173,"context_line":"                curr_state \u003d task.driver.power.get_power_state(task, node_obj)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FOE8%3D","line":170,"in_reply_to":"AAAATn%2F%2Fcqs%3D","updated":"2013-11-12 17:52:16.000000000","message":"I\u0027ve added in the check, but I\u0027m not sure how the target state would become non None at this point.","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":174,"context_line":"            except exception.IronicException as e:"},{"line_number":175,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":176,"context_line":"                    # target_power_state was set to new_state in"},{"line_number":177,"context_line":"                    # api/controllers/v1/node.py so we need to clear it"},{"line_number":178,"context_line":"                    node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":179,"context_line":"                    s \u003d \"Unable to change power state. \" + str(e)"},{"line_number":180,"context_line":"                    node_obj[\u0027last_error\u0027] \u003d s"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2Fcs8%3D","line":177,"updated":"2013-11-06 01:57:38.000000000","message":"Let\u0027s remove this clear.","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"560f29348330e71d67df3004c4de59c381adec92","unresolved":false,"context_lines":[{"line_number":174,"context_line":"            except exception.IronicException as e:"},{"line_number":175,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":176,"context_line":"                    # target_power_state was set to new_state in"},{"line_number":177,"context_line":"                    # api/controllers/v1/node.py so we need to clear it"},{"line_number":178,"context_line":"                    node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":179,"context_line":"                    s \u003d \"Unable to change power state. \" + str(e)"},{"line_number":180,"context_line":"                    node_obj[\u0027last_error\u0027] \u003d s"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FOEw%3D","line":177,"in_reply_to":"AAAATn%2F%2Fcs8%3D","updated":"2013-11-12 17:52:16.000000000","message":"Done.","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                    # target_power_state was set to new_state in"},{"line_number":177,"context_line":"                    # api/controllers/v1/node.py so we need to clear it"},{"line_number":178,"context_line":"                    node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":179,"context_line":"                    s \u003d \"Unable to change power state. \" + str(e)"},{"line_number":180,"context_line":"                    node_obj[\u0027last_error\u0027] \u003d s"},{"line_number":181,"context_line":"                    node_obj.save(context)"},{"line_number":182,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2Fcpg%3D","line":179,"updated":"2013-11-06 01:57:38.000000000","message":"Error should be i18n\u0027d, and we don\u0027t need str().\n\n  node_obj[\u0027last_error\u0027] \u003d _(\"Failed to change power state to %(target)s. Error: %(error)s.\") % {\u0027target\u0027: target_power_state, \u0027error\u0027: e}","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"560f29348330e71d67df3004c4de59c381adec92","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                    # target_power_state was set to new_state in"},{"line_number":177,"context_line":"                    # api/controllers/v1/node.py so we need to clear it"},{"line_number":178,"context_line":"                    node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":179,"context_line":"                    s \u003d \"Unable to change power state. \" + str(e)"},{"line_number":180,"context_line":"                    node_obj[\u0027last_error\u0027] \u003d s"},{"line_number":181,"context_line":"                    node_obj.save(context)"},{"line_number":182,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FOEo%3D","line":179,"in_reply_to":"AAAATn%2F%2Fcpg%3D","updated":"2013-11-12 17:52:16.000000000","message":"Thx.","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":184,"context_line":"                # This isn\u0027t considered an error; not setting last_error field"},{"line_number":185,"context_line":"                raise exception.NodeInWrongPowerState(node\u003dnode_id,"},{"line_number":186,"context_line":"                                                      pstate\u003dcurr_state)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"            # Set the target_power_state, and remove any last_error, since"},{"line_number":189,"context_line":"            # we\u0027re starting a new operation."},{"line_number":190,"context_line":"            # This will expose to other processes and clients that the work"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FcqY%3D","line":187,"updated":"2013-11-06 01:57:38.000000000","message":"Yep. set target state here -- this is where it should be","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"29e7b58b48dbf8e6e4513d1894a3bd85ceb40323","unresolved":false,"context_lines":[{"line_number":190,"context_line":"            # This will expose to other processes and clients that the work"},{"line_number":191,"context_line":"            # is in progress"},{"line_number":192,"context_line":"            node_obj[\u0027target_power_state\u0027] \u003d new_state"},{"line_number":193,"context_line":"            node_obj[\u0027last_error\u0027] \u003d None"},{"line_number":194,"context_line":"            node_obj.save(context)"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"            # take power action"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FbLU%3D","line":193,"updated":"2013-11-06 14:21:48.000000000","message":"IMO last_error should be cleared in task_manager if shared \u003d\u003d False.","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"560f29348330e71d67df3004c4de59c381adec92","unresolved":false,"context_lines":[{"line_number":190,"context_line":"            # This will expose to other processes and clients that the work"},{"line_number":191,"context_line":"            # is in progress"},{"line_number":192,"context_line":"            node_obj[\u0027target_power_state\u0027] \u003d new_state"},{"line_number":193,"context_line":"            node_obj[\u0027last_error\u0027] \u003d None"},{"line_number":194,"context_line":"            node_obj.save(context)"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"            # take power action"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FOEg%3D","line":193,"in_reply_to":"AAAATn%2F%2FbLU%3D","updated":"2013-11-12 17:52:16.000000000","message":"Yes, thx, I\u0027m going to do that when I handle the provision states (stay tuned).","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"c7c0888504c802a61bbf347e307711b4a28079bd","unresolved":false,"context_lines":[{"line_number":169,"context_line":"                    % {\u0027node\u0027: node_id, \u0027state\u0027: new_state})"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dFalse) as task:"},{"line_number":172,"context_line":"            node_obj.refresh()"},{"line_number":173,"context_line":"            if node_obj[\u0027target_power_state\u0027] is not None:"},{"line_number":174,"context_line":"                # Would this ever happen?"},{"line_number":175,"context_line":"                # Cannot set \u0027last_error\u0027 because presumably a power"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F%2FKgY%3D","line":172,"updated":"2013-11-13 14:28:21.000000000","message":"We have already fresh node: task.node, and see my comment in l173.","commit_id":"8c41a202c37397a1b3cca0e3782daf2b7ca525ea"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"d02638ad09798dc9af7013a6a20c10d61995e406","unresolved":false,"context_lines":[{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        with task_manager.acquire(context, node_id, shared\u003dFalse) as task:"},{"line_number":172,"context_line":"            node_obj.refresh()"},{"line_number":173,"context_line":"            if node_obj[\u0027target_power_state\u0027] is not None:"},{"line_number":174,"context_line":"                # Would this ever happen?"},{"line_number":175,"context_line":"                # Cannot set \u0027last_error\u0027 because presumably a power"},{"line_number":176,"context_line":"                # operation is in progress."}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F%2FKrQ%3D","line":173,"updated":"2013-11-13 13:50:48.000000000","message":"I think this code will never work, because power action executed inside task manager context with shared\u003dFalse and we will get an exception in line 171.","commit_id":"8c41a202c37397a1b3cca0e3782daf2b7ca525ea"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"d02638ad09798dc9af7013a6a20c10d61995e406","unresolved":false,"context_lines":[{"line_number":203,"context_line":"            # This will expose to other processes and clients that the work"},{"line_number":204,"context_line":"            # is in progress."},{"line_number":205,"context_line":"            node_obj[\u0027target_power_state\u0027] \u003d new_state"},{"line_number":206,"context_line":"            node_obj[\u0027last_error\u0027] \u003d None"},{"line_number":207,"context_line":"            node_obj.save(context)"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"            # take power action"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F%2FKqk%3D","line":206,"updated":"2013-11-13 13:50:48.000000000","message":"Maybe better to do this in task_manager.acquire()?","commit_id":"8c41a202c37397a1b3cca0e3782daf2b7ca525ea"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"d02638ad09798dc9af7013a6a20c10d61995e406","unresolved":false,"context_lines":[{"line_number":209,"context_line":"            # take power action"},{"line_number":210,"context_line":"            try:"},{"line_number":211,"context_line":"                task.driver.power.set_power_state(task, node_obj, new_state)"},{"line_number":212,"context_line":"            except exception.IronicException as e:"},{"line_number":213,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":214,"context_line":"                    node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":215,"context_line":"                    node_obj[\u0027last_error\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F%2FKp8%3D","line":212,"updated":"2013-11-13 13:50:48.000000000","message":"IMO better to use try-except-else-finally syntax here (210-224).","commit_id":"8c41a202c37397a1b3cca0e3782daf2b7ca525ea"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"2948f43ed404bf6a2f2234406f65e3c7aa23b47d","unresolved":false,"context_lines":[{"line_number":173,"context_line":"            try:"},{"line_number":174,"context_line":"                task.driver.power.validate(node)"},{"line_number":175,"context_line":"                curr_state \u003d task.driver.power.get_power_state(task, node)"},{"line_number":176,"context_line":"            except exception.IronicException as e:"},{"line_number":177,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":178,"context_line":"                    node[\u0027last_error\u0027] \u003d \\"},{"line_number":179,"context_line":"                        _(\"Failed to change power state to \u0027%(target)s\u0027. \""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATn%2F%2FE%2Bs%3D","line":176,"updated":"2013-11-14 18:05:53.000000000","message":"it may be good to catch all exceptions here, just in case the power driver throws something unexpected (like a Paramiko or ExcUtils exception)","commit_id":"83d6e0141915dcca42a91e439ecc026f63750fd4"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"2948f43ed404bf6a2f2234406f65e3c7aa23b47d","unresolved":false,"context_lines":[{"line_number":189,"context_line":"            # Set the target_power_state, since we\u0027re starting a new operation."},{"line_number":190,"context_line":"            # This will expose to other processes and clients that work is"},{"line_number":191,"context_line":"            # in progress."},{"line_number":192,"context_line":"            node[\u0027target_power_state\u0027] \u003d new_state"},{"line_number":193,"context_line":"            node.save(context)"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"            # take power action"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATn%2F%2FE%2B4%3D","line":192,"updated":"2013-11-14 18:05:53.000000000","message":"I think last_error should be cleared here. It\u0027s explicit and consistent with the intended solution to this bug.","commit_id":"83d6e0141915dcca42a91e439ecc026f63750fd4"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"8690c4562b6163100c3ef258ec7c27f1dad67f61","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            if curr_state \u003d\u003d new_state:"},{"line_number":183,"context_line":"                # not considered an error; clear last_error field"},{"line_number":184,"context_line":"                node[\u0027last_error\u0027] \u003d None"},{"line_number":185,"context_line":"                node.save(context)"},{"line_number":186,"context_line":"                raise exception.NodeInWrongPowerState(node\u003dnode_id,"},{"line_number":187,"context_line":"                                                      pstate\u003dcurr_state)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAATn%2F%2FC0c%3D","line":184,"updated":"2013-11-15 08:30:50.000000000","message":"I dont understand why NodeInWrongPowerState is not an error.","commit_id":"dcb8bbc6d6ff1441e7c7c34631e64a609b1dcdb3"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4524ef892d49cc678fa482d70cca96dae7bd16bc","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            if curr_state \u003d\u003d new_state:"},{"line_number":183,"context_line":"                # not considered an error; clear last_error field"},{"line_number":184,"context_line":"                node[\u0027last_error\u0027] \u003d None"},{"line_number":185,"context_line":"                node.save(context)"},{"line_number":186,"context_line":"                raise exception.NodeInWrongPowerState(node\u003dnode_id,"},{"line_number":187,"context_line":"                                                      pstate\u003dcurr_state)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAATn%2F%2B%2Fkk%3D","line":184,"in_reply_to":"AAAATn%2F%2FA9E%3D","updated":"2013-11-16 01:36:03.000000000","message":"Deva, that sounds reasonable to me.","commit_id":"dcb8bbc6d6ff1441e7c7c34631e64a609b1dcdb3"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1bb47b8948d6425cc2afaa265c03962da39e1961","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            if curr_state \u003d\u003d new_state:"},{"line_number":183,"context_line":"                # not considered an error; clear last_error field"},{"line_number":184,"context_line":"                node[\u0027last_error\u0027] \u003d None"},{"line_number":185,"context_line":"                node.save(context)"},{"line_number":186,"context_line":"                raise exception.NodeInWrongPowerState(node\u003dnode_id,"},{"line_number":187,"context_line":"                                                      pstate\u003dcurr_state)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAATn%2F%2FAV0%3D","line":184,"in_reply_to":"AAAATn%2F%2FC0c%3D","updated":"2013-11-15 20:08:24.000000000","message":"I put that comment there to see what people thought. Glad you saw it :-) I wasn\u0027t even sure why we want this to be an exception. If I were a user, and I did a power_on, and it was already powered on -- should that 1) cause an exception (which is logged but the user never sees); 2) cause an exception AND set last_error (that the user may see) to something like \"Can not change instance association while node xyz is in power state power on\"; 3) neither an exception nor setting of last_error? \n\nWhat do people think?","commit_id":"dcb8bbc6d6ff1441e7c7c34631e64a609b1dcdb3"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"a680d5d698a92ca5c2f74051d83e9f26a93752f2","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            if curr_state \u003d\u003d new_state:"},{"line_number":183,"context_line":"                # not considered an error; clear last_error field"},{"line_number":184,"context_line":"                node[\u0027last_error\u0027] \u003d None"},{"line_number":185,"context_line":"                node.save(context)"},{"line_number":186,"context_line":"                raise exception.NodeInWrongPowerState(node\u003dnode_id,"},{"line_number":187,"context_line":"                                                      pstate\u003dcurr_state)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAATn%2F%2FA9E%3D","line":184,"in_reply_to":"AAAATn%2F%2FC0c%3D","updated":"2013-11-15 20:16:55.000000000","message":"There is not a failure here. Neither the ironic service nor the hardware has erred. The node is, for some reason, already in the requested state, though we don\u0027t know why. Perhaps the user previously requested the node POWER_ON, the network delayed those IPMI packets, and they are trying again -- but the node finally responds to the first request, and so the second request gets to this check and stops.\n\nI would actually prefer this to just LOG a warning. Because change_node_power_state is an RPC CAST, the exception generated here won\u0027t propagate back to the client. It will just dump a stack trace into the log for something that I don\u0027t consider an error.","commit_id":"dcb8bbc6d6ff1441e7c7c34631e64a609b1dcdb3"}],"ironic/conductor/task_manager.py":[{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"38fae403af00dfe200802fc3d2f09fdefcfe3e39","unresolved":false,"context_lines":[{"line_number":128,"context_line":"                # clear any errors from previous operations, since we\u0027re"},{"line_number":129,"context_line":"                # probably starting a new operation"},{"line_number":130,"context_line":"                nmgr.node[\u0027last_error\u0027] \u003d None"},{"line_number":131,"context_line":"                nmgr.node.save(context)"},{"line_number":132,"context_line":"        yield t"},{"line_number":133,"context_line":"    finally:"},{"line_number":134,"context_line":"        for id in [r.id for r in t.resources]:"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATn%2F%2FFQs%3D","line":131,"updated":"2013-11-14 16:33:48.000000000","message":"As variant there is possibility to do this update in dbapi.reserve_nodes() for better performance. I tested \n\ncount \u003d query.update({\u0027reservation\u0027: tag, \u0027last_error\u0027: None},\n                                 synchronize_session\u003dFalse)\n\nin db api w/o new code in task_manager, and unittests were not broken.","commit_id":"a6524747f197f951bb976a8f39669513c5ca6b67"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5a4331ea7c88c26ba3a3c56f7574a0a733075ce3","unresolved":false,"context_lines":[{"line_number":128,"context_line":"                # clear any errors from previous operations, since we\u0027re"},{"line_number":129,"context_line":"                # probably starting a new operation"},{"line_number":130,"context_line":"                nmgr.node[\u0027last_error\u0027] \u003d None"},{"line_number":131,"context_line":"                nmgr.node.save(context)"},{"line_number":132,"context_line":"        yield t"},{"line_number":133,"context_line":"    finally:"},{"line_number":134,"context_line":"        for id in [r.id for r in t.resources]:"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATn%2F%2FFCs%3D","line":131,"in_reply_to":"AAAATn%2F%2FFQs%3D","updated":"2013-11-14 17:34:41.000000000","message":"I\u0027m not sure I like pushing it down to dbapi.reserve_nodes(), but I like the performance improvement :-)  Done.","commit_id":"a6524747f197f951bb976a8f39669513c5ca6b67"}],"ironic/db/sqlalchemy/api.py":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"2948f43ed404bf6a2f2234406f65e3c7aa23b47d","unresolved":false,"context_lines":[{"line_number":224,"context_line":"            query, query_by \u003d add_filter_by_many_identities(query, models.Node,"},{"line_number":225,"context_line":"                                                            nodes)"},{"line_number":226,"context_line":"            # Be optimistic and assume we usually get a reservation."},{"line_number":227,"context_line":"            # Clear any errors, since we\u0027re probably starting a new operation."},{"line_number":228,"context_line":"            _check_node_already_locked(query, query_by)"},{"line_number":229,"context_line":"            count \u003d query.update({\u0027last_error\u0027: None, \u0027reservation\u0027: tag},"},{"line_number":230,"context_line":"                                 synchronize_session\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATn%2F%2FE%2BU%3D","line":227,"updated":"2013-11-14 18:05:53.000000000","message":"I think this is at too low a level, and will lead to confusing behaviour.\n\nreserve_nodes() gets called for any non-shared task_manager lock, including conductor.manager.ConductorManager:update_node, which is invoked by the API service for any PATCH request. So, with this change, just updating the \"extra\" field is going to wipe the last_error field.","commit_id":"83d6e0141915dcca42a91e439ecc026f63750fd4"}],"ironic/db/sqlalchemy/models.py":[{"author":{"_account_id":8106,"name":"Haomeng,Wang","email":"wanghaomeng@gmail.com","username":"whaom"},"change_message_id":"0f810ae48742d732e32025fc5933e36587fee80b","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":119,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":120,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":121,"context_line":"    last_error \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":122,"context_line":"    provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":123,"context_line":"    target_provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":124,"context_line":"    properties \u003d Column(JSONEncodedDict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FtUo%3D","line":121,"updated":"2013-10-30 06:36:44.000000000","message":"Not sure if we can assume the error message length will be less than 255, for some complex context error message, it will be long, so the text will be truncated, how about JSONEncodedDict()?","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df2a45968eb9e3289285e3b4722f93ad5068f8f3","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":119,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":120,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":121,"context_line":"    last_error \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":122,"context_line":"    provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":123,"context_line":"    target_provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":124,"context_line":"    properties \u003d Column(JSONEncodedDict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2Frro%3D","line":121,"in_reply_to":"AAAATn%2F%2Fr18%3D","updated":"2013-10-30 13:48:53.000000000","message":"1) Some info for truncation https://bugs.launchpad.net/oslo/+bug/1224898\n\n2) IMO no performance issue because no any joins/manipulations with this column,\nonly update.","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ca0d771d0bec13a9ee2b5626c7c810492bee7712","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":119,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":120,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":121,"context_line":"    last_error \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":122,"context_line":"    provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":123,"context_line":"    target_provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":124,"context_line":"    properties \u003d Column(JSONEncodedDict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2Fr18%3D","line":121,"in_reply_to":"AAAATn%2F%2FsqU%3D","updated":"2013-10-30 13:20:32.000000000","message":"This stuff is foreign to me. I was going to check what happens if the string was longer, so thx for letting me know. Truncation I can live with, err\u0027ing I can\u0027t! I am fine using Text -- are there performance issues that I need to be concerned with, using Text vs String(255)?","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":8106,"name":"Haomeng,Wang","email":"wanghaomeng@gmail.com","username":"whaom"},"change_message_id":"c0d376be6cf1f7c3605a58b673a92a6d490efaa0","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":119,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":120,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":121,"context_line":"    last_error \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":122,"context_line":"    provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":123,"context_line":"    target_provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":124,"context_line":"    properties \u003d Column(JSONEncodedDict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FoMQ%3D","line":121,"in_reply_to":"AAAATn%2F%2FsqU%3D","updated":"2013-10-31 07:57:59.000000000","message":"yes, should be Text type.","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"b84e442d7280eac27bc45c681bcf525d9557cc00","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    chassis_id \u003d Column(Integer, ForeignKey(\u0027chassis.id\u0027), nullable\u003dTrue)"},{"line_number":119,"context_line":"    power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":120,"context_line":"    target_power_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":121,"context_line":"    last_error \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":122,"context_line":"    provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":123,"context_line":"    target_provision_state \u003d Column(String(15), nullable\u003dTrue)"},{"line_number":124,"context_line":"    properties \u003d Column(JSONEncodedDict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FsqU%3D","line":121,"in_reply_to":"AAAATn%2F%2FtUo%3D","updated":"2013-10-30 09:48:20.000000000","message":"\u003ethe text will be truncated\n\nHaomeng, also error possible, this is backend specific.\nBetter use sqlalchemy Text type here.","commit_id":"d6de64d27bdd93252915813fa6809c9cdcdee2d9"}],"ironic/tests/conductor/test_manager.py":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":314,"context_line":"            validate_mock.assert_called_once_with(node)"},{"line_number":315,"context_line":"            self.assertEqual(node[\u0027power_state\u0027], states.POWER_ON)"},{"line_number":316,"context_line":"            self.assertEqual(node[\u0027target_power_state\u0027], None)"},{"line_number":317,"context_line":"            self.assertEqual(node[\u0027last_error\u0027],"},{"line_number":318,"context_line":"                    \u0027Unable to change power state. wrong power driver info\u0027)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"    def test_change_node_power_state_set_power_failure(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FcoM%3D","line":317,"updated":"2013-11-06 01:57:38.000000000","message":"This test is coupled too tightly to the actual error string. It would be sufficient to asset that last_error is not none.","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"560f29348330e71d67df3004c4de59c381adec92","unresolved":false,"context_lines":[{"line_number":314,"context_line":"            validate_mock.assert_called_once_with(node)"},{"line_number":315,"context_line":"            self.assertEqual(node[\u0027power_state\u0027], states.POWER_ON)"},{"line_number":316,"context_line":"            self.assertEqual(node[\u0027target_power_state\u0027], None)"},{"line_number":317,"context_line":"            self.assertEqual(node[\u0027last_error\u0027],"},{"line_number":318,"context_line":"                    \u0027Unable to change power state. wrong power driver info\u0027)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"    def test_change_node_power_state_set_power_failure(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FOD4%3D","line":317,"in_reply_to":"AAAATn%2F%2FcoM%3D","updated":"2013-11-12 17:52:16.000000000","message":"Works for me!","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4f7f06c24b35a33cb791c6362d4e819b1b4121c8","unresolved":false,"context_lines":[{"line_number":345,"context_line":"                                                       states.POWER_ON)"},{"line_number":346,"context_line":"                self.assertEqual(node[\u0027power_state\u0027], states.POWER_OFF)"},{"line_number":347,"context_line":"                self.assertEqual(node[\u0027target_power_state\u0027], None)"},{"line_number":348,"context_line":"                self.assertEqual(node[\u0027last_error\u0027],"},{"line_number":349,"context_line":"                                      \u0027An unknown exception occurred.\u0027)"},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"    def test_vendor_action(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2FcoI%3D","line":348,"updated":"2013-11-06 01:57:38.000000000","message":"Ditto","commit_id":"c09fad3eac9e774e0cda1d079caa4736c4ba7695"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"2948f43ed404bf6a2f2234406f65e3c7aa23b47d","unresolved":false,"context_lines":[{"line_number":278,"context_line":"    def test_change_node_power_state_already_being_processed(self):"},{"line_number":279,"context_line":"        \"\"\"The target_power_state is expected to be None so it"},{"line_number":280,"context_line":"        isn\u0027t checked in the code. This is what happens if it"},{"line_number":281,"context_line":"        is not None (which shouldn\u0027t happen in normal situations)."},{"line_number":282,"context_line":"        \"\"\""},{"line_number":283,"context_line":"        ndict \u003d utils.get_test_node(driver\u003d\u0027fake\u0027,"},{"line_number":284,"context_line":"                                    power_state\u003dstates.POWER_ON,"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATn%2F%2FE9w%3D","line":281,"updated":"2013-11-14 18:05:53.000000000","message":"instead of saying, \"shouldn\u0027t happen\", perhaps describe a situation in which it could happen -- for example, if a conductor had died during a previous power-off attempt and left the target_power_state non-null, and the user was attempting to power-off again.","commit_id":"83d6e0141915dcca42a91e439ecc026f63750fd4"}]}
