)]}'
{"etc/ironic/ironic.conf.sample":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":541,"context_line":"# Deprecated group/name - [DEFAULT]/sql_connection"},{"line_number":542,"context_line":"# Deprecated group/name - [DATABASE]/sql_connection"},{"line_number":543,"context_line":"# Deprecated group/name - [sql]/connection"},{"line_number":544,"context_line":"#connection\u003dsqlite:///$state_path/ironic.sqlite"},{"line_number":545,"context_line":""},{"line_number":546,"context_line":"# The SQL mode to be used for MySQL sessions (default is"},{"line_number":547,"context_line":"# empty, meaning do not override any server-side SQL mode"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAWH%2F9rsU%3D","line":544,"updated":"2014-04-02 20:52:01.000000000","message":"Seems like this shouldn\u0027t be changed here.","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":8106,"name":"Haomeng,Wang","email":"wanghaomeng@gmail.com","username":"whaom"},"change_message_id":"f3971a2f8f96164a60ddbed572c4599660e9dbc6","unresolved":false,"context_lines":[{"line_number":861,"context_line":"# (list value)"},{"line_number":862,"context_line":"#hash_algorithms\u003dmd5"},{"line_number":863,"context_line":""},{"line_number":864,"context_line":""},{"line_number":865,"context_line":"[matchmaker_ring]"},{"line_number":866,"context_line":""},{"line_number":867,"context_line":"#"}],"source_content_type":"application/octet-stream","patch_set":97,"id":"1ae5cdf2_33bceadb","side":"PARENT","line":864,"updated":"2014-06-14 14:54:51.000000000","message":"Dont think we change these options within this patch, these are not sync with latest keystone code I think, so please update the keystone client to latest code and re-generate this ironic.ocnf.sample, thank you.","commit_id":"e2942075cc941a0c8ecee2cc39e13da5af93032d"}],"ironic/common/exception.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":251,"context_line":""},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"class NetworkError(IronicException):"},{"line_number":254,"context_line":"    message \u003d _(\"A networking error occurred for node %(node)s\")"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"class ChassisNotEmpty(Invalid):"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_7a8d4731","line":254,"updated":"2014-05-26 10:55:45.000000000","message":"I think there should be some clarification here: what kind of networking error? If it\u0027s risen from another exception, it can be str(exc)","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":251,"context_line":""},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"class NetworkError(IronicException):"},{"line_number":254,"context_line":"    message \u003d _(\"A networking error occurred for node %(node)s\")"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"class ChassisNotEmpty(Invalid):"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_df8802ea","line":254,"in_reply_to":"5adbc538_7a8d4731","updated":"2014-05-28 00:22:04.000000000","message":"I think it is reasonable to leave it basic like this. You can override the message (which is generally how I\u0027ve used it) or subclass it for more specific exceptions.","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"}],"ironic/common/glance_service/service_utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":188,"context_line":"    \"\"\""},{"line_number":189,"context_line":"    # The presence of an auth token implies this is an authenticated request"},{"line_number":190,"context_line":"    # TODO(JoshNang) break this into its own patch later."},{"line_number":191,"context_line":"    if CONF.glance.auth_strategy \u003d\u003d \u0027noauth\u0027:"},{"line_number":192,"context_line":"        return True"},{"line_number":193,"context_line":"    if hasattr(context, \u0027auth_token\u0027) and context.auth_token:"},{"line_number":194,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_bab50fcf","line":191,"updated":"2014-05-26 10:55:45.000000000","message":"I also think that it may be a separate patch, but anyway please create a bug for it.","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":188,"context_line":"    \"\"\""},{"line_number":189,"context_line":"    # The presence of an auth token implies this is an authenticated request"},{"line_number":190,"context_line":"    # TODO(JoshNang) break this into its own patch later."},{"line_number":191,"context_line":"    if CONF.glance.auth_strategy \u003d\u003d \u0027noauth\u0027:"},{"line_number":192,"context_line":"        return True"},{"line_number":193,"context_line":"    if hasattr(context, \u0027auth_token\u0027) and context.auth_token:"},{"line_number":194,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_3f580656","line":191,"in_reply_to":"5adbc538_bab50fcf","updated":"2014-05-28 00:22:04.000000000","message":"Done! https://bugs.launchpad.net/ironic/+bug/1323781","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":187,"context_line":"    without authentication turned on."},{"line_number":188,"context_line":"    \"\"\""},{"line_number":189,"context_line":"    # The presence of an auth token implies this is an authenticated request"},{"line_number":190,"context_line":"    # TODO(JoshNang) break this into its own patch later."},{"line_number":191,"context_line":"    if CONF.glance.auth_strategy \u003d\u003d \u0027noauth\u0027:"},{"line_number":192,"context_line":"        return True"},{"line_number":193,"context_line":"    if hasattr(context, \u0027auth_token\u0027) and context.auth_token:"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_94ea239e","line":190,"updated":"2014-06-20 13:05:38.000000000","message":"Just I reminder that this should be separated","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"}],"ironic/common/neutron.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        else:"},{"line_number":72,"context_line":"            params[\u0027token\u0027] \u003d context.auth_token"},{"line_number":73,"context_line":"            params[\u0027endpoint_url\u0027] \u003d CONF.neutron.url"},{"line_number":74,"context_line":"            params[\u0027auth_strategy\u0027] \u003d \u0027noauth\u0027"},{"line_number":75,"context_line":"        self.client \u003d clientv20.Client(**params)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def update_port_dhcp_opts(self, port_id, dhcp_options):"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_1adb631c","line":74,"updated":"2014-05-26 10:55:45.000000000","message":"Should probably be also a separate patch with a bug filed for it.","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        else:"},{"line_number":72,"context_line":"            params[\u0027token\u0027] \u003d context.auth_token"},{"line_number":73,"context_line":"            params[\u0027endpoint_url\u0027] \u003d CONF.neutron.url"},{"line_number":74,"context_line":"            params[\u0027auth_strategy\u0027] \u003d \u0027noauth\u0027"},{"line_number":75,"context_line":"        self.client \u003d clientv20.Client(**params)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def update_port_dhcp_opts(self, port_id, dhcp_options):"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_7f31ae0a","line":74,"in_reply_to":"5adbc538_1adb631c","updated":"2014-05-28 00:22:04.000000000","message":"Done! (at least filing a bug) https://bugs.launchpad.net/ironic/+bug/1323783","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"}],"ironic/drivers/agent.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":25,"context_line":"class AgentAndIPMIToolDriver(base.BaseDriver):"},{"line_number":26,"context_line":"    \"\"\"Agent + IPMITool driver."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    This driver implements the `core` functionality, combinding"},{"line_number":29,"context_line":"    :class:`ironic.drivers.ipmitool.IPMIPower` for power on/off and reboot with"},{"line_number":30,"context_line":"    :class:`ironic.driver.agent_deploy.AgentDeploy` for image deployment."},{"line_number":31,"context_line":"    Implementations are in those respective classes; this class is merely the"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rsM%3D","line":28,"updated":"2014-04-02 20:52:01.000000000","message":"s/combinding/combining/","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":47,"context_line":"class AgentAndIPMINativeDriver(base.BaseDriver):"},{"line_number":48,"context_line":"    \"\"\"Agent + IPMINative driver."},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    This driver implements the `core` functionality, combinding"},{"line_number":51,"context_line":"    :class:`ironic.drivers.ipminative.NativeIPMIPower` for power on/off and"},{"line_number":52,"context_line":"    reboot with"},{"line_number":53,"context_line":"    :class:`ironic.driver.agent_deploy.AgentDeploy` for image deployment."}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rrY%3D","line":50,"updated":"2014-04-02 20:52:01.000000000","message":"s/combinding/combining/","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        self.power \u003d ipminative.NativeIPMIPower()"},{"line_number":60,"context_line":"        self.deploy \u003d agent_deploy.AgentDeploy()"},{"line_number":61,"context_line":"        self.agent_vendor \u003d agent_passthru.AgentVendorInterface()"},{"line_number":62,"context_line":"        self.ipmi_vendor \u003d ipmitool.VendorPassthru()"},{"line_number":63,"context_line":"        #TODO(JoshNang) add lookup: nodeless passthru mapping when its added"},{"line_number":64,"context_line":"        #to utils.MixinVendorInterface"},{"line_number":65,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor,"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rrs%3D","line":62,"updated":"2014-04-02 20:52:01.000000000","message":"This should also be ipminative, yeah?","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    This driver implements the `core` functionality, combinding"},{"line_number":76,"context_line":"    :class:`ironic.drivers.ssh.SSH` for power on/off and reboot of virtual"},{"line_number":77,"context_line":"    machines tunneled over SSH, with :class:`ironic.driver.pxe.PXE` for image"},{"line_number":78,"context_line":"    deployment. Implementations are in those respective classes; this class is"},{"line_number":79,"context_line":"    merely the glue between them."},{"line_number":80,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rrE%3D","line":77,"updated":"2014-04-02 20:52:01.000000000","message":"s/pxe.PXE/agent_deploy/AgentDeploy/","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"77171d0fb1ca3b965b7d42b987152de3587c2bdc","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        self.power \u003d ssh.SSHPower()"},{"line_number":82,"context_line":"        self.deploy \u003d agent.AgentDeploy()"},{"line_number":83,"context_line":"        self.vendor \u003d agent.AgentVendorInterface()"},{"line_number":84,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor}"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAW3%2F%2FmaE%3D","line":84,"updated":"2014-04-11 21:02:57.000000000","message":"AttributeError: \u0027AgentAndSSHDriver\u0027 object has no attribute \u0027agent_vendor\u0027\n\n:)","commit_id":"dabf57af2a10f95fd7d644a05a87bf9ec3473bde"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":24,"context_line":"    \"\"\"Agent + IPMITool driver."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    This driver implements the `core` functionality, combining"},{"line_number":27,"context_line":"    :class:`ironic.drivers.ipmitool.IPMIPower` for power on/off and reboot with"},{"line_number":28,"context_line":"    :class:`ironic.driver.agent_deploy.AgentDeploy` for image deployment."},{"line_number":29,"context_line":"    Implementations are in those respective classes; this class is merely the"},{"line_number":30,"context_line":"    glue between them."}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6fg%3D","line":27,"updated":"2014-04-16 15:00:25.000000000","message":"ironic.drivers.ipmitool.IPMIPower -\u003e ironic.drivers.modules.ipmitool.IPMIPower","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3b71a99388636b9fd2cf52ef6df290715f7743df","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    This driver implements the `core` functionality, combining"},{"line_number":27,"context_line":"    :class:`ironic.drivers.ipmitool.IPMIPower` for power on/off and reboot with"},{"line_number":28,"context_line":"    :class:`ironic.driver.agent_deploy.AgentDeploy` for image deployment."},{"line_number":29,"context_line":"    Implementations are in those respective classes; this class is merely the"},{"line_number":30,"context_line":"    glue between them."},{"line_number":31,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F63g%3D","line":28,"updated":"2014-04-16 14:20:59.000000000","message":"ironic.driver.agent_deploy -\u003e ironic.drivers.agent_deploy","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    This driver implements the `core` functionality, combining"},{"line_number":27,"context_line":"    :class:`ironic.drivers.ipmitool.IPMIPower` for power on/off and reboot with"},{"line_number":28,"context_line":"    :class:`ironic.driver.agent_deploy.AgentDeploy` for image deployment."},{"line_number":29,"context_line":"    Implementations are in those respective classes; this class is merely the"},{"line_number":30,"context_line":"    glue between them."},{"line_number":31,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6eM%3D","line":28,"in_reply_to":"AAAAXH%2F%2F63g%3D","updated":"2014-04-16 15:00:25.000000000","message":"ironic.drivers.modules.agent.AgentDeploy even","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    \"\"\"Agent + IPMINative driver."},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    This driver implements the `core` functionality, combining"},{"line_number":49,"context_line":"    :class:`ironic.drivers.ipminative.NativeIPMIPower` for power on/off and"},{"line_number":50,"context_line":"    reboot with"},{"line_number":51,"context_line":"    :class:`ironic.driver.agent_deploy.AgentDeploy` for image deployment."},{"line_number":52,"context_line":"    Implementations are in those respective classes; this class is merely the"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6c8%3D","line":49,"updated":"2014-04-16 15:00:25.000000000","message":"ironic.drivers.ipminative.NativeIPMIPower -\u003e ironic.drivers.modules.ipminative.NativeIPMIPower","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    This driver implements the `core` functionality, combining"},{"line_number":49,"context_line":"    :class:`ironic.drivers.ipminative.NativeIPMIPower` for power on/off and"},{"line_number":50,"context_line":"    reboot with"},{"line_number":51,"context_line":"    :class:`ironic.driver.agent_deploy.AgentDeploy` for image deployment."},{"line_number":52,"context_line":"    Implementations are in those respective classes; this class is merely the"},{"line_number":53,"context_line":"    glue between them."},{"line_number":54,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6cM%3D","line":51,"updated":"2014-04-16 15:00:25.000000000","message":"ironic.driver.agent_deploy.AgentDeploy -\u003e ironic.drivers.modules.agent.AgentDeploy","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    NOTE: This driver is meant only for testing environments."},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    This driver implements the `core` functionality, combining"},{"line_number":74,"context_line":"    :class:`ironic.drivers.ssh.SSH` for power on/off and reboot of virtual"},{"line_number":75,"context_line":"    machines tunneled over SSH, with :class:`ironic.driver.modules"},{"line_number":76,"context_line":"    .agent_driver.AgentDeploy` for image deployment. Implementations are in"},{"line_number":77,"context_line":"    those respective classes; this class is merely the glue between them."}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6bg%3D","line":74,"updated":"2014-04-16 15:00:25.000000000","message":"ironic.drivers.ssh.SSH -\u003e ironic.drivers.modules.ssh.SSHPower","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    This driver implements the `core` functionality, combining"},{"line_number":74,"context_line":"    :class:`ironic.drivers.ssh.SSH` for power on/off and reboot of virtual"},{"line_number":75,"context_line":"    machines tunneled over SSH, with :class:`ironic.driver.modules"},{"line_number":76,"context_line":"    .agent_driver.AgentDeploy` for image deployment. Implementations are in"},{"line_number":77,"context_line":"    those respective classes; this class is merely the glue between them."},{"line_number":78,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6a4%3D","line":75,"updated":"2014-04-16 15:00:25.000000000","message":"ironic.driver.modules.agent_driver.AgentDeploy -\u003e  ironic.drivers.modules.agent.AgentDeploy","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87229961f41546b0aa33fc09f51035cf5ef5bb89","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        #TODO(JoshNang) add lookup: nodeless passthru mapping when its added"},{"line_number":40,"context_line":"        #to utils.MixinVendorInterface"},{"line_number":41,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor,"},{"line_number":42,"context_line":"                        \u0027set_boot_device\u0027: self.ipmi_vendor}"},{"line_number":43,"context_line":"        self.vendor \u003d utils.MixinVendorInterface(self.mapping)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2Fznk%3D","line":42,"updated":"2014-04-17 10:12:06.000000000","message":"Could you rebase this patch on top of https://review.openstack.org/#/c/86588/ and use management interface instead of vendor for set_boot_device?","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ff2964b2c6016f2963512048f49ad6d9552b5ca5","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        #TODO(JoshNang) add lookup: nodeless passthru mapping when its added"},{"line_number":40,"context_line":"        #to utils.MixinVendorInterface"},{"line_number":41,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor,"},{"line_number":42,"context_line":"                        \u0027set_boot_device\u0027: self.ipmi_vendor}"},{"line_number":43,"context_line":"        self.vendor \u003d utils.MixinVendorInterface(self.mapping)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2FwgY%3D","line":42,"in_reply_to":"AAAAXH%2F%2Fznk%3D","updated":"2014-04-17 20:37:36.000000000","message":"The dependency tree is a bit wonky already for this patch. It depends on nodeless vendor passthru, swift, some things that were already merged, and now this. I\u0027ll need to rebase over it (and the others) before merge would be successful.","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87229961f41546b0aa33fc09f51035cf5ef5bb89","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        #TODO(JoshNang) add lookup: nodeless passthru mapping when its added"},{"line_number":64,"context_line":"        #to utils.MixinVendorInterface"},{"line_number":65,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor,"},{"line_number":66,"context_line":"                        \u0027set_boot_device\u0027: self.ipmi_vendor}"},{"line_number":67,"context_line":"        self.vendor \u003d utils.MixinVendorInterface(self.mapping)"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2FznY%3D","line":66,"updated":"2014-04-17 10:12:06.000000000","message":"ditto","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87229961f41546b0aa33fc09f51035cf5ef5bb89","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        self.power \u003d ssh.SSHPower()"},{"line_number":85,"context_line":"        self.deploy \u003d agent.AgentDeploy()"},{"line_number":86,"context_line":"        self.agent_vendor \u003d agent.AgentVendorInterface()"},{"line_number":87,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor}"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2FzoI%3D","line":87,"updated":"2014-04-17 10:12:06.000000000","message":"Don\u0027t we need self.vendor \u003d utils.MixinVendorInterface(self.mapping) here?","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4e4e1e1766dbca45a0f0e11aeb054545463f91dc","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        self.power \u003d ssh.SSHPower()"},{"line_number":85,"context_line":"        self.deploy \u003d agent.AgentDeploy()"},{"line_number":86,"context_line":"        self.agent_vendor \u003d agent.AgentVendorInterface()"},{"line_number":87,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor}"},{"line_number":88,"context_line":"        self.vendor \u003d utils.MixinVendorInterface(self.mapping)"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAAXH%2F%2Fuhk%3D","line":87,"updated":"2014-04-17 22:08:53.000000000","message":"Does SSHPower() have a set_boot_device method?","commit_id":"ea3997ee82f8bf9c2ef4a42e85507a59eea34a75"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"308f105a4699c2875c386642f139e6c18ec935de","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        self.power \u003d ssh.SSHPower()"},{"line_number":85,"context_line":"        self.deploy \u003d agent.AgentDeploy()"},{"line_number":86,"context_line":"        self.agent_vendor \u003d agent.AgentVendorInterface()"},{"line_number":87,"context_line":"        self.mapping \u003d {\u0027heartbeat\u0027: self.agent_vendor}"},{"line_number":88,"context_line":"        self.vendor \u003d utils.MixinVendorInterface(self.mapping)"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAAXH%2F%2FuKk%3D","line":87,"in_reply_to":"AAAAXH%2F%2Fuhk%3D","updated":"2014-04-17 22:27:39.000000000","message":"nope, but we\u0027ll need to add it.","commit_id":"ea3997ee82f8bf9c2ef4a42e85507a59eea34a75"}],"ironic/drivers/modules/agent.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"eb64c6b96d44b8bf5fa812f837603c603d61cbb3","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."},{"line_number":12,"context_line":"# See the License for the specific language governing permissions and"},{"line_number":13,"context_line":"# limitations under the License."},{"line_number":14,"context_line":"import time"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from oslo.config import cfg"},{"line_number":17,"context_line":"from sqlalchemy.orm import exc"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAWH%2F9rCQ%3D","line":14,"updated":"2014-04-02 22:09:03.000000000","message":"Super nitpicky, but if you push a new patch, can you put a new line between the license and this import?","commit_id":"f24defbcd5192e0175ae7bc1f98a34102face62f"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"83126975e278acac42fe484ebc28cc1505041278","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        :param node: a single Node to validate."},{"line_number":78,"context_line":"        :raises: InvalidParameterValue"},{"line_number":79,"context_line":"        \"\"\""},{"line_number":80,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":81,"context_line":"            raise exception.InvalidParameterValue(_(\u0027Nodes require an \u0027"},{"line_number":82,"context_line":"                                                    \u0027agent_url.\u0027))"},{"line_number":83,"context_line":"        if node.instance_info is not None:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F9n9Q%3D","line":80,"updated":"2014-04-03 09:33:48.000000000","message":"I think it\u0027s worth making it DRYer too. Adding it to other required fields list would be nice. Please see my comment for 84L","commit_id":"883ac40370cbaed9a8cebb9f812eb134475d0db8"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"83126975e278acac42fe484ebc28cc1505041278","unresolved":false,"context_lines":[{"line_number":80,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":81,"context_line":"            raise exception.InvalidParameterValue(_(\u0027Nodes require an \u0027"},{"line_number":82,"context_line":"                                                    \u0027agent_url.\u0027))"},{"line_number":83,"context_line":"        if node.instance_info is not None:"},{"line_number":84,"context_line":"            if \u0027image_info\u0027 not in node.instance_info:"},{"line_number":85,"context_line":"                raise exception.InvalidParameterValue(_(\u0027Nodes require \u0027"},{"line_number":86,"context_line":"                                                        \u0027image_info.\u0027))"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F9oKE%3D","line":83,"updated":"2014-04-03 09:33:48.000000000","message":"If there is \u0027agent_url\u0027 in node.instance_info, there is\u0027no reason for this check. Node.instance_info always be not None. Otherwise, the exception from 81L will be raised.","commit_id":"883ac40370cbaed9a8cebb9f812eb134475d0db8"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"83126975e278acac42fe484ebc28cc1505041278","unresolved":false,"context_lines":[{"line_number":81,"context_line":"            raise exception.InvalidParameterValue(_(\u0027Nodes require an \u0027"},{"line_number":82,"context_line":"                                                    \u0027agent_url.\u0027))"},{"line_number":83,"context_line":"        if node.instance_info is not None:"},{"line_number":84,"context_line":"            if \u0027image_info\u0027 not in node.instance_info:"},{"line_number":85,"context_line":"                raise exception.InvalidParameterValue(_(\u0027Nodes require \u0027"},{"line_number":86,"context_line":"                                                        \u0027image_info.\u0027))"},{"line_number":87,"context_line":"            if \u0027metadata\u0027 not in node.instance_info:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F9oLA%3D","line":84,"updated":"2014-04-03 09:33:48.000000000","message":"Let\u0027s keep in DRYer. E.g.\n\nfor field in [\"image_info\", \"metadata\", \"files\"]:\n    if field not in node.instance_info:\n        raise exception.InvalidParameterValue(_(\u0027%(field) in instance_info required for deploy\u0027))","commit_id":"883ac40370cbaed9a8cebb9f812eb134475d0db8"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":193,"context_line":"            \u0027lookup\u0027: self._heartbeat_no_uuid"},{"line_number":194,"context_line":"        }"},{"line_number":195,"context_line":"        self.db_connection \u003d dbapi.get_backend()"},{"line_number":196,"context_line":"        self.LOG \u003d log.getLogger(__name__)"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    def validate(self, task, node, method, *args, **kwargs):"},{"line_number":199,"context_line":"        \"\"\"Validate the driver-specific Node deployment info."}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9j2A%3D","line":196,"updated":"2014-04-03 17:48:05.000000000","message":"LOG should be module-level, not instance-level","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        :param node: a single Node to validate."},{"line_number":206,"context_line":"        :raises: InvalidParameterValue"},{"line_number":207,"context_line":"        \"\"\""},{"line_number":208,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info and method \u003d\u003d \u0027deploy\u0027:"},{"line_number":209,"context_line":"            raise exception.InvalidParameterValue(_(\u0027agent_url is required to\u0027"},{"line_number":210,"context_line":"                                                    \u0027 talk to the agent\u0027))"},{"line_number":211,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9j1Q%3D","line":208,"updated":"2014-04-03 17:48:05.000000000","message":"deploy is a core interface, and not defined in either vendor_routes or driver_routes.\n\nWhy are you checking for a call to /v1/nodes/XXX/vendor_passthru?method\u003ddeploy ?","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":320,"context_line":"        \"\"\"Given a list of MAC addresses, find the ports that match the MACs"},{"line_number":321,"context_line":"        and return the node they are all connected to."},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"        raises NotFound if the ports point to multiple nodes or no"},{"line_number":324,"context_line":"        nodes."},{"line_number":325,"context_line":"        \"\"\""},{"line_number":326,"context_line":"        ports \u003d self._find_ports_by_macs(mac_addresses)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9jy0%3D","line":323,"updated":"2014-04-03 17:48:05.000000000","message":"formatting issue here\n\n  :raises: NotFound if the ports ...","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":324,"context_line":"        nodes."},{"line_number":325,"context_line":"        \"\"\""},{"line_number":326,"context_line":"        ports \u003d self._find_ports_by_macs(mac_addresses)"},{"line_number":327,"context_line":"        node_id \u003d self._get_node_id(ports)"},{"line_number":328,"context_line":"        try:"},{"line_number":329,"context_line":"            node_object \u003d node.Node.get_by_uuid(context, node_id)"},{"line_number":330,"context_line":"        except exc.NoResultFound:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9jzE%3D","line":327,"updated":"2014-04-03 17:48:05.000000000","message":"I would insert this line:\n\n  ports \u003d self._find_ports_by_mac(mac_addresses)\n  if not ports:\n    raise NodeNotFound(..)\n  node_id \u003d self._get_node_id(ports)\n\nand have every exception converted into a NodeNotFound. After all, this method is specifically searching for a node, and if it fails to find one, that\u0027s what it should raise.","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        except exc.NoResultFound:"},{"line_number":331,"context_line":"            self.LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":332,"context_line":"                                 \u0027provided MACs.\u0027))"},{"line_number":333,"context_line":"            raise exception.NotFound(_(\u0027Could not find matching node for the \u0027"},{"line_number":334,"context_line":"                                       \u0027provided MACs.\u0027))"},{"line_number":335,"context_line":"        return node_object"},{"line_number":336,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9j0c%3D","line":333,"updated":"2014-04-03 17:48:05.000000000","message":"There is a more specific NodeNotFound exception that could be used here.","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        \"\"\"Given a list of MAC addresses, find the ports that match the MACs"},{"line_number":339,"context_line":"        and return them as a list of Port objects."},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"        raises NotFound if the no matching ports are found."},{"line_number":342,"context_line":"        \"\"\""},{"line_number":343,"context_line":"        ports \u003d []"},{"line_number":344,"context_line":"        for mac in mac_addresses:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9jyw%3D","line":341,"updated":"2014-04-03 17:48:05.000000000","message":"ditto","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":354,"context_line":"                                   \u0027database\u0027) % mac)"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"        if not ports:"},{"line_number":357,"context_line":"            raise exception.NotFound(_(\u0027None of the provided MAC addresses \u0027"},{"line_number":358,"context_line":"                                       \u0027match a port.\u0027))"},{"line_number":359,"context_line":"        return ports"},{"line_number":360,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9j0E%3D","line":357,"updated":"2014-04-03 17:48:05.000000000","message":"I would simply return an empty set here. No need to raise.","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":366,"context_line":"        # See if all the ports point to the same node"},{"line_number":367,"context_line":"        node_ids \u003d set(port.node_id for port in ports)"},{"line_number":368,"context_line":"        if len(node_ids) \u003d\u003d 0:"},{"line_number":369,"context_line":"            raise exception.NotFound(_(\u0027No MAC addresses given match an \u0027"},{"line_number":370,"context_line":"                                       \u0027existing node.\u0027))"},{"line_number":371,"context_line":"        if len(node_ids) \u003e 1:"},{"line_number":372,"context_line":"            raise exception.NotFound(_(\u0027Ports matching mac addresses \u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9jzc%3D","line":369,"updated":"2014-04-03 17:48:05.000000000","message":"Again, I would use NodeNotFound here.","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"053173ac9e4d68c9bfbfed67cee1ddadd0d92d49","unresolved":false,"context_lines":[{"line_number":369,"context_line":"            raise exception.NotFound(_(\u0027No MAC addresses given match an \u0027"},{"line_number":370,"context_line":"                                       \u0027existing node.\u0027))"},{"line_number":371,"context_line":"        if len(node_ids) \u003e 1:"},{"line_number":372,"context_line":"            raise exception.NotFound(_(\u0027Ports matching mac addresses \u0027"},{"line_number":373,"context_line":"                                       \u0027match multiple nodes.\u0027))"},{"line_number":374,"context_line":"        # There is only one item left in the set. Pop and return it."},{"line_number":375,"context_line":"        return node_ids.pop()"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9jzs%3D","line":372,"updated":"2014-04-03 17:48:05.000000000","message":"That\u0027s misleading. And indicates a serious error, since ironic.ports.address is a UNIQUE field in the database....","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0cbf6ed1859b3eefce616782471d46c89dadebb6","unresolved":false,"context_lines":[{"line_number":369,"context_line":"            raise exception.NotFound(_(\u0027No MAC addresses given match an \u0027"},{"line_number":370,"context_line":"                                       \u0027existing node.\u0027))"},{"line_number":371,"context_line":"        if len(node_ids) \u003e 1:"},{"line_number":372,"context_line":"            raise exception.NotFound(_(\u0027Ports matching mac addresses \u0027"},{"line_number":373,"context_line":"                                       \u0027match multiple nodes.\u0027))"},{"line_number":374,"context_line":"        # There is only one item left in the set. Pop and return it."},{"line_number":375,"context_line":"        return node_ids.pop()"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9jTM%3D","line":372,"in_reply_to":"AAAAWH%2F9jzs%3D","updated":"2014-04-03 18:58:32.000000000","message":"node_ids would be a list of nodes that those ports are attached to. This would only happen if the agent sends back 2+ MAC addresses and the matching ports pointed to different nodes in the database. e.g. if you took a NIC out of one machine and put it in another and didn\u0027t notify Ironic of the switch. It\u0027s an unlikely scenario, sure, but possible.","commit_id":"16775262b7ea277ec31430455a5bc33a0dcf2ce7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from ironic.common import states"},{"line_number":23,"context_line":"from ironic.common import utils"},{"line_number":24,"context_line":"from ironic.conductor import utils as manager_utils"},{"line_number":25,"context_line":"from ironic.db.sqlalchemy import api as dbapi"},{"line_number":26,"context_line":"from ironic.drivers import base"},{"line_number":27,"context_line":"from ironic.drivers.modules import agent_client"},{"line_number":28,"context_line":"from ironic.objects import node"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7gQ%3D","line":25,"updated":"2014-04-08 13:52:15.000000000","message":"There is \"public\" db api module ironic.db.api","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from ironic.common import states"},{"line_number":23,"context_line":"from ironic.common import utils"},{"line_number":24,"context_line":"from ironic.conductor import utils as manager_utils"},{"line_number":25,"context_line":"from ironic.db.sqlalchemy import api as dbapi"},{"line_number":26,"context_line":"from ironic.drivers import base"},{"line_number":27,"context_line":"from ironic.drivers.modules import agent_client"},{"line_number":28,"context_line":"from ironic.objects import node"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F4wM%3D","line":25,"in_reply_to":"AAAAWn%2F%2F7gQ%3D","updated":"2014-04-08 20:07:38.000000000","message":"Done","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":195,"context_line":"        self.driver_routes \u003d {"},{"line_number":196,"context_line":"            \u0027lookup\u0027: self._heartbeat_no_uuid"},{"line_number":197,"context_line":"        }"},{"line_number":198,"context_line":"        self.db_connection \u003d dbapi.get_backend()"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    def validate(self, task, node, method, *args, **kwargs):"},{"line_number":201,"context_line":"        \"\"\"Validate the driver-specific Node deployment info."}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7e4%3D","line":198,"updated":"2014-04-08 13:52:15.000000000","message":"Instance of task manager contains \u0027\"dbapi\" attribute, should use task.dbapi.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":195,"context_line":"        self.driver_routes \u003d {"},{"line_number":196,"context_line":"            \u0027lookup\u0027: self._heartbeat_no_uuid"},{"line_number":197,"context_line":"        }"},{"line_number":198,"context_line":"        self.db_connection \u003d dbapi.get_backend()"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"    def validate(self, task, node, method, *args, **kwargs):"},{"line_number":201,"context_line":"        \"\"\"Validate the driver-specific Node deployment info."}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F4wQ%3D","line":198,"in_reply_to":"AAAAWn%2F%2F7e4%3D","updated":"2014-04-08 20:07:38.000000000","message":"Done","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        :param node: a single Node to validate."},{"line_number":208,"context_line":"        :raises: InvalidParameterValue"},{"line_number":209,"context_line":"        \"\"\""},{"line_number":210,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":211,"context_line":"            raise exception.InvalidParameterValue(_(\u0027agent_url is required to\u0027"},{"line_number":212,"context_line":"                                                    \u0027 talk to the agent\u0027))"},{"line_number":213,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7Tk%3D","line":210,"updated":"2014-04-08 13:52:15.000000000","message":"This method called by manager before vendor_passthru, looks like we should check kwargs instead of node.instance_info.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        :param node: a single Node to validate."},{"line_number":208,"context_line":"        :raises: InvalidParameterValue"},{"line_number":209,"context_line":"        \"\"\""},{"line_number":210,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":211,"context_line":"            raise exception.InvalidParameterValue(_(\u0027agent_url is required to\u0027"},{"line_number":212,"context_line":"                                                    \u0027 talk to the agent\u0027))"},{"line_number":213,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F4wU%3D","line":210,"in_reply_to":"AAAAWn%2F%2F7Tk%3D","updated":"2014-04-08 20:07:38.000000000","message":"Done","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":216,"context_line":"        Given method, route the command to the appropriate private function."},{"line_number":217,"context_line":"        \"\"\""},{"line_number":218,"context_line":"        if method not in self.driver_routes:"},{"line_number":219,"context_line":"            raise exception.InvalidParameterValue(_(\u0027No handler for method %s\u0027)"},{"line_number":220,"context_line":"                                                  % method)"},{"line_number":221,"context_line":"        func \u003d self.driver_routes[method]"},{"line_number":222,"context_line":"        return func(task, **kwargs)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7RI%3D","line":219,"updated":"2014-04-08 13:52:15.000000000","message":"Better move to validate.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":216,"context_line":"        Given method, route the command to the appropriate private function."},{"line_number":217,"context_line":"        \"\"\""},{"line_number":218,"context_line":"        if method not in self.driver_routes:"},{"line_number":219,"context_line":"            raise exception.InvalidParameterValue(_(\u0027No handler for method %s\u0027)"},{"line_number":220,"context_line":"                                                  % method)"},{"line_number":221,"context_line":"        func \u003d self.driver_routes[method]"},{"line_number":222,"context_line":"        return func(task, **kwargs)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F49g%3D","line":219,"in_reply_to":"AAAAWn%2F%2F7RI%3D","updated":"2014-04-08 20:07:38.000000000","message":"Unfortunately, since we have a split vendor_passthru (the normal passthru for an agent that knows its UUID) and driver_vendor_passthru (not an approved patch yet, but for UUID-less agents), validate doesn\u0027t know which way its getting called, and there are separate routes for each call.\n\nThis is likely getting reworked one way or another, so hopefully we can have unified routes and validation.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        \"\"\""},{"line_number":229,"context_line":"        method \u003d kwargs[\u0027method\u0027]  # Existence checked in mixin"},{"line_number":230,"context_line":"        if method not in self.vendor_routes:"},{"line_number":231,"context_line":"            raise exception.InvalidParameterValue(_(\u0027No handler for method \u0027"},{"line_number":232,"context_line":"                                                    \u0027%s\u0027) % method)"},{"line_number":233,"context_line":"        func \u003d self.vendor_routes[method]"},{"line_number":234,"context_line":"        return func(task, node, **kwargs)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7Qs%3D","line":231,"updated":"2014-04-08 13:52:15.000000000","message":"Ditto l219.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            raise exception.InvalidParameterValue(_(\u0027\"agent_url\" is a required\u0027"},{"line_number":248,"context_line":"                                                    \u0027 parameter\u0027))"},{"line_number":249,"context_line":"        instance_info \u003d node.instance_info"},{"line_number":250,"context_line":"        instance_info[\u0027last_heartbeat\u0027] \u003d int(_time())"},{"line_number":251,"context_line":"        instance_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":252,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":253,"context_line":"        node.save(task.context)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7OI%3D","line":250,"updated":"2014-04-08 13:52:15.000000000","message":"\u0027agent_last_heartbeat\u0027 IMO better.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            raise exception.InvalidParameterValue(_(\u0027\"agent_url\" is a required\u0027"},{"line_number":248,"context_line":"                                                    \u0027 parameter\u0027))"},{"line_number":249,"context_line":"        instance_info \u003d node.instance_info"},{"line_number":250,"context_line":"        instance_info[\u0027last_heartbeat\u0027] \u003d int(_time())"},{"line_number":251,"context_line":"        instance_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":252,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":253,"context_line":"        node.save(task.context)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F49M%3D","line":250,"in_reply_to":"AAAAWn%2F%2F7OI%3D","updated":"2014-04-08 20:07:38.000000000","message":"Done","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        instance_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":252,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":253,"context_line":"        node.save(task.context)"},{"line_number":254,"context_line":"        return node"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"    def _heartbeat_no_uuid(self, context, **kwargs):"},{"line_number":257,"context_line":"        \"\"\"Method to be called the first time a ramdisk agent checks in. This"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7G4%3D","line":254,"updated":"2014-04-08 13:52:15.000000000","message":"Currently driver\u0027s vendor_passthru run from manager in the background and returns nothing.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        instance_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":252,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":253,"context_line":"        node.save(task.context)"},{"line_number":254,"context_line":"        return node"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"    def _heartbeat_no_uuid(self, context, **kwargs):"},{"line_number":257,"context_line":"        \"\"\"Method to be called the first time a ramdisk agent checks in. This"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F48w%3D","line":254,"in_reply_to":"AAAAWn%2F%2F7G4%3D","updated":"2014-04-08 20:07:38.000000000","message":"Done","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        node_object \u003d self._find_node_by_macs(context, mac_addresses)"},{"line_number":313,"context_line":"        return {"},{"line_number":314,"context_line":"            \u0027heartbeat_timeout\u0027: CONF.agent_driver.heartbeat_timeout,"},{"line_number":315,"context_line":"            \u0027node\u0027: node_object"},{"line_number":316,"context_line":"        }"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    def _find_node_by_macs(self, context, mac_addresses):"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F7GA%3D","line":315,"updated":"2014-04-08 13:52:15.000000000","message":"Ditto as 254.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        node_object \u003d self._find_node_by_macs(context, mac_addresses)"},{"line_number":313,"context_line":"        return {"},{"line_number":314,"context_line":"            \u0027heartbeat_timeout\u0027: CONF.agent_driver.heartbeat_timeout,"},{"line_number":315,"context_line":"            \u0027node\u0027: node_object"},{"line_number":316,"context_line":"        }"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    def _find_node_by_macs(self, context, mac_addresses):"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F48I%3D","line":315,"in_reply_to":"AAAAWn%2F%2F7GA%3D","updated":"2014-04-08 20:07:38.000000000","message":"With the driver_vendor_passthru, we do return something because we need to tell the agent what its UUID is. That\u0027s the main reason for the patch.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"26307174cfd3a0e202bc662eccc95cedab20a7ce","unresolved":false,"context_lines":[{"line_number":329,"context_line":"        node_id \u003d self._get_node_id(ports)"},{"line_number":330,"context_line":"        try:"},{"line_number":331,"context_line":"            node_object \u003d node.Node.get_by_uuid(context, node_id)"},{"line_number":332,"context_line":"        except exc.NoResultFound:"},{"line_number":333,"context_line":"            LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":334,"context_line":"                            \u0027provided MACs.\u0027))"},{"line_number":335,"context_line":"            raise exception.NodeNotFound(_(\u0027Could not find matching node for \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F68M%3D","line":332,"updated":"2014-04-08 13:52:15.000000000","message":"exception.NodeNotFound should be here.","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"5d7bdf3e86f6b4536399822901d7fe92094d5e99","unresolved":false,"context_lines":[{"line_number":329,"context_line":"        node_id \u003d self._get_node_id(ports)"},{"line_number":330,"context_line":"        try:"},{"line_number":331,"context_line":"            node_object \u003d node.Node.get_by_uuid(context, node_id)"},{"line_number":332,"context_line":"        except exc.NoResultFound:"},{"line_number":333,"context_line":"            LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":334,"context_line":"                            \u0027provided MACs.\u0027))"},{"line_number":335,"context_line":"            raise exception.NodeNotFound(_(\u0027Could not find matching node for \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWn%2F%2F458%3D","line":332,"in_reply_to":"AAAAWn%2F%2F68M%3D","updated":"2014-04-08 20:07:38.000000000","message":"Done","commit_id":"75212745079583336ea77eeb3583d78f68ed0266"},{"author":{"_account_id":1726,"name":"Ghe Rivero","email":"ghe.rivero@gmail.com","username":"ghe.rivero"},"change_message_id":"8f2f6b676e8ae21f92e5461d813718efc4184e8b","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"def _time():"},{"line_number":59,"context_line":"    return time.time()"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"class AgentDeploy(base.DeployInterface):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAW3%2F%2F9n0%3D","line":59,"updated":"2014-04-09 08:21:11.000000000","message":"timeutils.utcnow() to deal with timezones","commit_id":"3779678985339c185e721dc5720b83d18cb401ec"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"ed212ad7c19a93ffafc64d45606b9845da5964ab","unresolved":false,"context_lines":[{"line_number":51,"context_line":"]"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"CONF \u003d cfg.CONF"},{"line_number":54,"context_line":"CONF.register_opts(agent_driver_opts, group\u003d\u0027agent_driver\u0027)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAW3%2F%2FUe8%3D","line":54,"updated":"2014-04-15 12:32:44.000000000","message":"I think group\u003d\u0027agent\u0027 better for consistency with another drivers.","commit_id":"8df74f85b4d93994b4cedc4428f6a52630cf8d9d"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        This method validates whether the \u0027instance_info\u0027 property of the"},{"line_number":74,"context_line":"        supplied node contains the required information for this driver to"},{"line_number":75,"context_line":"        deploy images to the node."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        :param node: a single Node to validate."},{"line_number":78,"context_line":"        :raises: InvalidParameterValue"},{"line_number":79,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6Yk%3D","line":76,"updated":"2014-04-16 15:00:25.000000000","message":"nit: forgotten\n\n:param task: a TaskManager instance.\n\nshould be right here","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"99d553443dd921a80990bb5fbddb2af188bc08be","unresolved":false,"context_lines":[{"line_number":203,"context_line":"        supplied node contains the required information for this driver to"},{"line_number":204,"context_line":"        deploy images to the node."},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        :param node: a single Node to validate."},{"line_number":207,"context_line":"        :raises: InvalidParameterValue"},{"line_number":208,"context_line":"        \"\"\""},{"line_number":209,"context_line":"        if \u0027agent_url\u0027 not in kwargs:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6W4%3D","line":206,"updated":"2014-04-16 15:00:25.000000000","message":"missed doc-stings for other than `node` params.","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3b71a99388636b9fd2cf52ef6df290715f7743df","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        \"\"\"Given a list of MAC addresses, find the ports that match the MACs"},{"line_number":336,"context_line":"        and return them as a list of Port objects."},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"        :raises: NotFound if the no matching ports are found."},{"line_number":339,"context_line":"        \"\"\""},{"line_number":340,"context_line":"        ports \u003d []"},{"line_number":341,"context_line":"        for mac in mac_addresses:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F614%3D","line":338,"updated":"2014-04-16 14:20:59.000000000","message":"That does not seem to be true - empty list is returned. It is _find_node_by_macs that raises NotFound now, nut I think it actually belongs here, just as the doctring states.","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3b71a99388636b9fd2cf52ef6df290715f7743df","unresolved":false,"context_lines":[{"line_number":367,"context_line":"        node_ids \u003d set(port.node_id for port in ports)"},{"line_number":368,"context_line":"        if len(node_ids) \u003e 1:"},{"line_number":369,"context_line":"            raise exception.NodeNotFound(_(\u0027Ports matching mac addresses \u0027"},{"line_number":370,"context_line":"                                           \u0027match multiple nodes.\u0027))"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":"        # Only have one node_id left, return it."},{"line_number":373,"context_line":"        return node_ids.pop()"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6tA%3D","line":370,"updated":"2014-04-16 14:20:59.000000000","message":"Could you include offending MAC into error message? I think you can take it from ports[0].id or something","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87229961f41546b0aa33fc09f51035cf5ef5bb89","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        return client"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def validate(self, task, node):"},{"line_number":71,"context_line":"        \"\"\"Validate the driver-specific git Node deployment info."},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"        This method validates whether the \u0027instance_info\u0027 property of the"},{"line_number":74,"context_line":"        supplied node contains the required information for this driver to"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2FzmU%3D","line":71,"updated":"2014-04-17 10:12:06.000000000","message":"I am a bit confused, what does the word \"git\" means here?","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87229961f41546b0aa33fc09f51035cf5ef5bb89","unresolved":false,"context_lines":[{"line_number":332,"context_line":"            LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":333,"context_line":"                            \u0027provided MACs.\u0027))"},{"line_number":334,"context_line":"            raise exception.NodeNotFound(_(\u0027Could not find matching node for \u0027"},{"line_number":335,"context_line":"                                           \u0027the provided MACs.\u0027))"},{"line_number":336,"context_line":"        return node_object"},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"    def _find_ports_by_macs(self, context, mac_addresses):"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2FzkU%3D","line":335,"updated":"2014-04-17 10:12:06.000000000","message":"Please log the provided macs and add them to exception message. Btw, do we need both logging and raising? I expect exception to be logged somewhere above, no?","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ff2964b2c6016f2963512048f49ad6d9552b5ca5","unresolved":false,"context_lines":[{"line_number":332,"context_line":"            LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":333,"context_line":"                            \u0027provided MACs.\u0027))"},{"line_number":334,"context_line":"            raise exception.NodeNotFound(_(\u0027Could not find matching node for \u0027"},{"line_number":335,"context_line":"                                           \u0027the provided MACs.\u0027))"},{"line_number":336,"context_line":"        return node_object"},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"    def _find_ports_by_macs(self, context, mac_addresses):"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2FxHo%3D","line":335,"in_reply_to":"AAAAXH%2F%2FzkU%3D","updated":"2014-04-17 20:37:36.000000000","message":"It isn\u0027t currently, but I\u0027ll add it upstream and having the mapping already doesn\u0027t hurt anything.","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"87229961f41546b0aa33fc09f51035cf5ef5bb89","unresolved":false,"context_lines":[{"line_number":340,"context_line":"        and return them as a list of Port objects, or an empty list if there"},{"line_number":341,"context_line":"        are no matches"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"        :raises: PortNotFound if a MAC address is not registered in the Ports"},{"line_number":344,"context_line":"        table."},{"line_number":345,"context_line":"        \"\"\""},{"line_number":346,"context_line":"        ports \u003d []"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAAXH%2F%2Fzk8%3D","line":343,"updated":"2014-04-17 10:12:06.000000000","message":"Could you explain how this method raises PortNotFound? I see this exception silenced and logged, empty list returned instead, and NodeNotFound raised on _find_node_by_macs. Maybe just remove this from docstring?","commit_id":"022ff27b30c9cff9ef2a3af4c6c63204a12cc437"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4e4e1e1766dbca45a0f0e11aeb054545463f91dc","unresolved":false,"context_lines":[{"line_number":210,"context_line":"        :param method: the vendor method to be called after validate"},{"line_number":211,"context_line":"        :raises: InvalidParameterValue"},{"line_number":212,"context_line":"        \"\"\""},{"line_number":213,"context_line":"        if \u0027agent_url\u0027 not in kwargs:"},{"line_number":214,"context_line":"            raise exception.InvalidParameterValue(_(\u0027\"agent_url\" is a required\u0027"},{"line_number":215,"context_line":"                                                    \u0027 parameter\u0027))"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAAXH%2F%2Fucs%3D","line":213,"updated":"2014-04-17 22:08:53.000000000","message":"This shouldn\u0027t be in the vendor validate() method. This gets into the DB via the heartbeat method, but the heartbeat method runs this validate() function. So heartbeat will always fail if this is here.","commit_id":"ea3997ee82f8bf9c2ef4a42e85507a59eea34a75"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4e4e1e1766dbca45a0f0e11aeb054545463f91dc","unresolved":false,"context_lines":[{"line_number":287,"context_line":"        considered down. This will be in a root level key called"},{"line_number":288,"context_line":"        \u0027heartbeat_timeout\u0027"},{"line_number":289,"context_line":"        \"\"\""},{"line_number":290,"context_line":"        if \u0027hardware\u0027 not in kwargs or not kwargs[\u0027hardware\u0027]:"},{"line_number":291,"context_line":"            raise exception.InvalidParameterValue(_(\u0027\"hardware\" is a \u0027"},{"line_number":292,"context_line":"                                                    \u0027required parameter and \u0027"},{"line_number":293,"context_line":"                                                    \u0027must not be empty\u0027))"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAAXH%2F%2Fua0%3D","line":290,"updated":"2014-04-17 22:08:53.000000000","message":"Can be `if not kwargs.get(\u0027hardware\u0027)`","commit_id":"ea3997ee82f8bf9c2ef4a42e85507a59eea34a75"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4e4e1e1766dbca45a0f0e11aeb054545463f91dc","unresolved":false,"context_lines":[{"line_number":328,"context_line":"        node_id \u003d self._get_node_id(ports)"},{"line_number":329,"context_line":"        try:"},{"line_number":330,"context_line":"            node_object \u003d node.Node.get_by_uuid(context, node_id)"},{"line_number":331,"context_line":"        except exception.NodeNotFound:"},{"line_number":332,"context_line":"            LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":333,"context_line":"                            \u0027provided MACs %S.\u0027) % mac_addresses)"},{"line_number":334,"context_line":"            raise exception.NodeNotFound(_(\u0027Could not find matching node for \u0027"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAAXH%2F%2FuXE%3D","line":331,"updated":"2014-04-17 22:08:53.000000000","message":"Would be better to use `excutils.save_and_reraise_exception()` here.","commit_id":"ea3997ee82f8bf9c2ef4a42e85507a59eea34a75"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"ae5c9d76e2bfb16e9ba2341371b3c9f44b7c5878","unresolved":false,"context_lines":[{"line_number":327,"context_line":"        except exception.NodeNotFound:"},{"line_number":328,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":329,"context_line":"                LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":330,"context_line":"                                \u0027provided MACs %S.\u0027) % mac_addresses)"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"        return node_object"},{"line_number":333,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAXH%2F%2FrEE%3D","line":330,"updated":"2014-04-18 11:04:20.000000000","message":"Typo %S -\u003e %s?\nThat\u0027s why I generally prefer having tests for all exceptional paths.","commit_id":"dce331e38922cfb788a7be0d0f74b19776f3a5a4"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"8c0c90837bd620e7853f7d7d2fbf94a97530b30f","unresolved":false,"context_lines":[{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _save_hardware(self, context, node, hardware, version):"},{"line_number":453,"context_line":"        \"\"\"Flatten nested dict into namespace.\"\"\""},{"line_number":454,"context_line":"        node.extra \u003d {}"},{"line_number":455,"context_line":"        for hardware_type, hardware_list in hardware.values():"},{"line_number":456,"context_line":"            if isinstance(hardware_list, list):"},{"line_number":457,"context_line":"                for index, hardware_item in enumerate(hardware_list):"}],"source_content_type":"text/x-python","patch_set":37,"id":"AAAAXH%2F%2FC%2Fc%3D","line":454,"updated":"2014-04-24 12:01:37.000000000","message":"This drops any info in node.extra.","commit_id":"501b2633e2cf3ef64f2a9ea844f51941fb8e5e0d"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"96b0a335e6d3488b70d0cde5711448e907e219de","unresolved":false,"context_lines":[{"line_number":464,"context_line":"                        node.extra[key_template] \u003d v"},{"line_number":465,"context_line":"            elif isinstance(hardware_list, dict):"},{"line_number":466,"context_line":"                for k, v in hardware_list.items():"},{"line_number":467,"context_line":"                    key_template \u003d \"hardware{type}/{key}\" % \\"},{"line_number":468,"context_line":"                                   {\u0027type\u0027: hardware_type,"},{"line_number":469,"context_line":"                                    \u0027key\u0027: k}"},{"line_number":470,"context_line":"                    node.extra[key_template] \u003d v"}],"source_content_type":"text/x-python","patch_set":37,"id":"AAAAXH%2F%2FKx8%3D","line":467,"updated":"2014-04-24 09:39:53.000000000","message":"missed slash maybe? shouldn\u0027t be \"hardware/{type}/{key}\" ?","commit_id":"501b2633e2cf3ef64f2a9ea844f51941fb8e5e0d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3d924ec993da1d8fa8567337f497c70c4f6cf24a","unresolved":false,"context_lines":[{"line_number":366,"context_line":"                    \u0027interfaces\u0027 not in inventory[\u0027inventory\u0027]):"},{"line_number":367,"context_line":"                raise exception.InvalidParameterValue(_("},{"line_number":368,"context_line":"                    \u0027Malformed network interfaces lookup: %s\u0027) % inventory)"},{"line_number":369,"context_line":"            interfaces \u003d inventory[\u0027inventory\u0027][\u0027interfaces\u0027]"},{"line_number":370,"context_line":""},{"line_number":371,"context_line":"        return interfaces"},{"line_number":372,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"AAAAXX%2F%2F6Ok%3D","line":369,"updated":"2014-04-25 11:45:04.000000000","message":"You could use:\n\n try:\n   interfaces \u003d ...\n except KeyError:\n   raise exception.InvalidParameterValue ...\n\nto save you some dict look-ups. Not critical though :)","commit_id":"24df3bc6da80eac08b6994ca483c5b36b7db01d1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3d924ec993da1d8fa8567337f497c70c4f6cf24a","unresolved":false,"context_lines":[{"line_number":449,"context_line":"        # Only have one node_id left, return it."},{"line_number":450,"context_line":"        return node_ids.pop()"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _save_hardware(self, context, node, hardware, version):"},{"line_number":453,"context_line":"        \"\"\"Flatten nested dict into namespace.\"\"\""},{"line_number":454,"context_line":"        for hardware_type, hardware_list in hardware.values():"},{"line_number":455,"context_line":"            if isinstance(hardware_list, list):"}],"source_content_type":"text/x-python","patch_set":38,"id":"AAAAXX%2F%2F6Mc%3D","line":452,"updated":"2014-04-25 11:45:04.000000000","message":"Could you write docstring explaining structure of `hardware` argument please? It may become obvious when this method is actually used, but now requires diving into all these loops.","commit_id":"24df3bc6da80eac08b6994ca483c5b36b7db01d1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3d924ec993da1d8fa8567337f497c70c4f6cf24a","unresolved":false,"context_lines":[{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _save_hardware(self, context, node, hardware, version):"},{"line_number":453,"context_line":"        \"\"\"Flatten nested dict into namespace.\"\"\""},{"line_number":454,"context_line":"        for hardware_type, hardware_list in hardware.values():"},{"line_number":455,"context_line":"            if isinstance(hardware_list, list):"},{"line_number":456,"context_line":"                for index, hardware_item in enumerate(hardware_list):"},{"line_number":457,"context_line":"                    for k, v in hardware_item.items():"}],"source_content_type":"text/x-python","patch_set":38,"id":"AAAAXX%2F%2F6MI%3D","line":454,"updated":"2014-04-25 11:45:04.000000000","message":"Questions due to lack of knowledge about `hardware` structure: is it really values() or rather items() here?","commit_id":"24df3bc6da80eac08b6994ca483c5b36b7db01d1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f2afe11c2d9287ed214ab2c6194cea58819f75cc","unresolved":false,"context_lines":[{"line_number":455,"context_line":"        {\u0027hardware\u0027: {\u0027interfaces\u0027: [{\u0027mac_address\u0027: \u0027aa:bb:cc:dd:ee:ff\u0027}]}}"},{"line_number":456,"context_line":"        becomes {\u0027hardware/interfaces/0/mac_address\u0027: \u0027aa:bb:cc:dd:ee:ff\u0027}"},{"line_number":457,"context_line":"        in the database."},{"line_number":458,"context_line":"        \"\"\""},{"line_number":459,"context_line":"        for hardware_type, hardware_list in hardware.items():"},{"line_number":460,"context_line":"            if isinstance(hardware_list, list):"},{"line_number":461,"context_line":"                for index, hardware_item in enumerate(hardware_list):"}],"source_content_type":"text/x-python","patch_set":40,"id":"AAAAXX%2F%2Fvvg%3D","line":458,"updated":"2014-04-28 09:43:50.000000000","message":"Thank you, much better, but I think docstring is a bit confusing. You include \u0027hardware\u0027 key in the example, but this function seems to operator on it\u0027s value, i.e. \n\n {\u0027interfaces\u0027: [{\u0027mac_address\u0027: ...}]}  -\u003e {\u0027hardware/interfaces/0/mac_address\u0027: ...}\n\nnot\n\n {\u0027hardware\u0027: ...}  -\u003e {\u0027hardware/interfaces/0/mac_address\u0027: \u0027aa:bb:cc:dd:ee:ff\u0027}\n\nThat said, while we don\u0027t have this method actually \"plugged\" into real code path, I\u0027d like to see at least one test on it, to avoid future confusion.","commit_id":"845afb0595a2a5988ca5dc65717a2bfbb2622a86"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6c22acb469a61d3326dd27cc0e592036170b01ed","unresolved":false,"context_lines":[{"line_number":190,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":191,"context_line":"            # First heartbeat is required to continue with deploy."},{"line_number":192,"context_line":"            while not node.instance_info.get(\u0027agent_url\u0027):"},{"line_number":193,"context_line":"                time.sleep(5)"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"    def clean_up(self, task, node):"},{"line_number":196,"context_line":"        \"\"\"Clean up the deployment environment for this node."}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_cd406838","line":193,"updated":"2014-04-30 12:10:46.000000000","message":"Can we have some timeout here?","commit_id":"e9223e692ae7a594013f8c9551e4e05a5b2c20bd"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"f7309cbed2a1d5a44b8992e176124fc5a5a28cde","unresolved":false,"context_lines":[{"line_number":190,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":191,"context_line":"            # First heartbeat is required to continue with deploy."},{"line_number":192,"context_line":"            while not node.instance_info.get(\u0027agent_url\u0027):"},{"line_number":193,"context_line":"                time.sleep(5)"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"    def clean_up(self, task, node):"},{"line_number":196,"context_line":"        \"\"\"Clean up the deployment environment for this node."}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_bb634b19","line":193,"in_reply_to":"9ad9bd40_cd406838","updated":"2014-04-30 21:46:01.000000000","message":"Done","commit_id":"e9223e692ae7a594013f8c9551e4e05a5b2c20bd"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6c22acb469a61d3326dd27cc0e592036170b01ed","unresolved":false,"context_lines":[{"line_number":418,"context_line":"                    LOG.warning(_(\u0027Malformed MAC in hardware entry %s.\u0027)"},{"line_number":419,"context_line":"                                % interface)"},{"line_number":420,"context_line":"                interfaces.append({"},{"line_number":421,"context_line":"                    \u0027mac_address\u0027: interface.get(\u0027id\u0027)"},{"line_number":422,"context_line":"                })"},{"line_number":423,"context_line":"        elif version \u003d\u003d \u00272\u0027:"},{"line_number":424,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_91ccba37","line":421,"updated":"2014-04-30 12:10:46.000000000","message":"No point in setting None to \u0027mac_address\u0027 here - it will result in duplicate error message on line #442. Better just move append() call into `if` body.","commit_id":"e9223e692ae7a594013f8c9551e4e05a5b2c20bd"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"f7309cbed2a1d5a44b8992e176124fc5a5a28cde","unresolved":false,"context_lines":[{"line_number":418,"context_line":"                    LOG.warning(_(\u0027Malformed MAC in hardware entry %s.\u0027)"},{"line_number":419,"context_line":"                                % interface)"},{"line_number":420,"context_line":"                interfaces.append({"},{"line_number":421,"context_line":"                    \u0027mac_address\u0027: interface.get(\u0027id\u0027)"},{"line_number":422,"context_line":"                })"},{"line_number":423,"context_line":"        elif version \u003d\u003d \u00272\u0027:"},{"line_number":424,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_fb6dd305","line":421,"in_reply_to":"9ad9bd40_91ccba37","updated":"2014-04-30 21:46:01.000000000","message":"Done","commit_id":"e9223e692ae7a594013f8c9551e4e05a5b2c20bd"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6c22acb469a61d3326dd27cc0e592036170b01ed","unresolved":false,"context_lines":[{"line_number":441,"context_line":"            except exception.InvalidMAC:"},{"line_number":442,"context_line":"                LOG.warning(_(\u0027Malformed MAC: %s\u0027) % interface.get("},{"line_number":443,"context_line":"                    \u0027mac_address\u0027))"},{"line_number":444,"context_line":"                continue"},{"line_number":445,"context_line":"        return mac_addresses"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"    def _find_node_by_macs(self, context, mac_addresses):"}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_31204ef7","line":444,"updated":"2014-04-30 12:10:46.000000000","message":"`continue` is redundant","commit_id":"e9223e692ae7a594013f8c9551e4e05a5b2c20bd"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"f7309cbed2a1d5a44b8992e176124fc5a5a28cde","unresolved":false,"context_lines":[{"line_number":441,"context_line":"            except exception.InvalidMAC:"},{"line_number":442,"context_line":"                LOG.warning(_(\u0027Malformed MAC: %s\u0027) % interface.get("},{"line_number":443,"context_line":"                    \u0027mac_address\u0027))"},{"line_number":444,"context_line":"                continue"},{"line_number":445,"context_line":"        return mac_addresses"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"    def _find_node_by_macs(self, context, mac_addresses):"}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_3b773bd6","line":444,"in_reply_to":"9ad9bd40_31204ef7","updated":"2014-04-30 21:46:01.000000000","message":"Done","commit_id":"e9223e692ae7a594013f8c9551e4e05a5b2c20bd"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":60,"context_line":"               help\u003d\u0027Template file for PXE configuration.\u0027),"},{"line_number":61,"context_line":"    cfg.StrOpt(\u0027dhcp_provider\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027neutron\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027The service responsible for providing DHCP and TFTP to\u0027"},{"line_number":64,"context_line":"                    \u0027booting agents. If set the \"neutron\", it expects a \u0027"},{"line_number":65,"context_line":"                    \u0027TFTP server local to each conductor where TFTP configs\u0027"},{"line_number":66,"context_line":"                    \u0027can be written out. If set to \"external\", it expects\u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_c794ad39","line":63,"updated":"2014-05-01 08:32:35.000000000","message":"missing trailing space within the quotes on several lines, in many of these option messages.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":60,"context_line":"               help\u003d\u0027Template file for PXE configuration.\u0027),"},{"line_number":61,"context_line":"    cfg.StrOpt(\u0027dhcp_provider\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027neutron\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027The service responsible for providing DHCP and TFTP to\u0027"},{"line_number":64,"context_line":"                    \u0027booting agents. If set the \"neutron\", it expects a \u0027"},{"line_number":65,"context_line":"                    \u0027TFTP server local to each conductor where TFTP configs\u0027"},{"line_number":66,"context_line":"                    \u0027can be written out. If set to \"external\", it expects\u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_cc74c0ff","line":63,"in_reply_to":"9ad9bd40_c794ad39","updated":"2014-05-02 16:51:13.000000000","message":"Done","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":75,"context_line":"               help\u003d\u0027The path to the kernel image used to boot the agent.\u0027"},{"line_number":76,"context_line":"                    \u0027This will be put into the DHCP file if dhcp_provider\u0027"},{"line_number":77,"context_line":"                    \u0027is set to \"neutron\".\u0027),"},{"line_number":78,"context_line":"    cfg.StrOpt(\u0027agent_kernel_args\u0027,"},{"line_number":79,"context_line":"               help\u003d\u0027Addtitional kernel args that will be passed to the \u0027"},{"line_number":80,"context_line":"                    \u0027agent PXE config file. \u0027),"},{"line_number":81,"context_line":"    cfg.StrOpt(\u0027ironic_api_url\u0027,"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_a71249b2","line":78,"updated":"2014-05-01 08:32:35.000000000","message":"as a starting point, I\u0027d suggest using the same kernel args that the PXE driver uses -- unless you have a good reason for other args.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":75,"context_line":"               help\u003d\u0027The path to the kernel image used to boot the agent.\u0027"},{"line_number":76,"context_line":"                    \u0027This will be put into the DHCP file if dhcp_provider\u0027"},{"line_number":77,"context_line":"                    \u0027is set to \"neutron\".\u0027),"},{"line_number":78,"context_line":"    cfg.StrOpt(\u0027agent_kernel_args\u0027,"},{"line_number":79,"context_line":"               help\u003d\u0027Addtitional kernel args that will be passed to the \u0027"},{"line_number":80,"context_line":"                    \u0027agent PXE config file. \u0027),"},{"line_number":81,"context_line":"    cfg.StrOpt(\u0027ironic_api_url\u0027,"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_2ca0cc42","line":78,"in_reply_to":"9ad9bd40_a71249b2","updated":"2014-05-02 16:51:13.000000000","message":"Done","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        if node.instance_info is None:"},{"line_number":121,"context_line":"            raise exception.InvalidParameterValue(_(\u0027instance_info cannot be \u0027"},{"line_number":122,"context_line":"                                                    \u0027null.\u0027))"},{"line_number":123,"context_line":"        required_fields \u003d [\u0027agent_url\u0027, \u0027image_source\u0027, \u0027configdrive\u0027]"},{"line_number":124,"context_line":"        for field in required_fields:"},{"line_number":125,"context_line":"            if field not in node.instance_info:"},{"line_number":126,"context_line":"                raise exception.InvalidParameterValue(_(\u0027%s is required in \u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_073bf53a","line":123,"updated":"2014-05-01 08:32:35.000000000","message":"I think agent_url should be in driver_info ... the others look good. However, you\u0027ll need changes in nova.virt.ironic to pass them in.\n\nAlso note that Ruby has a change up for review that exposes the list of required fields to the API, so you\u0027ll want to incorporate that functionality at some point","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        if node.instance_info is None:"},{"line_number":121,"context_line":"            raise exception.InvalidParameterValue(_(\u0027instance_info cannot be \u0027"},{"line_number":122,"context_line":"                                                    \u0027null.\u0027))"},{"line_number":123,"context_line":"        required_fields \u003d [\u0027agent_url\u0027, \u0027image_source\u0027, \u0027configdrive\u0027]"},{"line_number":124,"context_line":"        for field in required_fields:"},{"line_number":125,"context_line":"            if field not in node.instance_info:"},{"line_number":126,"context_line":"                raise exception.InvalidParameterValue(_(\u0027%s is required in \u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_6c89f4c9","line":123,"in_reply_to":"9ad9bd40_073bf53a","updated":"2014-05-02 16:51:13.000000000","message":"I agree. Heh I think we had it in driver_info at one point.\n\nI\u0027ll keep an eye on Ruby\u0027s change.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        \"\"\""},{"line_number":142,"context_line":"        image_source \u003d node.instance_info.get(\u0027image_source\u0027)"},{"line_number":143,"context_line":"        configdrive \u003d node.instance_info.get(\u0027configdrive\u0027)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        # Get the swift temp url"},{"line_number":146,"context_line":"        glance \u003d image_service.Service(version\u003d2, context\u003dtask.context)"},{"line_number":147,"context_line":"        image_info \u003d glance.show(image_source)"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_67f2019c","line":144,"updated":"2014-05-01 08:32:35.000000000","message":"should turn the power on here. See my comment on L195","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        \"\"\""},{"line_number":142,"context_line":"        image_source \u003d node.instance_info.get(\u0027image_source\u0027)"},{"line_number":143,"context_line":"        configdrive \u003d node.instance_info.get(\u0027configdrive\u0027)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        # Get the swift temp url"},{"line_number":146,"context_line":"        glance \u003d image_service.Service(version\u003d2, context\u003dtask.context)"},{"line_number":147,"context_line":"        image_info \u003d glance.show(image_source)"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_cc7e80ae","line":144,"in_reply_to":"9ad9bd40_67f2019c","updated":"2014-05-02 16:51:13.000000000","message":"Done","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":156,"context_line":"        # TODO(jimrollenhagen) client.run_image(node)"},{"line_number":157,"context_line":"        manager_utils.node_set_boot_device(task, \u0027disk\u0027)"},{"line_number":158,"context_line":"        manager_utils.node_power_action(task, node, states.REBOOT)"},{"line_number":159,"context_line":"        # TODO(JoshNang) don\u0027t return until we have a totally working"},{"line_number":160,"context_line":"        # machine, so we\u0027ll need to do some kind of smoke testing here."},{"line_number":161,"context_line":"        return states.DEPLOYDONE"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_67c4c140","line":159,"updated":"2014-05-01 08:32:35.000000000","message":"current PXE-based drivers return once the node is powering-on into the user\u0027s environment -- for physical hardware, it is probably still doing POST.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":156,"context_line":"        # TODO(jimrollenhagen) client.run_image(node)"},{"line_number":157,"context_line":"        manager_utils.node_set_boot_device(task, \u0027disk\u0027)"},{"line_number":158,"context_line":"        manager_utils.node_power_action(task, node, states.REBOOT)"},{"line_number":159,"context_line":"        # TODO(JoshNang) don\u0027t return until we have a totally working"},{"line_number":160,"context_line":"        # machine, so we\u0027ll need to do some kind of smoke testing here."},{"line_number":161,"context_line":"        return states.DEPLOYDONE"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_ac585c57","line":159,"in_reply_to":"9ad9bd40_67c4c140","updated":"2014-05-02 16:51:13.000000000","message":"Done","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":181,"context_line":"        return states.DELETING"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    def prepare(self, task, node):"},{"line_number":184,"context_line":"        \"\"\"Prepare the deployment environment for this node."},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"        :param task: a TaskManager instance."},{"line_number":187,"context_line":"        :param node: the Node for which to prepare a deployment environment"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_27d1d9fb","line":184,"updated":"2014-05-01 08:32:35.000000000","message":"The intent with the hash-ring is that prepare may be called on multiple nodes in parallel, eg, to prepare their local environments ahead of the actual deploy // so that one can take over for another should it fail.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":181,"context_line":"        return states.DELETING"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    def prepare(self, task, node):"},{"line_number":184,"context_line":"        \"\"\"Prepare the deployment environment for this node."},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"        :param task: a TaskManager instance."},{"line_number":187,"context_line":"        :param node: the Node for which to prepare a deployment environment"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_8c5b9853","line":184,"in_reply_to":"9ad9bd40_27d1d9fb","updated":"2014-05-02 16:51:13.000000000","message":"Done","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":189,"context_line":"        \"\"\""},{"line_number":190,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":191,"context_line":"            LOG.info(\u0027Booting agent via neutron\u0027)"},{"line_number":192,"context_line":"            # Write out the TFTP file"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"            # Boot the box, wait for the first heartbeat, then deploy."},{"line_number":195,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_47cedd5b","line":192,"updated":"2014-05-01 08:32:35.000000000","message":"so, creating the necessary TFTP files within prepare is good","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":189,"context_line":"        \"\"\""},{"line_number":190,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":191,"context_line":"            LOG.info(\u0027Booting agent via neutron\u0027)"},{"line_number":192,"context_line":"            # Write out the TFTP file"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"            # Boot the box, wait for the first heartbeat, then deploy."},{"line_number":195,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_2c452c70","line":192,"in_reply_to":"9ad9bd40_47cedd5b","updated":"2014-05-02 16:51:13.000000000","message":"Done","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":192,"context_line":"            # Write out the TFTP file"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"            # Boot the box, wait for the first heartbeat, then deploy."},{"line_number":195,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"},{"line_number":196,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"            # First heartbeat is required to continue with deploy."}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_67dbe11b","line":195,"updated":"2014-05-01 08:32:35.000000000","message":"but issuing the actual POWER_ON command should be done within deploy()","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":192,"context_line":"            # Write out the TFTP file"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"            # Boot the box, wait for the first heartbeat, then deploy."},{"line_number":195,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"},{"line_number":196,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"            # First heartbeat is required to continue with deploy."}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_0c506831","line":195,"in_reply_to":"9ad9bd40_67dbe11b","updated":"2014-05-02 16:51:13.000000000","message":"Done","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":416,"context_line":"        pass"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"    def _pre_cache(self, task, node, **kwargs):"},{"line_number":419,"context_line":"        \"\"\"Using some predetermined metric, decide which image should be"},{"line_number":420,"context_line":"        pre-written to a certain node to make boot time speedier."},{"line_number":421,"context_line":"        \"\"\""},{"line_number":422,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_a7c7a911","line":419,"updated":"2014-05-01 08:32:35.000000000","message":"I see nothing wrong with the ability to precache images on nodes and, at boot time, identify \"warm\" nodes that will boot a given image faster, but I think the heuristics and decision-making as to what images to optimistically precache may need to be implemented at a higher layer (ie, outside of Ironic)...","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":416,"context_line":"        pass"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"    def _pre_cache(self, task, node, **kwargs):"},{"line_number":419,"context_line":"        \"\"\"Using some predetermined metric, decide which image should be"},{"line_number":420,"context_line":"        pre-written to a certain node to make boot time speedier."},{"line_number":421,"context_line":"        \"\"\""},{"line_number":422,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_2c3c4ce2","line":419,"in_reply_to":"9ad9bd40_a7c7a911","updated":"2014-05-02 16:51:13.000000000","message":"Totally agree. My plan is to make this a vendor interface an outside server or something in a nova extension (which would have a lot of useful data for the heuristic) could call to, and then add a filter to nova-scheduler to attempt to deploy to a precached machine if possible, probably falling back to either a pool of uncached servers or overwrite another precached machine based on a LRU or other heuristic.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        \"\"\""},{"line_number":203,"context_line":"        # Unnecessary for external DHCP."},{"line_number":204,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":205,"context_line":"            utils.unlink_without_raise(tftp._get_pxe_config_file_path("},{"line_number":206,"context_line":"                node.uuid))"},{"line_number":207,"context_line":"            for port in driver_utils.get_node_mac_addresses(task, node):"},{"line_number":208,"context_line":"                mac_path \u003d tftp._get_pxe_mac_path(port)"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_cbb81de8","line":205,"updated":"2014-05-02 11:23:04.000000000","message":"Leading _ suggests the function is private for `tftp` module. Could you make it public (probably in the underlying patch)?","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        \"\"\""},{"line_number":203,"context_line":"        # Unnecessary for external DHCP."},{"line_number":204,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":205,"context_line":"            utils.unlink_without_raise(tftp._get_pxe_config_file_path("},{"line_number":206,"context_line":"                node.uuid))"},{"line_number":207,"context_line":"            for port in driver_utils.get_node_mac_addresses(task, node):"},{"line_number":208,"context_line":"                mac_path \u003d tftp._get_pxe_mac_path(port)"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_e52425b1","line":205,"in_reply_to":"9ad9bd40_cbb81de8","updated":"2014-05-02 17:59:53.000000000","message":"Done","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":205,"context_line":"            utils.unlink_without_raise(tftp._get_pxe_config_file_path("},{"line_number":206,"context_line":"                node.uuid))"},{"line_number":207,"context_line":"            for port in driver_utils.get_node_mac_addresses(task, node):"},{"line_number":208,"context_line":"                mac_path \u003d tftp._get_pxe_mac_path(port)"},{"line_number":209,"context_line":"                utils.unlink_without_raise(mac_path)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            utils.rmtree_without_raise("}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_ebcec182","line":208,"updated":"2014-05-02 11:23:04.000000000","message":"ditto about _","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":205,"context_line":"            utils.unlink_without_raise(tftp._get_pxe_config_file_path("},{"line_number":206,"context_line":"                node.uuid))"},{"line_number":207,"context_line":"            for port in driver_utils.get_node_mac_addresses(task, node):"},{"line_number":208,"context_line":"                mac_path \u003d tftp._get_pxe_mac_path(port)"},{"line_number":209,"context_line":"                utils.unlink_without_raise(mac_path)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            utils.rmtree_without_raise("}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_25360de8","line":208,"in_reply_to":"9ad9bd40_ebcec182","updated":"2014-05-02 17:59:53.000000000","message":"Done","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":209,"context_line":"                utils.unlink_without_raise(mac_path)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            utils.rmtree_without_raise("},{"line_number":212,"context_line":"                os.path.join(CONF.tftp.tftp_root, node.uuid))"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def take_over(self, task, node):"},{"line_number":215,"context_line":"        \"\"\"Take over management of this node from a dead conductor."}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_0bca056e","line":212,"updated":"2014-05-02 11:23:04.000000000","message":"Just a note about the future: if my patch about ImageCache[1] lands, this may need also clean up of the cache.\n\n[1] https://review.openstack.org/#/c/85387/","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":209,"context_line":"                utils.unlink_without_raise(mac_path)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            utils.rmtree_without_raise("},{"line_number":212,"context_line":"                os.path.join(CONF.tftp.tftp_root, node.uuid))"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def take_over(self, task, node):"},{"line_number":215,"context_line":"        \"\"\"Take over management of this node from a dead conductor."}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_54dca512","line":212,"in_reply_to":"9ad9bd40_0bca056e","updated":"2014-05-02 17:59:53.000000000","message":"I\u0027ve been keeping an eye on that patch (which looks good BTW). I\u0027d rebase the TFTP patch on top of it, but patch management during testing has become slightly cumbersome at times, and we don\u0027t expect to merge for a bit.","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":231,"context_line":"        \"\"\""},{"line_number":232,"context_line":"        # Unnecessary for external DHCP."},{"line_number":233,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":234,"context_line":"            tftp._update_neutron(task, node)"},{"line_number":235,"context_line":""},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"class AgentVendorInterface(base.VendorInterface):"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_2bc98978","line":234,"updated":"2014-05-02 11:23:04.000000000","message":"ditto about _","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":231,"context_line":"        \"\"\""},{"line_number":232,"context_line":"        # Unnecessary for external DHCP."},{"line_number":233,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":234,"context_line":"            tftp._update_neutron(task, node)"},{"line_number":235,"context_line":""},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"class AgentVendorInterface(base.VendorInterface):"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_653015e9","line":234,"in_reply_to":"9ad9bd40_2bc98978","updated":"2014-05-02 17:59:53.000000000","message":"Done","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":419,"context_line":"        # }"},{"line_number":420,"context_line":""},{"line_number":421,"context_line":"        # self._save_hardware(node, hardware, version)"},{"line_number":422,"context_line":"        # self._save_ports(context, node, interfaces)"},{"line_number":423,"context_line":"        # node.save(context)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"        return {"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_2ba0a99e","line":422,"updated":"2014-05-02 11:23:04.000000000","message":"Signature of _save_ports:\n\n  def _save_ports(self, node, interfaces)\n\n`context` seems to be required in _save_hardware though","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":419,"context_line":"        # }"},{"line_number":420,"context_line":""},{"line_number":421,"context_line":"        # self._save_hardware(node, hardware, version)"},{"line_number":422,"context_line":"        # self._save_ports(context, node, interfaces)"},{"line_number":423,"context_line":"        # node.save(context)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"        return {"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_54f3c59d","line":422,"in_reply_to":"9ad9bd40_2ba0a99e","updated":"2014-05-02 17:59:53.000000000","message":"I wound up dumping this function. After some integration with neutron, it became unnecessary","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":554,"context_line":"        # Only have one node_id left, return it."},{"line_number":555,"context_line":"        return node_ids.pop()"},{"line_number":556,"context_line":""},{"line_number":557,"context_line":"    def _save_ports(self, node, interfaces):"},{"line_number":558,"context_line":"        #TODO(JoshNang) look for existing port first"},{"line_number":559,"context_line":"        ports \u003d []"},{"line_number":560,"context_line":"        for interface in interfaces:"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_6b90f143","line":557,"updated":"2014-05-02 11:23:04.000000000","message":"Could you add at least a small docstring here?","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":554,"context_line":"        # Only have one node_id left, return it."},{"line_number":555,"context_line":"        return node_ids.pop()"},{"line_number":556,"context_line":""},{"line_number":557,"context_line":"    def _save_ports(self, node, interfaces):"},{"line_number":558,"context_line":"        #TODO(JoshNang) look for existing port first"},{"line_number":559,"context_line":"        ports \u003d []"},{"line_number":560,"context_line":"        for interface in interfaces:"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_54fd8539","line":557,"in_reply_to":"9ad9bd40_6b90f143","updated":"2014-05-02 17:59:53.000000000","message":"Done","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":566,"context_line":"            ports.append(self.dbapi.create_port(port_dict))"},{"line_number":567,"context_line":"        return ports"},{"line_number":568,"context_line":""},{"line_number":569,"context_line":"    def _flatten_dict(self, item, path\u003d\u0027\u0027, flattened\u003d{}):"},{"line_number":570,"context_line":"        \"\"\"Do a depth first search through the \u0027tree\u0027 of the dictionary"},{"line_number":571,"context_line":"        to flatten it out. Turns {\u0027a\u0027: {\u0027b\u0027: [\u0027c\u0027, \u0027d\u0027]}} into"},{"line_number":572,"context_line":"        {\u0027a/b/0\u0027: \u0027c\u0027, \u0027a/b/1\u0027: \u0027d\u0027}"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_eb26c115","line":569,"updated":"2014-05-02 11:23:04.000000000","message":"This function does not need self, so it should be module-level function. You may even consider placing it somewhere in `utils` module (especially if separator is an argument with default value).","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":566,"context_line":"            ports.append(self.dbapi.create_port(port_dict))"},{"line_number":567,"context_line":"        return ports"},{"line_number":568,"context_line":""},{"line_number":569,"context_line":"    def _flatten_dict(self, item, path\u003d\u0027\u0027, flattened\u003d{}):"},{"line_number":570,"context_line":"        \"\"\"Do a depth first search through the \u0027tree\u0027 of the dictionary"},{"line_number":571,"context_line":"        to flatten it out. Turns {\u0027a\u0027: {\u0027b\u0027: [\u0027c\u0027, \u0027d\u0027]}} into"},{"line_number":572,"context_line":"        {\u0027a/b/0\u0027: \u0027c\u0027, \u0027a/b/1\u0027: \u0027d\u0027}"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_0fd20800","line":569,"in_reply_to":"9ad9bd40_eb26c115","updated":"2014-05-02 17:59:53.000000000","message":"Done","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":613,"context_line":"        flattened_dict \u003d self._flatten_dict(hardware)"},{"line_number":614,"context_line":"        extra \u003d node.extra"},{"line_number":615,"context_line":"        for key, value in flattened_dict.items():"},{"line_number":616,"context_line":"            key \u003d \u0027%(top_key)s/%(key)s\u0027 % {\u0027top_key\u0027: \u0027hardware\u0027, \u0027key\u0027: key}"},{"line_number":617,"context_line":"            extra[key] \u003d value"},{"line_number":618,"context_line":"        node.extra \u003d extra"},{"line_number":619,"context_line":"        node.save(context)"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_0bcda55d","line":616,"updated":"2014-05-02 11:23:04.000000000","message":"Will `top_key` substitution always be a constant? According to docstring yes, and than it can be build into format string itself.","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":613,"context_line":"        flattened_dict \u003d self._flatten_dict(hardware)"},{"line_number":614,"context_line":"        extra \u003d node.extra"},{"line_number":615,"context_line":"        for key, value in flattened_dict.items():"},{"line_number":616,"context_line":"            key \u003d \u0027%(top_key)s/%(key)s\u0027 % {\u0027top_key\u0027: \u0027hardware\u0027, \u0027key\u0027: key}"},{"line_number":617,"context_line":"            extra[key] \u003d value"},{"line_number":618,"context_line":"        node.extra \u003d extra"},{"line_number":619,"context_line":"        node.save(context)"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_cfe820b7","line":616,"in_reply_to":"9ad9bd40_0bcda55d","updated":"2014-05-02 17:59:53.000000000","message":"Done","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0ed96c9f7bf576fbedd04560965b5fd405fd017f","unresolved":false,"context_lines":[{"line_number":635,"context_line":"            # Shouldn\u0027t need this."},{"line_number":636,"context_line":"            \u0027ipa_advertise_host\u0027: \u0027\u0027"},{"line_number":637,"context_line":"        }"},{"line_number":638,"context_line":"        return tftp._build_pxe_config(node,"},{"line_number":639,"context_line":"                                      pxe_options,"},{"line_number":640,"context_line":"                                      CONF.agent.pxe_config_template)"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_eb540156","line":638,"updated":"2014-05-02 11:23:04.000000000","message":"ditto about _","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"0ff2b6e0479c006008f92fb07184d4dca94fcf85","unresolved":false,"context_lines":[{"line_number":635,"context_line":"            # Shouldn\u0027t need this."},{"line_number":636,"context_line":"            \u0027ipa_advertise_host\u0027: \u0027\u0027"},{"line_number":637,"context_line":"        }"},{"line_number":638,"context_line":"        return tftp._build_pxe_config(node,"},{"line_number":639,"context_line":"                                      pxe_options,"},{"line_number":640,"context_line":"                                      CONF.agent.pxe_config_template)"}],"source_content_type":"text/x-python","patch_set":56,"id":"9ad9bd40_c5580135","line":638,"in_reply_to":"9ad9bd40_eb540156","updated":"2014-05-02 17:59:53.000000000","message":"Done","commit_id":"2157f3d028f8bb71b0a1569b7b3330b571910fc7"},{"author":{"_account_id":10626,"name":"Russell Haering","email":"russellhaering@gmail.com","username":"russell_h"},"change_message_id":"bb1086357362ec5f83b605f1f2d4858b300696ff","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    cfg.StrOpt(\u0027dhcp_provider\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027neutron\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027The service responsible for providing DHCP and TFTP to \u0027"},{"line_number":64,"context_line":"                    \u0027booting agents. If set the \"neutron\", it expects a \u0027"},{"line_number":65,"context_line":"                    \u0027TFTP server local to each conductor where TFTP configs \u0027"},{"line_number":66,"context_line":"                    \u0027can be written out. If set to \"external\", it expects \u0027"},{"line_number":67,"context_line":"                    \u0027a pre-configured DHCP and TFTP service (such as a DHCP \u0027"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_cb6d6634","line":64,"updated":"2014-05-03 03:55:54.000000000","message":"Typo here, \"If set the\" -\u003e \"If set to\".","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"e620e1b048ea9b89b6c389afa1677162208eac62","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    cfg.StrOpt(\u0027dhcp_provider\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027neutron\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027The service responsible for providing DHCP and TFTP to \u0027"},{"line_number":64,"context_line":"                    \u0027booting agents. If set the \"neutron\", it expects a \u0027"},{"line_number":65,"context_line":"                    \u0027TFTP server local to each conductor where TFTP configs \u0027"},{"line_number":66,"context_line":"                    \u0027can be written out. If set to \"external\", it expects \u0027"},{"line_number":67,"context_line":"                    \u0027a pre-configured DHCP and TFTP service (such as a DHCP \u0027"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_4c7e9e1a","line":64,"in_reply_to":"9ad9bd40_cb6d6634","updated":"2014-05-06 18:03:03.000000000","message":"Done","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"e620e1b048ea9b89b6c389afa1677162208eac62","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    cfg.StrOpt(\u0027dhcp_provider\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027neutron\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027The service responsible for providing DHCP and TFTP to \u0027"},{"line_number":64,"context_line":"                    \u0027booting agents. If set the \"neutron\", it expects a \u0027"},{"line_number":65,"context_line":"                    \u0027TFTP server local to each conductor where TFTP configs \u0027"},{"line_number":66,"context_line":"                    \u0027can be written out. If set to \"external\", it expects \u0027"},{"line_number":67,"context_line":"                    \u0027a pre-configured DHCP and TFTP service (such as a DHCP \u0027"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_51ae37e7","line":64,"in_reply_to":"9ad9bd40_cb6d6634","updated":"2014-05-06 18:03:03.000000000","message":"Done","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10626,"name":"Russell Haering","email":"russellhaering@gmail.com","username":"russell_h"},"change_message_id":"bb1086357362ec5f83b605f1f2d4858b300696ff","unresolved":false,"context_lines":[{"line_number":154,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"},{"line_number":155,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"        return states.DEPLOYWAIT"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def tear_down(self, task, node):"},{"line_number":160,"context_line":"        \"\"\"Reboot the machine and begin decom."}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_a18763d6","line":157,"updated":"2014-05-03 03:55:54.000000000","message":"Mentioned this in IRC, but if you factored _continue_deploy out of the vendor interface, you could call it here immediately if the node is already powered on. Just an optimization though, this should work fine.","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"e620e1b048ea9b89b6c389afa1677162208eac62","unresolved":false,"context_lines":[{"line_number":154,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"},{"line_number":155,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"        return states.DEPLOYWAIT"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def tear_down(self, task, node):"},{"line_number":160,"context_line":"        \"\"\"Reboot the machine and begin decom."}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_2caf9a95","line":157,"in_reply_to":"9ad9bd40_a18763d6","updated":"2014-05-06 18:03:03.000000000","message":"Added to todo list for when we add caching images.","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10626,"name":"Russell Haering","email":"russellhaering@gmail.com","username":"russell_h"},"change_message_id":"bb1086357362ec5f83b605f1f2d4858b300696ff","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        node_object \u003d task.node"},{"line_number":301,"context_line":"        instance_info \u003d node_object.instance_info"},{"line_number":302,"context_line":"        driver_info \u003d node_object.driver_info"},{"line_number":303,"context_line":"        # TODO(JoshNang) should this be instance or driver info?"},{"line_number":304,"context_line":"        instance_info[\u0027agent_last_heartbeat\u0027] \u003d int(_time())"},{"line_number":305,"context_line":"        driver_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":306,"context_line":"        node_object.instance_info \u003d instance_info"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_885b6486","line":303,"updated":"2014-05-03 03:55:54.000000000","message":"IMO \u0027agent_last_heartbeat\u0027 should go on driver_info. It certainly isn\u0027t info about the instance.","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"e620e1b048ea9b89b6c389afa1677162208eac62","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        node_object \u003d task.node"},{"line_number":301,"context_line":"        instance_info \u003d node_object.instance_info"},{"line_number":302,"context_line":"        driver_info \u003d node_object.driver_info"},{"line_number":303,"context_line":"        # TODO(JoshNang) should this be instance or driver info?"},{"line_number":304,"context_line":"        instance_info[\u0027agent_last_heartbeat\u0027] \u003d int(_time())"},{"line_number":305,"context_line":"        driver_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":306,"context_line":"        node_object.instance_info \u003d instance_info"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_4cd05e1f","line":303,"in_reply_to":"9ad9bd40_885b6486","updated":"2014-05-06 18:03:03.000000000","message":"Done","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"45888f39e172eb493950a88dc95cfdcdc3327e6b","unresolved":false,"context_lines":[{"line_number":316,"context_line":"                and self._deploy_is_done(node_object)):"},{"line_number":317,"context_line":"            self._reboot_to_instance(task, **kwargs)"},{"line_number":318,"context_line":""},{"line_number":319,"context_line":"    def _deploy_is_done(self, node_object):"},{"line_number":320,"context_line":"        return self._client.deploy_is_done(node_object)"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    def _continue_deploy(self, task, **kwargs):"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_3f27d113","line":319,"updated":"2014-05-05 09:31:35.000000000","message":"What\u0027s the point in this as a separate method?","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"e620e1b048ea9b89b6c389afa1677162208eac62","unresolved":false,"context_lines":[{"line_number":316,"context_line":"                and self._deploy_is_done(node_object)):"},{"line_number":317,"context_line":"            self._reboot_to_instance(task, **kwargs)"},{"line_number":318,"context_line":""},{"line_number":319,"context_line":"    def _deploy_is_done(self, node_object):"},{"line_number":320,"context_line":"        return self._client.deploy_is_done(node_object)"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    def _continue_deploy(self, task, **kwargs):"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_ccbc6edf","line":319,"in_reply_to":"9ad9bd40_3f27d113","updated":"2014-05-06 18:03:03.000000000","message":"This can get called asynchronously from heartbeat and we\u0027d like to keep everything cleanly separated there instead of it being a large function with a ton of code paths.","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10626,"name":"Russell Haering","email":"russellhaering@gmail.com","username":"russell_h"},"change_message_id":"bb1086357362ec5f83b605f1f2d4858b300696ff","unresolved":false,"context_lines":[{"line_number":334,"context_line":"        LOG.debug(\u0027Got image info: %s\u0027, image_info)"},{"line_number":335,"context_line":"        image_info[\u0027urls\u0027] \u003d [swift_temp_url]"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"        # Tell the client to download and run the image with the given args"},{"line_number":338,"context_line":"        res \u003d self._client.prepare_image(node_object, image_info, configdrive)"},{"line_number":339,"context_line":"        LOG.debug(\u0027prepare_image got response %s\u0027, res)"},{"line_number":340,"context_line":"        # TODO(jimrollenhagen) error checking"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_cb548656","line":337,"updated":"2014-05-03 03:55:54.000000000","message":"Comment is wrong, this tells the client to download and write out the specified image with the specified config drive. It doesn\u0027t actually run it.","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"e620e1b048ea9b89b6c389afa1677162208eac62","unresolved":false,"context_lines":[{"line_number":334,"context_line":"        LOG.debug(\u0027Got image info: %s\u0027, image_info)"},{"line_number":335,"context_line":"        image_info[\u0027urls\u0027] \u003d [swift_temp_url]"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"        # Tell the client to download and run the image with the given args"},{"line_number":338,"context_line":"        res \u003d self._client.prepare_image(node_object, image_info, configdrive)"},{"line_number":339,"context_line":"        LOG.debug(\u0027prepare_image got response %s\u0027, res)"},{"line_number":340,"context_line":"        # TODO(jimrollenhagen) error checking"}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_2cb87ae4","line":337,"in_reply_to":"9ad9bd40_cb548656","updated":"2014-05-06 18:03:03.000000000","message":"Done","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"9a1dc68992a409531320c4125f0d6c45621e0d75","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        node_object \u003d task.node"},{"line_number":331,"context_line":"        instance_info \u003d node_object.instance_info"},{"line_number":332,"context_line":"        driver_info \u003d node_object.driver_info"},{"line_number":333,"context_line":"        LOG.info(_(\u0027Heartbeat from %(node)s, last heartbeat at %(heartbeat).\u0027),"},{"line_number":334,"context_line":"                 {\u0027node\u0027: node_object.uuid,"},{"line_number":335,"context_line":"                  \u0027heartbeat\u0027: driver_info.get(\u0027agent_last_heartbeat\u0027)})"},{"line_number":336,"context_line":"        driver_info[\u0027agent_last_heartbeat\u0027] \u003d int(_time())"}],"source_content_type":"text/x-python","patch_set":73,"id":"7adec928_33cd9032","line":333,"updated":"2014-05-09 01:07:14.000000000","message":"%(heartbeat) -\u003e  %(heartbeat)s","commit_id":"3df7752c1a7cb28e348d7bbdf9671c2a4f66add5"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"1c1923116c759a0900b6434deb66bfd06ad000a2","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                    \u0027agent will send its initial lookup call to. Defaults \u0027"},{"line_number":85,"context_line":"                    \u0027to my_ip.\u0027,"},{"line_number":86,"context_line":"               default\u003d\u0027$my_ip\u0027),"},{"line_number":87,"context_line":"    cfg.IntOpt(\u0027agent_boot_max_wait\u0027,"},{"line_number":88,"context_line":"               default\u003d300,"},{"line_number":89,"context_line":"               help\u003d\u0027The amount of time in seconds to wait for an agent to \u0027"},{"line_number":90,"context_line":"                    \u0027boot when using neutron as the dhcp_provider.\u0027)"}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_21b261e6","line":87,"updated":"2014-05-13 14:31:46.000000000","message":"This option not used.","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"c57fe97d1e437c69ec56a848aa73f4eb593a315c","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                    \u0027agent will send its initial lookup call to. Defaults \u0027"},{"line_number":85,"context_line":"                    \u0027to my_ip.\u0027,"},{"line_number":86,"context_line":"               default\u003d\u0027$my_ip\u0027),"},{"line_number":87,"context_line":"    cfg.IntOpt(\u0027agent_boot_max_wait\u0027,"},{"line_number":88,"context_line":"               default\u003d300,"},{"line_number":89,"context_line":"               help\u003d\u0027The amount of time in seconds to wait for an agent to \u0027"},{"line_number":90,"context_line":"                    \u0027boot when using neutron as the dhcp_provider.\u0027)"}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_341c4b13","line":87,"in_reply_to":"7adec928_21b261e6","updated":"2014-05-16 22:31:07.000000000","message":"Done","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"1c1923116c759a0900b6434deb66bfd06ad000a2","unresolved":false,"context_lines":[{"line_number":159,"context_line":"                     node.id)"},{"line_number":160,"context_line":"            # Boot the box, wait for the first heartbeat, then deploy."},{"line_number":161,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"},{"line_number":162,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"        return states.DEPLOYWAIT"},{"line_number":165,"context_line":""}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_ef9b0570","line":162,"updated":"2014-05-13 14:31:46.000000000","message":"I think better do reboot here w/o l157.","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"898d62efeb9c7bacd8c5ffd78b5e87d43eb735b4","unresolved":false,"context_lines":[{"line_number":159,"context_line":"                     node.id)"},{"line_number":160,"context_line":"            # Boot the box, wait for the first heartbeat, then deploy."},{"line_number":161,"context_line":"            manager_utils.node_set_boot_device(task, \u0027pxe\u0027)"},{"line_number":162,"context_line":"            manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"        return states.DEPLOYWAIT"},{"line_number":165,"context_line":""}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_57de4f6e","line":162,"in_reply_to":"7adec928_ef9b0570","updated":"2014-05-13 15:05:37.000000000","message":"If the node is already powered on, we don\u0027t want to reboot it.","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"1c1923116c759a0900b6434deb66bfd06ad000a2","unresolved":false,"context_lines":[{"line_number":199,"context_line":"                     on this Conductor."},{"line_number":200,"context_line":"        \"\"\""},{"line_number":201,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":202,"context_line":"            LOG.info(_(\u0027Creating PXE config for node %s.\u0027), node.id)"},{"line_number":203,"context_line":"            # Create the TFTP file."},{"line_number":204,"context_line":"            pxe_options \u003d self._get_pxe_config()"},{"line_number":205,"context_line":"            tftp.create_pxe_config("}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_7417cc51","line":202,"updated":"2014-05-13 14:31:46.000000000","message":"id is db internal, please use node.uuid","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"c57fe97d1e437c69ec56a848aa73f4eb593a315c","unresolved":false,"context_lines":[{"line_number":199,"context_line":"                     on this Conductor."},{"line_number":200,"context_line":"        \"\"\""},{"line_number":201,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"},{"line_number":202,"context_line":"            LOG.info(_(\u0027Creating PXE config for node %s.\u0027), node.id)"},{"line_number":203,"context_line":"            # Create the TFTP file."},{"line_number":204,"context_line":"            pxe_options \u003d self._get_pxe_config()"},{"line_number":205,"context_line":"            tftp.create_pxe_config("}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_d427a762","line":202,"in_reply_to":"7adec928_7417cc51","updated":"2014-05-16 22:31:07.000000000","message":"Done","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"1c1923116c759a0900b6434deb66bfd06ad000a2","unresolved":false,"context_lines":[{"line_number":406,"context_line":"                 node.uuid)"},{"line_number":407,"context_line":"        # TODO(jimrollenhagen) client.run_image(node)"},{"line_number":408,"context_line":"        manager_utils.node_set_boot_device(task, \u0027hd\u0027)"},{"line_number":409,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"        node.provision_state \u003d states.ACTIVE"},{"line_number":412,"context_line":"        node.target_provision_state \u003d states.NOSTATE"}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_afd9fd84","line":409,"updated":"2014-05-13 14:31:46.000000000","message":"Maybe reboot here and remove l399?","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"898d62efeb9c7bacd8c5ffd78b5e87d43eb735b4","unresolved":false,"context_lines":[{"line_number":406,"context_line":"                 node.uuid)"},{"line_number":407,"context_line":"        # TODO(jimrollenhagen) client.run_image(node)"},{"line_number":408,"context_line":"        manager_utils.node_set_boot_device(task, \u0027hd\u0027)"},{"line_number":409,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_ON)"},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"        node.provision_state \u003d states.ACTIVE"},{"line_number":412,"context_line":"        node.target_provision_state \u003d states.NOSTATE"}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_77c0ab7c","line":409,"in_reply_to":"7adec928_afd9fd84","updated":"2014-05-13 15:05:37.000000000","message":"We need to change from provisioning network to the network the instance should be on while powered off - no sooner, no later. We cannot have agents on the client network or clients on the provisioning network.","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":161,"context_line":"        for field in required_instance_fields:"},{"line_number":162,"context_line":"            if field not in node.instance_info:"},{"line_number":163,"context_line":"                raise exception.InvalidParameterValue(_(\u0027%s is required in \u0027"},{"line_number":164,"context_line":"                                                      \u0027instance_info\u0027) %"},{"line_number":165,"context_line":"                                                      field)"},{"line_number":166,"context_line":"        if \u0027agent_url\u0027 not in node.driver_info:"},{"line_number":167,"context_line":"            raise exception.InvalidParameterValue(_(\u0027agent_url is required in \u0027"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_bad6efc3","line":164,"updated":"2014-05-26 10:55:45.000000000","message":"Indentation nit: should be one more space","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":161,"context_line":"        for field in required_instance_fields:"},{"line_number":162,"context_line":"            if field not in node.instance_info:"},{"line_number":163,"context_line":"                raise exception.InvalidParameterValue(_(\u0027%s is required in \u0027"},{"line_number":164,"context_line":"                                                      \u0027instance_info\u0027) %"},{"line_number":165,"context_line":"                                                      field)"},{"line_number":166,"context_line":"        if \u0027agent_url\u0027 not in node.driver_info:"},{"line_number":167,"context_line":"            raise exception.InvalidParameterValue(_(\u0027agent_url is required in \u0027"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_7f18ce84","line":164,"in_reply_to":"5adbc538_bad6efc3","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":206,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_OFF)"},{"line_number":207,"context_line":"        manager_utils.node_set_boot_device(task, \u0027pxe\u0027, persistent\u003dTrue)"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"        LOG.debug(_(\u0027Switching to provisioning network for node %s\u0027),"},{"line_number":210,"context_line":"                  node.uuid)"},{"line_number":211,"context_line":"        # Remove public network, add provisioning network"},{"line_number":212,"context_line":"        neutron_client \u003d _get_neutron_client(task.context)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_1a58c355","line":209,"updated":"2014-05-26 10:55:45.000000000","message":"Per global policy, debug messages should no longer be translated","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":206,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_OFF)"},{"line_number":207,"context_line":"        manager_utils.node_set_boot_device(task, \u0027pxe\u0027, persistent\u003dTrue)"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"        LOG.debug(_(\u0027Switching to provisioning network for node %s\u0027),"},{"line_number":210,"context_line":"                  node.uuid)"},{"line_number":211,"context_line":"        # Remove public network, add provisioning network"},{"line_number":212,"context_line":"        neutron_client \u003d _get_neutron_client(task.context)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_1f098a31","line":209,"in_reply_to":"5adbc538_1a58c355","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":363,"context_line":"            {\u0027node\u0027: node.uuid,"},{"line_number":364,"context_line":"             \u0027heartbeat\u0027: driver_info.get(\u0027agent_last_heartbeat\u0027)})"},{"line_number":365,"context_line":"        driver_info[\u0027agent_last_heartbeat\u0027] \u003d int(_time())"},{"line_number":366,"context_line":"        driver_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":367,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":368,"context_line":"        node.driver_info \u003d driver_info"},{"line_number":369,"context_line":"        node.save(task.context)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_1a9363fb","line":366,"updated":"2014-05-26 10:55:45.000000000","message":"Why is this in driver_info?","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":363,"context_line":"            {\u0027node\u0027: node.uuid,"},{"line_number":364,"context_line":"             \u0027heartbeat\u0027: driver_info.get(\u0027agent_last_heartbeat\u0027)})"},{"line_number":365,"context_line":"        driver_info[\u0027agent_last_heartbeat\u0027] \u003d int(_time())"},{"line_number":366,"context_line":"        driver_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":367,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":368,"context_line":"        node.driver_info \u003d driver_info"},{"line_number":369,"context_line":"        node.save(task.context)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_da0e5034","line":366,"in_reply_to":"5adbc538_1a9363fb","updated":"2014-05-28 00:22:04.000000000","message":"This is info needed by the driver to communicate with the agent and is longer lived than just an instance (well, not currently, but will be)","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":365,"context_line":"        driver_info[\u0027agent_last_heartbeat\u0027] \u003d int(_time())"},{"line_number":366,"context_line":"        driver_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":367,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":368,"context_line":"        node.driver_info \u003d driver_info"},{"line_number":369,"context_line":"        node.save(task.context)"},{"line_number":370,"context_line":""},{"line_number":371,"context_line":"        # Async call backs don\u0027t set error state on their own"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_1aaa8319","line":368,"updated":"2014-05-26 10:55:45.000000000","message":"Seems like you\u0027re changing only one of these, why update both?","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":365,"context_line":"        driver_info[\u0027agent_last_heartbeat\u0027] \u003d int(_time())"},{"line_number":366,"context_line":"        driver_info[\u0027agent_url\u0027] \u003d kwargs[\u0027agent_url\u0027]"},{"line_number":367,"context_line":"        node.instance_info \u003d instance_info"},{"line_number":368,"context_line":"        node.driver_info \u003d driver_info"},{"line_number":369,"context_line":"        node.save(task.context)"},{"line_number":370,"context_line":""},{"line_number":371,"context_line":"        # Async call backs don\u0027t set error state on their own"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_5a1a406f","line":368,"in_reply_to":"5adbc538_1aaa8319","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":403,"context_line":"        glance \u003d image_service.Service(version\u003d2, context\u003dtask.context)"},{"line_number":404,"context_line":"        image_info \u003d glance.show(image_source)"},{"line_number":405,"context_line":"        swift_temp_url \u003d glance.swift_temp_url(image_info)"},{"line_number":406,"context_line":"        LOG.debug(_(\u0027Got image info: %s\u0027), image_info)"},{"line_number":407,"context_line":"        image_info[\u0027urls\u0027] \u003d [swift_temp_url]"},{"line_number":408,"context_line":""},{"line_number":409,"context_line":"        # Tell the client to download and write the image with the given args"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_5a188b84","line":406,"updated":"2014-05-26 10:55:45.000000000","message":"ditto about debug","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":403,"context_line":"        glance \u003d image_service.Service(version\u003d2, context\u003dtask.context)"},{"line_number":404,"context_line":"        image_info \u003d glance.show(image_source)"},{"line_number":405,"context_line":"        swift_temp_url \u003d glance.swift_temp_url(image_info)"},{"line_number":406,"context_line":"        LOG.debug(_(\u0027Got image info: %s\u0027), image_info)"},{"line_number":407,"context_line":"        image_info[\u0027urls\u0027] \u003d [swift_temp_url]"},{"line_number":408,"context_line":""},{"line_number":409,"context_line":"        # Tell the client to download and write the image with the given args"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_9a2be881","line":406,"in_reply_to":"5adbc538_5a188b84","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":408,"context_line":""},{"line_number":409,"context_line":"        # Tell the client to download and write the image with the given args"},{"line_number":410,"context_line":"        res \u003d self._client.prepare_image(node, image_info, configdrive)"},{"line_number":411,"context_line":"        LOG.debug(_(\u0027prepare_image got response %(res)s for node %(node)s\u0027),"},{"line_number":412,"context_line":"                  {\u0027res\u0027: res, \u0027node\u0027: node})"},{"line_number":413,"context_line":""},{"line_number":414,"context_line":"    def _check_deploy_success(self, node):"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_9a3bf3ea","line":411,"updated":"2014-05-26 10:55:45.000000000","message":"ditto about debug","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":408,"context_line":""},{"line_number":409,"context_line":"        # Tell the client to download and write the image with the given args"},{"line_number":410,"context_line":"        res \u003d self._client.prepare_image(node, image_info, configdrive)"},{"line_number":411,"context_line":"        LOG.debug(_(\u0027prepare_image got response %(res)s for node %(node)s\u0027),"},{"line_number":412,"context_line":"                  {\u0027res\u0027: res, \u0027node\u0027: node})"},{"line_number":413,"context_line":""},{"line_number":414,"context_line":"    def _check_deploy_success(self, node):"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_ba20a49c","line":411,"in_reply_to":"5adbc538_9a3bf3ea","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":435,"context_line":"            node.save(task.context)"},{"line_number":436,"context_line":"            return  # save error on node"},{"line_number":437,"context_line":""},{"line_number":438,"context_line":"        LOG.debug(_(\u0027Powering off node %s\u0027), node.uuid)"},{"line_number":439,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_OFF)"},{"line_number":440,"context_line":"        # Remove provisioning network, commit public network"},{"line_number":441,"context_line":"        LOG.debug(_(\u0027Switching to public network for node %s\u0027), node.uuid)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_da0bbb29","line":438,"updated":"2014-05-26 10:55:45.000000000","message":"ditto about debug","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":435,"context_line":"            node.save(task.context)"},{"line_number":436,"context_line":"            return  # save error on node"},{"line_number":437,"context_line":""},{"line_number":438,"context_line":"        LOG.debug(_(\u0027Powering off node %s\u0027), node.uuid)"},{"line_number":439,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_OFF)"},{"line_number":440,"context_line":"        # Remove provisioning network, commit public network"},{"line_number":441,"context_line":"        LOG.debug(_(\u0027Switching to public network for node %s\u0027), node.uuid)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_da2570ac","line":438,"in_reply_to":"5adbc538_da0bbb29","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":438,"context_line":"        LOG.debug(_(\u0027Powering off node %s\u0027), node.uuid)"},{"line_number":439,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_OFF)"},{"line_number":440,"context_line":"        # Remove provisioning network, commit public network"},{"line_number":441,"context_line":"        LOG.debug(_(\u0027Switching to public network for node %s\u0027), node.uuid)"},{"line_number":442,"context_line":"        neutron_client \u003d _get_neutron_client(task.context)"},{"line_number":443,"context_line":"        neutron_client.remove_provisioning_network(node)"},{"line_number":444,"context_line":"        neutron_client.configure_instance_networks(node)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_1a060321","line":441,"updated":"2014-05-26 10:55:45.000000000","message":"ditto about debug","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":438,"context_line":"        LOG.debug(_(\u0027Powering off node %s\u0027), node.uuid)"},{"line_number":439,"context_line":"        manager_utils.node_power_action(task, node, states.POWER_OFF)"},{"line_number":440,"context_line":"        # Remove provisioning network, commit public network"},{"line_number":441,"context_line":"        LOG.debug(_(\u0027Switching to public network for node %s\u0027), node.uuid)"},{"line_number":442,"context_line":"        neutron_client \u003d _get_neutron_client(task.context)"},{"line_number":443,"context_line":"        neutron_client.remove_provisioning_network(node)"},{"line_number":444,"context_line":"        neutron_client.configure_instance_networks(node)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_fa394cd9","line":441,"in_reply_to":"5adbc538_1a060321","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":447,"context_line":"                 node.uuid)"},{"line_number":448,"context_line":"        # TODO(jimrollenhagen) client.run_image(node)"},{"line_number":449,"context_line":"        task.driver.ipmi_vendor._bmc_reset(task, warm\u003dTrue)"},{"line_number":450,"context_line":"        task.driver.ipmi_vendor._send_raw_bytes(task, \u00270x00 0x08 0x03 0x08\u0027)"},{"line_number":451,"context_line":"        manager_utils.node_set_boot_device(task, \u0027disk\u0027, persistent\u003dTrue)"},{"line_number":452,"context_line":"        task.driver.ipmi_vendor._set_bootparam("},{"line_number":453,"context_line":"            task, \u0027set bootflag force_disk\u0027)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_c5259cac","line":450,"updated":"2014-05-26 10:55:45.000000000","message":"It seems strange to me, that you\u0027re using private methods from ipmi_vendor. If they\u0027re supposed to be used from outside, they should be made public by removing _","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":447,"context_line":"                 node.uuid)"},{"line_number":448,"context_line":"        # TODO(jimrollenhagen) client.run_image(node)"},{"line_number":449,"context_line":"        task.driver.ipmi_vendor._bmc_reset(task, warm\u003dTrue)"},{"line_number":450,"context_line":"        task.driver.ipmi_vendor._send_raw_bytes(task, \u00270x00 0x08 0x03 0x08\u0027)"},{"line_number":451,"context_line":"        manager_utils.node_set_boot_device(task, \u0027disk\u0027, persistent\u003dTrue)"},{"line_number":452,"context_line":"        task.driver.ipmi_vendor._set_bootparam("},{"line_number":453,"context_line":"            task, \u0027set bootflag force_disk\u0027)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_baf34409","line":450,"in_reply_to":"5adbc538_c5259cac","updated":"2014-05-28 00:22:04.000000000","message":"I haven\u0027t decided what the best way to do this yet is. I think adding these calls as vendor passthrus will probably be the most acceptable, which would leave them private. Thoughts on that?\n\nFor now, I\u0027m just skirting around the normal calls we\u0027d through manager_utils to the vendor passthru interface. There\u0027s some larger fixes for ipmitools I think I\u0027ll need to submit based on our testing, which again, should be their own patch.","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":520,"context_line":""},{"line_number":521,"context_line":"        Originally, the agent did not send versioned hardware payloads."},{"line_number":522,"context_line":"        Unversioned payloads will be treated as v0 until they can be fully"},{"line_number":523,"context_line":"        depreciated."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"        The interfaces list should include a list of the non-IPMI MAC addresses"},{"line_number":526,"context_line":"        in the form aa:bb:cc:dd:ee:ff."}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_a557b001","line":523,"updated":"2014-05-26 10:55:45.000000000","message":"did you mean \"deprecated\"?","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":520,"context_line":""},{"line_number":521,"context_line":"        Originally, the agent did not send versioned hardware payloads."},{"line_number":522,"context_line":"        Unversioned payloads will be treated as v0 until they can be fully"},{"line_number":523,"context_line":"        depreciated."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"        The interfaces list should include a list of the non-IPMI MAC addresses"},{"line_number":526,"context_line":"        in the form aa:bb:cc:dd:ee:ff."}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_1a48b82c","line":523,"in_reply_to":"5adbc538_a557b001","updated":"2014-05-28 00:22:04.000000000","message":"heh yes. Fixed.","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":530,"context_line":"        considered down. This will be in a root level key called"},{"line_number":531,"context_line":"        \u0027heartbeat_timeout\u0027"},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        :raises: NotFound if no matching node is found."},{"line_number":534,"context_line":"        \"\"\""},{"line_number":535,"context_line":"        version \u003d kwargs.get(\u0027version\u0027)"},{"line_number":536,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_254ba05a","line":533,"updated":"2014-05-26 10:55:45.000000000","message":"Also raises InvalidParameterValue","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":530,"context_line":"        considered down. This will be in a root level key called"},{"line_number":531,"context_line":"        \u0027heartbeat_timeout\u0027"},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        :raises: NotFound if no matching node is found."},{"line_number":534,"context_line":"        \"\"\""},{"line_number":535,"context_line":"        version \u003d kwargs.get(\u0027version\u0027)"},{"line_number":536,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_5ad8801d","line":533,"in_reply_to":"5adbc538_254ba05a","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":554,"context_line":"        }"},{"line_number":555,"context_line":"        if version \u003e\u003d 2:"},{"line_number":556,"context_line":"            for key in kwargs:"},{"line_number":557,"context_line":"                if kwargs !\u003d \u0027interfaces\u0027:"},{"line_number":558,"context_line":"                    hardware[\u0027hardware\u0027][key] \u003d kwargs[key]"},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        self._save_hardware(context, node, hardware, version)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_e5953889","line":557,"updated":"2014-05-26 10:55:45.000000000","message":"maybe s/kwargs/key/? Also you should be iterating over items:\n\n for key, value in kwargs.items():\n\nas you use value afterwards","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":554,"context_line":"        }"},{"line_number":555,"context_line":"        if version \u003e\u003d 2:"},{"line_number":556,"context_line":"            for key in kwargs:"},{"line_number":557,"context_line":"                if kwargs !\u003d \u0027interfaces\u0027:"},{"line_number":558,"context_line":"                    hardware[\u0027hardware\u0027][key] \u003d kwargs[key]"},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        self._save_hardware(context, node, hardware, version)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_9a1768a3","line":557,"in_reply_to":"5adbc538_e5953889","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":581,"context_line":"    def _get_interfaces(self, version, inventory):"},{"line_number":582,"context_line":"        # Coerce versions 0 and 1 to version 2"},{"line_number":583,"context_line":"        interfaces \u003d []"},{"line_number":584,"context_line":"        if version in [None, \u00271\u0027]:"},{"line_number":585,"context_line":""},{"line_number":586,"context_line":"            if version is None:"},{"line_number":587,"context_line":"                inventory_key \u003d \u0027hardware\u0027"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_c5467c23","line":584,"updated":"2014-05-26 10:55:45.000000000","message":"I think building a list for the sake of 2 comparisons is a bit suboptimal, why not just\n\n if not version or version \u003d\u003d \u00271\u0027:","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":599,"context_line":"                    continue"},{"line_number":600,"context_line":"                if \u0027id\u0027 not in interface:"},{"line_number":601,"context_line":"                    LOG.warning(_(\u0027Malformed MAC in hardware entry %s.\u0027)"},{"line_number":602,"context_line":"                                % interface)"},{"line_number":603,"context_line":"                    continue"},{"line_number":604,"context_line":"                interfaces.append({"},{"line_number":605,"context_line":"                    \u0027mac_address\u0027: interface.get(\u0027id\u0027)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_056f8493","line":602,"updated":"2014-05-26 10:55:45.000000000","message":"s/%/,/","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":599,"context_line":"                    continue"},{"line_number":600,"context_line":"                if \u0027id\u0027 not in interface:"},{"line_number":601,"context_line":"                    LOG.warning(_(\u0027Malformed MAC in hardware entry %s.\u0027)"},{"line_number":602,"context_line":"                                % interface)"},{"line_number":603,"context_line":"                    continue"},{"line_number":604,"context_line":"                interfaces.append({"},{"line_number":605,"context_line":"                    \u0027mac_address\u0027: interface.get(\u0027id\u0027)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_a6bb2e0d","line":602,"in_reply_to":"5adbc538_056f8493","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":602,"context_line":"                                % interface)"},{"line_number":603,"context_line":"                    continue"},{"line_number":604,"context_line":"                interfaces.append({"},{"line_number":605,"context_line":"                    \u0027mac_address\u0027: interface.get(\u0027id\u0027)"},{"line_number":606,"context_line":"                })"},{"line_number":607,"context_line":"        elif version \u003d\u003d \u00272\u0027:"},{"line_number":608,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_2503a0b9","line":605,"updated":"2014-05-26 10:55:45.000000000","message":"As you already checked for presence, you can just use interface[\u0027id\u0027]","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":602,"context_line":"                                % interface)"},{"line_number":603,"context_line":"                    continue"},{"line_number":604,"context_line":"                interfaces.append({"},{"line_number":605,"context_line":"                    \u0027mac_address\u0027: interface.get(\u0027id\u0027)"},{"line_number":606,"context_line":"                })"},{"line_number":607,"context_line":"        elif version \u003d\u003d \u00272\u0027:"},{"line_number":608,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_e63c5696","line":605,"in_reply_to":"5adbc538_2503a0b9","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":623,"context_line":"                mac_addresses.append(utils.validate_and_normalize_mac("},{"line_number":624,"context_line":"                    interface.get(\u0027mac_address\u0027)))"},{"line_number":625,"context_line":"            except exception.InvalidMAC:"},{"line_number":626,"context_line":"                LOG.warning(_(\u0027Malformed MAC: %s\u0027) % interface.get("},{"line_number":627,"context_line":"                    \u0027mac_address\u0027))"},{"line_number":628,"context_line":"        return mac_addresses"},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_c52bdc2e","line":626,"updated":"2014-05-26 10:55:45.000000000","message":"s/%/,/","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":623,"context_line":"                mac_addresses.append(utils.validate_and_normalize_mac("},{"line_number":624,"context_line":"                    interface.get(\u0027mac_address\u0027)))"},{"line_number":625,"context_line":"            except exception.InvalidMAC:"},{"line_number":626,"context_line":"                LOG.warning(_(\u0027Malformed MAC: %s\u0027) % interface.get("},{"line_number":627,"context_line":"                    \u0027mac_address\u0027))"},{"line_number":628,"context_line":"        return mac_addresses"},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_26471e21","line":626,"in_reply_to":"5adbc538_c52bdc2e","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":637,"context_line":"        ports \u003d self._find_ports_by_macs(context, mac_addresses)"},{"line_number":638,"context_line":"        if not ports:"},{"line_number":639,"context_line":"            raise exception.NodeNotFound(_(\u0027No ports matching the given MAC \u0027"},{"line_number":640,"context_line":"                                           \u0027addresses exist in the database.\u0027))"},{"line_number":641,"context_line":"        node_id \u003d self._get_node_id(ports)"},{"line_number":642,"context_line":"        try:"},{"line_number":643,"context_line":"            node \u003d node_module.Node.get_by_id(context, node_id)"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_251ac017","line":640,"updated":"2014-05-26 10:55:45.000000000","message":"Please provide \u0027given MAC addresses\u0027 within the exception message","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":637,"context_line":"        ports \u003d self._find_ports_by_macs(context, mac_addresses)"},{"line_number":638,"context_line":"        if not ports:"},{"line_number":639,"context_line":"            raise exception.NodeNotFound(_(\u0027No ports matching the given MAC \u0027"},{"line_number":640,"context_line":"                                           \u0027addresses exist in the database.\u0027))"},{"line_number":641,"context_line":"        node_id \u003d self._get_node_id(ports)"},{"line_number":642,"context_line":"        try:"},{"line_number":643,"context_line":"            node \u003d node_module.Node.get_by_id(context, node_id)"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_4620aa49","line":640,"in_reply_to":"5adbc538_251ac017","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":644,"context_line":"        except exception.NodeNotFound:"},{"line_number":645,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":646,"context_line":"                LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":647,"context_line":"                                \u0027provided MACs %s.\u0027) % mac_addresses)"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"        return node"},{"line_number":650,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_c5e2fc02","line":647,"updated":"2014-05-26 10:55:45.000000000","message":"s/%/,/","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":644,"context_line":"        except exception.NodeNotFound:"},{"line_number":645,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":646,"context_line":"                LOG.exception(_(\u0027Could not find matching node for the \u0027"},{"line_number":647,"context_line":"                                \u0027provided MACs %s.\u0027) % mac_addresses)"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"        return node"},{"line_number":650,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_a617aeec","line":647,"in_reply_to":"5adbc538_c5e2fc02","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":664,"context_line":""},{"line_number":665,"context_line":"            except exception.PortNotFound:"},{"line_number":666,"context_line":"                LOG.warning(_(\u0027MAC address %s not found in \u0027"},{"line_number":667,"context_line":"                              \u0027database\u0027) % mac)"},{"line_number":668,"context_line":""},{"line_number":669,"context_line":"        return ports"},{"line_number":670,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_e5e61816","line":667,"updated":"2014-05-26 10:55:45.000000000","message":"s/%/,/","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":664,"context_line":""},{"line_number":665,"context_line":"            except exception.PortNotFound:"},{"line_number":666,"context_line":"                LOG.warning(_(\u0027MAC address %s not found in \u0027"},{"line_number":667,"context_line":"                              \u0027database\u0027) % mac)"},{"line_number":668,"context_line":""},{"line_number":669,"context_line":"        return ports"},{"line_number":670,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_46950a3f","line":667,"in_reply_to":"5adbc538_e5e61816","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":670,"context_line":""},{"line_number":671,"context_line":"    def _get_node_id(self, ports):"},{"line_number":672,"context_line":"        \"\"\"Given a list of ports, either return the node_id they all share or"},{"line_number":673,"context_line":"        raise a NotFound if there are multiple node_ids (indicating some"},{"line_number":674,"context_line":"        ports are connected to one node and other ports are connected to"},{"line_number":675,"context_line":"        different nodes in the DB"},{"line_number":676,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_85bf14d0","line":673,"updated":"2014-05-26 10:55:45.000000000","message":"Opening bracket is never closed","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":670,"context_line":""},{"line_number":671,"context_line":"    def _get_node_id(self, ports):"},{"line_number":672,"context_line":"        \"\"\"Given a list of ports, either return the node_id they all share or"},{"line_number":673,"context_line":"        raise a NotFound if there are multiple node_ids (indicating some"},{"line_number":674,"context_line":"        ports are connected to one node and other ports are connected to"},{"line_number":675,"context_line":"        different nodes in the DB"},{"line_number":676,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_66920659","line":673,"in_reply_to":"5adbc538_85bf14d0","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":702,"context_line":"        flattened_dict \u003d agent_utils.flatten_dict(hardware)"},{"line_number":703,"context_line":"        extra \u003d node[\u0027extra\u0027]"},{"line_number":704,"context_line":"        for key, value in flattened_dict.items():"},{"line_number":705,"context_line":"            extra[key] \u003d value"},{"line_number":706,"context_line":"        node[\u0027extra\u0027] \u003d extra"},{"line_number":707,"context_line":"        node.save(context)"},{"line_number":708,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_259f2061","line":705,"updated":"2014-05-26 10:55:45.000000000","message":"Just\n\n extra.update(flattened_dict)","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":702,"context_line":"        flattened_dict \u003d agent_utils.flatten_dict(hardware)"},{"line_number":703,"context_line":"        extra \u003d node[\u0027extra\u0027]"},{"line_number":704,"context_line":"        for key, value in flattened_dict.items():"},{"line_number":705,"context_line":"            extra[key] \u003d value"},{"line_number":706,"context_line":"        node[\u0027extra\u0027] \u003d extra"},{"line_number":707,"context_line":"        node.save(context)"},{"line_number":708,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_e6945639","line":705,"in_reply_to":"5adbc538_259f2061","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"aa53d9561d2acf4dba259534c32897a03de5842d","unresolved":false,"context_lines":[{"line_number":322,"context_line":""},{"line_number":323,"context_line":"    def driver_vendor_passthru(self, task, method, **kwargs):"},{"line_number":324,"context_line":"        \"\"\"A node that does not know its UUID should POST to this method."},{"line_number":325,"context_line":"        Given method, route the command to the appropriate private function."},{"line_number":326,"context_line":"        \"\"\""},{"line_number":327,"context_line":"        if method not in self.driver_routes:"},{"line_number":328,"context_line":"            raise exception.InvalidParameterValue(_(\u0027No handler for method %s\u0027)"}],"source_content_type":"text/x-python","patch_set":90,"id":"3ae8d1ca_31ce6b84","line":325,"updated":"2014-05-28 04:21:16.000000000","message":"You should probably add param explanations.","commit_id":"f8a1aa510618c2a9078e1572817c1b1b2f7d9eb7"},{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"aa53d9561d2acf4dba259534c32897a03de5842d","unresolved":false,"context_lines":[{"line_number":334,"context_line":"        \"\"\"A node that knows its UUID should heartbeat to this passthru."},{"line_number":335,"context_line":""},{"line_number":336,"context_line":"        It will get its node object back, with what Ironic thinks its provision"},{"line_number":337,"context_line":"        state is and the target provision state is."},{"line_number":338,"context_line":"        \"\"\""},{"line_number":339,"context_line":"        method \u003d kwargs[\u0027method\u0027]  # Existence checked in mixin"},{"line_number":340,"context_line":"        if method not in self.vendor_routes:"}],"source_content_type":"text/x-python","patch_set":90,"id":"3ae8d1ca_b1a19bab","line":337,"updated":"2014-05-28 04:21:16.000000000","message":"ditto","commit_id":"f8a1aa510618c2a9078e1572817c1b1b2f7d9eb7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"7d940cd7c2453e29b70fa9937648f66b9bff33f8","unresolved":false,"context_lines":[{"line_number":157,"context_line":"        :param node: a single Node to validate."},{"line_number":158,"context_line":"        :raises: InvalidParameterValue"},{"line_number":159,"context_line":"        \"\"\""},{"line_number":160,"context_line":"        if node.instance_info is None:"},{"line_number":161,"context_line":"            raise exception.InvalidParameterValue(_(\u0027instance_info cannot be \u0027"},{"line_number":162,"context_line":"                                                    \u0027null.\u0027))"},{"line_number":163,"context_line":"        required_instance_fields \u003d [\u0027image_source\u0027, \u0027configdrive\u0027]"}],"source_content_type":"text/x-python","patch_set":96,"id":"1ae5cdf2_ce02dc3d","line":160,"updated":"2014-06-02 13:48:14.000000000","message":"This is not really needed, I think we should only check required fields.","commit_id":"f4eb7b850bb28a371f4ee2378b49461d96c9b489"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"7d940cd7c2453e29b70fa9937648f66b9bff33f8","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        node."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        :param task: a TaskManager instance."},{"line_number":182,"context_line":"        :param node: the Node to act upon."},{"line_number":183,"context_line":"        :returns: status of the deploy. One of ironic.common.states."},{"line_number":184,"context_line":"        \"\"\""},{"line_number":185,"context_line":"        if task.node.power_state \u003d\u003d states.POWER_OFF:"}],"source_content_type":"text/x-python","patch_set":96,"id":"1ae5cdf2_ee2078b2","line":182,"updated":"2014-06-02 13:48:14.000000000","message":"This parameter absents.","commit_id":"f4eb7b850bb28a371f4ee2378b49461d96c9b489"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"7d940cd7c2453e29b70fa9937648f66b9bff33f8","unresolved":false,"context_lines":[{"line_number":200,"context_line":"        Public networks will already be removed by Nova."},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"        :param task: a TaskManager instance."},{"line_number":203,"context_line":"        :param node: the Node to act upon."},{"line_number":204,"context_line":"        :returns: status of the deploy. One of ironic.common.states."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        LOG.info(_(\u0027Tearing down node %s, powering off.\u0027), task.node.uuid)"}],"source_content_type":"text/x-python","patch_set":96,"id":"1ae5cdf2_111ea563","line":203,"updated":"2014-06-02 13:48:14.000000000","message":"ditto","commit_id":"f4eb7b850bb28a371f4ee2378b49461d96c9b489"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"7d940cd7c2453e29b70fa9937648f66b9bff33f8","unresolved":false,"context_lines":[{"line_number":232,"context_line":"        \"\"\"Prepare the deployment environment for this node."},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"        :param task: a TaskManager instance."},{"line_number":235,"context_line":"        :param node: the Node for which to prepare a deployment environment"},{"line_number":236,"context_line":"                     on this Conductor."},{"line_number":237,"context_line":"        \"\"\""},{"line_number":238,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"}],"source_content_type":"text/x-python","patch_set":96,"id":"1ae5cdf2_f1aa19d1","line":235,"updated":"2014-06-02 13:48:14.000000000","message":"ditto","commit_id":"f4eb7b850bb28a371f4ee2378b49461d96c9b489"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"7d940cd7c2453e29b70fa9937648f66b9bff33f8","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        This method is called before `tear_down`."},{"line_number":259,"context_line":""},{"line_number":260,"context_line":"        :param task: a TaskManager instance."},{"line_number":261,"context_line":"        :param node: the Node whose deployment environment should be cleaned up"},{"line_number":262,"context_line":"                     on this Conductor."},{"line_number":263,"context_line":"        \"\"\""},{"line_number":264,"context_line":"        # Unnecessary for external DHCP."}],"source_content_type":"text/x-python","patch_set":96,"id":"1ae5cdf2_5183cd55","line":261,"updated":"2014-06-02 13:48:14.000000000","message":"ditto","commit_id":"f4eb7b850bb28a371f4ee2378b49461d96c9b489"},{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"717524a55f6ff9e07ee53276d9766c9552cbbebc","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            This is performed within the `takeover` method."},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        :param task: a TaskManager instance."},{"line_number":292,"context_line":"        :param node: the Node which is now being managed by this Conductor."},{"line_number":293,"context_line":"        \"\"\""},{"line_number":294,"context_line":"        # Unnecessary for external DHCP."},{"line_number":295,"context_line":"        if CONF.agent.dhcp_provider \u003d\u003d \u0027neutron\u0027:"}],"source_content_type":"text/x-python","patch_set":96,"id":"1ae5cdf2_cb58e58c","line":292,"updated":"2014-06-03 12:05:50.000000000","message":"Same as Yuriy is saying, this parameter absents.","commit_id":"f4eb7b850bb28a371f4ee2378b49461d96c9b489"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                help\u003d\u0027The length of time in seconds until the driver will \u0027"},{"line_number":54,"context_line":"                     \u0027consider the agent down. The agent will attempt to \u0027"},{"line_number":55,"context_line":"                     \u0027contact Ironic at some set fraction of this time \u0027"},{"line_number":56,"context_line":"                     \u0027(defaulting to 2/3 the max time).\u0027"},{"line_number":57,"context_line":"                     \u0027Defaults to 5 minutes.\u0027),"},{"line_number":58,"context_line":"    cfg.StrOpt(\u0027pxe_config_template\u0027,"},{"line_number":59,"context_line":"               default\u003dpaths.basedir_def("}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_f409a784","line":56,"updated":"2014-06-20 13:05:38.000000000","message":"space after dot","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":73,"context_line":"                    \u0027This will be put into the DHCP file if dhcp_provider \u0027"},{"line_number":74,"context_line":"                    \u0027is set to \"neutron\".\u0027),"},{"line_number":75,"context_line":"    cfg.StrOpt(\u0027agent_initrd_path\u0027,"},{"line_number":76,"context_line":"               help\u003d\u0027The path to the kernel image used to boot the agent. \u0027"},{"line_number":77,"context_line":"                    \u0027This will be put into the DHCP file if dhcp_provider \u0027"},{"line_number":78,"context_line":"                    \u0027is set to \"neutron\".\u0027),"},{"line_number":79,"context_line":"    cfg.StrOpt(\u0027agent_kernel_args\u0027,"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_34278f13","line":76,"updated":"2014-06-20 13:05:38.000000000","message":"s/kernel/ramdisk/","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        msg \u003d (_(\u0027Node %s failed to power off while handling deploy \u0027"},{"line_number":129,"context_line":"                 \u0027failure. This may be a serious condition. Node \u0027"},{"line_number":130,"context_line":"                 \u0027should be removed from Ironic or put in maintenance \u0027"},{"line_number":131,"context_line":"                 \u0027mode until the problem is resolved.\u0027) % node.uuid)"},{"line_number":132,"context_line":"        LOG.error(msg)"},{"line_number":133,"context_line":"    finally:"},{"line_number":134,"context_line":"        # NOTE(deva): node_power_action() erases node.last_error"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_7474b7fd","line":131,"updated":"2014-06-20 13:05:38.000000000","message":"instead of formatting here, use \n\n LOG.error(msg, node.uuid)\n\nYou may also want to either add real error message or use LOG.exception to show traceback","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        \u0027destroy\u0027: [states.POWER_OFF, states.NOSTATE]"},{"line_number":147,"context_line":"    }"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    def validate(self, task, node):"},{"line_number":150,"context_line":"        \"\"\"Validate the driver-specific Node deployment info."},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"        This method validates whether the \u0027instance_info\u0027 property of the"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_94f4e355","line":149,"updated":"2014-06-20 13:05:38.000000000","message":"node argument was deleted from validate()","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":323,"context_line":"        No validation necessary."},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"        :param task: a TaskManager instance"},{"line_number":326,"context_line":"        :param method: the vendor method to be called after validate"},{"line_number":327,"context_line":"        \"\"\""},{"line_number":328,"context_line":"        pass"},{"line_number":329,"context_line":""}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_14a0d340","line":326,"updated":"2014-06-20 13:05:38.000000000","message":"there is no method argument in signature","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":395,"context_line":"                    and not self._deploy_is_done(node)):"},{"line_number":396,"context_line":"                return"},{"line_number":397,"context_line":"        except Exception:"},{"line_number":398,"context_line":"            LOG.exception(\u0027Async exception for %(node)s: %(msg)s\u0027,"},{"line_number":399,"context_line":"                          {\u0027node\u0027: node,"},{"line_number":400,"context_line":"                           \u0027msg\u0027: msg})"},{"line_number":401,"context_line":"            _set_failed_state(task, msg)"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_747e77b0","line":398,"updated":"2014-06-20 13:05:38.000000000","message":"\"Async exception\" may be vague for an operator. I would expand to something like \"Exception during action %(action)s in response to heartbeat from node %(node)s: %(msg)s\".\n\naction would designate what you tried to do based on node.provision_state","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":406,"context_line":"    def _continue_deploy(self, task, **kwargs):"},{"line_number":407,"context_line":"        node \u003d task.node"},{"line_number":408,"context_line":"        node.provision_state \u003d states.DEPLOYING"},{"line_number":409,"context_line":"        node.save(task.context)"},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"        LOG.info(_(\u0027Continuing deploy for %s\u0027), node.uuid)"},{"line_number":412,"context_line":""}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_14137365","line":409,"updated":"2014-06-20 13:05:38.000000000","message":"I suggest moving this block after line #422, so that DEPLOYING state is not set in case of exception and action is retried on next heartbeat","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":424,"context_line":"        # Tell the client to download and write the image with the given args"},{"line_number":425,"context_line":"        res \u003d self._client.prepare_image(node, image_info, configdrive)"},{"line_number":426,"context_line":"        LOG.debug(\u0027prepare_image got response %(res)s for node %(node)s\u0027,"},{"line_number":427,"context_line":"                  {\u0027res\u0027: res, \u0027node\u0027: node})"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _check_deploy_success(self, node):"},{"line_number":430,"context_line":"        # should only ever be called after we\u0027ve validated that"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_b7756199","line":427,"updated":"2014-06-20 13:05:38.000000000","message":"It\u0027s arguable, but based on recent discussions about logging, I would suggest having one more info() log in the end, so that we designate both beginning and ending of this unit-of-work","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":441,"context_line":"        if error is not None:"},{"line_number":442,"context_line":"            # TODO(jimrollenhagen) power off if using neutron dhcp to"},{"line_number":443,"context_line":"            #                      align with pxe driver?"},{"line_number":444,"context_line":"            LOG.error(_(\u0027node %(node)s command status errored: %(error)s\u0027),"},{"line_number":445,"context_line":"                      {\u0027node\u0027: node.uuid,"},{"line_number":446,"context_line":"                       \u0027error\u0027: error})"},{"line_number":447,"context_line":"            node.provision_state \u003d states.DEPLOYFAIL"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_373b11d2","line":444,"updated":"2014-06-20 13:05:38.000000000","message":"I would suggest \"Agent on node %(node)s reported error after deploy: %(error)s\"","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":461,"context_line":"        LOG.info(_(\u0027Powering on node %s to finish deploying instance.\u0027),"},{"line_number":462,"context_line":"                 node.uuid)"},{"line_number":463,"context_line":"        # TODO(jimrollenhagen) client.run_image(node)"},{"line_number":464,"context_line":"        task.driver.ipmi_vendor._bmc_reset(task, warm\u003dTrue)"},{"line_number":465,"context_line":"        task.driver.ipmi_vendor._send_raw_bytes(task, \u00270x00 0x08 0x03 0x08\u0027)"},{"line_number":466,"context_line":"        manager_utils.node_set_boot_device(task, \u0027disk\u0027, persistent\u003dTrue)"},{"line_number":467,"context_line":"        #NOTE(JoshNang) probably not needed. Testing before deleting."}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_375f9142","line":464,"updated":"2014-06-20 13:05:38.000000000","message":"these methods should be converted to public there (no more _, proper docstrings etc)","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":471,"context_line":""},{"line_number":472,"context_line":"        node.provision_state \u003d states.ACTIVE"},{"line_number":473,"context_line":"        node.target_provision_state \u003d states.NOSTATE"},{"line_number":474,"context_line":"        node.save(task.context)"},{"line_number":475,"context_line":""},{"line_number":476,"context_line":"    def _continue_tear_down(self, task, **kwargs):"},{"line_number":477,"context_line":"        # TODO(jimrollenhagen) decom things"}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_f76b69b6","line":474,"updated":"2014-06-20 13:05:38.000000000","message":"See above about logging in the end","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":537,"context_line":""},{"line_number":538,"context_line":"        Originally, the agent did not send versioned hardware payloads."},{"line_number":539,"context_line":"        Unversioned payloads will be treated as v0 until they can be fully"},{"line_number":540,"context_line":"        deprecated."},{"line_number":541,"context_line":""},{"line_number":542,"context_line":"        The interfaces list should include a list of the non-IPMI MAC addresses"},{"line_number":543,"context_line":"        in the form aa:bb:cc:dd:ee:ff."}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_520fcb2d","line":540,"updated":"2014-06-20 13:05:38.000000000","message":"Btw, this is one of the things I want to see in the spec: when old interfaces are going to be deprecated","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":674,"context_line":"        \"\"\""},{"line_number":675,"context_line":"        ports \u003d []"},{"line_number":676,"context_line":"        for mac in mac_addresses:"},{"line_number":677,"context_line":"            # Will do a search by mac if the mac isn\u0027t malformed"},{"line_number":678,"context_line":"            try:"},{"line_number":679,"context_line":"                # TODO(JoshNang) add port.get_by_mac() to Ironic"},{"line_number":680,"context_line":"                # port.get_by_uuid() would technically work but shouldn\u0027t."}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_523d0bba","line":677,"updated":"2014-06-20 13:05:38.000000000","message":"\"if the mac isn\u0027t malformed\" \u003c- IIUC check on mac correctness was done before in _get_mac_addresses","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"}],"ironic/drivers/modules/agent_client.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        self.log \u003d log.getLogger(__name__)"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def _get_command_url(self, node):"},{"line_number":31,"context_line":"        if \u0027agent_url\u0027 not in node.driver_info:"},{"line_number":32,"context_line":"            raise exception.IronicException(_(\u0027REST Agent requires agent_url\u0027))"},{"line_number":33,"context_line":"        return \u0027{0}/v1.0/commands\u0027.format(node.driver_info[\u0027agent_url\u0027])"},{"line_number":34,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rlc%3D","line":31,"updated":"2014-04-02 20:52:01.000000000","message":"Should be instance_info, not driver_info, here. See the passthru stuff where it\u0027s stored.","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def _get_command_url(self, node):"},{"line_number":31,"context_line":"        if \u0027agent_url\u0027 not in node.driver_info:"},{"line_number":32,"context_line":"            raise exception.IronicException(_(\u0027REST Agent requires agent_url\u0027))"},{"line_number":33,"context_line":"        return \u0027{0}/v1.0/commands\u0027.format(node.driver_info[\u0027agent_url\u0027])"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def _get_command_body(self, method, params):"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rpg%3D","line":32,"updated":"2014-04-02 20:52:01.000000000","message":"maybe s/REST Agent/Agent driver/ ?","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                             },"},{"line_number":84,"context_line":"                             wait\u003dwait)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    #TODO(pcsforeducation) match agent function def to this."},{"line_number":87,"context_line":"    def run_image(self, node, wait\u003dFalse):"},{"line_number":88,"context_line":"        \"\"\"Run the specified image.\"\"\""},{"line_number":89,"context_line":"        self.log.debug(_(\u0027Running image on node %s.\u0027) %"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9roQ%3D","line":86,"updated":"2014-04-02 20:52:01.000000000","message":"Is this still a TODO? This matches agent side afaik.","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3b71a99388636b9fd2cf52ef6df290715f7743df","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        return jsonutils.dumps({"},{"line_number":37,"context_line":"            \u0027name\u0027: method,"},{"line_number":38,"context_line":"            \u0027params\u0027: params,"},{"line_number":39,"context_line":"        })"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def _command(self, node, method, params, wait\u003dFalse):"},{"line_number":42,"context_line":"        url \u003d self._get_command_url(node)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6xo%3D","line":39,"updated":"2014-04-16 14:20:59.000000000","message":"Is there any particular reason to keep this one-liner as a separate method? It seems to me that it is used only in one place.","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4e4e1e1766dbca45a0f0e11aeb054545463f91dc","unresolved":false,"context_lines":[{"line_number":24,"context_line":"    \"\"\"Client for interacting with nodes via a REST API.\"\"\""},{"line_number":25,"context_line":"    def __init__(self):"},{"line_number":26,"context_line":"        self.session \u003d requests.Session()"},{"line_number":27,"context_line":"        self.log \u003d log.getLogger(__name__)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def _get_command_url(self, node):"},{"line_number":30,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAAXH%2F%2FuTY%3D","line":27,"updated":"2014-04-17 22:08:53.000000000","message":"Shouldn\u0027t this be top-level?","commit_id":"ea3997ee82f8bf9c2ef4a42e85507a59eea34a75"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        self.session \u003d requests.Session()"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def _get_command_url(self, node):"},{"line_number":31,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":32,"context_line":"            raise exception.IronicException(_(\u0027Agent driver requires \u0027"},{"line_number":33,"context_line":"                                              \u0027agent_url\u0027))"},{"line_number":34,"context_line":"        return \u0027{0}/v1.0/commands\u0027.format(node.instance_info[\u0027agent_url\u0027])"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_67f121cd","line":31,"updated":"2014-05-01 08:32:35.000000000","message":"Shouldn\u0027t this be stashed in node.driver_info?\n\nThe intent - AIUI - is for driver_info to store the private details needed by the driver to manage the node, and for instance_info to store the more public, temporary information related to the Nova instance running on the node.\n\nMaybe I misunderstand something, but why would agent_url be related to the Nova instance? It seems pretty clearly a driver detail.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        self.session \u003d requests.Session()"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def _get_command_url(self, node):"},{"line_number":31,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":32,"context_line":"            raise exception.IronicException(_(\u0027Agent driver requires \u0027"},{"line_number":33,"context_line":"                                              \u0027agent_url\u0027))"},{"line_number":34,"context_line":"        return \u0027{0}/v1.0/commands\u0027.format(node.instance_info[\u0027agent_url\u0027])"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_2f219e9f","line":31,"in_reply_to":"9ad9bd40_67f121cd","updated":"2014-05-02 16:51:13.000000000","message":"Definitely. Agent URL is definitely a driver detail.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":32,"context_line":"            raise exception.IronicException(_(\u0027Agent driver requires \u0027"},{"line_number":33,"context_line":"                                              \u0027agent_url\u0027))"},{"line_number":34,"context_line":"        return \u0027{0}/v1.0/commands\u0027.format(node.instance_info[\u0027agent_url\u0027])"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def _get_command_body(self, method, params):"},{"line_number":37,"context_line":"        return jsonutils.dumps({"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_07b135f8","line":34,"updated":"2014-05-01 08:32:35.000000000","message":"A constant string with both major and minor version does not seem very flexible. How will you handle changes in the agent\u0027s API? How will you handle upgrades?","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        if \u0027agent_url\u0027 not in node.instance_info:"},{"line_number":32,"context_line":"            raise exception.IronicException(_(\u0027Agent driver requires \u0027"},{"line_number":33,"context_line":"                                              \u0027agent_url\u0027))"},{"line_number":34,"context_line":"        return \u0027{0}/v1.0/commands\u0027.format(node.instance_info[\u0027agent_url\u0027])"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def _get_command_body(self, method, params):"},{"line_number":37,"context_line":"        return jsonutils.dumps({"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_8f10ea4f","line":34,"in_reply_to":"9ad9bd40_07b135f8","updated":"2014-05-02 16:51:13.000000000","message":"Good call. I added a config option. The agent API is currently versioned similarly to the Ironic API.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4c169ee76573c130ae8da9a8090a9bae3209a15b","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        headers \u003d {"},{"line_number":49,"context_line":"            \u0027Content-Type\u0027: \u0027application/json\u0027"},{"line_number":50,"context_line":"        }"},{"line_number":51,"context_line":"        response \u003d self.session.post(url,"},{"line_number":52,"context_line":"                                     params\u003drequest_params,"},{"line_number":53,"context_line":"                                     data\u003dbody,"},{"line_number":54,"context_line":"                                     headers\u003dheaders)"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_879c656b","line":51,"updated":"2014-05-01 08:32:35.000000000","message":"It appears that all interactions with the agent are synchronous... how are you going to handle operations longer than HTTP timeout?","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"67eb312c36a5a964c8582bbb5b020e599ae7a31b","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        headers \u003d {"},{"line_number":49,"context_line":"            \u0027Content-Type\u0027: \u0027application/json\u0027"},{"line_number":50,"context_line":"        }"},{"line_number":51,"context_line":"        response \u003d self.session.post(url,"},{"line_number":52,"context_line":"                                     params\u003drequest_params,"},{"line_number":53,"context_line":"                                     data\u003dbody,"},{"line_number":54,"context_line":"                                     headers\u003dheaders)"}],"source_content_type":"text/x-python","patch_set":49,"id":"9ad9bd40_4cd7d0c1","line":51,"in_reply_to":"9ad9bd40_879c656b","updated":"2014-05-02 16:51:13.000000000","message":"The wait param determines if the agent will immediately return (and you can poll command status to check for command completion) if wait\u003dFalse or wait until the entire command is completed if wait\u003dTrue.\n\nThis whole library needs a lot more documentation, so things like this are more obvious.","commit_id":"03c20077a1fa08adfe1246777affa9269a164662"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"5f81b5e88bf0cc66ca3f4b9e42a01e1fa342219a","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def cache_image(self, node, image_info, force\u003dFalse, wait\u003dFalse):"},{"line_number":94,"context_line":"        \"\"\"Attempt to cache the specified image.\"\"\""},{"line_number":95,"context_line":"        LOG.debug(_(\u0027Caching image %(image)s on node %(node)s.\u0027) %"},{"line_number":96,"context_line":"                  {\u0027image\u0027: image_info.get(\u0027image_id\u0027),"},{"line_number":97,"context_line":"                   \u0027node\u0027: self._get_command_url(node)})"},{"line_number":98,"context_line":"        params \u003d {"}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_1851a462","line":95,"updated":"2014-05-08 11:11:11.000000000","message":"Please don\u0027t interpolate Python\u0027s logging (`%` -\u003e `,`)\n\n    LOG.debug(_(\u0027Caching image %(image)s on node %(node)s.\u0027),\n              {\u0027image\u0027: image_info.get(\u0027image_id\u0027), \n               \u0027node\u0027: self._get_command_url(node)})\n\nthis also applies to others.","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"cdbde9f9334b85e8ab11d2bd78ce09c6f0446401","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def cache_image(self, node, image_info, force\u003dFalse, wait\u003dFalse):"},{"line_number":94,"context_line":"        \"\"\"Attempt to cache the specified image.\"\"\""},{"line_number":95,"context_line":"        LOG.debug(_(\u0027Caching image %(image)s on node %(node)s.\u0027) %"},{"line_number":96,"context_line":"                  {\u0027image\u0027: image_info.get(\u0027image_id\u0027),"},{"line_number":97,"context_line":"                   \u0027node\u0027: self._get_command_url(node)})"},{"line_number":98,"context_line":"        params \u003d {"}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_50de9240","line":95,"in_reply_to":"7adec928_1851a462","updated":"2014-05-08 23:26:46.000000000","message":"Done","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"1c1923116c759a0900b6434deb66bfd06ad000a2","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        if \u0027agent_url\u0027 not in node.driver_info:"},{"line_number":41,"context_line":"            raise exception.IronicException(_(\u0027Agent driver requires \u0027"},{"line_number":42,"context_line":"                                              \u0027agent_url in driver_info\u0027))"},{"line_number":43,"context_line":"        return (_(\u0027%(agent_url)s/%(api_version)s/commands\u0027) %"},{"line_number":44,"context_line":"                {\u0027agent_url\u0027: node.driver_info[\u0027agent_url\u0027],"},{"line_number":45,"context_line":"                 \u0027api_version\u0027: CONF.agent.agent_api_version})"},{"line_number":46,"context_line":""}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_41176d51","line":43,"updated":"2014-05-13 14:31:46.000000000","message":"I think translation (_) not needed here.","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"c57fe97d1e437c69ec56a848aa73f4eb593a315c","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        if \u0027agent_url\u0027 not in node.driver_info:"},{"line_number":41,"context_line":"            raise exception.IronicException(_(\u0027Agent driver requires \u0027"},{"line_number":42,"context_line":"                                              \u0027agent_url in driver_info\u0027))"},{"line_number":43,"context_line":"        return (_(\u0027%(agent_url)s/%(api_version)s/commands\u0027) %"},{"line_number":44,"context_line":"                {\u0027agent_url\u0027: node.driver_info[\u0027agent_url\u0027],"},{"line_number":45,"context_line":"                 \u0027api_version\u0027: CONF.agent.agent_api_version})"},{"line_number":46,"context_line":""}],"source_content_type":"text/x-python","patch_set":78,"id":"7adec928_f42ae32a","line":43,"in_reply_to":"7adec928_41176d51","updated":"2014-05-16 22:31:07.000000000","message":"Done","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def cache_image(self, node, image_info, force\u003dFalse, wait\u003dFalse):"},{"line_number":94,"context_line":"        \"\"\"Attempt to cache the specified image.\"\"\""},{"line_number":95,"context_line":"        LOG.debug(_(\u0027Caching image %(image)s on node %(node)s.\u0027),"},{"line_number":96,"context_line":"                  {\u0027image\u0027: image_info.get(\u0027image_id\u0027),"},{"line_number":97,"context_line":"                   \u0027node\u0027: self._get_command_url(node)})"},{"line_number":98,"context_line":"        params \u003d {"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_a58250fe","line":95,"updated":"2014-05-26 10:55:45.000000000","message":"debug messages should not be translated","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def cache_image(self, node, image_info, force\u003dFalse, wait\u003dFalse):"},{"line_number":94,"context_line":"        \"\"\"Attempt to cache the specified image.\"\"\""},{"line_number":95,"context_line":"        LOG.debug(_(\u0027Caching image %(image)s on node %(node)s.\u0027),"},{"line_number":96,"context_line":"                  {\u0027image\u0027: image_info.get(\u0027image_id\u0027),"},{"line_number":97,"context_line":"                   \u0027node\u0027: self._get_command_url(node)})"},{"line_number":98,"context_line":"        params \u003d {"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_3afc943e","line":95,"in_reply_to":"5adbc538_a58250fe","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def prepare_image(self, node, image_info, configdrive, wait\u003dFalse):"},{"line_number":108,"context_line":"        \"\"\"Call the `prepare_image` method on the node.\"\"\""},{"line_number":109,"context_line":"        LOG.debug(_(\u0027Preparing image %(image)s on node %(node)s.\u0027),"},{"line_number":110,"context_line":"                  {\u0027image\u0027: image_info.get(\u0027id\u0027),"},{"line_number":111,"context_line":"                   \u0027node\u0027: self._get_command_url(node)})"},{"line_number":112,"context_line":"        return self._command(node\u003dnode,"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_e57b7827","line":109,"updated":"2014-05-26 10:55:45.000000000","message":"ditto","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def prepare_image(self, node, image_info, configdrive, wait\u003dFalse):"},{"line_number":108,"context_line":"        \"\"\"Call the `prepare_image` method on the node.\"\"\""},{"line_number":109,"context_line":"        LOG.debug(_(\u0027Preparing image %(image)s on node %(node)s.\u0027),"},{"line_number":110,"context_line":"                  {\u0027image\u0027: image_info.get(\u0027id\u0027),"},{"line_number":111,"context_line":"                   \u0027node\u0027: self._get_command_url(node)})"},{"line_number":112,"context_line":"        return self._command(node\u003dnode,"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_5af9604c","line":109,"in_reply_to":"5adbc538_e57b7827","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def run_image(self, node, wait\u003dFalse):"},{"line_number":121,"context_line":"        \"\"\"Run the specified image.\"\"\""},{"line_number":122,"context_line":"        LOG.debug(_(\u0027Running image on node %s.\u0027),"},{"line_number":123,"context_line":"                  self._get_command_url(node))"},{"line_number":124,"context_line":"        return self._command(node\u003dnode,"},{"line_number":125,"context_line":"                             method\u003d\u0027standby.run_image\u0027,"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_2576403f","line":122,"updated":"2014-05-26 10:55:45.000000000","message":"ditto","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def run_image(self, node, wait\u003dFalse):"},{"line_number":121,"context_line":"        \"\"\"Run the specified image.\"\"\""},{"line_number":122,"context_line":"        LOG.debug(_(\u0027Running image on node %s.\u0027),"},{"line_number":123,"context_line":"                  self._get_command_url(node))"},{"line_number":124,"context_line":"        return self._command(node\u003dnode,"},{"line_number":125,"context_line":"                             method\u003d\u0027standby.run_image\u0027,"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_7a953ce3","line":122,"in_reply_to":"5adbc538_2576403f","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    def secure_drives(self, node, drives, key, wait\u003dFalse):"},{"line_number":130,"context_line":"        \"\"\"Secures given drives with given key.\"\"\""},{"line_number":131,"context_line":"        LOG.info(\u0027Securing drives %s for node %s\u0027,"},{"line_number":132,"context_line":"                 drives, self._get_command_url(node))"},{"line_number":133,"context_line":"        params \u003d {"},{"line_number":134,"context_line":"            \u0027drives\u0027: drives,"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_65b688de","line":131,"updated":"2014-05-26 10:55:45.000000000","message":"Afaik, when there is more than 1 parameter to substitute, the best practice is to use dict substitution","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    def secure_drives(self, node, drives, key, wait\u003dFalse):"},{"line_number":130,"context_line":"        \"\"\"Secures given drives with given key.\"\"\""},{"line_number":131,"context_line":"        LOG.info(\u0027Securing drives %s for node %s\u0027,"},{"line_number":132,"context_line":"                 drives, self._get_command_url(node))"},{"line_number":133,"context_line":"        params \u003d {"},{"line_number":134,"context_line":"            \u0027drives\u0027: drives,"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_5a03200f","line":131,"in_reply_to":"5adbc538_65b688de","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def erase_drives(self, node, drives, key, wait\u003dFalse):"},{"line_number":143,"context_line":"        \"\"\"Erases given drives.\"\"\""},{"line_number":144,"context_line":"        LOG.info(\u0027Erasing drives %s for node %s\u0027,"},{"line_number":145,"context_line":"                 drives, self._get_command_url(node))"},{"line_number":146,"context_line":"        params \u003d {"},{"line_number":147,"context_line":"            \u0027drives\u0027: drives,"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_85bb94c3","line":144,"updated":"2014-05-26 10:55:45.000000000","message":"ditto","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def erase_drives(self, node, drives, key, wait\u003dFalse):"},{"line_number":143,"context_line":"        \"\"\"Erases given drives.\"\"\""},{"line_number":144,"context_line":"        LOG.info(\u0027Erasing drives %s for node %s\u0027,"},{"line_number":145,"context_line":"                 drives, self._get_command_url(node))"},{"line_number":146,"context_line":"        params \u003d {"},{"line_number":147,"context_line":"            \u0027drives\u0027: drives,"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_c0ff4200","line":144,"in_reply_to":"5adbc538_85bb94c3","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":8106,"name":"Haomeng,Wang","email":"wanghaomeng@gmail.com","username":"whaom"},"change_message_id":"f3971a2f8f96164a60ddbed572c4599660e9dbc6","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    def secure_drives(self, node, drives, key, wait\u003dFalse):"},{"line_number":130,"context_line":"        \"\"\"Secures given drives with given key.\"\"\""},{"line_number":131,"context_line":"        LOG.info(\u0027Securing drives %(drives)s for node %(node)s\u0027,"},{"line_number":132,"context_line":"                 {\u0027drives\u0027: drives,"},{"line_number":133,"context_line":"                  \u0027node\u0027: self._get_command_url(node)})"},{"line_number":134,"context_line":"        params \u003d {"}],"source_content_type":"text/x-python","patch_set":97,"id":"1ae5cdf2_33a30ab3","line":131,"updated":"2014-06-14 14:54:51.000000000","message":"I understand this agent client codes are runing from our Ironic Conductor, so for the non-debug log items, we need to enable i18n with \u0027_(\"\")\u0027, this comment can be applied for all such same log codes, thank you.","commit_id":"2113c89222d3c900bf09b5eb04589aad0bce886a"}],"ironic/drivers/modules/agent_config.template":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"82d173a803fb91a6eca1c8e74fb0874314553351","unresolved":false,"context_lines":[{"line_number":2,"context_line":""},{"line_number":3,"context_line":"label deploy"},{"line_number":4,"context_line":"kernel {{ agent_options.deployment_aki_path }}"},{"line_number":5,"context_line":"append initrd\u003d{{ pxe_options.deployment_ari_path }} root\u003dsquashfs: {{ agent_options.kernel_command_args }} state\u003dtmpfs: ipa-api-url\u003d{% if agent_options.ipa_api_url %}{{ agent_options.ipa_api_url }}{% endif %} ipa-advertise-host\u003d{% if agent_options.ipa_advertise_host %}{{ agent_options.ipa_advertise_host }}{% endif %}"}],"source_content_type":"application/octet-stream","patch_set":57,"id":"9ad9bd40_184ec76f","line":5,"updated":"2014-05-02 19:02:33.000000000","message":"I think the if blocks should be around the entire argument, so you don\u0027t end up with: ipa-api-url\u003d ipa-advertise-host\u003d\n\nAlso, should probably add in all available ipa arguments.","commit_id":"01736d254587ee94b0c3227601fbae1d8c7e7378"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"1c1923116c759a0900b6434deb66bfd06ad000a2","unresolved":false,"context_lines":[{"line_number":1,"context_line":"default deploy"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"label deploy"},{"line_number":4,"context_line":"kernel {{ agent_options.deployment_aki_path }}"}],"source_content_type":"application/octet-stream","patch_set":78,"id":"7adec928_0479f392","line":1,"updated":"2014-05-13 14:31:46.000000000","message":"Maybe better name for this file \u0027agent_pxe_config.template\u0027.","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"c57fe97d1e437c69ec56a848aa73f4eb593a315c","unresolved":false,"context_lines":[{"line_number":1,"context_line":"default deploy"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"label deploy"},{"line_number":4,"context_line":"kernel {{ agent_options.deployment_aki_path }}"}],"source_content_type":"application/octet-stream","patch_set":78,"id":"7adec928_9406ffcc","line":1,"in_reply_to":"7adec928_0479f392","updated":"2014-05-16 22:31:07.000000000","message":"Done","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"}],"ironic/drivers/modules/agent_deploy.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        :param node: a single Node to validate."},{"line_number":51,"context_line":"        :raises: InvalidParameterValue"},{"line_number":52,"context_line":"        \"\"\""},{"line_number":53,"context_line":"        if \u0027agent_url\u0027 not in node.driver_info:"},{"line_number":54,"context_line":"            raise exception.InvalidParameterValue(_(\u0027Nodes require an \u0027"},{"line_number":55,"context_line":"                                                    \u0027agent_url.\u0027))"},{"line_number":56,"context_line":"        if node.instance_info is not None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rlY%3D","line":53,"updated":"2014-04-02 20:52:01.000000000","message":"Again this is stored in instance_info","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"}],"ironic/drivers/modules/agent_passthru.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"4dea7909f99a3a5911b863924c8f6eb2b8c40673","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from ironic.db.sqlalchemy import api as dbapi"},{"line_number":24,"context_line":"from ironic.drivers import base"},{"line_number":25,"context_line":"from ironic.objects import node"},{"line_number":26,"context_line":"#TODO(pcsforeducation) drop this when we move into Ironic"},{"line_number":27,"context_line":"from ironic.openstack.common.gettextutils import _"},{"line_number":28,"context_line":"from ironic.openstack.common import log"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9rmE%3D","line":26,"updated":"2014-04-02 20:52:01.000000000","message":"Should probably do this when moving into ironic ;)","commit_id":"5367f4a9a20808ba3a24459ca1d854569150c2c4"}],"ironic/drivers/modules/agent_utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"45888f39e172eb493950a88dc95cfdcdc3327e6b","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        information"},{"line_number":41,"context_line":"        \"\"\""},{"line_number":42,"context_line":"        for k, v in node[\u0027extra\u0027].items():"},{"line_number":43,"context_line":"            pass"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def remove_provisioning_network(self):"},{"line_number":46,"context_line":"        \"\"\"Remove the provisioning server from the node.\"\"\""}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_7fe6b9b5","line":43,"updated":"2014-05-05 09:31:35.000000000","message":"this function does not seem to be finished :) please at least leave a TODO here","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"e620e1b048ea9b89b6c389afa1677162208eac62","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        information"},{"line_number":41,"context_line":"        \"\"\""},{"line_number":42,"context_line":"        for k, v in node[\u0027extra\u0027].items():"},{"line_number":43,"context_line":"            pass"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def remove_provisioning_network(self):"},{"line_number":46,"context_line":"        \"\"\"Remove the provisioning server from the node.\"\"\""}],"source_content_type":"text/x-python","patch_set":62,"id":"9ad9bd40_05eff2e9","line":43,"in_reply_to":"9ad9bd40_7fe6b9b5","updated":"2014-05-06 18:03:03.000000000","message":"Done","commit_id":"e0eba7b1f28f6ad510bf0bd69da619a18da6abec"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            raise exception.InvalidParameterValue(_("},{"line_number":63,"context_line":"                \u0027Could not get interface info out of node\\\u0027s extra field.\u0027))"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def add_provisioning_network(self, node):"},{"line_number":66,"context_line":"        LOG.info(_(\u0027Adding the provisioning network for %s\u0027), node.uuid)"},{"line_number":67,"context_line":"        portmap \u003d self._get_node_portmap(node)"},{"line_number":68,"context_line":"        if not portmap:"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_05c78446","line":65,"updated":"2014-05-26 10:55:45.000000000","message":"docstring please","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            raise exception.InvalidParameterValue(_("},{"line_number":63,"context_line":"                \u0027Could not get interface info out of node\\\u0027s extra field.\u0027))"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def add_provisioning_network(self, node):"},{"line_number":66,"context_line":"        LOG.info(_(\u0027Adding the provisioning network for %s\u0027), node.uuid)"},{"line_number":67,"context_line":"        portmap \u003d self._get_node_portmap(node)"},{"line_number":68,"context_line":"        if not portmap:"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_e6e296d4","line":65,"in_reply_to":"5adbc538_05c78446","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    :param item: The dictionary to be flattened, or the current node"},{"line_number":208,"context_line":"    in the tree to examine in the recursive call"},{"line_number":209,"context_line":"    :param path: The path so far, separated by \u0027/\u0027 towards the leaf."},{"line_number":210,"context_line":"    \"\"\""},{"line_number":211,"context_line":"    if flattened is None:"},{"line_number":212,"context_line":"        flattened \u003d {}"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_e56c5839","line":209,"updated":"2014-05-26 10:55:45.000000000","message":"please document the remaining arguments","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":224,"context_line":"        if path:"},{"line_number":225,"context_line":"            path +\u003d separator"},{"line_number":226,"context_line":"        else:"},{"line_number":227,"context_line":"            path \u003d \u0027\u0027"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"        if isinstance(item, dict):"},{"line_number":230,"context_line":"            for k, v in item.items():"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_8509d497","line":227,"updated":"2014-05-26 10:55:45.000000000","message":"else clause is not needed","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":224,"context_line":"        if path:"},{"line_number":225,"context_line":"            path +\u003d separator"},{"line_number":226,"context_line":"        else:"},{"line_number":227,"context_line":"            path \u003d \u0027\u0027"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"        if isinstance(item, dict):"},{"line_number":230,"context_line":"            for k, v in item.items():"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_46026a3f","line":227,"in_reply_to":"5adbc538_8509d497","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":272,"context_line":""},{"line_number":273,"context_line":"            # Index out of range"},{"line_number":274,"context_line":"            if index \u003e\u003d len(array):"},{"line_number":275,"context_line":"                array +\u003d [{}] * (index - len(array) + 1)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"            # Set the item in the array"},{"line_number":278,"context_line":"            parent_item \u003d sub_item"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_65c76813","line":275,"updated":"2014-05-26 10:55:45.000000000","message":"I\u0027m not quite sure, is it intended that you create list of (index - len(array) + 1) copies of the same empty dict? If not, you should use:\n\n array +\u003d [{} for _ in range(index - len(array) + 1)]","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"ebfdcf3451851be122c2a5f7dc840bb5ef5f02c5","unresolved":false,"context_lines":[{"line_number":272,"context_line":""},{"line_number":273,"context_line":"            # Index out of range"},{"line_number":274,"context_line":"            if index \u003e\u003d len(array):"},{"line_number":275,"context_line":"                array +\u003d [{}] * (index - len(array) + 1)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"            # Set the item in the array"},{"line_number":278,"context_line":"            parent_item \u003d sub_item"}],"source_content_type":"text/x-python","patch_set":88,"id":"3ae8d1ca_a62c0ead","line":275,"in_reply_to":"5adbc538_65c76813","updated":"2014-05-28 00:22:04.000000000","message":"Done","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"dbe1edff00f87c6b81f9184378ad93d4cc8f90ec","unresolved":false,"context_lines":[{"line_number":222,"context_line":"                     \u0027node\u0027: node.uuid})"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"def flatten_dict(item, path\u003d\u0027\u0027, separator\u003d\u0027/\u0027, flattened\u003dNone):"},{"line_number":226,"context_line":"    \"\"\"Do a depth first search through the \u0027tree\u0027 of the dictionary"},{"line_number":227,"context_line":"    to flatten it out. Turns {\u0027a\u0027: {\u0027b\u0027: [\u0027c\u0027, \u0027d\u0027]}} into"},{"line_number":228,"context_line":"    {\u0027a/b/0\u0027: \u0027c\u0027, \u0027a/b/1\u0027: \u0027d\u0027}"}],"source_content_type":"text/x-python","patch_set":96,"id":"1ae5cdf2_64086029","line":225,"updated":"2014-06-06 14:48:58.000000000","message":"I found an issue with flatten_dict or unflaten_dict.\n\nhttp://paste.openstack.org/show/82789/ test snippet","commit_id":"f4eb7b850bb28a371f4ee2378b49461d96c9b489"}],"ironic/drivers/modules/ipmitool.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0dc63d40a92b7495be68851812a0f97797a37f62","unresolved":false,"context_lines":[{"line_number":383,"context_line":"            raise exception.IPMIFailure(cmd\u003dcmd)"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    # TODO(JoshNang) split these into separate patch"},{"line_number":386,"context_line":"    def _send_raw_bytes(self, task, raw_bytes):"},{"line_number":387,"context_line":"        \"\"\"Send raw bytes to the BMC. Bytes should be a string of bytes.\"\"\""},{"line_number":388,"context_line":"        LOG.debug(\"Sending raw bytes %(bytes)s to node %(node)s\","},{"line_number":389,"context_line":"                  {\"bytes\": raw_bytes,"}],"source_content_type":"text/x-python","patch_set":88,"id":"5adbc538_c5d67cc5","line":386,"updated":"2014-05-26 10:55:45.000000000","message":"If you use these methods from outside (and you do), they should not be marked as private (_)","commit_id":"75ebfa621b523d58b58a072de6196b911608ffbf"},{"author":{"_account_id":8106,"name":"Haomeng,Wang","email":"wanghaomeng@gmail.com","username":"whaom"},"change_message_id":"f3971a2f8f96164a60ddbed572c4599660e9dbc6","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            raise exception.IPMIFailure(cmd\u003dcmd)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"    # TODO(JoshNang) split these into separate patch"},{"line_number":385,"context_line":"    def _send_raw_bytes(self, task, raw_bytes):"},{"line_number":386,"context_line":"        \"\"\"Send raw bytes to the BMC. Bytes should be a string of bytes.\"\"\""},{"line_number":387,"context_line":"        LOG.debug(\"Sending raw bytes %(bytes)s to node %(node)s\","},{"line_number":388,"context_line":"                  {\"bytes\": raw_bytes,"}],"source_content_type":"text/x-python","patch_set":97,"id":"1ae5cdf2_b3963a4a","line":385,"updated":"2014-06-14 14:54:51.000000000","message":"It is better that we add the method arguments document string here for the these new methods, thanks.","commit_id":"2113c89222d3c900bf09b5eb04589aad0bce886a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"991df2bf6b9404e3438800b2372e0b997850cfc4","unresolved":false,"context_lines":[{"line_number":378,"context_line":"        except Exception:"},{"line_number":379,"context_line":"            raise exception.IPMIFailure(cmd\u003dcmd)"},{"line_number":380,"context_line":""},{"line_number":381,"context_line":"    # TODO(JoshNang) split these into separate patch"},{"line_number":382,"context_line":"    def _send_raw_bytes(self, task, raw_bytes):"},{"line_number":383,"context_line":"        \"\"\"Send raw bytes to the BMC. Bytes should be a string of bytes.\"\"\""},{"line_number":384,"context_line":"        LOG.debug(\"Sending raw bytes %(bytes)s to node %(node)s\","}],"source_content_type":"text/x-python","patch_set":98,"id":"1ae5cdf2_f26b77b6","line":381,"updated":"2014-06-20 13:05:38.000000000","message":"Should be separate patch, agreed, and these methods should be w/o _ as they\u0027re public","commit_id":"f2eb5fc0aaefd7cebc6aec0a0c9a396d0aa9ff1d"}],"ironic/drivers/modules/pxe.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6c22acb469a61d3326dd27cc0e592036170b01ed","unresolved":false,"context_lines":[{"line_number":64,"context_line":"               default\u003d\u0027/var/lib/ironic/master_images\u0027,"},{"line_number":65,"context_line":"               help\u003d\u0027Directory where master instance images are stored on \u0027"},{"line_number":66,"context_line":"                    \u0027disk.\u0027),"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    ]"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"LOG \u003d logging.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_71bc966d","side":"PARENT","line":67,"updated":"2014-04-30 12:10:46.000000000","message":"While it\u0027s a valid change, this will cause unnecessary conflicts with other changes (e.g. I modify this peace of code, and some other patches also do)","commit_id":"59b26bcceeeb1fc3dd094b661178bc8d3245a393"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"f7309cbed2a1d5a44b8992e176124fc5a5a28cde","unresolved":false,"context_lines":[{"line_number":64,"context_line":"               default\u003d\u0027/var/lib/ironic/master_images\u0027,"},{"line_number":65,"context_line":"               help\u003d\u0027Directory where master instance images are stored on \u0027"},{"line_number":66,"context_line":"                    \u0027disk.\u0027),"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    ]"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"LOG \u003d logging.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":43,"id":"9ad9bd40_5ff94c4c","side":"PARENT","line":67,"in_reply_to":"9ad9bd40_71bc966d","updated":"2014-04-30 21:46:01.000000000","message":"Gotcha. Must have been a copy paste fail or something.","commit_id":"59b26bcceeeb1fc3dd094b661178bc8d3245a393"}],"ironic/nova/tests/virt/ironic/test_driver.py":[{"author":{"_account_id":7882,"name":"Yuiko Takada Mori","email":"yuiko-mori@nec.com","username":"YuikoTakada"},"change_message_id":"9a1dc68992a409531320c4125f0d6c45621e0d75","unresolved":false,"context_lines":[{"line_number":978,"context_line":"        self.driver._add_driver_fields(node, instance, {\u0027id\u0027: \u0027test\u0027}, None)"},{"line_number":979,"context_line":"        mock_update.assert_called_once_with(node_uuid, expected_body)"},{"line_number":980,"context_line":""},{"line_number":981,"context_line":"        mock_update.assert_called_once_with(node_uuid, expected_body)"},{"line_number":982,"context_line":""},{"line_number":983,"context_line":"    @mock.patch.object(FAKE_CLIENT.node, \u0027update\u0027)"},{"line_number":984,"context_line":"    def test__cleanup_agent_deploy(self, mock_update):"}],"source_content_type":"text/x-python","patch_set":73,"id":"7adec928_b35b6053","line":981,"updated":"2014-05-09 01:07:14.000000000","message":"Could you please teach my why mock_update.assert_called_once_with(node_uuid, expected_body) is called 2 times?","commit_id":"3df7752c1a7cb28e348d7bbdf9671c2a4f66add5"}],"ironic/nova/virt/ironic/driver.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3d924ec993da1d8fa8567337f497c70c4f6cf24a","unresolved":false,"context_lines":[{"line_number":629,"context_line":"        # Compress file"},{"line_number":630,"context_line":"        uncompressed.seek(0)"},{"line_number":631,"context_line":"        g \u003d gzip.GzipFile(fileobj\u003dcompressed, mode\u003d\u0027wb\u0027)"},{"line_number":632,"context_line":"        g.writelines(uncompressed.readlines())"},{"line_number":633,"context_line":"        #TODO(JoshNang) add option to upload to swift. For now, base64 encode"},{"line_number":634,"context_line":"        # and store in DB field."},{"line_number":635,"context_line":"        compressed.seek(0)"}],"source_content_type":"text/x-python","patch_set":38,"id":"AAAAXX%2F%2F6G4%3D","line":632,"updated":"2014-04-25 11:45:04.000000000","message":"you\u0027d better close GzipFile. Using `with` statement with GzipFIle was not possible in Py2.6, but you have alternatives like contextlib.clising and just plain try..finally.","commit_id":"24df3bc6da80eac08b6994ca483c5b36b7db01d1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3d924ec993da1d8fa8567337f497c70c4f6cf24a","unresolved":false,"context_lines":[{"line_number":635,"context_line":"        compressed.seek(0)"},{"line_number":636,"context_line":"        encoded_configdrive \u003d base64.b64encode(compressed.read())"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"        # Close the files to ensure immediate deletion"},{"line_number":639,"context_line":"        uncompressed.close()"},{"line_number":640,"context_line":"        compressed.close()"},{"line_number":641,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"AAAAXX%2F%2F6Fw%3D","line":638,"updated":"2014-04-25 11:45:04.000000000","message":"Also, to _ensure_ immediate deletion, use `with` statement (if it\u0027s available on Py2.6) or try..finally","commit_id":"24df3bc6da80eac08b6994ca483c5b36b7db01d1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f2afe11c2d9287ed214ab2c6194cea58819f75cc","unresolved":false,"context_lines":[{"line_number":634,"context_line":"                # Compress file"},{"line_number":635,"context_line":"                uncompressed.seek(0)"},{"line_number":636,"context_line":"                g \u003d gzip.GzipFile(fileobj\u003dcompressed, mode\u003d\u0027wb\u0027)"},{"line_number":637,"context_line":"                g.writelines(uncompressed.readlines())"},{"line_number":638,"context_line":""},{"line_number":639,"context_line":"                #TODO(JoshNang) add option to upload to swift. For now,"},{"line_number":640,"context_line":"                # base64 encode and store in DB field."}],"source_content_type":"text/x-python","patch_set":40,"id":"AAAAXX%2F%2FvsI%3D","line":637,"updated":"2014-04-28 09:43:50.000000000","message":"Please do explicitly close `g` here. I don\u0027t need proper try..finally, as it\u0027s temporary files, just g.close() will be enough. Otherwise, there\u0027s a risk, that gzip footer won\u0027t be written.","commit_id":"845afb0595a2a5988ca5dc65717a2bfbb2622a86"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"dc8be221e8dc2551f265db3a89b927b587dc21fa","unresolved":false,"context_lines":[{"line_number":635,"context_line":"                # Compress file"},{"line_number":636,"context_line":"                uncompressed.seek(0)"},{"line_number":637,"context_line":"                g \u003d gzip.GzipFile(fileobj\u003dcompressed, mode\u003d\u0027wb\u0027)"},{"line_number":638,"context_line":"                g.writelines(uncompressed.readlines())"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"                #TODO(JoshNang) add option to upload to swift. For now,"},{"line_number":641,"context_line":"                # base64 encode and store in DB field."}],"source_content_type":"text/x-python","patch_set":41,"id":"bad4c104_761d6d73","line":638,"updated":"2014-04-29 13:05:03.000000000","message":"Hi! Do you have any objections against calling g.close()? We can discuss it on IRC, if you in doubts","commit_id":"2d1765acded1fffcb35ae902261991a4cca06496"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"a309792d77ca8ef6f75de68c7f6394521e94e240","unresolved":false,"context_lines":[{"line_number":635,"context_line":"                # Compress file"},{"line_number":636,"context_line":"                uncompressed.seek(0)"},{"line_number":637,"context_line":"                g \u003d gzip.GzipFile(fileobj\u003dcompressed, mode\u003d\u0027wb\u0027)"},{"line_number":638,"context_line":"                g.writelines(uncompressed.readlines())"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"                #TODO(JoshNang) add option to upload to swift. For now,"},{"line_number":641,"context_line":"                # base64 encode and store in DB field."}],"source_content_type":"text/x-python","patch_set":41,"id":"bad4c104_b8351f48","line":638,"in_reply_to":"bad4c104_761d6d73","updated":"2014-04-29 15:11:20.000000000","message":"It\u0027s unnecessary according to the docs because we pass in a fileobj instead of filename and don\u0027t write anything else to the file. g.close() wouldn\u0027t hurt so I\u0027ll add it just so its clear :)","commit_id":"2d1765acded1fffcb35ae902261991a4cca06496"}],"ironic/tests/drivers/test_agent.py":[{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"ed212ad7c19a93ffafc64d45606b9845da5964ab","unresolved":false,"context_lines":[{"line_number":21,"context_line":"from ironic.openstack.common import test"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"class FakeNode(object):"},{"line_number":25,"context_line":"    provision_state \u003d states.NOSTATE"},{"line_number":26,"context_line":"    target_provision_state \u003d states.NOSTATE"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAW3%2F%2FUDU%3D","line":24,"updated":"2014-04-15 12:32:44.000000000","message":"There is get_test_node() method. Usage https://github.com/openstack/ironic/blob/master/ironic/tests/drivers/test_pxe.py#L61","commit_id":"8df74f85b4d93994b4cedc4428f6a52630cf8d9d"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"ed212ad7c19a93ffafc64d45606b9845da5964ab","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        self.context \u003d {}"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"class FakePort(object):"},{"line_number":64,"context_line":"    def __init__(self, uuid\u003dNone, node_id\u003dNone):"},{"line_number":65,"context_line":"        self.uuid \u003d uuid or \u0027fake-uuid\u0027"},{"line_number":66,"context_line":"        self.node_id \u003d node_id or \u0027fake-node\u0027"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAW3%2F%2FUC8%3D","line":63,"updated":"2014-04-15 12:32:44.000000000","message":"ditto l24","commit_id":"8df74f85b4d93994b4cedc4428f6a52630cf8d9d"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"ed212ad7c19a93ffafc64d45606b9845da5964ab","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                                          node_mock):"},{"line_number":250,"context_line":"        ports_mock.return_value \u003d []"},{"line_number":251,"context_line":"        node_id_mock.return_value \u003d \u0027fake-uuid\u0027"},{"line_number":252,"context_line":"        node_mock.side_effect \u003d db_exc.NoResultFound()"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        macs \u003d [\u0027aa:bb:cc:dd:ee:ff\u0027]"},{"line_number":255,"context_line":"        self.assertRaises(exception.NodeNotFound,"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAW3%2F%2FUJQ%3D","line":252,"updated":"2014-04-15 12:32:44.000000000","message":"exception.NodeNotFound should be used here.","commit_id":"8df74f85b4d93994b4cedc4428f6a52630cf8d9d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3b71a99388636b9fd2cf52ef6df290715f7743df","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        time_patcher \u003d mock.patch.object(agent, \u0027_time\u0027)"},{"line_number":133,"context_line":"        self.time_mock \u003d time_patcher.start()"},{"line_number":134,"context_line":"        self.fake_time \u003d 1395964422"},{"line_number":135,"context_line":"        self.time_mock.return_value \u003d self.fake_time"},{"line_number":136,"context_line":"        self.task \u003d FakeTask()"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    def _create_test_node(self, **kwargs):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAXH%2F%2F6vw%3D","line":135,"updated":"2014-04-16 14:20:59.000000000","message":"Please consider making this 3 mocks class-level decorators. Feel free to ping me (dtantsur) on irc, if you need more details.","commit_id":"f98eec3da0070008d1c0a9c3a8986f18ae7f12e3"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"ae5c9d76e2bfb16e9ba2341371b3c9f44b7c5878","unresolved":false,"context_lines":[{"line_number":215,"context_line":"    @mock.patch(\u0027ironic.drivers.modules.agent.AgentVendorInterface\u0027"},{"line_number":216,"context_line":"                \u0027._find_ports_by_macs\u0027)"},{"line_number":217,"context_line":"    def test_find_node_by_macs_bad_params(self, ports_mock, node_id_mock,"},{"line_number":218,"context_line":"                                          node_mock):"},{"line_number":219,"context_line":"        ports_mock.return_value \u003d []"},{"line_number":220,"context_line":"        node_id_mock.return_value \u003d \u0027fake-uuid\u0027"},{"line_number":221,"context_line":"        node_mock.side_effect \u003d exception.NodeNotFound(node\u003d\"123\")"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAXH%2F%2FrDY%3D","line":218,"updated":"2014-04-18 11:04:20.000000000","message":"Could you also add a short test on get_by_uuid returning NodeNotFound?","commit_id":"dce331e38922cfb788a7be0d0f74b19776f3a5a4"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"5f81b5e88bf0cc66ca3f4b9e42a01e1fa342219a","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        }"},{"line_number":53,"context_line":"        self.node \u003d self._create_test_node(**n)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def _create_test_node(self, **kwargs):"},{"line_number":56,"context_line":"        n \u003d db_utils.get_test_node(**kwargs)"},{"line_number":57,"context_line":"        return self.dbapi.create_node(n)"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_b8999070","line":55,"updated":"2014-05-08 11:11:11.000000000","message":"@Chris is doing a refactor on those functions and moved this _create_test_node functions to a common place[1]\nhttps://github.com/openstack/ironic/blob/master/ironic/tests/objects/utils.py#L34","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"cdbde9f9334b85e8ab11d2bd78ce09c6f0446401","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        }"},{"line_number":53,"context_line":"        self.node \u003d self._create_test_node(**n)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def _create_test_node(self, **kwargs):"},{"line_number":56,"context_line":"        n \u003d db_utils.get_test_node(**kwargs)"},{"line_number":57,"context_line":"        return self.dbapi.create_node(n)"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_90e73a12","line":55,"in_reply_to":"7adec928_b8999070","updated":"2014-05-08 23:26:46.000000000","message":"Done","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"5f81b5e88bf0cc66ca3f4b9e42a01e1fa342219a","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        self.node \u003d self._create_test_node(**n)"},{"line_number":161,"context_line":"        self.task.node \u003d self.node"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def _create_test_node(self, **kwargs):"},{"line_number":164,"context_line":"        n \u003d db_utils.get_test_node(**kwargs)"},{"line_number":165,"context_line":"        return self.dbapi.create_node(n)"},{"line_number":166,"context_line":""}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_d89e5c56","line":163,"updated":"2014-05-08 11:11:11.000000000","message":"ditto","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"cdbde9f9334b85e8ab11d2bd78ce09c6f0446401","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        self.node \u003d self._create_test_node(**n)"},{"line_number":161,"context_line":"        self.task.node \u003d self.node"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def _create_test_node(self, **kwargs):"},{"line_number":164,"context_line":"        n \u003d db_utils.get_test_node(**kwargs)"},{"line_number":165,"context_line":"        return self.dbapi.create_node(n)"},{"line_number":166,"context_line":""}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_b0e4360e","line":163,"in_reply_to":"7adec928_d89e5c56","updated":"2014-05-08 23:26:46.000000000","message":"Done","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"}],"ironic/tests/drivers/test_agent_utils.py":[{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"5f81b5e88bf0cc66ca3f4b9e42a01e1fa342219a","unresolved":false,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":"class TestAgentDeploy(db_base.DbTestCase):"},{"line_number":35,"context_line":"    def test_flatten_dict(self):"},{"line_number":36,"context_line":"        hardware \u003d {"},{"line_number":37,"context_line":"            \u0027interfaces\u0027: ["},{"line_number":38,"context_line":"                {"},{"line_number":39,"context_line":"                    \u0027mac_address\u0027: \u0027aa:bb:cc:dd:ee:fe\u0027,"}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_b8dd1045","line":36,"range":{"start_line":36,"start_character":8,"end_line":36,"end_character":16},"updated":"2014-05-08 11:11:11.000000000","message":"This is hard coded. It\u0027s should be in constant variable.","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"cdbde9f9334b85e8ab11d2bd78ce09c6f0446401","unresolved":false,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":"class TestAgentDeploy(db_base.DbTestCase):"},{"line_number":35,"context_line":"    def test_flatten_dict(self):"},{"line_number":36,"context_line":"        hardware \u003d {"},{"line_number":37,"context_line":"            \u0027interfaces\u0027: ["},{"line_number":38,"context_line":"                {"},{"line_number":39,"context_line":"                    \u0027mac_address\u0027: \u0027aa:bb:cc:dd:ee:fe\u0027,"}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_d0f1c2ce","line":36,"in_reply_to":"7adec928_b8dd1045","updated":"2014-05-08 23:26:46.000000000","message":"Done","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"5f81b5e88bf0cc66ca3f4b9e42a01e1fa342219a","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                }"},{"line_number":54,"context_line":"            ],"},{"line_number":55,"context_line":"        }"},{"line_number":56,"context_line":"        expected_hardware \u003d {"},{"line_number":57,"context_line":"            \u0027interfaces/0/mac_address\u0027: \u0027aa:bb:cc:dd:ee:fe\u0027,"},{"line_number":58,"context_line":"            \u0027interfaces/0/name\u0027: \u0027eth0\u0027,"},{"line_number":59,"context_line":"            \u0027interfaces/0/switch_chassis_descr\u0027: \u0027tor1\u0027,"}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_d8b01cf7","line":56,"range":{"start_line":56,"start_character":8,"end_line":56,"end_character":25},"updated":"2014-05-08 11:11:11.000000000","message":"ditto","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"cdbde9f9334b85e8ab11d2bd78ce09c6f0446401","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                }"},{"line_number":54,"context_line":"            ],"},{"line_number":55,"context_line":"        }"},{"line_number":56,"context_line":"        expected_hardware \u003d {"},{"line_number":57,"context_line":"            \u0027interfaces/0/mac_address\u0027: \u0027aa:bb:cc:dd:ee:fe\u0027,"},{"line_number":58,"context_line":"            \u0027interfaces/0/name\u0027: \u0027eth0\u0027,"},{"line_number":59,"context_line":"            \u0027interfaces/0/switch_chassis_descr\u0027: \u0027tor1\u0027,"}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_f0eebeeb","line":56,"in_reply_to":"7adec928_d8b01cf7","updated":"2014-05-08 23:26:46.000000000","message":"Done","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"5f81b5e88bf0cc66ca3f4b9e42a01e1fa342219a","unresolved":false,"context_lines":[{"line_number":163,"context_line":""},{"line_number":164,"context_line":"        }"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"    def _create_test_node(self, **kwargs):"},{"line_number":167,"context_line":"        n \u003d db_utils.get_test_node(**kwargs)"},{"line_number":168,"context_line":"        return self.dbapi.create_node(n)"},{"line_number":169,"context_line":""}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_98a694c0","line":166,"range":{"start_line":166,"start_character":8,"end_line":166,"end_character":25},"updated":"2014-05-08 11:11:11.000000000","message":"As @Lucas said @Chris is doing a refactor on those functions and moved this _create_test_node functions to a common place[1]\n\nhttps://github.com/openstack/ironic/blob/master/ironic/tests/objects/utils.py#L34","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"cdbde9f9334b85e8ab11d2bd78ce09c6f0446401","unresolved":false,"context_lines":[{"line_number":163,"context_line":""},{"line_number":164,"context_line":"        }"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"    def _create_test_node(self, **kwargs):"},{"line_number":167,"context_line":"        n \u003d db_utils.get_test_node(**kwargs)"},{"line_number":168,"context_line":"        return self.dbapi.create_node(n)"},{"line_number":169,"context_line":""}],"source_content_type":"text/x-python","patch_set":71,"id":"7adec928_500db28f","line":166,"in_reply_to":"7adec928_98a694c0","updated":"2014-05-08 23:26:46.000000000","message":"Done","commit_id":"ece8a1c811217044bba459d7f4874105f7477c32"}],"setup.cfg":[{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"1c1923116c759a0900b6434deb66bfd06ad000a2","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"ironic.drivers \u003d"},{"line_number":33,"context_line":"    agent_ipmitool \u003d ironic.drivers.agent:AgentAndIPMIToolDriver"},{"line_number":34,"context_line":"    agent_pyghmi \u003d ironic.drivers.agent:AgentAndIPMINativeDriver"},{"line_number":35,"context_line":"    agent_ssh \u003d ironic.drivers.agent:AgentAndSSHDriver"},{"line_number":36,"context_line":"    fake \u003d ironic.drivers.fake:FakeDriver"},{"line_number":37,"context_line":"    fake_ipmitool \u003d ironic.drivers.fake:FakeIPMIToolDriver"}],"source_content_type":"text/x-ttcn-cfg","patch_set":78,"id":"7adec928_44cf7bb0","line":34,"updated":"2014-05-13 14:31:46.000000000","message":"\u0027agent_ipminative\u0027  name better for consistency.","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"898d62efeb9c7bacd8c5ffd78b5e87d43eb735b4","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"ironic.drivers \u003d"},{"line_number":33,"context_line":"    agent_ipmitool \u003d ironic.drivers.agent:AgentAndIPMIToolDriver"},{"line_number":34,"context_line":"    agent_pyghmi \u003d ironic.drivers.agent:AgentAndIPMINativeDriver"},{"line_number":35,"context_line":"    agent_ssh \u003d ironic.drivers.agent:AgentAndSSHDriver"},{"line_number":36,"context_line":"    fake \u003d ironic.drivers.fake:FakeDriver"},{"line_number":37,"context_line":"    fake_ipmitool \u003d ironic.drivers.fake:FakeIPMIToolDriver"}],"source_content_type":"text/x-ttcn-cfg","patch_set":78,"id":"7adec928_d706dfcd","line":34,"in_reply_to":"7adec928_44cf7bb0","updated":"2014-05-13 15:05:37.000000000","message":"That name is 16 characters, the driver column in the DB is only 15. :)","commit_id":"2b3d2f24c425aee0793e3bdcbed98f1d6527db64"}]}
