)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"4e4e768e39464818855061e6fd4a84fad108ed46","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Necessary node power cycles added to PXE"},{"line_number":10,"context_line":"driver."},{"line_number":11,"context_line":"node_power_action() added to deploy_utils."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Partially implements blueprint pxe-mount-and-dd"},{"line_number":14,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAATn%2F%2FlWk%3D","line":11,"updated":"2013-10-31 22:32:09.000000000","message":"This is wrapped very oddly. The rule for commit messages is wrap at 70 columns, but you\u0027ve wrapped at (I think) 50.","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"776f60ff20c378832b8b8a2777365639f95d7b62","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Necessary node power cycles added to PXE"},{"line_number":10,"context_line":"driver."},{"line_number":11,"context_line":"node_power_action() added to deploy_utils."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Partially implements blueprint pxe-mount-and-dd"},{"line_number":14,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAATn%2F%2Fa%2F0%3D","line":11,"in_reply_to":"AAAATn%2F%2FlWk%3D","updated":"2013-11-06 16:05:07.000000000","message":"Done","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"4e4e768e39464818855061e6fd4a84fad108ed46","unresolved":false,"context_lines":[{"line_number":10,"context_line":"driver."},{"line_number":11,"context_line":"node_power_action() added to deploy_utils."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Partially implements blueprint pxe-mount-and-dd"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ic13c046c621211d9c1533325812955233441d2da"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAATn%2F%2FlWc%3D","line":13,"updated":"2013-10-31 22:32:09.000000000","message":"This is the syntax (from the GitCommitMessages wiki page):\n\nImplements: blueprint libvirt-xml-cpu-model\n\nThere should be no space between the pseudo-headers.","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"776f60ff20c378832b8b8a2777365639f95d7b62","unresolved":false,"context_lines":[{"line_number":10,"context_line":"driver."},{"line_number":11,"context_line":"node_power_action() added to deploy_utils."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Partially implements blueprint pxe-mount-and-dd"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ic13c046c621211d9c1533325812955233441d2da"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAATn%2F%2Fa%2F4%3D","line":13,"in_reply_to":"AAAATn%2F%2FlWc%3D","updated":"2013-11-06 16:05:07.000000000","message":"Done","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"}],"ironic/conductor/utils.py":[{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"a7126978e6debb2253d603cde6190f321d20ad14","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        the node power state is directly set to \u0027state\u0027."},{"line_number":33,"context_line":"    \"\"\""},{"line_number":34,"context_line":"    context \u003d task.context"},{"line_number":35,"context_line":"    new_state \u003d states.POWER_ON if state \u003d\u003d states.REBOOT else state"},{"line_number":36,"context_line":"    try:"},{"line_number":37,"context_line":"        task.driver.power.validate(node)"},{"line_number":38,"context_line":"        if state !\u003d states.REBOOT:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F%2BH5w%3D","line":35,"updated":"2013-12-02 10:59:39.000000000","message":"Why don\u0027t you validation check whether the \u0027state\u0027 parameter is states.ON/states.REBOOT/states.OFF or other than these?","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"adb6ab60f97a0c04b7bfdc1ad8b43fff95235212","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        the node power state is directly set to \u0027state\u0027."},{"line_number":33,"context_line":"    \"\"\""},{"line_number":34,"context_line":"    context \u003d task.context"},{"line_number":35,"context_line":"    new_state \u003d states.POWER_ON if state \u003d\u003d states.REBOOT else state"},{"line_number":36,"context_line":"    try:"},{"line_number":37,"context_line":"        task.driver.power.validate(node)"},{"line_number":38,"context_line":"        if state !\u003d states.REBOOT:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F%2BDvI%3D","line":35,"in_reply_to":"AAAATn%2F%2BH2w%3D","updated":"2013-12-02 23:46:00.000000000","message":"OK, I understand.","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"32851abd26623a1173d325c35c875f293cf79ee6","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        the node power state is directly set to \u0027state\u0027."},{"line_number":33,"context_line":"    \"\"\""},{"line_number":34,"context_line":"    context \u003d task.context"},{"line_number":35,"context_line":"    new_state \u003d states.POWER_ON if state \u003d\u003d states.REBOOT else state"},{"line_number":36,"context_line":"    try:"},{"line_number":37,"context_line":"        task.driver.power.validate(node)"},{"line_number":38,"context_line":"        if state !\u003d states.REBOOT:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F%2BH2w%3D","line":35,"in_reply_to":"AAAATn%2F%2BH5w%3D","updated":"2013-12-02 11:14:39.000000000","message":"There is todo for API: https://github.com/openstack/ironic/blob/master/ironic/api/controllers/v1/node.py#L88","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"0410616454d460c6cb04944d03f0bd022c13bdcf","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                           \"current state \u003d requested state \u003d \u0027%(state)s\u0027.\")"},{"line_number":54,"context_line":"                         % {\u0027state\u0027: curr_state})"},{"line_number":55,"context_line":"                return"},{"line_number":56,"context_line":"    except Exception as e:"},{"line_number":57,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":58,"context_line":"            node[\u0027last_error\u0027] \u003d \\"},{"line_number":59,"context_line":"                 _(\"Failed to change power state to \u0027%(target)s\u0027. \""}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATn%2F93x0%3D","line":56,"updated":"2013-12-05 00:45:29.000000000","message":"This except should not have moved when you copied this method out of the ConductorManager class. It should only be around the two calls to driver.power.validate and driver.power.get_power_state -- it should *not* catch exceptions generated by node.save.\n\nThis section of code should read:\n\n  context \u003d ...\n  new_state \u003d ...\n  try:\n    task.driver.power.validate(node)\n    if state !\u003d states.REBOOT:\n      curr_state \u003d task.driver.power.get_power_state(task, node)\n  except Exception as e:\n    with excutils.save_and_reraise_exception():\n      ...\n  if curr_state \u003d\u003d new_state:\n    # comment\n    node[\u0027last_error\u0027] \u003d None\n    node.save\n    LOG.warn(...)\n    return","commit_id":"125c5420d2beeeee1229d2756b94d917e93b0fea"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"aecc5f52fb0fccc94a3b8bab5e93112033dd40ae","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                           \"current state \u003d requested state \u003d \u0027%(state)s\u0027.\")"},{"line_number":54,"context_line":"                         % {\u0027state\u0027: curr_state})"},{"line_number":55,"context_line":"                return"},{"line_number":56,"context_line":"    except Exception as e:"},{"line_number":57,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":58,"context_line":"            node[\u0027last_error\u0027] \u003d \\"},{"line_number":59,"context_line":"                 _(\"Failed to change power state to \u0027%(target)s\u0027. \""}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATn%2F92oY%3D","line":56,"in_reply_to":"AAAATn%2F93x0%3D","updated":"2013-12-05 08:40:48.000000000","message":"Done. Extra check state !\u003d states.REBOOT needs in this case.","commit_id":"125c5420d2beeeee1229d2756b94d917e93b0fea"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"0410616454d460c6cb04944d03f0bd022c13bdcf","unresolved":false,"context_lines":[{"line_number":74,"context_line":"            task.driver.power.set_power_state(task, node, new_state)"},{"line_number":75,"context_line":"        else:"},{"line_number":76,"context_line":"            task.driver.power.reboot(task, node)"},{"line_number":77,"context_line":"        node[\u0027power_state\u0027] \u003d new_state"},{"line_number":78,"context_line":"    except Exception as e:"},{"line_number":79,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":80,"context_line":"            node[\u0027last_error\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATn%2F93yw%3D","line":77,"updated":"2013-12-05 00:45:29.000000000","message":"I\u0027m not sure why you moved this line out of the try-except-else block. I don\u0027t think it makes any difference in this case, though.","commit_id":"125c5420d2beeeee1229d2756b94d917e93b0fea"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"aecc5f52fb0fccc94a3b8bab5e93112033dd40ae","unresolved":false,"context_lines":[{"line_number":74,"context_line":"            task.driver.power.set_power_state(task, node, new_state)"},{"line_number":75,"context_line":"        else:"},{"line_number":76,"context_line":"            task.driver.power.reboot(task, node)"},{"line_number":77,"context_line":"        node[\u0027power_state\u0027] \u003d new_state"},{"line_number":78,"context_line":"    except Exception as e:"},{"line_number":79,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":80,"context_line":"            node[\u0027last_error\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATn%2F92oM%3D","line":77,"in_reply_to":"AAAATn%2F93yw%3D","updated":"2013-12-05 08:40:48.000000000","message":"Done","commit_id":"125c5420d2beeeee1229d2756b94d917e93b0fea"}],"ironic/drivers/modules/deploy_utils.py":[{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"4e4e768e39464818855061e6fd4a84fad108ed46","unresolved":false,"context_lines":[{"line_number":214,"context_line":""},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"def node_power_action(task, node_obj, action):"},{"line_number":217,"context_line":"    \"\"\"Change power state or reset for a node.\"\"\""},{"line_number":218,"context_line":"    task.driver.power.validate(node_obj)"},{"line_number":219,"context_line":"    ctx \u003d context.get_admin_context()"},{"line_number":220,"context_line":"    new_state \u003d states.POWER_ON if action \u003d\u003d states.REBOOT else action"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FlVs%3D","line":217,"updated":"2013-10-31 22:32:09.000000000","message":"Please include parameter definitions in docstrings. Like this:\n\n \"\"\"Change power state or reset for a node.\n\n :param task: The Ironic task being acted on.\n :param node_obj: The Ironic node being acted on.\n :param action: Any ironic.common.states state. If the action is \u0027REBOOT\u0027 then\n     a reboot will be attempted, otherwise the node power state is directly set to action.\n \"\"\"","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"776f60ff20c378832b8b8a2777365639f95d7b62","unresolved":false,"context_lines":[{"line_number":214,"context_line":""},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"def node_power_action(task, node_obj, action):"},{"line_number":217,"context_line":"    \"\"\"Change power state or reset for a node.\"\"\""},{"line_number":218,"context_line":"    task.driver.power.validate(node_obj)"},{"line_number":219,"context_line":"    ctx \u003d context.get_admin_context()"},{"line_number":220,"context_line":"    new_state \u003d states.POWER_ON if action \u003d\u003d states.REBOOT else action"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2Fa%2F8%3D","line":217,"in_reply_to":"AAAATn%2F%2FlVs%3D","updated":"2013-11-06 16:05:07.000000000","message":"Done","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"4e4e768e39464818855061e6fd4a84fad108ed46","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    ctx \u003d context.get_admin_context()"},{"line_number":220,"context_line":"    new_state \u003d states.POWER_ON if action \u003d\u003d states.REBOOT else action"},{"line_number":221,"context_line":"    node_obj[\u0027target_power_state\u0027] \u003d new_state"},{"line_number":222,"context_line":"    node_obj.save(ctx)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    try:"},{"line_number":225,"context_line":"        if action \u003d\u003d states.REBOOT:"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FlWE%3D","line":222,"updated":"2013-10-31 22:32:09.000000000","message":"There is a race condition here: you are setting and saving the object state before you attempt the task. So if this task stalls (or is hard-interrupted), Ironic will think the node is on, but it will be off.","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"e4f067a66ae72baa9ac85f6681e606aa43795dbd","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    ctx \u003d context.get_admin_context()"},{"line_number":220,"context_line":"    new_state \u003d states.POWER_ON if action \u003d\u003d states.REBOOT else action"},{"line_number":221,"context_line":"    node_obj[\u0027target_power_state\u0027] \u003d new_state"},{"line_number":222,"context_line":"    node_obj.save(ctx)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    try:"},{"line_number":225,"context_line":"        if action \u003d\u003d states.REBOOT:"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2Fjho%3D","line":222,"in_reply_to":"AAAATn%2F%2FlWE%3D","updated":"2013-11-01 12:57:03.000000000","message":"Good point, must wait fix for https://bugs.launchpad.net/ironic/+bug/1237688","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"776f60ff20c378832b8b8a2777365639f95d7b62","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    ctx \u003d context.get_admin_context()"},{"line_number":220,"context_line":"    new_state \u003d states.POWER_ON if action \u003d\u003d states.REBOOT else action"},{"line_number":221,"context_line":"    node_obj[\u0027target_power_state\u0027] \u003d new_state"},{"line_number":222,"context_line":"    node_obj.save(ctx)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    try:"},{"line_number":225,"context_line":"        if action \u003d\u003d states.REBOOT:"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FbBw%3D","line":222,"in_reply_to":"AAAATn%2F%2FlWE%3D","updated":"2013-11-06 16:05:07.000000000","message":"This method intended for use inside task context. There is part of global problem in Ironic with stalled/interrupted tasks, see: https://blueprints.launchpad.net/ironic/+spec/breaking-resource-locks","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"4e4e768e39464818855061e6fd4a84fad108ed46","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        if action \u003d\u003d states.REBOOT:"},{"line_number":226,"context_line":"            task.driver.power.reboot(task, node_obj)"},{"line_number":227,"context_line":"        else:"},{"line_number":228,"context_line":"            task.driver.power.set_power_state(task, node_obj, new_state)"},{"line_number":229,"context_line":"    except exception.IronicException:"},{"line_number":230,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":231,"context_line":"            node_obj[\u0027power_state\u0027] \u003d states.ERROR"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FlV8%3D","line":228,"updated":"2013-10-31 22:32:09.000000000","message":"This might be clearer if you used action rather than new_state, since action is passed in not calculated.","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"776f60ff20c378832b8b8a2777365639f95d7b62","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        if action \u003d\u003d states.REBOOT:"},{"line_number":226,"context_line":"            task.driver.power.reboot(task, node_obj)"},{"line_number":227,"context_line":"        else:"},{"line_number":228,"context_line":"            task.driver.power.set_power_state(task, node_obj, new_state)"},{"line_number":229,"context_line":"    except exception.IronicException:"},{"line_number":230,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":231,"context_line":"            node_obj[\u0027power_state\u0027] \u003d states.ERROR"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FbA8%3D","line":228,"in_reply_to":"AAAATn%2F%2FlV8%3D","updated":"2013-11-06 16:05:07.000000000","message":"Done","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"c86aa23a64518b13222add09590be9b1b19ce525","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":240,"context_line":"            node_obj[\u0027last_error\u0027] \u003d str(e)"},{"line_number":241,"context_line":"    else:"},{"line_number":242,"context_line":"        node_obj[\u0027power_state\u0027] \u003d new_state"},{"line_number":243,"context_line":"    finally:"},{"line_number":244,"context_line":"        node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":245,"context_line":"        node_obj.save(ctx)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAATn%2F%2Bw7c%3D","line":242,"updated":"2013-11-20 14:48:35.000000000","message":"Maybe to move this to the end of try block to decrease complexity?","commit_id":"c8a582b746ef1c4d676d016bcef7c9b033c20135"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"04b3a011160317fa9a3644f088d8ec9a385002c4","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        with excutils.save_and_reraise_exception():"},{"line_number":240,"context_line":"            node_obj[\u0027last_error\u0027] \u003d str(e)"},{"line_number":241,"context_line":"    else:"},{"line_number":242,"context_line":"        node_obj[\u0027power_state\u0027] \u003d new_state"},{"line_number":243,"context_line":"    finally:"},{"line_number":244,"context_line":"        node_obj[\u0027target_power_state\u0027] \u003d states.NOSTATE"},{"line_number":245,"context_line":"        node_obj.save(ctx)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAATn%2F%2BtOQ%3D","line":242,"in_reply_to":"AAAATn%2F%2Bw7c%3D","updated":"2013-11-21 10:36:13.000000000","message":"Agree.","commit_id":"c8a582b746ef1c4d676d016bcef7c9b033c20135"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"1ba8eb5cbb082dd19a23b312eb2d3876ec8a5150","unresolved":false,"context_lines":[{"line_number":215,"context_line":""},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"@task_manager.require_exclusive_lock"},{"line_number":218,"context_line":"def node_power_action(task, node_obj, action):"},{"line_number":219,"context_line":"    \"\"\"Change power state or reset for a node."},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"    :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATn%2F%2BS0Q%3D","line":218,"updated":"2013-11-27 19:09:59.000000000","message":"Take a look at conductor.manager.ConductorManager:change_node_power_state()\n\nRuby\u0027s patch a few weeks ago significantly improved this method, and I think your node_power_action method is too similar (and lacks her improvements) to warrant being a separate method. Like this, it will be difficult to keep changes to one in sync with the other.\n\nDoes the PXE driver really need a separate method to handle power changes, or can it share the same code with ConductorManager:change_node_power_state?","commit_id":"a54c3377d9c8a6b6045a153362b02be7fb019342"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"6a845893c02a4e167d1e2a578401467d4c525ef9","unresolved":false,"context_lines":[{"line_number":215,"context_line":""},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"@task_manager.require_exclusive_lock"},{"line_number":218,"context_line":"def node_power_action(task, node_obj, action):"},{"line_number":219,"context_line":"    \"\"\"Change power state or reset for a node."},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"    :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATn%2F%2BPUI%3D","line":218,"in_reply_to":"AAAATn%2F%2BS0Q%3D","updated":"2013-11-28 13:08:25.000000000","message":"Agree, done.","commit_id":"a54c3377d9c8a6b6045a153362b02be7fb019342"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"28828c30ad10c32a26fa19ba51dedd7eb157cc5d","unresolved":false,"context_lines":[{"line_number":221,"context_line":"    :param task: a TaskManager instance."},{"line_number":222,"context_line":"    :param node_obj: the Node to act upon."},{"line_number":223,"context_line":"    :param action: Any power state from ironic.common.states. If the action is"},{"line_number":224,"context_line":"    \u0027REBOOT\u0027 then a reboot will be attempted, otherwise the node power state is"},{"line_number":225,"context_line":"    directly set to action."},{"line_number":226,"context_line":"    \"\"\""},{"line_number":227,"context_line":"    ctx \u003d context.get_admin_context()"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATn%2F%2BdAA%3D","line":224,"updated":"2013-11-25 21:52:38.000000000","message":"A hanging indent here is usual I think - makes reading the plain text docstrings easier.\n\n :param action: Any...\n     \u0027REBOOT\u0027 ....","commit_id":"a54c3377d9c8a6b6045a153362b02be7fb019342"}],"ironic/drivers/modules/pxe.py":[{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"4e4e768e39464818855061e6fd4a84fad108ed46","unresolved":false,"context_lines":[{"line_number":455,"context_line":"        _cache_images(node, pxe_info)"},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        # we have exclusive lock already"},{"line_number":458,"context_line":"        deploy_utils.node_power_action(task, node, states.REBOOT)"},{"line_number":459,"context_line":""},{"line_number":460,"context_line":"        return states.DEPLOYING"},{"line_number":461,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FlVI%3D","line":458,"updated":"2013-10-31 22:32:09.000000000","message":"Not for this patch, but there is a clear optimisation here: we can start the reboot once we have the tftp imges ready, *before* we have the disk image ready. Then the deploy ramdisk can wait for use to finish the disk image prep.","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"4e4e768e39464818855061e6fd4a84fad108ed46","unresolved":false,"context_lines":[{"line_number":572,"context_line":"            node.save(ctx)"},{"line_number":573,"context_line":"            deploy_utils.deploy(**params)"},{"line_number":574,"context_line":"            with task_manager.acquire(node_id, shared\u003dFalse) as power_task:"},{"line_number":575,"context_line":"                deploy_utils.node_power_action(power_task, node, states.REBOOT)"},{"line_number":576,"context_line":"        except Exception as e:"},{"line_number":577,"context_line":"            LOG.error(_(\u0027deployment to node %s failed\u0027) % node_id)"},{"line_number":578,"context_line":"            node[\u0027provision_state\u0027] \u003d states.DEPLOYFAIL"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FlVU%3D","line":575,"updated":"2013-10-31 22:32:09.000000000","message":"This seems wrong to me: it prevents the super useful kexec optimisation.","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"776f60ff20c378832b8b8a2777365639f95d7b62","unresolved":false,"context_lines":[{"line_number":572,"context_line":"            node.save(ctx)"},{"line_number":573,"context_line":"            deploy_utils.deploy(**params)"},{"line_number":574,"context_line":"            with task_manager.acquire(node_id, shared\u003dFalse) as power_task:"},{"line_number":575,"context_line":"                deploy_utils.node_power_action(power_task, node, states.REBOOT)"},{"line_number":576,"context_line":"        except Exception as e:"},{"line_number":577,"context_line":"            LOG.error(_(\u0027deployment to node %s failed\u0027) % node_id)"},{"line_number":578,"context_line":"            node[\u0027provision_state\u0027] \u003d states.DEPLOYFAIL"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F%2FbC4%3D","line":575,"in_reply_to":"AAAATn%2F%2FlVU%3D","updated":"2013-11-06 16:05:07.000000000","message":"Good point. I think deploy ramdisk will choose to do reboot or no.","commit_id":"09ce9e2417c94d8de35c26c446a4190f80bb3cec"}],"ironic/tests/conductor/test_conductor_utils.py":[{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"a7126978e6debb2253d603cde6190f321d20ad14","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        db \u003d dbapi.get_instance()"},{"line_number":36,"context_line":"        self.node \u003d db.create_node(n)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def test_node_power_action(self):"},{"line_number":39,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":40,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":41,"context_line":"            utils.node_power_action(task, self.node, states.POWER_ON)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F%2BH8Y%3D","line":38,"updated":"2013-12-02 10:59:39.000000000","message":"Why don\u0027t you create test_node_power_action_on and test_node_power_action_off instead of test_node_power_action?","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"db508469d76a34d0833146d3e06e933332714ec3","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        db \u003d dbapi.get_instance()"},{"line_number":36,"context_line":"        self.node \u003d db.create_node(n)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def test_node_power_action(self):"},{"line_number":39,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":40,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":41,"context_line":"            utils.node_power_action(task, self.node, states.POWER_ON)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F99RQ%3D","line":38,"in_reply_to":"AAAATn%2F%2BH1o%3D","updated":"2013-12-04 01:21:47.000000000","message":"Actually, those tests are all testing the code which your patch moves out of conductor/manager.py and into conductor/utils.py. So, sorry to make you do more work, but I would prefer to see those tests moved out of test_conductor.py and into this file.","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"adb6ab60f97a0c04b7bfdc1ad8b43fff95235212","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        db \u003d dbapi.get_instance()"},{"line_number":36,"context_line":"        self.node \u003d db.create_node(n)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def test_node_power_action(self):"},{"line_number":39,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":40,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":41,"context_line":"            utils.node_power_action(task, self.node, states.POWER_ON)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F%2BDvU%3D","line":38,"in_reply_to":"AAAATn%2F%2BH1o%3D","updated":"2013-12-02 23:46:00.000000000","message":"All right, I understand. Sorry, I didn\u0027t know these tests.","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"32851abd26623a1173d325c35c875f293cf79ee6","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        db \u003d dbapi.get_instance()"},{"line_number":36,"context_line":"        self.node \u003d db.create_node(n)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def test_node_power_action(self):"},{"line_number":39,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":40,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":41,"context_line":"            utils.node_power_action(task, self.node, states.POWER_ON)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F%2BH1o%3D","line":38,"in_reply_to":"AAAATn%2F%2BH8Y%3D","updated":"2013-12-02 11:14:39.000000000","message":"There is not big difference in code for on/off, and we have already these tests in test_manager: https://github.com/openstack/ironic/blob/master/ironic/tests/conductor/test_manager.py#L183","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"5cd0258839292e56991454b76b6fded3bfb35186","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        db \u003d dbapi.get_instance()"},{"line_number":36,"context_line":"        self.node \u003d db.create_node(n)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def test_node_power_action(self):"},{"line_number":39,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":40,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":41,"context_line":"            utils.node_power_action(task, self.node, states.POWER_ON)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATn%2F96sg%3D","line":38,"in_reply_to":"AAAATn%2F99RQ%3D","updated":"2013-12-04 14:22:53.000000000","message":"Done","commit_id":"2089168318aa662310500cfc6f36547b6b9f6dc7"},{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"506fa624bcac769b84795f42a9348389d8941003","unresolved":false,"context_lines":[{"line_number":89,"context_line":"            self.assertEqual(node[\u0027target_power_state\u0027], None)"},{"line_number":90,"context_line":"            self.assertEqual(node[\u0027last_error\u0027], None)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def test_change_node_power_state_to_invalid_state(self):"},{"line_number":93,"context_line":"        \"\"\"Test if an exception is thrown when changing to an invalid"},{"line_number":94,"context_line":"        power state."},{"line_number":95,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATn%2F931s%3D","line":92,"updated":"2013-12-05 00:23:21.000000000","message":"Just a matter of taste, needn\u0027t  \"to_\"?","commit_id":"125c5420d2beeeee1229d2756b94d917e93b0fea"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"aecc5f52fb0fccc94a3b8bab5e93112033dd40ae","unresolved":false,"context_lines":[{"line_number":89,"context_line":"            self.assertEqual(node[\u0027target_power_state\u0027], None)"},{"line_number":90,"context_line":"            self.assertEqual(node[\u0027last_error\u0027], None)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def test_change_node_power_state_to_invalid_state(self):"},{"line_number":93,"context_line":"        \"\"\"Test if an exception is thrown when changing to an invalid"},{"line_number":94,"context_line":"        power state."},{"line_number":95,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATn%2F92io%3D","line":92,"in_reply_to":"AAAATn%2F931s%3D","updated":"2013-12-05 08:40:48.000000000","message":"Done","commit_id":"125c5420d2beeeee1229d2756b94d917e93b0fea"}],"ironic/tests/drivers/test_deploy_utils.py":[{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"2c173f14668c413ee5b9c33c5299504d054b2c4c","unresolved":false,"context_lines":[{"line_number":17,"context_line":"#    under the License."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import fixtures"},{"line_number":20,"context_line":"import mock"},{"line_number":21,"context_line":"import os"},{"line_number":22,"context_line":"import tempfile"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FYGs%3D","line":20,"updated":"2013-11-07 21:52:41.000000000","message":"Fixtures and mock are both part of the third-party section for imports:\n\n \u003cstdlib\u003e\n\n \u003cthird party\u003e\n\n \u003cthis code tree\u003e\n\ne.g.\n\n import os\n import tempfile\n\n import fixtures\n import mock\n\n from ironic.common...","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"2446598c3b3abfe993274e7cd8aaf91484eb2005","unresolved":false,"context_lines":[{"line_number":17,"context_line":"#    under the License."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import fixtures"},{"line_number":20,"context_line":"import mock"},{"line_number":21,"context_line":"import os"},{"line_number":22,"context_line":"import tempfile"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FW9M%3D","line":20,"in_reply_to":"AAAATn%2F%2FYGs%3D","updated":"2013-11-08 09:41:57.000000000","message":"Done","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"2c173f14668c413ee5b9c33c5299504d054b2c4c","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        name_list \u003d [\u0027get_dev\u0027, \u0027get_image_mb\u0027, \u0027discovery\u0027, \u0027login_iscsi\u0027,"},{"line_number":88,"context_line":"                     \u0027logout_iscsi\u0027, \u0027make_partitions\u0027, \u0027is_block_device\u0027,"},{"line_number":89,"context_line":"                     \u0027dd\u0027, \u0027mkswap\u0027, \u0027block_uuid\u0027, \u0027switch_pxe_config\u0027,"},{"line_number":90,"context_line":"                     \u0027notify\u0027]"},{"line_number":91,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":92,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":93,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FYGo%3D","line":90,"updated":"2013-11-07 21:52:41.000000000","message":"I like the compression, could you please alpha-sort the names - easier to scan for things in future.","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"2446598c3b3abfe993274e7cd8aaf91484eb2005","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        name_list \u003d [\u0027get_dev\u0027, \u0027get_image_mb\u0027, \u0027discovery\u0027, \u0027login_iscsi\u0027,"},{"line_number":88,"context_line":"                     \u0027logout_iscsi\u0027, \u0027make_partitions\u0027, \u0027is_block_device\u0027,"},{"line_number":89,"context_line":"                     \u0027dd\u0027, \u0027mkswap\u0027, \u0027block_uuid\u0027, \u0027switch_pxe_config\u0027,"},{"line_number":90,"context_line":"                     \u0027notify\u0027]"},{"line_number":91,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":92,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":93,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FW8c%3D","line":90,"in_reply_to":"AAAATn%2F%2FYGo%3D","updated":"2013-11-08 09:41:57.000000000","message":"Done","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"2c173f14668c413ee5b9c33c5299504d054b2c4c","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                     \u0027dd\u0027, \u0027mkswap\u0027, \u0027block_uuid\u0027, \u0027switch_pxe_config\u0027,"},{"line_number":90,"context_line":"                     \u0027notify\u0027]"},{"line_number":91,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":92,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        parent_mock \u003d mock.MagicMock()"},{"line_number":95,"context_line":"        for mocker, name in zip(mock_list, name_list):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FYGM%3D","line":92,"updated":"2013-11-07 21:52:41.000000000","message":"Please add\n\n  for patcher in patch_list:\n      self.addCleanup(patcher.stop)","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"2446598c3b3abfe993274e7cd8aaf91484eb2005","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                     \u0027dd\u0027, \u0027mkswap\u0027, \u0027block_uuid\u0027, \u0027switch_pxe_config\u0027,"},{"line_number":90,"context_line":"                     \u0027notify\u0027]"},{"line_number":91,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":92,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        parent_mock \u003d mock.MagicMock()"},{"line_number":95,"context_line":"        for mocker, name in zip(mock_list, name_list):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FW8Y%3D","line":92,"in_reply_to":"AAAATn%2F%2FYGM%3D","updated":"2013-11-08 09:41:57.000000000","message":"Done","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"2c173f14668c413ee5b9c33c5299504d054b2c4c","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        self.assertEqual(calls_expected, parent_mock.mock_calls)"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        for patcher in patch_list:"},{"line_number":124,"context_line":"            patcher.stop()"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    def test_always_logout_iscsi(self):"},{"line_number":127,"context_line":"        \"\"\"logout_iscsi() must be called once login_iscsi() is called.\"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FYGU%3D","line":124,"updated":"2013-11-07 21:52:41.000000000","message":"This should be addCleanup based - see above.","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"2446598c3b3abfe993274e7cd8aaf91484eb2005","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        self.assertEqual(calls_expected, parent_mock.mock_calls)"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        for patcher in patch_list:"},{"line_number":124,"context_line":"            patcher.stop()"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    def test_always_logout_iscsi(self):"},{"line_number":127,"context_line":"        \"\"\"logout_iscsi() must be called once login_iscsi() is called.\"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FW8Q%3D","line":124,"in_reply_to":"AAAATn%2F%2FYGU%3D","updated":"2013-11-08 09:41:57.000000000","message":"Done","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"2c173f14668c413ee5b9c33c5299504d054b2c4c","unresolved":false,"context_lines":[{"line_number":140,"context_line":"            pass"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"        name_list \u003d [\u0027get_dev\u0027, \u0027get_image_mb\u0027, \u0027discovery\u0027, \u0027login_iscsi\u0027,"},{"line_number":143,"context_line":"                     \u0027logout_iscsi\u0027, \u0027work_on_disk\u0027]"},{"line_number":144,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":145,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":146,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FYGE%3D","line":143,"updated":"2013-11-07 21:52:41.000000000","message":"And sort here too please.","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"2446598c3b3abfe993274e7cd8aaf91484eb2005","unresolved":false,"context_lines":[{"line_number":140,"context_line":"            pass"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"        name_list \u003d [\u0027get_dev\u0027, \u0027get_image_mb\u0027, \u0027discovery\u0027, \u0027login_iscsi\u0027,"},{"line_number":143,"context_line":"                     \u0027logout_iscsi\u0027, \u0027work_on_disk\u0027]"},{"line_number":144,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":145,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":146,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FW7A%3D","line":143,"in_reply_to":"AAAATn%2F%2FYGE%3D","updated":"2013-11-08 09:41:57.000000000","message":"Done","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"2c173f14668c413ee5b9c33c5299504d054b2c4c","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        name_list \u003d [\u0027get_dev\u0027, \u0027get_image_mb\u0027, \u0027discovery\u0027, \u0027login_iscsi\u0027,"},{"line_number":143,"context_line":"                     \u0027logout_iscsi\u0027, \u0027work_on_disk\u0027]"},{"line_number":144,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":145,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        parent_mock \u003d mock.MagicMock()"},{"line_number":148,"context_line":"        for mocker, name in zip(mock_list, name_list):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FYGI%3D","line":145,"updated":"2013-11-07 21:52:41.000000000","message":"Ditto.","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"2446598c3b3abfe993274e7cd8aaf91484eb2005","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        name_list \u003d [\u0027get_dev\u0027, \u0027get_image_mb\u0027, \u0027discovery\u0027, \u0027login_iscsi\u0027,"},{"line_number":143,"context_line":"                     \u0027logout_iscsi\u0027, \u0027work_on_disk\u0027]"},{"line_number":144,"context_line":"        patch_list \u003d [mock.patch.object(utils, name) for name in name_list]"},{"line_number":145,"context_line":"        mock_list \u003d [patcher.start() for patcher in patch_list]"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        parent_mock \u003d mock.MagicMock()"},{"line_number":148,"context_line":"        for mocker, name in zip(mock_list, name_list):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FW60%3D","line":145,"in_reply_to":"AAAATn%2F%2FYGI%3D","updated":"2013-11-08 09:41:57.000000000","message":"Done","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"2c173f14668c413ee5b9c33c5299504d054b2c4c","unresolved":false,"context_lines":[{"line_number":180,"context_line":"        def cleanup():"},{"line_number":181,"context_line":"            os.unlink(self.fname)"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"        self.addCleanup(cleanup)"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"    def test_switch_pxe_config(self):"},{"line_number":186,"context_line":"        utils.switch_pxe_config(self.fname,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FYF8%3D","line":183,"updated":"2013-11-07 21:52:41.000000000","message":"You don\u0027t need the closure, just do:\n\n self.addCleanup(os.unlink, self.fname)","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"2446598c3b3abfe993274e7cd8aaf91484eb2005","unresolved":false,"context_lines":[{"line_number":180,"context_line":"        def cleanup():"},{"line_number":181,"context_line":"            os.unlink(self.fname)"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"        self.addCleanup(cleanup)"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"    def test_switch_pxe_config(self):"},{"line_number":186,"context_line":"        utils.switch_pxe_config(self.fname,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2FW6Q%3D","line":183,"in_reply_to":"AAAATn%2F%2FYF8%3D","updated":"2013-11-08 09:41:57.000000000","message":"Done","commit_id":"777f7b57325d85868417d17e199ce01d8fe09aff"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"c86aa23a64518b13222add09590be9b1b19ce525","unresolved":false,"context_lines":[{"line_number":201,"context_line":"            utils.node_power_action(task, self.node, states.POWER_ON)"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"        self.assertEqual(self.node[\u0027power_state\u0027], states.POWER_ON)"},{"line_number":204,"context_line":"        self.assertEqual(self.node[\u0027target_power_state\u0027], states.NOSTATE)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    def test_node_power_action_fail(self):"},{"line_number":207,"context_line":"        fake_exception \u003d exception.IronicException(\u0027fake error\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAATn%2F%2Bw3M%3D","line":204,"updated":"2013-11-20 14:48:35.000000000","message":"Maybe also to ensure that last_error is clear?","commit_id":"c8a582b746ef1c4d676d016bcef7c9b033c20135"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"04b3a011160317fa9a3644f088d8ec9a385002c4","unresolved":false,"context_lines":[{"line_number":201,"context_line":"            utils.node_power_action(task, self.node, states.POWER_ON)"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"        self.assertEqual(self.node[\u0027power_state\u0027], states.POWER_ON)"},{"line_number":204,"context_line":"        self.assertEqual(self.node[\u0027target_power_state\u0027], states.NOSTATE)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    def test_node_power_action_fail(self):"},{"line_number":207,"context_line":"        fake_exception \u003d exception.IronicException(\u0027fake error\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAATn%2F%2BtOM%3D","line":204,"in_reply_to":"AAAATn%2F%2Bw3M%3D","updated":"2013-11-21 10:36:13.000000000","message":"Done","commit_id":"c8a582b746ef1c4d676d016bcef7c9b033c20135"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"c86aa23a64518b13222add09590be9b1b19ce525","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        self.assertEqual(self.node[\u0027target_power_state\u0027], states.NOSTATE)"},{"line_number":221,"context_line":"        self.assertEqual(self.node[\u0027last_error\u0027], str(fake_exception))"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"class OtherFunctionTestCase(tests_base.TestCase):"},{"line_number":225,"context_line":"    def test_get_dev(self):"},{"line_number":226,"context_line":"        expected \u003d \u0027/dev/disk/by-path/ip-1.2.3.4:5678-iscsi-iqn.fake-lun-9\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAATn%2F%2Bw3Y%3D","line":223,"updated":"2013-11-20 14:48:35.000000000","message":"Could the following tests be helpful?\n\n1. Ensure that when we perform node_power_action on the node with non-empty last_error, and this action is successful -\u003e the last_error is cleared.\n\n2. Ensure that driver.reboot is used for reboot, set_power_state for ohters.\n\n3. Ensure that it validates driver (task.driver.power.validate(node_obj)). I mean force validate mock to throw exception and check similar to test_node_power_action_fail","commit_id":"c8a582b746ef1c4d676d016bcef7c9b033c20135"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"04b3a011160317fa9a3644f088d8ec9a385002c4","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        self.assertEqual(self.node[\u0027target_power_state\u0027], states.NOSTATE)"},{"line_number":221,"context_line":"        self.assertEqual(self.node[\u0027last_error\u0027], str(fake_exception))"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"class OtherFunctionTestCase(tests_base.TestCase):"},{"line_number":225,"context_line":"    def test_get_dev(self):"},{"line_number":226,"context_line":"        expected \u003d \u0027/dev/disk/by-path/ip-1.2.3.4:5678-iscsi-iqn.fake-lun-9\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAATn%2F%2BtBw%3D","line":223,"in_reply_to":"AAAATn%2F%2Bw3Y%3D","updated":"2013-11-21 10:36:13.000000000","message":"Agree with 2 and +1 for mock.","commit_id":"c8a582b746ef1c4d676d016bcef7c9b033c20135"}]}
