)]}'
{".zuul.yaml":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"change_message_id":"766348441bb6749de5dddd322925ecae10c7ea4e","unresolved":false,"context_lines":[{"line_number":228,"context_line":"      - ^tools/.*$"},{"line_number":229,"context_line":"      - ^tox.ini$"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"- project:"},{"line_number":232,"context_line":"    # Please try to keep the list of job names sorted alphabetically."},{"line_number":233,"context_line":"    templates:"},{"line_number":234,"context_line":"#      - check-requirements"},{"line_number":235,"context_line":"#      - integrated-gate-py3"},{"line_number":236,"context_line":"#      - openstack-cover-jobs"},{"line_number":237,"context_line":"#      - openstack-lower-constraints-jobs"},{"line_number":238,"context_line":"#      - openstack-python-jobs"},{"line_number":239,"context_line":"#      - openstack-python35-jobs"},{"line_number":240,"context_line":"#      - openstack-python36-jobs"},{"line_number":241,"context_line":"#      - periodic-stable-jobs"},{"line_number":242,"context_line":"#      - publish-openstack-docs-pti"},{"line_number":243,"context_line":"#      - release-notes-jobs-python3"},{"line_number":244,"context_line":"    check:"},{"line_number":245,"context_line":"      jobs:"},{"line_number":246,"context_line":"        # We define our own irrelevant-files so we don\u0027t run the job"},{"line_number":247,"context_line":"        # on things like nova docs-only changes."},{"line_number":248,"context_line":"        - ironic-tempest-ipa-wholedisk-bios-agent_ipmitool-tinyipa:"},{"line_number":249,"context_line":"            voting: false"},{"line_number":250,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":251,"context_line":"#        - devstack-plugin-ceph-tempest:"},{"line_number":252,"context_line":"#            voting: false"},{"line_number":253,"context_line":"#            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":254,"context_line":"#        - neutron-grenade-multinode:"},{"line_number":255,"context_line":"#            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":256,"context_line":"#        - neutron-tempest-linuxbridge:"},{"line_number":257,"context_line":"#            irrelevant-files:"},{"line_number":258,"context_line":"#              # NOTE(mriedem): This job has its own irrelevant-files section"},{"line_number":259,"context_line":"#              # so that we only run it on changes to networking and libvirt/vif"},{"line_number":260,"context_line":"#              # code; we don\u0027t need to run this on all changes, nor do we run"},{"line_number":261,"context_line":"#              # it in the gate."},{"line_number":262,"context_line":"#              - ^(?!nova/network/.*)(?!nova/virt/libvirt/vif.py).*$"},{"line_number":263,"context_line":"#        - nova-grenade-live-migration"},{"line_number":264,"context_line":"#        - nova-live-migration"},{"line_number":265,"context_line":"#        - nova-lvm"},{"line_number":266,"context_line":"#        - nova-next"},{"line_number":267,"context_line":"#        - nova-tox-functional"},{"line_number":268,"context_line":"#        - nova-tox-functional-py35"},{"line_number":269,"context_line":"#        - tempest-full-py3:"},{"line_number":270,"context_line":"#            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":271,"context_line":"#        - tempest-multinode-full:"},{"line_number":272,"context_line":"#            voting: false"},{"line_number":273,"context_line":"#            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":274,"context_line":"#        - tempest-slow-py3:"},{"line_number":275,"context_line":"#            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":276,"context_line":"#        - grenade-py3:"},{"line_number":277,"context_line":"#            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":278,"context_line":"    gate:"},{"line_number":279,"context_line":"      jobs:"},{"line_number":280,"context_line":"        - nova-grenade-live-migration"},{"line_number":281,"context_line":"        - nova-live-migration"},{"line_number":282,"context_line":"        - nova-tox-functional"},{"line_number":283,"context_line":"        - nova-tox-functional-py35"},{"line_number":284,"context_line":"        - nova-next"},{"line_number":285,"context_line":"        - tempest-full-py3:"},{"line_number":286,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":287,"context_line":"        - tempest-slow-py3:"},{"line_number":288,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":289,"context_line":"        - grenade-py3:"},{"line_number":290,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":291,"context_line":"    experimental:"},{"line_number":292,"context_line":"      jobs:"},{"line_number":293,"context_line":"        - ironic-tempest-bfv:"},{"line_number":294,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":295,"context_line":"        - ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode:"},{"line_number":296,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":297,"context_line":"        - barbican-simple-crypto-devstack-tempest:"},{"line_number":298,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":299,"context_line":"        - devstack-plugin-ceph-tempest-py3:"},{"line_number":300,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":301,"context_line":"        - legacy-grenade-dsvm-neutron-multinode-zero-downtime:"},{"line_number":302,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":303,"context_line":"        - legacy-tempest-dsvm-full-devstack-plugin-nfs:"},{"line_number":304,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":305,"context_line":"        - tempest-full-py3-opensuse150:"},{"line_number":306,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":307,"context_line":"        - tempest-pg-full:"},{"line_number":308,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":309,"context_line":"        - nova-cells-v1"},{"line_number":310,"context_line":"        - nova-tempest-full-oslo.versionedobjects:"},{"line_number":311,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":312,"context_line":"        - legacy-tempest-dsvm-nova-libvirt-kvm-apr:"},{"line_number":313,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":314,"context_line":"        - nova-tempest-v2-api:"},{"line_number":315,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":316,"context_line":"        - legacy-tempest-dsvm-neutron-dvr-multinode-full:"},{"line_number":317,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":318,"context_line":"        - neutron-tempest-dvr-ha-multinode-full:"},{"line_number":319,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":320,"context_line":"        - os-vif-ovs:"},{"line_number":321,"context_line":"            irrelevant-files: *dsvm-irrelevant-files"},{"line_number":322,"context_line":"        - openstack-tox-py37"},{"line_number":323,"context_line":"        # NOTE(mriedem): Consider moving nova-tox-functional-py36 to the"},{"line_number":324,"context_line":"        # check and gate queues once it\u0027s stable (like openstack-python36-jobs)"},{"line_number":325,"context_line":"        - nova-tox-functional-py36"},{"line_number":326,"context_line":"        - nova-tox-functional-py37"}],"source_content_type":"text/x-yaml","patch_set":1,"id":"5fc1f717_b4d238ff","line":326,"range":{"start_line":231,"start_character":2,"end_line":326,"end_character":0},"updated":"2019-03-12 21:45:10.000000000","message":"expected a list for dictionary value @ data[\u0027templates\u0027]","commit_id":"ff4c35db7c39f32f07396ed0dbad698e1b4eb697"}],"/COMMIT_MSG":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"c8d5ff4ab998035cc976e7522cffe57d764c0aa6","unresolved":false,"context_lines":[{"line_number":13,"context_line":"API call, GET /v1/nodes/{node_ident} [1]."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"The framework simply comprises a new attribute on the IronicDriver,"},{"line_number":16,"context_line":"ironicconn, built using the get_sdk_adapter util. The ironicclient"},{"line_number":17,"context_line":"attribute will go away along with the entire client_wrapper module once"},{"line_number":18,"context_line":"all python-ironicclient calls have been swapped out."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":40,"id":"7faddb67_c45f013f","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":10},"updated":"2019-08-15 22:01:28.000000000","message":"this is no longer true","commit_id":"5c2b9ccf1c154f2289274c1c8db35f9210e1c7b3"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"c8d5ff4ab998035cc976e7522cffe57d764c0aa6","unresolved":false,"context_lines":[{"line_number":25,"context_line":"This dep sets devstack\u0027s retry counts/intervals, via conf options sdk"},{"line_number":26,"context_line":"understands, to values equivalent to what\u0027s used for the ironicclient"},{"line_number":27,"context_line":"paths:"},{"line_number":28,"context_line":"Depends-On: https://review.opendev.org/676268"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"Blueprint: openstacksdk-in-nova"},{"line_number":31,"context_line":"Change-Id: I641f1b07beb0c44001f8018326105bcb3fc603cf"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":40,"id":"7faddb67_e45c7d4c","line":28,"range":{"start_line":28,"start_character":0,"end_line":28,"end_character":45},"updated":"2019-08-15 22:01:28.000000000","message":"style nit: should be grouped below","commit_id":"5c2b9ccf1c154f2289274c1c8db35f9210e1c7b3"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a45d8d8e680dae125ade877186494faf2d6a6ffc","unresolved":false,"context_lines":[{"line_number":22,"context_line":"[1] https://developer.openstack.org/api-ref/baremetal/?expanded\u003dshow-node-details-detail#show-node-details"},{"line_number":23,"context_line":"[2] https://docs.openstack.org/openstacksdk/latest/user/proxies/baremetal.html#openstack.baremetal.v1._proxy.Proxy.get_node"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"This dep sets devstack\u0027s retry counts/intervals, via conf options sdk"},{"line_number":26,"context_line":"understands, to values equivalent to what\u0027s used for the ironicclient"},{"line_number":27,"context_line":"paths:"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Depends-On: https://review.opendev.org/676268"},{"line_number":30,"context_line":"Blueprint: openstacksdk-in-nova"},{"line_number":31,"context_line":"Change-Id: I641f1b07beb0c44001f8018326105bcb3fc603cf"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":41,"id":"7faddb67_75ea120f","line":29,"range":{"start_line":25,"start_character":0,"end_line":29,"end_character":45},"updated":"2019-08-22 13:19:59.000000000","message":"This dep has merged now","commit_id":"8a47f053cf8cdf2c0a87c86f6f121d79fc8222f3"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"769500eae577b0ec66f5256851469fa326f46c6e","unresolved":false,"context_lines":[{"line_number":22,"context_line":"[1] https://developer.openstack.org/api-ref/baremetal/?expanded\u003dshow-node-details-detail#show-node-details"},{"line_number":23,"context_line":"[2] https://docs.openstack.org/openstacksdk/latest/user/proxies/baremetal.html#openstack.baremetal.v1._proxy.Proxy.get_node"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"This dep sets devstack\u0027s retry counts/intervals, via conf options sdk"},{"line_number":26,"context_line":"understands, to values equivalent to what\u0027s used for the ironicclient"},{"line_number":27,"context_line":"paths:"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Depends-On: https://review.opendev.org/676268"},{"line_number":30,"context_line":"Blueprint: openstacksdk-in-nova"},{"line_number":31,"context_line":"Change-Id: I641f1b07beb0c44001f8018326105bcb3fc603cf"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":41,"id":"7faddb67_06ca8f45","line":29,"range":{"start_line":25,"start_character":0,"end_line":29,"end_character":45},"in_reply_to":"7faddb67_75ea120f","updated":"2019-08-22 17:20:10.000000000","message":"Done","commit_id":"8a47f053cf8cdf2c0a87c86f6f121d79fc8222f3"}],"nova/tests/unit/virt/ironic/test_driver.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"02007e002ac29e1704115d3fb22e7a283c038096","unresolved":false,"context_lines":[{"line_number":3575,"context_line":""},{"line_number":3576,"context_line":"        self.driver \u003d ironic_driver.IronicDriver(fake.FakeVirtAPI())"},{"line_number":3577,"context_line":""},{"line_number":3578,"context_line":"        # FIXME(dustinc): This access a private object in SDK and should be"},{"line_number":3579,"context_line":"        #  replaced with a public fixture provided by SDK when available."},{"line_number":3580,"context_line":"        self.mock_conn \u003d self.useFixture("},{"line_number":3581,"context_line":"            fixtures.MockPatchObject("},{"line_number":3582,"context_line":"                self.driver, \u0027_ironicconn\u0027,"},{"line_number":3583,"context_line":"                spec\u003dopenstack.baremetal.v1._proxy.Proxy)).mock"},{"line_number":3584,"context_line":""},{"line_number":3585,"context_line":"        self.ctx \u003d nova_context.get_admin_context()"},{"line_number":3586,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"7faddb67_c5d7a2ed","line":3583,"range":{"start_line":3578,"start_character":0,"end_line":3583,"end_character":63},"updated":"2019-08-06 18:38:54.000000000","message":"- Is the spec\u003d necessary? What breaks if you take that out? Cause if you can do without it, you don\u0027t really need the FIXME.\n- Consider defining this fixture once, at the top of this file, possibly via an intermediary base test class.","commit_id":"8e4f3a21befa45b98c69adb506ee49295f788492"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"9418b23005063661fdeb6cabe37b4a77542de19a","unresolved":false,"context_lines":[{"line_number":3575,"context_line":""},{"line_number":3576,"context_line":"        self.driver \u003d ironic_driver.IronicDriver(fake.FakeVirtAPI())"},{"line_number":3577,"context_line":""},{"line_number":3578,"context_line":"        # FIXME(dustinc): This access a private object in SDK and should be"},{"line_number":3579,"context_line":"        #  replaced with a public fixture provided by SDK when available."},{"line_number":3580,"context_line":"        self.mock_conn \u003d self.useFixture("},{"line_number":3581,"context_line":"            fixtures.MockPatchObject("},{"line_number":3582,"context_line":"                self.driver, \u0027_ironicconn\u0027,"},{"line_number":3583,"context_line":"                spec\u003dopenstack.baremetal.v1._proxy.Proxy)).mock"},{"line_number":3584,"context_line":""},{"line_number":3585,"context_line":"        self.ctx \u003d nova_context.get_admin_context()"},{"line_number":3586,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"7faddb67_57ab6986","line":3583,"range":{"start_line":3578,"start_character":0,"end_line":3583,"end_character":63},"in_reply_to":"7faddb67_c5d7a2ed","updated":"2019-08-06 19:53:43.000000000","message":"It mattered once upon a time, but I just tested and it doesn\u0027t seem to be needed. Patch incoming...","commit_id":"8e4f3a21befa45b98c69adb506ee49295f788492"}],"nova/tests/unit/virt/ironic/utils.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"c85247b1febbc783790c5a928594f4801ede4091","unresolved":false,"context_lines":[{"line_number":30,"context_line":"def get_test_node(fields\u003dNone, **kw):"},{"line_number":31,"context_line":"    # TODO(dustinc): Once all uses of node id/uuid, instance uuid/id, and"},{"line_number":32,"context_line":"    #  maintenance/is_maintenance are normalized, the duplicates can be removed"},{"line_number":33,"context_line":"    node \u003d {\u0027uuid\u0027: kw.get(\u0027uuid\u0027,"},{"line_number":34,"context_line":"                           kw.get(\u0027id\u0027,"},{"line_number":35,"context_line":"                                  \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)),"},{"line_number":36,"context_line":"            \u0027id\u0027: kw.get(\u0027id\u0027,"},{"line_number":37,"context_line":"                         kw.get(\u0027uuid\u0027,"},{"line_number":38,"context_line":"                                \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)),"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_ded73b4f","line":35,"range":{"start_line":33,"start_character":0,"end_line":35,"end_character":75},"updated":"2019-08-09 10:26:53.000000000","message":"nit: this wrapping is really weird\n\n  node \u003d {\u0027uuid\u0027: kw.get(\n              \u0027uuid\u0027, kw.get(\u0027id\u0027, \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)),\n\nWould probably have done the trick. Alternatively,\n\n  _uuid \u003d kw.get(\u0027uuid\u0027) or kw.get(\u0027id\u0027, \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)\n  node \u003d {\u0027uuid\u0027: _uuid,\n          \u0027id\u0027: kw.get(\u0027id\u0027, _uuid),\n\nDitto for the rest of this","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"30e0943591dea142c622ecda2b6717fac878f6a3","unresolved":false,"context_lines":[{"line_number":30,"context_line":"def get_test_node(fields\u003dNone, **kw):"},{"line_number":31,"context_line":"    # TODO(dustinc): Once all uses of node id/uuid, instance uuid/id, and"},{"line_number":32,"context_line":"    #  maintenance/is_maintenance are normalized, the duplicates can be removed"},{"line_number":33,"context_line":"    node \u003d {\u0027uuid\u0027: kw.get(\u0027uuid\u0027,"},{"line_number":34,"context_line":"                           kw.get(\u0027id\u0027,"},{"line_number":35,"context_line":"                                  \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)),"},{"line_number":36,"context_line":"            \u0027id\u0027: kw.get(\u0027id\u0027,"},{"line_number":37,"context_line":"                         kw.get(\u0027uuid\u0027,"},{"line_number":38,"context_line":"                                \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)),"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_b23367f6","line":35,"range":{"start_line":33,"start_character":0,"end_line":35,"end_character":75},"in_reply_to":"7faddb67_041b2773","updated":"2019-08-13 04:27:35.000000000","message":"Sorry, I blame my auto formatter :). I went ahead and just prechecked the values similar to how Stephen suggested, this should in theory be ever slightly faster and is almost definitely easier to read.","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"7efecc7170f132d306595800a8d040ddf2840e81","unresolved":false,"context_lines":[{"line_number":30,"context_line":"def get_test_node(fields\u003dNone, **kw):"},{"line_number":31,"context_line":"    # TODO(dustinc): Once all uses of node id/uuid, instance uuid/id, and"},{"line_number":32,"context_line":"    #  maintenance/is_maintenance are normalized, the duplicates can be removed"},{"line_number":33,"context_line":"    node \u003d {\u0027uuid\u0027: kw.get(\u0027uuid\u0027,"},{"line_number":34,"context_line":"                           kw.get(\u0027id\u0027,"},{"line_number":35,"context_line":"                                  \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)),"},{"line_number":36,"context_line":"            \u0027id\u0027: kw.get(\u0027id\u0027,"},{"line_number":37,"context_line":"                         kw.get(\u0027uuid\u0027,"},{"line_number":38,"context_line":"                                \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)),"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_041b2773","line":35,"range":{"start_line":33,"start_character":0,"end_line":35,"end_character":75},"in_reply_to":"7faddb67_ded73b4f","updated":"2019-08-12 10:27:58.000000000","message":"FWIW, I am OK with it. I had a double take at it, but its gonna be deleted soon anyways.","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bf8bab5c4490c3a1eefebb1842b0a5e5d21c879a","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    # TODO(dustinc): Once all uses of id/uuid and portgroup/port_group are"},{"line_number":71,"context_line":"    #  normalized, the duplicates can be removed"},{"line_number":72,"context_line":"    return type(\u0027port\u0027, (object,),"},{"line_number":73,"context_line":"               {\u0027uuid\u0027: kw.get(\u0027uuid\u0027,"},{"line_number":74,"context_line":"                               kw.get(\u0027id\u0027,"},{"line_number":75,"context_line":"                                      \u0027gggggggg-uuuu-qqqq-ffff-llllllllllll\u0027)),"},{"line_number":76,"context_line":"                \u0027node_uuid\u0027: kw.get(\u0027node_uuid\u0027,"},{"line_number":77,"context_line":"                                    kw.get(\u0027node_id\u0027,"},{"line_number":78,"context_line":"                                           get_test_node().id)),"}],"source_content_type":"text/x-python","patch_set":38,"id":"7faddb67_7b6ce79b","line":75,"range":{"start_line":73,"start_character":0,"end_line":75,"end_character":79},"updated":"2019-08-13 09:42:34.000000000","message":"Probably could have fixed these too","commit_id":"4137de8a790b54c1af3b52fadc7cedd7e70d68df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f658d65fa5d770319cad5e3fccdbb812ba397e76","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"def get_test_node(fields\u003dNone, **kw):"},{"line_number":31,"context_line":"    # TODO(dustinc): Once the usages of id/uuid, maintenance/is_maintenance,"},{"line_number":32,"context_line":"    #  and portgroup/port_group are normalized, the duplicates can be removed"},{"line_number":33,"context_line":"    _id \u003d kw.get(\u0027id\u0027) or kw.get(\u0027uuid\u0027,"},{"line_number":34,"context_line":"                                 \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027)"},{"line_number":35,"context_line":"    _instance_id \u003d kw.get(\u0027instance_id\u0027) or kw.get(\u0027instance_uuid\u0027)"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_82db477b","line":32,"range":{"start_line":32,"start_character":11,"end_line":32,"end_character":31},"updated":"2019-08-30 14:56:55.000000000","message":"I think you mean instance_id/instance_uuid.","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f658d65fa5d770319cad5e3fccdbb812ba397e76","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    _id \u003d kw.get(\u0027id\u0027) or kw.get(\u0027uuid\u0027,"},{"line_number":73,"context_line":"                                 \u0027gggggggg-uuuu-qqqq-ffff-llllllllllll\u0027)"},{"line_number":74,"context_line":"    _node_id \u003d kw.get(\u0027node_uuid\u0027) or kw.get(\u0027node_id\u0027, get_test_node().id)"},{"line_number":75,"context_line":"    _port_group_id \u003d kw.get(\u0027port_group_id\u0027) or kw.get(\u0027portgroup_uuid\u0027)"},{"line_number":76,"context_line":"    return type(\u0027port\u0027, (object,),"},{"line_number":77,"context_line":"               {\u0027uuid\u0027: _id,"},{"line_number":78,"context_line":"                \u0027id\u0027: _id,"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_e2cb1ba1","line":75,"range":{"start_line":75,"start_character":21,"end_line":75,"end_character":44},"updated":"2019-08-30 14:56:55.000000000","message":"This seems unrelated to this change.","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f658d65fa5d770319cad5e3fccdbb812ba397e76","unresolved":false,"context_lines":[{"line_number":88,"context_line":""},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"def get_test_portgroup(**kw):"},{"line_number":91,"context_line":"    # TODO(dustinc): Once the usages of id/uuid, maintenance/is_maintenance,"},{"line_number":92,"context_line":"    #  and portgroup/port_group are normalized, the duplicates can be removed"},{"line_number":93,"context_line":"    _id \u003d kw.get(\u0027id\u0027) or kw.get(\u0027uuid\u0027,"},{"line_number":94,"context_line":"                                 \u0027deaffeed-1234-5678-9012-fedcbafedcba\u0027)"},{"line_number":95,"context_line":"    _node_id \u003d kw.get(\u0027node_id\u0027) or kw.get(\u0027node_uuid\u0027, get_test_node().id)"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_c23b7f98","line":92,"range":{"start_line":91,"start_character":49,"end_line":92,"end_character":31},"updated":"2019-08-30 14:56:55.000000000","message":"More copy/paste that doesn\u0027t fit here.","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"}],"nova/virt/ironic/client_wrapper.py":[{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"4044498d91a88ce95df6ccec51c2b14a92a6ae5d","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                NotFound) on error."},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        if not node_uuid:"},{"line_number":78,"context_line":"            val \u003d \u0027\u003cNone\u003e\u0027 if node_uuid is None else node_uuid"},{"line_number":79,"context_line":"            raise exception.ValidationError(_(\"Invalid node_uuid: %s\", val))"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        path \u003d \u0027/nodes/\u0027 + node_uuid"}],"source_content_type":"text/x-python","patch_set":7,"id":"5fc1f717_29923d4d","line":78,"updated":"2019-03-14 20:53:22.000000000","message":"q: what non-true values other than None would be expected here?","commit_id":"09833628fca72a571b191f6a0d161e6cb74365ff"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"cb5cd40f4bad244bb15026d642bd3a27e19869c0","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                NotFound) on error."},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        if not node_uuid:"},{"line_number":78,"context_line":"            val \u003d \u0027\u003cNone\u003e\u0027 if node_uuid is None else node_uuid"},{"line_number":79,"context_line":"            raise exception.ValidationError(_(\"Invalid node_uuid: %s\", val))"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        path \u003d \u0027/nodes/\u0027 + node_uuid"}],"source_content_type":"text/x-python","patch_set":7,"id":"5fc1f717_694e05c2","line":78,"in_reply_to":"5fc1f717_29923d4d","updated":"2019-03-14 21:04:34.000000000","message":"Empty string.\n\nI don\u0027t think they would actually be expected necessarily, but this is just used for the exception message.","commit_id":"09833628fca72a571b191f6a0d161e6cb74365ff"}],"nova/virt/ironic/driver.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f0c58104fe68abf7515afe92130c0e0f0eaf36b3","unresolved":false,"context_lines":[{"line_number":200,"context_line":"        \"\"\""},{"line_number":201,"context_line":"        node \u003d self.ironicconn.get_node(node_uuid)"},{"line_number":202,"context_line":"        # TODO(efried): Make consumers use the right fields and stop doing this"},{"line_number":203,"context_line":"        node.uuid \u003d node.id"},{"line_number":204,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":205,"context_line":"        # TODO(efried): Is this one right?"},{"line_number":206,"context_line":"        node.maintenance \u003d node.maintenance_reason"}],"source_content_type":"text/x-python","patch_set":12,"id":"5fc1f717_99360751","line":203,"range":{"start_line":203,"start_character":8,"end_line":203,"end_character":27},"updated":"2019-03-16 14:54:39.000000000","message":"In PS11 I replaced this everywhere in the code, but I didn\u0027t think about the fact that some code paths are still getting their \u0027node\u0027 from other APIs via ironicclient. For now, this is simpler. Once all APIs have been swapped out, we can comb through the code and s/node.uuid/node.id/g.","commit_id":"e340b76061213073f13fb589b54af339fc00613b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f0c58104fe68abf7515afe92130c0e0f0eaf36b3","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        # TODO(efried): Make consumers use the right fields and stop doing this"},{"line_number":203,"context_line":"        node.uuid \u003d node.id"},{"line_number":204,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":205,"context_line":"        # TODO(efried): Is this one right?"},{"line_number":206,"context_line":"        node.maintenance \u003d node.maintenance_reason"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    def _validate_instance_and_node(self, instance):"},{"line_number":209,"context_line":"        \"\"\"Get the node associated with the instance."}],"source_content_type":"text/x-python","patch_set":12,"id":"5fc1f717_394113aa","line":206,"range":{"start_line":205,"start_character":8,"end_line":206,"end_character":50},"updated":"2019-03-16 14:54:39.000000000","message":"Ironic-y reviewers - help needed here.","commit_id":"e340b76061213073f13fb589b54af339fc00613b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"37e630b7e772d19fb9d5e6b94d874fb226562fa9","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        # TODO(efried): Make consumers use the right fields and stop doing this"},{"line_number":203,"context_line":"        node.uuid \u003d node.id"},{"line_number":204,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":205,"context_line":"        # TODO(efried): Is this one right?"},{"line_number":206,"context_line":"        node.maintenance \u003d node.maintenance_reason"},{"line_number":207,"context_line":"        return node"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def _validate_instance_and_node(self, instance):"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fce034c_bd3f79b2","line":206,"range":{"start_line":205,"start_character":0,"end_line":206,"end_character":50},"updated":"2019-04-18 16:25:48.000000000","message":"Nope:\n\n node.maintenance \u003d node.is_maintenance","commit_id":"c9250873ea95d29762484e0af7c453ab74353844"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"ae49d02fc3335bdc2a40f07c9706a287d11a78c3","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        # TODO(efried): Make consumers use the right fields and stop doing this"},{"line_number":203,"context_line":"        node.uuid \u003d node.id"},{"line_number":204,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":205,"context_line":"        # TODO(efried): Is this one right?"},{"line_number":206,"context_line":"        node.maintenance \u003d node.maintenance_reason"},{"line_number":207,"context_line":"        return node"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def _validate_instance_and_node(self, instance):"}],"source_content_type":"text/x-python","patch_set":20,"id":"ffb9cba7_fa08e32d","line":206,"range":{"start_line":205,"start_character":0,"end_line":206,"end_character":50},"in_reply_to":"3fce034c_bd3f79b2","updated":"2019-04-24 21:32:05.000000000","message":"Done","commit_id":"c9250873ea95d29762484e0af7c453ab74353844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f68e044988aa2535d8b17dd521fd296f5bfe58ec","unresolved":false,"context_lines":[{"line_number":212,"context_line":"        \"\"\""},{"line_number":213,"context_line":"        node \u003d self.ironicconn.get_node(node_id)"},{"line_number":214,"context_line":"        # TODO(dustinc): Make consumers use the right fields and remove this"},{"line_number":215,"context_line":"        if hasattr(node, \"id\"):"},{"line_number":216,"context_line":"            node.uuid \u003d node.id"},{"line_number":217,"context_line":"        if hasattr(node, \"instance_id\"):"},{"line_number":218,"context_line":"            node.instance_uuid \u003d node.instance_id"}],"source_content_type":"text/x-python","patch_set":28,"id":"9fb8cfa7_e5d5281d","line":215,"range":{"start_line":215,"start_character":0,"end_line":215,"end_character":31},"updated":"2019-06-13 12:00:01.000000000","message":"nit: These fields are always present in openstacksdk","commit_id":"2a7e846cab61bedcfab2c1629c661409b3b6d2b8"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"82045b44cda5915b613573f93ea5e32ab509e7dc","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        self.servicegroup_api \u003d servicegroup.API()"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"        self.ironicclient \u003d client_wrapper.IronicClientWrapper()"},{"line_number":200,"context_line":"        self.ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"        # This is needed for the instance flavor migration in Pike, and should"},{"line_number":203,"context_line":"        # be removed in Queens. Since this will run several times in the life"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_3fe3f7a6","line":200,"updated":"2019-07-23 22:02:09.000000000","message":"This doesn\u0027t look so good in the logs:\n\nhttp://logs.openstack.org/99/642899/33/check/ironic-tempest-ipa-wholedisk-bios-agent_ipmitool-tinyipa/402a8bc/controller/logs/screen-n-cpu.txt.gz#_Jul_22_23_28_10_378185\n\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: CRITICAL nova [None req-1e30afaa-1083-4160-a27f-af60b453fa66 None None] Unhandled error: NotSupported: The baremetal service for 10.210.65.84:RegionOne exists but does not have any supported versions.\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova Traceback (most recent call last):\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/usr/local/bin/nova-compute\", line 10, in \u003cmodule\u003e\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     sys.exit(main())\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/opt/stack/nova/nova/cmd/compute.py\", line 57, in main\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     topic\u003dcompute_rpcapi.RPC_TOPIC)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/opt/stack/nova/nova/service.py\", line 258, in create\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     periodic_interval_max\u003dperiodic_interval_max)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/opt/stack/nova/nova/service.py\", line 130, in __init__\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     self.manager \u003d manager_class(host\u003dself.host, *args, **kwargs)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/opt/stack/nova/nova/compute/manager.py\", line 577, in __init__\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     self.driver \u003d driver.load_compute_driver(self.virtapi, compute_driver)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/opt/stack/nova/nova/virt/driver.py\", line 1888, in load_compute_driver\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     virtapi)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/usr/local/lib/python2.7/dist-packages/oslo_utils/importutils.py\", line 44, in import_object\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     return import_class(import_str)(*args, **kwargs)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/opt/stack/nova/nova/virt/ironic/driver.py\", line 200, in __init__\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     self.ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/opt/stack/nova/nova/utils.py\", line 1253, in get_sdk_adapter\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     return getattr(conn, service_type)\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/usr/local/lib/python2.7/dist-packages/openstack/service_description.py\", line 86, in __get__\nJul 22 23:28:10.378185 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     instance._proxies[self.service_type] \u003d self._make_proxy(instance)\nJul 22 23:28:10.379940 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova   File \"/usr/local/lib/python2.7/dist-packages/openstack/service_description.py\", line 205, in _make_proxy\nJul 22 23:28:10.379940 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova     region_name\u003dregion_name))\nJul 22 23:28:10.379940 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova NotSupported: The baremetal service for 10.210.65.84:RegionOne exists but does not have any supported versions.\nJul 22 23:28:10.379940 ubuntu-bionic-rax-ord-0009204631 nova-compute[15187]: ERROR nova \nJul 22 23:28:10.546045 ubuntu-bionic-rax-ord-0009204631 systemd[1]: devstack@n-cpu.service: Main process exited, code\u003dexited, status\u003d1/FAILURE\nJul 22 23:28:10.546067 ubuntu-bionic-rax-ord-0009204631 systemd[1]: devstack@n-cpu.service: Failed with result \u0027exit-code\u0027.\nJul 22 23:32:57.943693 ubuntu-bionic-rax-ord-0009204631 systemd[1]: Started Devstack devstack@n-cpu.service.\n\nIs this an issue where we\u0027re trying to hit ironic before ironic api is actually available? Because later things seem to be fine.\n\nI thought there was some code in the driver (added by jroll?) that waited for the \"hypervisor\" to be ready.\n\nHaving said that, before this change we also hit VirtDriverNotReady tracebacks in the logs depending on when the compute service is started before ironic is available:\n\nhttp://logs.openstack.org/26/551026/4/check/ironic-tempest-ipa-wholedisk-bios-agent_ipmitool-tinyipa/e372b1b/controller/logs/screen-n-cpu.txt.gz#_Jul_23_17_25_16_947848\n\nThe difference seems to be the new code kills the service on startup whereas the thing before didn\u0027t (it was bombing out in a periodic). I think the previous thing only doesn\u0027t kill the service because it\u0027s handled here:\n\nhttps://github.com/openstack/nova/blob/383a4cf3710b5da2fe0b580bc25783ec8fefed48/nova/compute/manager.py#L8290\n\nAs seen in the logs:\n\nhttp://logs.openstack.org/26/551026/4/check/ironic-tempest-ipa-wholedisk-bios-agent_ipmitool-tinyipa/e372b1b/controller/logs/screen-n-cpu.txt.gz#_Jul_23_17_24_28_825895\n\nSo I guess the question is, should we similarly swallow and not kill the service if we hit the sdk connection error and try to reconnect later if we can, maybe using a property method for the ironicconn attribute so we can make the connection on first attempt if we haven\u0027t successfully connected yet? Or just say f it, if the \"hypervisor\" isn\u0027t available we should fail to start the service (would the libvirt driver fail to start if we can\u0027t connect to libvirtd? I\u0027m guessing yes).","commit_id":"fb8a2f4af5e7fbf001da818d65adb6ec387d5a61"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"7564dcdafecdd781f1f341e1e9a4d2ca85938544","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        self.servicegroup_api \u003d servicegroup.API()"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"        self.ironicclient \u003d client_wrapper.IronicClientWrapper()"},{"line_number":200,"context_line":"        self.ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"        # This is needed for the instance flavor migration in Pike, and should"},{"line_number":203,"context_line":"        # be removed in Queens. Since this will run several times in the life"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_5cb08143","line":200,"in_reply_to":"7faddb67_3fe3f7a6","updated":"2019-08-06 02:01:03.000000000","message":"Matt,\nDo you think lazy initialization of the client would work? What about something like this (on the IronicDriver class):\n     def ironicconn(self, method, *args, **kwargs):\n         if self.ironicconn is None:\n             self._ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)\n         return getattr(self._ironicconn, method)(*args, **kwargs)\n\nAnd then call the ironicconn with \n self.ironicconn(\u0027method_name\u0027, args)","commit_id":"fb8a2f4af5e7fbf001da818d65adb6ec387d5a61"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"510178f2188e1d3cf68cc03a29eef0294f7412fb","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        self.servicegroup_api \u003d servicegroup.API()"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"        self.ironicclient \u003d client_wrapper.IronicClientWrapper()"},{"line_number":200,"context_line":"        self.ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"        # This is needed for the instance flavor migration in Pike, and should"},{"line_number":203,"context_line":"        # be removed in Queens. Since this will run several times in the life"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_bc7e5567","line":200,"in_reply_to":"7faddb67_5cb08143","updated":"2019-08-06 02:02:20.000000000","message":"Whoops, that being\n if self._ironicconn is None:","commit_id":"fb8a2f4af5e7fbf001da818d65adb6ec387d5a61"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"82045b44cda5915b613573f93ea5e32ab509e7dc","unresolved":false,"context_lines":[{"line_number":543,"context_line":"        _log_ironic_polling(message, node, instance)"},{"line_number":544,"context_line":""},{"line_number":545,"context_line":"    def init_host(self, host):"},{"line_number":546,"context_line":"        \"\"\"Initialize anything that is necessary for the driver to function."},{"line_number":547,"context_line":""},{"line_number":548,"context_line":"        :param host: the hostname of the compute host."},{"line_number":549,"context_line":""}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_3f91b7f2","line":546,"updated":"2019-07-23 22:02:09.000000000","message":"Would this be a better place to setup the sdk connection? Probably not, that\u0027s actually called before ComputeManager.pre_start_hook which calls update_available_resource where we could still hit the VirtDriverNotReady error.\n\nThere is also a post_start_hook we could implement in the compute manager but I\u0027m not sure if it would help because, at least in our CI jobs, ironic might still not be setup yet.\n\nCan we create the sdk connection on the first call to the ironic API somehow? I know the ironic client wrapper code in nova wraps python-ironicclient, and presumably that would have some kind of logic like that?","commit_id":"fb8a2f4af5e7fbf001da818d65adb6ec387d5a61"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"82045b44cda5915b613573f93ea5e32ab509e7dc","unresolved":false,"context_lines":[{"line_number":629,"context_line":"        If unable to connect ironic server, an empty list is returned."},{"line_number":630,"context_line":""},{"line_number":631,"context_line":"        :returns: a list of raw node from ironic"},{"line_number":632,"context_line":"        :raises: VirtDriverNotReady"},{"line_number":633,"context_line":""},{"line_number":634,"context_line":"        \"\"\""},{"line_number":635,"context_line":"        node_list \u003d []"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_ff931fff","line":632,"updated":"2019-07-23 22:02:09.000000000","message":"This is the thing I was thinking of (I think) and this is eventually called from get_available_nodes.","commit_id":"fb8a2f4af5e7fbf001da818d65adb6ec387d5a61"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"adae5be3eae476b749030d7884dc700b17b01cbd","unresolved":false,"context_lines":[{"line_number":204,"context_line":"        # of the driver, track the instances that have already been migrated."},{"line_number":205,"context_line":"        self._migrated_instance_uuids \u003d set()"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    def _ironicconn(self, method, *args, **kwargs):"},{"line_number":208,"context_line":"        if self._ironicsdk is None:"},{"line_number":209,"context_line":"            self._ironicsdk \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":210,"context_line":"        return getattr(self._ironicsdk, method)(*args, **kwargs)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def _get_node(self, node_id):"},{"line_number":213,"context_line":"        \"\"\"Get a node by its UUID."}],"source_content_type":"text/x-python","patch_set":34,"id":"7faddb67_4e243c0d","line":210,"range":{"start_line":207,"start_character":4,"end_line":210,"end_character":64},"updated":"2019-08-06 13:17:46.000000000","message":"I\u0027m good with the lazy load, but if you make this a @property, you can keep the syntax you had before.\n\n @property\n def ironicconn(self):\n     if self._ironicconn is None:\n         self._ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)\n     return self._ironicconn","commit_id":"7364bbd6860e69aaefbcb617d1e9f1e7321dc436"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"68813f89fbc7150034b59ddd2b0defc78b58e283","unresolved":false,"context_lines":[{"line_number":209,"context_line":"           actually UUID\u0027s."},{"line_number":210,"context_line":"        \"\"\""},{"line_number":211,"context_line":"        return self.ironicclient.call(\u0027node.get\u0027, node_uuid,"},{"line_number":212,"context_line":"                                      fields\u003d_NODE_FIELDS)"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def _validate_instance_and_node(self, instance):"},{"line_number":215,"context_line":"        \"\"\"Get the node associated with the instance."}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_641bfb1b","side":"PARENT","line":212,"range":{"start_line":212,"start_character":45,"end_line":212,"end_character":57},"updated":"2019-08-12 10:44:04.000000000","message":"I missed we were dropping this, spotted it on a follow on change... I need to double check this.","commit_id":"9f64b9900e705e040aadb07ec3b9db140b4fc11b"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"4de520b6e42b69d66440f4c8a025f951281c3b31","unresolved":false,"context_lines":[{"line_number":209,"context_line":"           actually UUID\u0027s."},{"line_number":210,"context_line":"        \"\"\""},{"line_number":211,"context_line":"        return self.ironicclient.call(\u0027node.get\u0027, node_uuid,"},{"line_number":212,"context_line":"                                      fields\u003d_NODE_FIELDS)"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def _validate_instance_and_node(self, instance):"},{"line_number":215,"context_line":"        \"\"\"Get the node associated with the instance."}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_84b4f7f3","side":"PARENT","line":212,"range":{"start_line":212,"start_character":45,"end_line":212,"end_character":57},"in_reply_to":"7faddb67_641bfb1b","updated":"2019-08-12 10:47:51.000000000","message":"So this was added as a performance improvement to reduce DB load in ironic and reduce network traffic between ironic and nova...\nhttps://github.com/openstack/nova/commit/26c69a6a62a138ccdb88ecc5bf75330a04e5de0b\n\nNow its possible it doesn\u0027t make much of a difference, but I think we need to take a look at this before merge. And have a comment in the git commit about why this is OK.","commit_id":"9f64b9900e705e040aadb07ec3b9db140b4fc11b"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"30e0943591dea142c622ecda2b6717fac878f6a3","unresolved":false,"context_lines":[{"line_number":209,"context_line":"           actually UUID\u0027s."},{"line_number":210,"context_line":"        \"\"\""},{"line_number":211,"context_line":"        return self.ironicclient.call(\u0027node.get\u0027, node_uuid,"},{"line_number":212,"context_line":"                                      fields\u003d_NODE_FIELDS)"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def _validate_instance_and_node(self, instance):"},{"line_number":215,"context_line":"        \"\"\"Get the node associated with the instance."}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_0dfd7c3a","side":"PARENT","line":212,"range":{"start_line":212,"start_character":45,"end_line":212,"end_character":57},"in_reply_to":"7faddb67_84b4f7f3","updated":"2019-08-13 04:27:35.000000000","message":"Added back","commit_id":"9f64b9900e705e040aadb07ec3b9db140b4fc11b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"c85247b1febbc783790c5a928594f4801ede4091","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        self._migrated_instance_uuids \u003d set()"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    @property"},{"line_number":208,"context_line":"    def ironicconn(self):"},{"line_number":209,"context_line":"        if self._ironicconn is None:"},{"line_number":210,"context_line":"            self._ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":211,"context_line":"        return self._ironicconn"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_1b172554","line":208,"range":{"start_line":208,"start_character":8,"end_line":208,"end_character":18},"updated":"2019-08-09 10:26:53.000000000","message":"This is such a nit, but \u0027ironic_conn\u0027 (or, better, \u0027ironic_connection\u0027). Surely we\u0027re not that stuck for horizontal space? :)","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"7efecc7170f132d306595800a8d040ddf2840e81","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        self._migrated_instance_uuids \u003d set()"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    @property"},{"line_number":208,"context_line":"    def ironicconn(self):"},{"line_number":209,"context_line":"        if self._ironicconn is None:"},{"line_number":210,"context_line":"            self._ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":211,"context_line":"        return self._ironicconn"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_e91b467d","line":208,"range":{"start_line":208,"start_character":8,"end_line":208,"end_character":18},"in_reply_to":"7faddb67_1b172554","updated":"2019-08-12 10:27:58.000000000","message":"+1, but, not blocking on that.","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"30e0943591dea142c622ecda2b6717fac878f6a3","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        self._migrated_instance_uuids \u003d set()"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    @property"},{"line_number":208,"context_line":"    def ironicconn(self):"},{"line_number":209,"context_line":"        if self._ironicconn is None:"},{"line_number":210,"context_line":"            self._ironicconn \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":211,"context_line":"        return self._ironicconn"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_d2df0364","line":208,"range":{"start_line":208,"start_character":8,"end_line":208,"end_character":18},"in_reply_to":"7faddb67_e91b467d","updated":"2019-08-13 04:27:35.000000000","message":"Easy enough change","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"c85247b1febbc783790c5a928594f4801ede4091","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        node \u003d self.ironicconn.get_node(node_id)"},{"line_number":220,"context_line":"        # TODO(dustinc): Make consumers use the right fields and remove this"},{"line_number":221,"context_line":"        node.uuid \u003d node.id"},{"line_number":222,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":223,"context_line":"        node.maintenance \u003d node.is_maintenance"},{"line_number":224,"context_line":"        return node"},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    def _validate_instance_and_node(self, instance):"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_7e8f2775","line":223,"range":{"start_line":222,"start_character":0,"end_line":223,"end_character":46},"updated":"2019-08-09 10:26:53.000000000","message":"I\u0027m assuming these objects are a weird type that let you set random attributes like this","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"30e0943591dea142c622ecda2b6717fac878f6a3","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        node \u003d self.ironicconn.get_node(node_id)"},{"line_number":220,"context_line":"        # TODO(dustinc): Make consumers use the right fields and remove this"},{"line_number":221,"context_line":"        node.uuid \u003d node.id"},{"line_number":222,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":223,"context_line":"        node.maintenance \u003d node.is_maintenance"},{"line_number":224,"context_line":"        return node"},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    def _validate_instance_and_node(self, instance):"}],"source_content_type":"text/x-python","patch_set":36,"id":"7faddb67_d28aa362","line":223,"range":{"start_line":222,"start_character":0,"end_line":223,"end_character":46},"in_reply_to":"7faddb67_7e8f2775","updated":"2019-08-13 04:27:35.000000000","message":"Correct, they are defined in https://github.com/openstack/openstacksdk/blob/master/openstack/baremetal/v1/node.py","commit_id":"a8b40ec664be8faea5bbfa2846f946fbb302f641"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8b2a20dac4b41a372320fbc2c69b7ea83fc1316a","unresolved":false,"context_lines":[{"line_number":216,"context_line":"           Some methods pass in variables named nodename, but are"},{"line_number":217,"context_line":"           actually UUID\u0027s."},{"line_number":218,"context_line":"        \"\"\""},{"line_number":219,"context_line":"        node \u003d self.ironic_connection.get_node(node_id, fields\u003d_NODE_FIELDS)"},{"line_number":220,"context_line":"        # TODO(dustinc): Make consumers use the right fields and remove this"},{"line_number":221,"context_line":"        node.uuid \u003d node.id"},{"line_number":222,"context_line":"        node.instance_uuid \u003d node.instance_id"}],"source_content_type":"text/x-python","patch_set":38,"id":"7faddb67_fb977739","line":219,"range":{"start_line":219,"start_character":56,"end_line":219,"end_character":75},"updated":"2019-08-13 09:51:32.000000000","message":"fields are not supported in the SDK, let\u0027s leave a FIXME for now?","commit_id":"4137de8a790b54c1af3b52fadc7cedd7e70d68df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"8cdb510319d1e1a037921bdec691dad3f016814f","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        self._migrated_instance_uuids \u003d set()"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    @property"},{"line_number":208,"context_line":"    def ironic_connection(self):"},{"line_number":209,"context_line":"        if self._ironic_connection is None:"},{"line_number":210,"context_line":"            self._ironic_connection \u003d utils.get_sdk_adapter(\u0027baremetal\u0027)"},{"line_number":211,"context_line":"        return self._ironic_connection"}],"source_content_type":"text/x-python","patch_set":41,"id":"7faddb67_80850a5c","line":208,"updated":"2019-08-22 13:57:36.000000000","message":"Compared to the last time I looked at this (PS33) it looks like this did the trick for avoiding the traceback on start of the driver when ironic-api isn\u0027t yet running, so that\u0027s good.","commit_id":"8a47f053cf8cdf2c0a87c86f6f121d79fc8222f3"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c45591fa3ae46195c252bebb451a2ac082db1027","unresolved":false,"context_lines":[{"line_number":209,"context_line":"    def ironic_connection(self):"},{"line_number":210,"context_line":"        if self._ironic_connection is None:"},{"line_number":211,"context_line":"            # Ask get_sdk_adapter to raise ServiceUnavailable if the baremetal"},{"line_number":212,"context_line":"            # service isn\u0027t ready yet. Consumers of ironic_connection are set"},{"line_number":213,"context_line":"            # up to handle this and raise VirtDriverNotReady as appropriate."},{"line_number":214,"context_line":"            self._ironic_connection \u003d utils.get_sdk_adapter("},{"line_number":215,"context_line":"                \u0027baremetal\u0027, check_service\u003dTrue)"},{"line_number":216,"context_line":"        return self._ironic_connection"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_c7cb911a","line":213,"range":{"start_line":212,"start_character":39,"end_line":213,"end_character":76},"updated":"2019-08-30 14:29:10.000000000","message":"Really? Where? I see lots of calls to self._get_node() that aren\u0027t handling ServiceUnavailable. Is this comment old?","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f658d65fa5d770319cad5e3fccdbb812ba397e76","unresolved":false,"context_lines":[{"line_number":209,"context_line":"    def ironic_connection(self):"},{"line_number":210,"context_line":"        if self._ironic_connection is None:"},{"line_number":211,"context_line":"            # Ask get_sdk_adapter to raise ServiceUnavailable if the baremetal"},{"line_number":212,"context_line":"            # service isn\u0027t ready yet. Consumers of ironic_connection are set"},{"line_number":213,"context_line":"            # up to handle this and raise VirtDriverNotReady as appropriate."},{"line_number":214,"context_line":"            self._ironic_connection \u003d utils.get_sdk_adapter("},{"line_number":215,"context_line":"                \u0027baremetal\u0027, check_service\u003dTrue)"},{"line_number":216,"context_line":"        return self._ironic_connection"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_428c6f7f","line":213,"range":{"start_line":212,"start_character":39,"end_line":213,"end_character":76},"in_reply_to":"7faddb67_271e2570","updated":"2019-08-30 14:56:55.000000000","message":"Ack, will let it slide...this time!","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8a00931ce95cccc51cde1eb6ce0bcdc9c97ab339","unresolved":false,"context_lines":[{"line_number":209,"context_line":"    def ironic_connection(self):"},{"line_number":210,"context_line":"        if self._ironic_connection is None:"},{"line_number":211,"context_line":"            # Ask get_sdk_adapter to raise ServiceUnavailable if the baremetal"},{"line_number":212,"context_line":"            # service isn\u0027t ready yet. Consumers of ironic_connection are set"},{"line_number":213,"context_line":"            # up to handle this and raise VirtDriverNotReady as appropriate."},{"line_number":214,"context_line":"            self._ironic_connection \u003d utils.get_sdk_adapter("},{"line_number":215,"context_line":"                \u0027baremetal\u0027, check_service\u003dTrue)"},{"line_number":216,"context_line":"        return self._ironic_connection"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_271e2570","line":213,"range":{"start_line":212,"start_character":39,"end_line":213,"end_character":76},"in_reply_to":"7faddb67_c7cb911a","updated":"2019-08-30 14:37:03.000000000","message":"Bleh, actually the comment is premature. The VirtDriverNotReady business happens in the next patch: https://review.opendev.org/#/c/656027/29/nova/virt/ironic/driver.py@655","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c45591fa3ae46195c252bebb451a2ac082db1027","unresolved":false,"context_lines":[{"line_number":222,"context_line":"           actually UUID\u0027s."},{"line_number":223,"context_line":"        \"\"\""},{"line_number":224,"context_line":"        node \u003d self.ironic_connection.get_node(node_id, fields\u003d_NODE_FIELDS)"},{"line_number":225,"context_line":"        # TODO(dustinc): Make consumers use the right fields and remove this"},{"line_number":226,"context_line":"        node.uuid \u003d node.id"},{"line_number":227,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":228,"context_line":"        node.maintenance \u003d node.is_maintenance"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_0778c9f5","line":225,"updated":"2019-08-30 14:29:10.000000000","message":"So does the ironic API define id/instance_id/is_maintenance but python-ironicclient was returning uuid/instance_uuid/maintenance so that\u0027s what the nova driver was using, but the SDK is using the ironic API fields directly?\n\nLooking at the baremetal API ref, it looks like the other way around:\n\nhttps://docs.openstack.org/api-ref/baremetal/?expanded\u003dshow-node-details-detail#id9\n\nThe SDK is returning specifically different fields from the API? That seems not so good for an SDK.","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8a00931ce95cccc51cde1eb6ce0bcdc9c97ab339","unresolved":false,"context_lines":[{"line_number":222,"context_line":"           actually UUID\u0027s."},{"line_number":223,"context_line":"        \"\"\""},{"line_number":224,"context_line":"        node \u003d self.ironic_connection.get_node(node_id, fields\u003d_NODE_FIELDS)"},{"line_number":225,"context_line":"        # TODO(dustinc): Make consumers use the right fields and remove this"},{"line_number":226,"context_line":"        node.uuid \u003d node.id"},{"line_number":227,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":228,"context_line":"        node.maintenance \u003d node.is_maintenance"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_c2037f0b","line":225,"in_reply_to":"7faddb67_0778c9f5","updated":"2019-08-30 14:37:03.000000000","message":"I believe this was an intentional architectural decision to make what the SDK exposes consistent across all services. Might have to take this one up with mordred.","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f658d65fa5d770319cad5e3fccdbb812ba397e76","unresolved":false,"context_lines":[{"line_number":222,"context_line":"           actually UUID\u0027s."},{"line_number":223,"context_line":"        \"\"\""},{"line_number":224,"context_line":"        node \u003d self.ironic_connection.get_node(node_id, fields\u003d_NODE_FIELDS)"},{"line_number":225,"context_line":"        # TODO(dustinc): Make consumers use the right fields and remove this"},{"line_number":226,"context_line":"        node.uuid \u003d node.id"},{"line_number":227,"context_line":"        node.instance_uuid \u003d node.instance_id"},{"line_number":228,"context_line":"        node.maintenance \u003d node.is_maintenance"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_8296e793","line":225,"in_reply_to":"7faddb67_c2037f0b","updated":"2019-08-30 14:56:55.000000000","message":"OK.","commit_id":"0176390531aa7bba56a12960334be4de2dd409ef"}]}
