)]}'
{"nova/tests/unit/virt/ironic/test_driver.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c76fa2bac0570a051b456363a300f9357836f2b2","unresolved":false,"context_lines":[{"line_number":1881,"context_line":"                resource_class\u003d\"dummy\","},{"line_number":1882,"context_line":"                network_interface\u003d\"flat\")"},{"line_number":1883,"context_line":"        mock_get_by_host.return_value \u003d [instance]"},{"line_number":1884,"context_line":"        mock_get_node_list.return_value \u003d [node]"},{"line_number":1885,"context_line":"        self.assertEqual({}, instance.flavor.extra_specs)"},{"line_number":1886,"context_line":"        self.driver.init_host(hostname)"},{"line_number":1887,"context_line":"        mock_save.assert_called_once_with()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_6e87a511","line":1884,"updated":"2017-07-20 14:17:11.000000000","message":"How about making sure we do more than just the one?","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"705b326cf858f4f63994cfe7a8ac6d0b415250a3","unresolved":false,"context_lines":[{"line_number":1881,"context_line":"                resource_class\u003d\"dummy\","},{"line_number":1882,"context_line":"                network_interface\u003d\"flat\")"},{"line_number":1883,"context_line":"        mock_get_by_host.return_value \u003d [instance]"},{"line_number":1884,"context_line":"        mock_get_node_list.return_value \u003d [node]"},{"line_number":1885,"context_line":"        self.assertEqual({}, instance.flavor.extra_specs)"},{"line_number":1886,"context_line":"        self.driver.init_host(hostname)"},{"line_number":1887,"context_line":"        mock_save.assert_called_once_with()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_0b211aa0","line":1884,"in_reply_to":"1f1a1f67_6e87a511","updated":"2017-07-21 12:45:45.000000000","message":"Done","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c76fa2bac0570a051b456363a300f9357836f2b2","unresolved":false,"context_lines":[{"line_number":1910,"context_line":"                resource_class\u003d\"dummy\","},{"line_number":1911,"context_line":"                network_interface\u003d\"flat\")"},{"line_number":1912,"context_line":"        mock_get_by_host.return_value \u003d [instance]"},{"line_number":1913,"context_line":"        mock_get_node_list.return_value \u003d [node]"},{"line_number":1914,"context_line":"        self.driver.init_host(hostname)"},{"line_number":1915,"context_line":"        mock_save.assert_not_called()"},{"line_number":1916,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_ce8d992b","line":1913,"updated":"2017-07-20 14:17:11.000000000","message":"I think you should have one converted and one unconverted instance here to make sure that we skip and continue per the code.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"705b326cf858f4f63994cfe7a8ac6d0b415250a3","unresolved":false,"context_lines":[{"line_number":1910,"context_line":"                resource_class\u003d\"dummy\","},{"line_number":1911,"context_line":"                network_interface\u003d\"flat\")"},{"line_number":1912,"context_line":"        mock_get_by_host.return_value \u003d [instance]"},{"line_number":1913,"context_line":"        mock_get_node_list.return_value \u003d [node]"},{"line_number":1914,"context_line":"        self.driver.init_host(hostname)"},{"line_number":1915,"context_line":"        mock_save.assert_not_called()"},{"line_number":1916,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_cb3a02cc","line":1913,"in_reply_to":"1f1a1f67_ce8d992b","updated":"2017-07-21 12:45:45.000000000","message":"Done","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"35059e2c06aff92ec9ef8f714a8da89231fc1724","unresolved":false,"context_lines":[{"line_number":1944,"context_line":"        # blocking. We want it to block for the test so that we can verify that"},{"line_number":1945,"context_line":"        # the correct calls were made."},{"line_number":1946,"context_line":"        thread \u003d self.driver.init_host(hostname)"},{"line_number":1947,"context_line":"        thread.join()"},{"line_number":1948,"context_line":"        # Since one instance already had its extra_specs updated with the"},{"line_number":1949,"context_line":"        # custom resource_class, only the other one should be updated and"},{"line_number":1950,"context_line":"        # saved."}],"source_content_type":"text/x-python","patch_set":8,"id":"1f1a1f67_c1365eb5","line":1947,"updated":"2017-07-21 16:17:19.000000000","message":"When you convert to spawn, we have a spawn-is-synchronous fixture that will make the code in the thread operate immediately on the spawn and you won\u0027t have to worry about this.\n\nOtherwise, these are better now with the multiple instance/node simulation, thanks.","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"43b20ecc55e7d1bb90970bbf913a226a148464fa","unresolved":false,"context_lines":[{"line_number":1944,"context_line":"        # blocking. We want it to block for the test so that we can verify that"},{"line_number":1945,"context_line":"        # the correct calls were made."},{"line_number":1946,"context_line":"        thread \u003d self.driver.init_host(hostname)"},{"line_number":1947,"context_line":"        thread.join()"},{"line_number":1948,"context_line":"        # Since one instance already had its extra_specs updated with the"},{"line_number":1949,"context_line":"        # custom resource_class, only the other one should be updated and"},{"line_number":1950,"context_line":"        # saved."}],"source_content_type":"text/x-python","patch_set":8,"id":"ff346bd7_22cc0cbb","line":1947,"in_reply_to":"1f1a1f67_c1365eb5","updated":"2017-07-24 16:07:15.000000000","message":"Done","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4b14886f28921a99fa75e8f85f0b9f475d138e4b","unresolved":false,"context_lines":[{"line_number":2021,"context_line":"        mock_refresh_cache.side_effect \u003d fake_refresh"},{"line_number":2022,"context_line":""},{"line_number":2023,"context_line":"        self.driver.init_host(hostname)"},{"line_number":2024,"context_line":"        # Since one instance already had its extra_specs updated with the"},{"line_number":2025,"context_line":"        # custom resource_class, only the other one should be updated and"},{"line_number":2026,"context_line":"        # saved."},{"line_number":2027,"context_line":"        self.assertEqual(1, mock_save.call_count)"},{"line_number":2028,"context_line":"        expected_specs \u003d {}"},{"line_number":2029,"context_line":"        self.assertEqual(expected_specs, inst1.flavor.extra_specs)"}],"source_content_type":"text/x-python","patch_set":12,"id":"ff346bd7_d7b619da","line":2026,"range":{"start_line":2024,"start_character":9,"end_line":2026,"end_character":16},"updated":"2017-07-24 22:00:58.000000000","message":"This is copy/paste from above, but isn\u0027t right for this case.","commit_id":"5a7a7c3826de879b5e5a0d83d08808813de81e87"}],"nova/virt/ironic/driver.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3874a96a73d689b6884c741d26fd31ff748ba763","unresolved":false,"context_lines":[{"line_number":463,"context_line":"            cn \u003d objects.ComputeNode.get_by_host_and_nodename(ctx, inst.host,"},{"line_number":464,"context_line":"                    inst.node)"},{"line_number":465,"context_line":"            rp \u003d objects.ResourceProvider.get_by_uuid(ctx, cn.uuid)"},{"line_number":466,"context_line":"            # Delete any existing allocations so that we can update the"},{"line_number":467,"context_line":"            # inventory"},{"line_number":468,"context_line":"            allocs \u003d objects.AllocationList.get_all_by_resource_provider_uuid("},{"line_number":469,"context_line":"                    ctx, rp.uuid)"},{"line_number":470,"context_line":"            allocs.delete_all()"},{"line_number":471,"context_line":"            # Create the Inventory object for the node"},{"line_number":472,"context_line":"            inv \u003d objects.Inventory(ctx, resource_provider\u003drp,"},{"line_number":473,"context_line":"                    resource_class\u003drc, total\u003d1, reserved\u003d0, min_unit\u003d1,"},{"line_number":474,"context_line":"                    max_unit\u003d1, allocation_ratio\u003d1.0, step_size\u003d1)"},{"line_number":475,"context_line":"            inv_list \u003d objects.InventoryList(objects\u003d[inv])"},{"line_number":476,"context_line":"            rp.set_inventory(inv_list)"},{"line_number":477,"context_line":"            # Now create the single allocation against the inventory"},{"line_number":478,"context_line":"            alloc \u003d objects.Allocation(ctx, resource_provider\u003drp,"},{"line_number":479,"context_line":"                    consumer_id\u003dinst.uuid, resource_class\u003drc, used\u003d1)"},{"line_number":480,"context_line":"            alloc_list \u003d objects.AllocationList(ctx, objects\u003d[alloc])"},{"line_number":481,"context_line":"            alloc_list.create_all()"},{"line_number":482,"context_line":"            # Change the instance.flavor\u0027s extra_specs"},{"line_number":483,"context_line":"            specs \u003d inst.flavor.extra_specs"},{"line_number":484,"context_line":"            res_key \u003d \"resources:%s\" % rc"}],"source_content_type":"text/x-python","patch_set":1,"id":"1f1a1f67_7e70b808","line":481,"range":{"start_line":466,"start_character":12,"end_line":481,"end_character":35},"updated":"2017-07-18 21:23:55.000000000","message":"We don\u0027t want to be doing this stuff in here, we should let this handle it:\n\nhttps://review.openstack.org/#/c/484935/","commit_id":"e3b445d5006d1ff3ccff9416bd361d65a6113cb3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e2883be92097af8a6c4ee977a211f41a7e54b957","unresolved":false,"context_lines":[{"line_number":446,"context_line":"        \"\"\""},{"line_number":447,"context_line":"        # --------------------------------------------------------------------"},{"line_number":448,"context_line":"        # NOTE(edleafe): This code is needed in Pike in order to migrate the"},{"line_number":449,"context_line":"        # old-style allocations for Ironic nodes to the new-style that uses"},{"line_number":450,"context_line":"        # custom resource classes. everything between the dotted comment lines"},{"line_number":451,"context_line":"        # should be removed in Queens, so that this method is returned to a"},{"line_number":452,"context_line":"        # simple no-op \u0027return\u0027 statement."}],"source_content_type":"text/x-python","patch_set":2,"id":"1f1a1f67_79de92da","line":449,"range":{"start_line":449,"start_character":20,"end_line":449,"end_character":31},"updated":"2017-07-18 21:59:51.000000000","message":"\"instance flavors\"","commit_id":"76319fe6ccbd57c49a342d36443e2e103f7ece61"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e2883be92097af8a6c4ee977a211f41a7e54b957","unresolved":false,"context_lines":[{"line_number":447,"context_line":"        # --------------------------------------------------------------------"},{"line_number":448,"context_line":"        # NOTE(edleafe): This code is needed in Pike in order to migrate the"},{"line_number":449,"context_line":"        # old-style allocations for Ironic nodes to the new-style that uses"},{"line_number":450,"context_line":"        # custom resource classes. everything between the dotted comment lines"},{"line_number":451,"context_line":"        # should be removed in Queens, so that this method is returned to a"},{"line_number":452,"context_line":"        # simple no-op \u0027return\u0027 statement."},{"line_number":453,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"}],"source_content_type":"text/x-python","patch_set":2,"id":"1f1a1f67_39f6da64","line":450,"range":{"start_line":450,"start_character":35,"end_line":450,"end_character":78},"updated":"2017-07-18 21:59:51.000000000","message":"Instead of this, we should just put this code in a \"migrate_pike_stuff()\" method or something and docstring that as fated to disappear.","commit_id":"76319fe6ccbd57c49a342d36443e2e103f7ece61"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e2883be92097af8a6c4ee977a211f41a7e54b957","unresolved":false,"context_lines":[{"line_number":459,"context_line":"                continue"},{"line_number":460,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":461,"context_line":"            # There can be only one instance per node."},{"line_number":462,"context_line":"            inst \u003d objects.Instance.get_by_uuid(ctx, node.instance_uuid)"},{"line_number":463,"context_line":"            # Change the instance.flavor\u0027s extra_specs"},{"line_number":464,"context_line":"            specs \u003d inst.flavor.extra_specs"},{"line_number":465,"context_line":"            res_key \u003d \"resources:%s\" % rc"}],"source_content_type":"text/x-python","patch_set":2,"id":"1f1a1f67_f984e2d4","line":462,"updated":"2017-07-18 21:59:51.000000000","message":"There could potentially be tons of instances behind us in ironic. Doing a db query per isn\u0027t that great. I would recommend we use a batch size of something reasonable, and work through batches with get_by_filters().\n\nAlso, you want to pre-join flavor otherwise you\u0027re going to do _two_ per instance.","commit_id":"76319fe6ccbd57c49a342d36443e2e103f7ece61"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"25606f9c270223e15a6de650de588d78a7895f68","unresolved":false,"context_lines":[{"line_number":460,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":461,"context_line":"            # There can be only one instance per node."},{"line_number":462,"context_line":"            inst \u003d objects.Instance.get_by_uuid(ctx, node.instance_uuid)"},{"line_number":463,"context_line":"            # Change the instance.flavor\u0027s extra_specs"},{"line_number":464,"context_line":"            specs \u003d inst.flavor.extra_specs"},{"line_number":465,"context_line":"            res_key \u003d \"resources:%s\" % rc"},{"line_number":466,"context_line":"            specs[res_key] \u003d 1"},{"line_number":467,"context_line":"            # Zero out the standard VM resource classes"},{"line_number":468,"context_line":"            for std_class in (\"VCPU\", \"MEMORY_MB\", \"DISK_GB\"):"},{"line_number":469,"context_line":"                res_key \u003d \"resources:%s\" % std_class"},{"line_number":470,"context_line":"                specs[res_key] \u003d 0"},{"line_number":471,"context_line":"            inst.save()"},{"line_number":472,"context_line":"        # --------------------------------------------------------------------"},{"line_number":473,"context_line":"        return"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1f1a1f67_593196a2","line":471,"range":{"start_line":463,"start_character":0,"end_line":471,"end_character":23},"updated":"2017-07-18 21:42:33.000000000","message":"We should be able to optimize this to not attempt an update of anything if it\u0027s already set. We only want to migrate these things once.","commit_id":"76319fe6ccbd57c49a342d36443e2e103f7ece61"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e2883be92097af8a6c4ee977a211f41a7e54b957","unresolved":false,"context_lines":[{"line_number":460,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":461,"context_line":"            # There can be only one instance per node."},{"line_number":462,"context_line":"            inst \u003d objects.Instance.get_by_uuid(ctx, node.instance_uuid)"},{"line_number":463,"context_line":"            # Change the instance.flavor\u0027s extra_specs"},{"line_number":464,"context_line":"            specs \u003d inst.flavor.extra_specs"},{"line_number":465,"context_line":"            res_key \u003d \"resources:%s\" % rc"},{"line_number":466,"context_line":"            specs[res_key] \u003d 1"},{"line_number":467,"context_line":"            # Zero out the standard VM resource classes"},{"line_number":468,"context_line":"            for std_class in (\"VCPU\", \"MEMORY_MB\", \"DISK_GB\"):"},{"line_number":469,"context_line":"                res_key \u003d \"resources:%s\" % std_class"},{"line_number":470,"context_line":"                specs[res_key] \u003d 0"},{"line_number":471,"context_line":"            inst.save()"},{"line_number":472,"context_line":"        # --------------------------------------------------------------------"},{"line_number":473,"context_line":"        return"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1f1a1f67_9975eefc","line":471,"range":{"start_line":463,"start_character":0,"end_line":471,"end_character":23},"in_reply_to":"1f1a1f67_593196a2","updated":"2017-07-18 21:59:51.000000000","message":"We can\u0027t do this in pike, right? If we zero these out then the resource tracker will stop asking for allocations of the standard resources and flavors without overrides will start matching hosts with instances on them.\n\nI think we need to allocate the standard and custom types in pike and then stop in queens. In queens we\u0027ll just stop asking for those by flavor overrides.","commit_id":"76319fe6ccbd57c49a342d36443e2e103f7ece61"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e2883be92097af8a6c4ee977a211f41a7e54b957","unresolved":false,"context_lines":[{"line_number":659,"context_line":"        rc_name \u003d info.get(\u0027resource_class\u0027)"},{"line_number":660,"context_line":"        if rc_name is not None:"},{"line_number":661,"context_line":"            norm_name \u003d obj_fields.ResourceClass.normalize_name(rc_name)"},{"line_number":662,"context_line":"        if norm_name is not None:"},{"line_number":663,"context_line":"            result \u003d {norm_name: {"},{"line_number":664,"context_line":"                \u0027total\u0027: 1,"},{"line_number":665,"context_line":"                \u0027reserved\u0027: 0,"},{"line_number":666,"context_line":"                \u0027min_unit\u0027: 1,"},{"line_number":667,"context_line":"                \u0027max_unit\u0027: 1,"},{"line_number":668,"context_line":"                \u0027step_size\u0027: 1,"},{"line_number":669,"context_line":"                \u0027allocation_ratio\u0027: 1.0,"},{"line_number":670,"context_line":"            }}"},{"line_number":671,"context_line":"        else:"},{"line_number":672,"context_line":"            result \u003d {"},{"line_number":673,"context_line":"                obj_fields.ResourceClass.VCPU: {"}],"source_content_type":"text/x-python","patch_set":2,"id":"1f1a1f67_f9d2a2d0","line":670,"range":{"start_line":662,"start_character":0,"end_line":670,"end_character":14},"updated":"2017-07-18 21:59:51.000000000","message":"My understanding is that we\u0027ve already encouraged people to set the resource class on their ironic nodes in ocata or before. If you do this, ironic nodes will immediately stop reporting the standard resources, which means all existing flavors will stop working.\n\nYou need to continue to expose both the standard and custom ones in Pike.","commit_id":"76319fe6ccbd57c49a342d36443e2e103f7ece61"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"6e74bc17db39a5e7421efe5ffeaae2f197c00512","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":469,"context_line":"            inst \u003d inst_by_uuid.get(node.instance_uuid)"},{"line_number":470,"context_line":"            if not inst:"},{"line_number":471,"context_line":"                LOG.warning(\"Instance UUID %(uuid)s not found on host \""},{"line_number":472,"context_line":"                        \"\u0027%(host)s\u0027 and node \u0027%(node)s during Pike ironic \""},{"line_number":473,"context_line":"                        \"flavor migration.\", {\"uuid\": node.instance_uuid,"},{"line_number":474,"context_line":"                        \"host\": host, \"node\": node})"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f1a1f67_8c123261","line":471,"updated":"2017-07-19 15:18:23.000000000","message":"I\u0027m confused why this is a warning, but that may be because I\u0027m confused by how ironic works. Above the call to _get_node_list gets all the ironic nodes. inst_by_uuid is those instances associated with the host that that this virt driver is running on. If there are multiple hosts running ironic then there will be many ironic nodes that are not in inst_by_uuid and this warning will happen a fair bit but isn\u0027t actually \"wrong\".\n\nGiven that there\u0027s a hash ring and a cache, maybe there is something that can be done with that? It appears that the get_available_nodes() call which \"Returns the UUIDs of Ironic nodes managed by this compute service.\" may be of some use so we\u0027re only working with nodes that this host cares about?\n\nOr is that not being used because we want to get all this done before any of that code is availalbe? If so, then at least the log call shouldn\u0027t be a warning.","commit_id":"48eb3bb689bd7f77fabae6905d205a6366ff0dc4"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"e2f045d246578d3a8880fe947544dfee48f0d267","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":469,"context_line":"            inst \u003d inst_by_uuid.get(node.instance_uuid)"},{"line_number":470,"context_line":"            if not inst:"},{"line_number":471,"context_line":"                LOG.warning(\"Instance UUID %(uuid)s not found on host \""},{"line_number":472,"context_line":"                        \"\u0027%(host)s\u0027 and node \u0027%(node)s during Pike ironic \""},{"line_number":473,"context_line":"                        \"flavor migration.\", {\"uuid\": node.instance_uuid,"},{"line_number":474,"context_line":"                        \"host\": host, \"node\": node})"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f1a1f67_c11470eb","line":471,"in_reply_to":"1f1a1f67_8c123261","updated":"2017-07-19 16:45:36.000000000","message":"This was based on a misunderstanding I got from talking aobut the meaning of \u0027associated\u003dTrue\u0027 in the _get_node_list() call. Now that the actual effect is clear, I\u0027ll re-write this part.","commit_id":"48eb3bb689bd7f77fabae6905d205a6366ff0dc4"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c76fa2bac0570a051b456363a300f9357836f2b2","unresolved":false,"context_lines":[{"line_number":447,"context_line":"        self._temp_pike_migration(host)"},{"line_number":448,"context_line":"        return"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"    def _temp_pike_migration(self, host):"},{"line_number":451,"context_line":"        # --------------------------------------------------------------------"},{"line_number":452,"context_line":"        # NOTE(edleafe): This code is needed in Pike in order to migrate the"},{"line_number":453,"context_line":"        # old-style instance flavors for Ironic instances to the new-style that"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_4b23bbbf","line":450,"range":{"start_line":450,"start_character":9,"end_line":450,"end_character":13},"updated":"2017-07-20 14:17:11.000000000","message":"It seems strange to me to have the word \"temp\" in a method name. Especially since this will be in pike forever, and may not even be removed in queens if we decide we need to straddle this line for longer. Just _pike_flavor_migration() or something would be better IMHO.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"2eac3fc5ebd7441c82b50d77ab2505c23f6a4e70","unresolved":false,"context_lines":[{"line_number":447,"context_line":"        self._temp_pike_migration(host)"},{"line_number":448,"context_line":"        return"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"    def _temp_pike_migration(self, host):"},{"line_number":451,"context_line":"        # --------------------------------------------------------------------"},{"line_number":452,"context_line":"        # NOTE(edleafe): This code is needed in Pike in order to migrate the"},{"line_number":453,"context_line":"        # old-style instance flavors for Ironic instances to the new-style that"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_e6e2c3a0","line":450,"updated":"2017-07-20 12:28:54.000000000","message":"this method badly needs some vertical whitespace, fur shure","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"705b326cf858f4f63994cfe7a8ac6d0b415250a3","unresolved":false,"context_lines":[{"line_number":447,"context_line":"        self._temp_pike_migration(host)"},{"line_number":448,"context_line":"        return"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"    def _temp_pike_migration(self, host):"},{"line_number":451,"context_line":"        # --------------------------------------------------------------------"},{"line_number":452,"context_line":"        # NOTE(edleafe): This code is needed in Pike in order to migrate the"},{"line_number":453,"context_line":"        # old-style instance flavors for Ironic instances to the new-style that"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_8b68a121","line":450,"range":{"start_line":450,"start_character":9,"end_line":450,"end_character":13},"in_reply_to":"1f1a1f67_4b23bbbf","updated":"2017-07-21 12:45:45.000000000","message":"Done","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c76fa2bac0570a051b456363a300f9357836f2b2","unresolved":false,"context_lines":[{"line_number":455,"context_line":"        # init_host(), should be removed in Queens."},{"line_number":456,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":457,"context_line":"        instances \u003d objects.InstanceList.get_by_host(ctx, host,"},{"line_number":458,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":459,"context_line":"        # This will return all nodes with associated instances"},{"line_number":460,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":461,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_6e0c453b","line":458,"updated":"2017-07-20 14:17:11.000000000","message":"For a single ironic worker, which I think is the most common case, this will pull every ironic instance in the deployment in a single shot. As I said before, I think it would make the most sense to pull the node list, and process batches of 25 instances or so out of that until exhausted.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"705b326cf858f4f63994cfe7a8ac6d0b415250a3","unresolved":false,"context_lines":[{"line_number":455,"context_line":"        # init_host(), should be removed in Queens."},{"line_number":456,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":457,"context_line":"        instances \u003d objects.InstanceList.get_by_host(ctx, host,"},{"line_number":458,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":459,"context_line":"        # This will return all nodes with associated instances"},{"line_number":460,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":461,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_ab6b5d1d","line":458,"in_reply_to":"1f1a1f67_6e0c453b","updated":"2017-07-21 12:45:45.000000000","message":"Since compute nodes aren\u0027t supposed to be started up very often, that might take too long to process all of the instances, which would leave many vulnerable to their nodes being re-selected by placement until the operator had restarted the node a number of times. I\u0027ll make this async instead.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"84f2c24c5810fcc03beb8ebd318517f275f5167d","unresolved":false,"context_lines":[{"line_number":455,"context_line":"        # init_host(), should be removed in Queens."},{"line_number":456,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":457,"context_line":"        instances \u003d objects.InstanceList.get_by_host(ctx, host,"},{"line_number":458,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":459,"context_line":"        # This will return all nodes with associated instances"},{"line_number":460,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":461,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_1766d952","line":458,"in_reply_to":"1f1a1f67_ab6b5d1d","updated":"2017-07-21 14:51:14.000000000","message":"No, there\u0027s no gap until the operator changes their flavor.\n\nAlso, lots of config management tools restart services a lot during deployment. Go look at the tripleo ci logs. They bounce each service a bunch of times when effecting any change on the system. It\u0027s obnoxious, but I\u0027m sure it\u0027s not abnormal.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c76fa2bac0570a051b456363a300f9357836f2b2","unresolved":false,"context_lines":[{"line_number":475,"context_line":"            res_key \u003d \"resources:%s\" % rc"},{"line_number":476,"context_line":"            if res_key in specs:"},{"line_number":477,"context_line":"                # Flavor has already been updated"},{"line_number":478,"context_line":"                LOG.debug(\"Ironic instance %(inst)s has already had its \""},{"line_number":479,"context_line":"                        \"flavor extra_specs updated.\","},{"line_number":480,"context_line":"                        {\"inst\": instance.uuid})"},{"line_number":481,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_ee3055eb","line":478,"updated":"2017-07-20 14:17:11.000000000","message":"After the initial migration, this will log every single instance on every startup. I think it makes more sense to just log the ones we\u0027re migrating and not the ones we\u0027re skipping. Imagine a thousand lines of this on every startup for a year.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"46914bc45c40ab05326fd7b2919e9f31f1f73fdc","unresolved":false,"context_lines":[{"line_number":475,"context_line":"            res_key \u003d \"resources:%s\" % rc"},{"line_number":476,"context_line":"            if res_key in specs:"},{"line_number":477,"context_line":"                # Flavor has already been updated"},{"line_number":478,"context_line":"                LOG.debug(\"Ironic instance %(inst)s has already had its \""},{"line_number":479,"context_line":"                        \"flavor extra_specs updated.\","},{"line_number":480,"context_line":"                        {\"inst\": instance.uuid})"},{"line_number":481,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_d4540824","line":478,"in_reply_to":"1f1a1f67_ee3055eb","updated":"2017-07-20 15:09:42.000000000","message":"Done","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c76fa2bac0570a051b456363a300f9357836f2b2","unresolved":false,"context_lines":[{"line_number":481,"context_line":"                continue"},{"line_number":482,"context_line":"            specs[res_key] \u003d 1"},{"line_number":483,"context_line":"            # Zero out the standard VM resource classes"},{"line_number":484,"context_line":"            for std_class in (\"VCPU\", \"MEMORY_MB\", \"DISK_GB\"):"},{"line_number":485,"context_line":"                res_key \u003d \"resources:%s\" % std_class"},{"line_number":486,"context_line":"                specs[res_key] \u003d 0"},{"line_number":487,"context_line":"            instance.save()"},{"line_number":488,"context_line":"            LOG.debug(\"The flavor extra_specs for Ironic instance %(inst)s \""},{"line_number":489,"context_line":"                    \"have been updated for custom resource class \u0027%(rc)s\u0027.\","}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_aea49dba","line":486,"range":{"start_line":484,"start_character":0,"end_line":486,"end_character":34},"updated":"2017-07-20 14:17:11.000000000","message":"Again, you can\u0027t do this in pike. If you do, as soon as the computes are restarted, the scheduler will start sending instances here that are not booted with flavors that have the overrides because it looks like no instances are consuming the base resources anymore. But operators can\u0027t add the overrides until all the computes are upgraded. We discussed this specific case in Atlanta, and said that we would have to do this as a two-step process across a release boundary.\n\nSo, in pike, the old flavors will continue to work as they did before. Instances on existing nodes will have their flavors converted to also consume the custom resource type. Old flavors will still match the nodes and work. When flavors are converted, they can avoid requesting base resources and only request the custom ones to effect the transition. In Queens, we can just make the ironic driver stop reporting the base resources as inventory at all, which will leave the converted flavors operational. We can decide whether we want to expose or convert the instance flavors and their allocations, or just let time filter those out as things come and go with the new flavors.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9c63b6fc5db8c452c464d36e4932d48a1a1255dd","unresolved":false,"context_lines":[{"line_number":481,"context_line":"                continue"},{"line_number":482,"context_line":"            specs[res_key] \u003d 1"},{"line_number":483,"context_line":"            # Zero out the standard VM resource classes"},{"line_number":484,"context_line":"            for std_class in (\"VCPU\", \"MEMORY_MB\", \"DISK_GB\"):"},{"line_number":485,"context_line":"                res_key \u003d \"resources:%s\" % std_class"},{"line_number":486,"context_line":"                specs[res_key] \u003d 0"},{"line_number":487,"context_line":"            instance.save()"},{"line_number":488,"context_line":"            LOG.debug(\"The flavor extra_specs for Ironic instance %(inst)s \""},{"line_number":489,"context_line":"                    \"have been updated for custom resource class \u0027%(rc)s\u0027.\","}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_5fa2514d","line":486,"range":{"start_line":484,"start_character":0,"end_line":486,"end_character":34},"in_reply_to":"1f1a1f67_3f3f95b6","updated":"2017-07-20 15:25:06.000000000","message":"The whole point of this is to get the instances to have the custom class in their extra_specs, so that we fix up the allocations in placement. If we don\u0027t do that, then when the operators do change their base flavors, they\u0027ll start sending instances to nodes that don\u0027t claim to have their one custom class resource used. The opposite problem of what I described above.\n\nIn order to switch from A to B, something has to support A and B at the same time.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"46914bc45c40ab05326fd7b2919e9f31f1f73fdc","unresolved":false,"context_lines":[{"line_number":481,"context_line":"                continue"},{"line_number":482,"context_line":"            specs[res_key] \u003d 1"},{"line_number":483,"context_line":"            # Zero out the standard VM resource classes"},{"line_number":484,"context_line":"            for std_class in (\"VCPU\", \"MEMORY_MB\", \"DISK_GB\"):"},{"line_number":485,"context_line":"                res_key \u003d \"resources:%s\" % std_class"},{"line_number":486,"context_line":"                specs[res_key] \u003d 0"},{"line_number":487,"context_line":"            instance.save()"},{"line_number":488,"context_line":"            LOG.debug(\"The flavor extra_specs for Ironic instance %(inst)s \""},{"line_number":489,"context_line":"                    \"have been updated for custom resource class \u0027%(rc)s\u0027.\","}],"source_content_type":"text/x-python","patch_set":7,"id":"1f1a1f67_3f3f95b6","line":486,"range":{"start_line":484,"start_character":0,"end_line":486,"end_character":34},"in_reply_to":"1f1a1f67_aea49dba","updated":"2017-07-20 15:09:42.000000000","message":"If that\u0027s the case, then I\u0027m not sure why we need to muck with extra_specs for existing instances at all now.","commit_id":"1fed92763958a9b88026da77a038c21b0bab0588"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06ba637e81a74dd2537148ec6579c89af6b3d188","unresolved":false,"context_lines":[{"line_number":451,"context_line":"        thd \u003d threading.Thread(target\u003dself._pike_flavor_migration,"},{"line_number":452,"context_line":"                args\u003d(host,))"},{"line_number":453,"context_line":"        thd.setDaemon(True)"},{"line_number":454,"context_line":"        thd.start()"},{"line_number":455,"context_line":"        # Return the thread so that tests can run predictably"},{"line_number":456,"context_line":"        return thd"},{"line_number":457,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"1f1a1f67_57e0d196","line":454,"updated":"2017-07-21 14:59:25.000000000","message":"Um, WAT?\n\nThis should be a spawn() like everything else.","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"43b20ecc55e7d1bb90970bbf913a226a148464fa","unresolved":false,"context_lines":[{"line_number":451,"context_line":"        thd \u003d threading.Thread(target\u003dself._pike_flavor_migration,"},{"line_number":452,"context_line":"                args\u003d(host,))"},{"line_number":453,"context_line":"        thd.setDaemon(True)"},{"line_number":454,"context_line":"        thd.start()"},{"line_number":455,"context_line":"        # Return the thread so that tests can run predictably"},{"line_number":456,"context_line":"        return thd"},{"line_number":457,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"ff346bd7_82bcd805","line":454,"in_reply_to":"1f1a1f67_57e0d196","updated":"2017-07-24 16:07:15.000000000","message":"I was under the impression that we were not encouraging more eventlet usage, so I went with threading. I\u0027ve changed it to use utils.spawn_n instead","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"aacb5c03007d82ea47f47e2b524bf4def5a6eec8","unresolved":false,"context_lines":[{"line_number":451,"context_line":"        thd \u003d threading.Thread(target\u003dself._pike_flavor_migration,"},{"line_number":452,"context_line":"                args\u003d(host,))"},{"line_number":453,"context_line":"        thd.setDaemon(True)"},{"line_number":454,"context_line":"        thd.start()"},{"line_number":455,"context_line":"        # Return the thread so that tests can run predictably"},{"line_number":456,"context_line":"        return thd"},{"line_number":457,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"ff346bd7_42c15054","line":454,"in_reply_to":"ff346bd7_82bcd805","updated":"2017-07-24 16:11:37.000000000","message":"I think you\u0027re referencing the move from eventlet to wsgi for nova-api. That wouldn\u0027t apply here, and even still, in nova-api we\u0027re still using our spawn wrapper for all of that kind of thing, AFAIK because we have to continue to work in both modes.","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06ba637e81a74dd2537148ec6579c89af6b3d188","unresolved":false,"context_lines":[{"line_number":456,"context_line":"        return thd"},{"line_number":457,"context_line":""},{"line_number":458,"context_line":"    def _pike_flavor_migration(self, host):"},{"line_number":459,"context_line":"        # --------------------------------------------------------------------"},{"line_number":460,"context_line":"        # NOTE(edleafe): This code is needed in Pike to prevent problems where"},{"line_number":461,"context_line":"        # an operator has already adjusted their flavors to add the custom"},{"line_number":462,"context_line":"        # resource class to extra_specs. Since existing ironic instances will"}],"source_content_type":"text/x-python","patch_set":8,"id":"1f1a1f67_d7ed018c","line":459,"updated":"2017-07-21 14:59:25.000000000","message":"I think you can drop this line.","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"43b20ecc55e7d1bb90970bbf913a226a148464fa","unresolved":false,"context_lines":[{"line_number":456,"context_line":"        return thd"},{"line_number":457,"context_line":""},{"line_number":458,"context_line":"    def _pike_flavor_migration(self, host):"},{"line_number":459,"context_line":"        # --------------------------------------------------------------------"},{"line_number":460,"context_line":"        # NOTE(edleafe): This code is needed in Pike to prevent problems where"},{"line_number":461,"context_line":"        # an operator has already adjusted their flavors to add the custom"},{"line_number":462,"context_line":"        # resource class to extra_specs. Since existing ironic instances will"}],"source_content_type":"text/x-python","patch_set":8,"id":"ff346bd7_6237b4b2","line":459,"in_reply_to":"1f1a1f67_d7ed018c","updated":"2017-07-24 16:07:15.000000000","message":"Done","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06ba637e81a74dd2537148ec6579c89af6b3d188","unresolved":false,"context_lines":[{"line_number":470,"context_line":"        # VCPU, MEMORY_MB, and DISK_GB."},{"line_number":471,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":472,"context_line":"        instances \u003d objects.InstanceList.get_by_host(ctx, host,"},{"line_number":473,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":474,"context_line":"        # This will return all nodes with associated instances"},{"line_number":475,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":476,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"}],"source_content_type":"text/x-python","patch_set":8,"id":"1f1a1f67_379435e8","line":473,"updated":"2017-07-21 14:59:25.000000000","message":"Again, I think this needs to be batched. Imagine if I have my ironic compute running in a memory-limited container and a thousand instances. This will have to load them all into memory at once. Since we batch for other things, that\u0027s normally fine, but this will now explode.","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"43b20ecc55e7d1bb90970bbf913a226a148464fa","unresolved":false,"context_lines":[{"line_number":470,"context_line":"        # VCPU, MEMORY_MB, and DISK_GB."},{"line_number":471,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":472,"context_line":"        instances \u003d objects.InstanceList.get_by_host(ctx, host,"},{"line_number":473,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":474,"context_line":"        # This will return all nodes with associated instances"},{"line_number":475,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":476,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"}],"source_content_type":"text/x-python","patch_set":8,"id":"ff346bd7_025fc8e2","line":473,"in_reply_to":"1f1a1f67_379435e8","updated":"2017-07-24 16:07:15.000000000","message":"I don\u0027t see any reasonable way of batching, but the new version just gets instances one at a time, so the memory explosion should not be an issue.","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"aacb5c03007d82ea47f47e2b524bf4def5a6eec8","unresolved":false,"context_lines":[{"line_number":470,"context_line":"        # VCPU, MEMORY_MB, and DISK_GB."},{"line_number":471,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":472,"context_line":"        instances \u003d objects.InstanceList.get_by_host(ctx, host,"},{"line_number":473,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":474,"context_line":"        # This will return all nodes with associated instances"},{"line_number":475,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":476,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"}],"source_content_type":"text/x-python","patch_set":8,"id":"ff346bd7_02b0e8f3","line":473,"in_reply_to":"ff346bd7_025fc8e2","updated":"2017-07-24 16:11:37.000000000","message":"Just pick a number, say 25 at a time, and use get_by_filters() with uuid\u003duuids[n:n+25] ?","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06ba637e81a74dd2537148ec6579c89af6b3d188","unresolved":false,"context_lines":[{"line_number":473,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":474,"context_line":"        # This will return all nodes with associated instances"},{"line_number":475,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":476,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"},{"line_number":477,"context_line":"        nodes_by_inst \u003d {node.instance_uuid: node for node in node_list}"},{"line_number":478,"context_line":"        for instance in instances:"},{"line_number":479,"context_line":"            node \u003d nodes_by_inst.get(instance.uuid)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1f1a1f67_db164b4a","line":476,"updated":"2017-07-21 14:59:25.000000000","message":"Why are you doing this instead of just using the inbuilt node list caching stuff? If you build the cache before you spawn this thread, then the regular driver stuff can use the same cached data as this process... Otherwise we\u0027re pulling the same data for no reason, which is what the cache is supposed to fix.","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"43b20ecc55e7d1bb90970bbf913a226a148464fa","unresolved":false,"context_lines":[{"line_number":473,"context_line":"                expected_attrs\u003d[\"flavor\"])"},{"line_number":474,"context_line":"        # This will return all nodes with associated instances"},{"line_number":475,"context_line":"        node_list \u003d self._get_node_list(associated\u003dTrue, limit\u003d0,"},{"line_number":476,"context_line":"                fields\u003d[\"instance_uuid\", \"uuid\", \"resource_class\"])"},{"line_number":477,"context_line":"        nodes_by_inst \u003d {node.instance_uuid: node for node in node_list}"},{"line_number":478,"context_line":"        for instance in instances:"},{"line_number":479,"context_line":"            node \u003d nodes_by_inst.get(instance.uuid)"}],"source_content_type":"text/x-python","patch_set":8,"id":"ff346bd7_420a70d2","line":476,"in_reply_to":"1f1a1f67_db164b4a","updated":"2017-07-24 16:07:15.000000000","message":"Done","commit_id":"6fae2a7cb7c1ad91b65568b41898f9a5d4f0b9ad"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"75746c94fbbe1dc2b85c30f16bd609e8df720a7e","unresolved":false,"context_lines":[{"line_number":465,"context_line":"        \"\"\""},{"line_number":466,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":467,"context_line":"        if not self.node_cache:"},{"line_number":468,"context_line":"            self._refresh_cache()"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # Using itervalues here as the number of nodes can be very high"},{"line_number":471,"context_line":"        for node in six.itervalues(self.node_cache):"}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_c2f66090","line":468,"updated":"2017-07-24 16:17:38.000000000","message":"This might race with something else such that we\u0027re building the cache in two places at once, right? It won\u0027t harm anything that I know of, but I think we could be hammering ironic twice as hard as we need to be. That\u0027s why I was suggesting that we refresh the cache in init_host before we spawn this, where we know we\u0027re single-threaded.","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"00c4979c2b1be8f8f30a3ed56b5e7e75694b67c1","unresolved":false,"context_lines":[{"line_number":465,"context_line":"        \"\"\""},{"line_number":466,"context_line":"        ctx \u003d nova_context.get_admin_context()"},{"line_number":467,"context_line":"        if not self.node_cache:"},{"line_number":468,"context_line":"            self._refresh_cache()"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # Using itervalues here as the number of nodes can be very high"},{"line_number":471,"context_line":"        for node in six.itervalues(self.node_cache):"}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_25f3f60c","line":468,"in_reply_to":"ff346bd7_c2f66090","updated":"2017-07-24 16:47:38.000000000","message":"Done","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"75746c94fbbe1dc2b85c30f16bd609e8df720a7e","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            self._refresh_cache()"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # Using itervalues here as the number of nodes can be very high"},{"line_number":471,"context_line":"        for node in six.itervalues(self.node_cache):"},{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_821e18b8","line":471,"updated":"2017-07-24 16:17:38.000000000","message":"Still worried about the perf hit of doing either all at once or one at a time. Every ironic service will iterate every instance it has assigned to it on every service start for all of pike... Maybe we get a second opinion and if I\u0027m the only one concerned about it then we can just deal with it if/when we get bugs reported.","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5310bbd810116db92da7159648104efd39e73a76","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            self._refresh_cache()"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # Using itervalues here as the number of nodes can be very high"},{"line_number":471,"context_line":"        for node in six.itervalues(self.node_cache):"},{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_eb5edfe4","line":471,"in_reply_to":"ff346bd7_05ec72c5","updated":"2017-07-24 17:39:40.000000000","message":"I\u0027m not talking about per service start. I\u0027m talking about batching the queries we make each time. Making ten 25-instance queries is less load than 250 queries, and uses a fraction of the memory of querying all of them at once.","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"00c4979c2b1be8f8f30a3ed56b5e7e75694b67c1","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            self._refresh_cache()"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # Using itervalues here as the number of nodes can be very high"},{"line_number":471,"context_line":"        for node in six.itervalues(self.node_cache):"},{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_05ec72c5","line":471,"in_reply_to":"ff346bd7_821e18b8","updated":"2017-07-24 16:47:38.000000000","message":"Sorry, but even if this was a concern, I don\u0027t see how we could only run a subset with each start of the service, as there would not be any way of persisting the information as to which were not done. We would also have to check those nodes that were done in case new instances have been built on them in between service starts.","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"04ae08df6a6db7e936113bc4298879e8e1ea169a","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            self._refresh_cache()"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # Using itervalues here as the number of nodes can be very high"},{"line_number":471,"context_line":"        for node in six.itervalues(self.node_cache):"},{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_7632d6f3","line":471,"in_reply_to":"ff346bd7_eb049f7d","updated":"2017-07-24 18:06:28.000000000","message":"Yeah, I think doing a batched InstanceList.get_by_uuids(ctx, list_instances_uuids) for batches of 20-50 would be a good idea, especially if it\u0027s relatively easy to do here.","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"abd574968bd9f35bc25655dd27c4c807f8a661f0","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            self._refresh_cache()"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # Using itervalues here as the number of nodes can be very high"},{"line_number":471,"context_line":"        for node in six.itervalues(self.node_cache):"},{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_eb049f7d","line":471,"in_reply_to":"ff346bd7_eb5edfe4","updated":"2017-07-24 17:49:41.000000000","message":"Just to be clear, I\u0027d rather do one at a time like you have here than all at once, and I\u0027m willing to punt to the point in the future where this becomes a problem, if need be. It seems like a trivial thing to fix now, but don\u0027t want to delay over it.","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"75746c94fbbe1dc2b85c30f16bd609e8df720a7e","unresolved":false,"context_lines":[{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"            instance \u003d objects.Instance.get_by_uuid(ctx, node.instance_uuid)"},{"line_number":476,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":477,"context_line":"            specs \u003d instance.flavor.extra_specs"},{"line_number":478,"context_line":"            res_key \u003d \"resources:%s\" % rc"}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_2299ac6d","line":475,"updated":"2017-07-24 16:17:38.000000000","message":"You dropped the preload of the flavor, right?","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"00c4979c2b1be8f8f30a3ed56b5e7e75694b67c1","unresolved":false,"context_lines":[{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"            instance \u003d objects.Instance.get_by_uuid(ctx, node.instance_uuid)"},{"line_number":476,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":477,"context_line":"            specs \u003d instance.flavor.extra_specs"},{"line_number":478,"context_line":"            res_key \u003d \"resources:%s\" % rc"}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_e5c5ee8f","line":475,"in_reply_to":"ff346bd7_2299ac6d","updated":"2017-07-24 16:47:38.000000000","message":"crap - yeah. Fixed.","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"04ae08df6a6db7e936113bc4298879e8e1ea169a","unresolved":false,"context_lines":[{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"            instance \u003d objects.Instance.get_by_uuid(ctx, node.instance_uuid)"},{"line_number":476,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":477,"context_line":"            specs \u003d instance.flavor.extra_specs"},{"line_number":478,"context_line":"            res_key \u003d \"resources:%s\" % rc"},{"line_number":479,"context_line":"            if res_key in specs:"}],"source_content_type":"text/x-python","patch_set":9,"id":"ff346bd7_f60da637","line":476,"range":{"start_line":476,"start_character":57,"end_line":476,"end_character":76},"updated":"2017-07-24 18:06:28.000000000","message":"Are we handling cases where node.resource_class isn\u0027t set (yet)?","commit_id":"a47e5bda141c8da979b16106c0c2250f8a6a2b67"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4b14886f28921a99fa75e8f85f0b9f475d138e4b","unresolved":false,"context_lines":[{"line_number":472,"context_line":"            if not node.instance_uuid:"},{"line_number":473,"context_line":"                continue"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"            if not node.resource_class:"},{"line_number":476,"context_line":"                LOG.warning(\"Node %(node)s does not have its resource_class \""},{"line_number":477,"context_line":"                        \"set.\", {\"node\": node.uuid})"},{"line_number":478,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":12,"id":"ff346bd7_d7ba99dc","line":475,"range":{"start_line":475,"start_character":15,"end_line":475,"end_character":39},"updated":"2017-07-24 22:00:58.000000000","message":"_node_resource() hits this unconditionally, so I assume it\u0027s safe to do so here as well.","commit_id":"5a7a7c3826de879b5e5a0d83d08808813de81e87"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4b14886f28921a99fa75e8f85f0b9f475d138e4b","unresolved":false,"context_lines":[{"line_number":474,"context_line":""},{"line_number":475,"context_line":"            if not node.resource_class:"},{"line_number":476,"context_line":"                LOG.warning(\"Node %(node)s does not have its resource_class \""},{"line_number":477,"context_line":"                        \"set.\", {\"node\": node.uuid})"},{"line_number":478,"context_line":"                continue"},{"line_number":479,"context_line":"            rc \u003d obj_fields.ResourceClass.normalize_name(node.resource_class)"},{"line_number":480,"context_line":"            instance \u003d objects.Instance.get_by_uuid(ctx, node.instance_uuid,"}],"source_content_type":"text/x-python","patch_set":12,"id":"ff346bd7_178f012b","line":477,"updated":"2017-07-24 22:00:58.000000000","message":"We could probably use a more verbose and stern warning here, like \"Unable to fix up $instance, migration to custom resource classes will break. Aaoogahh! Achtung!\"\n\nBut, better than nothing :)","commit_id":"5a7a7c3826de879b5e5a0d83d08808813de81e87"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6705c2e40019a1b028627f0b888c702bee0c0638","unresolved":false,"context_lines":[{"line_number":487,"context_line":"            specs[res_key] \u003d 1"},{"line_number":488,"context_line":"            instance.save()"},{"line_number":489,"context_line":"            LOG.debug(\"The flavor extra_specs for Ironic instance %(inst)s \""},{"line_number":490,"context_line":"                    \"have been updated for custom resource class \u0027%(rc)s\u0027.\","},{"line_number":491,"context_line":"                    {\"inst\": instance.uuid, \"rc\": rc})"},{"line_number":492,"context_line":"        return"},{"line_number":493,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"ff346bd7_574c69c6","line":490,"updated":"2017-07-24 22:04:22.000000000","message":"ew alignment","commit_id":"7fe1246cb5726ce7902148fa482c0496a48e82d8"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"d92a5a67802a53acb8ac21025979e77f52afe22e","unresolved":false,"context_lines":[{"line_number":487,"context_line":"            specs[res_key] \u003d 1"},{"line_number":488,"context_line":"            instance.save()"},{"line_number":489,"context_line":"            LOG.debug(\"The flavor extra_specs for Ironic instance %(inst)s \""},{"line_number":490,"context_line":"                    \"have been updated for custom resource class \u0027%(rc)s\u0027.\","},{"line_number":491,"context_line":"                    {\"inst\": instance.uuid, \"rc\": rc})"},{"line_number":492,"context_line":"        return"},{"line_number":493,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"ff346bd7_9773f1e7","line":490,"in_reply_to":"ff346bd7_574c69c6","updated":"2017-07-24 22:06:53.000000000","message":"but line 477 is OK? :)","commit_id":"7fe1246cb5726ce7902148fa482c0496a48e82d8"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"c271ee87c0cb244257c68db4ba93f837236a73a8","unresolved":false,"context_lines":[{"line_number":487,"context_line":"            specs[res_key] \u003d 1"},{"line_number":488,"context_line":"            instance.save()"},{"line_number":489,"context_line":"            LOG.debug(\"The flavor extra_specs for Ironic instance %(inst)s \""},{"line_number":490,"context_line":"                    \"have been updated for custom resource class \u0027%(rc)s\u0027.\","},{"line_number":491,"context_line":"                    {\"inst\": instance.uuid, \"rc\": rc})"},{"line_number":492,"context_line":"        return"},{"line_number":493,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"ff346bd7_f2b5abef","line":490,"in_reply_to":"ff346bd7_72b89b29","updated":"2017-07-24 22:23:09.000000000","message":"2 levels (8 spaces) is one standard (the best, IMO) for continued lines. Visual alignment is the other.","commit_id":"7fe1246cb5726ce7902148fa482c0496a48e82d8"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2398bd86ce4409dfe9e806c784a27b2aacad76d4","unresolved":false,"context_lines":[{"line_number":487,"context_line":"            specs[res_key] \u003d 1"},{"line_number":488,"context_line":"            instance.save()"},{"line_number":489,"context_line":"            LOG.debug(\"The flavor extra_specs for Ironic instance %(inst)s \""},{"line_number":490,"context_line":"                    \"have been updated for custom resource class \u0027%(rc)s\u0027.\","},{"line_number":491,"context_line":"                    {\"inst\": instance.uuid, \"rc\": rc})"},{"line_number":492,"context_line":"        return"},{"line_number":493,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"ff346bd7_72b89b29","line":490,"in_reply_to":"ff346bd7_9773f1e7","updated":"2017-07-24 22:13:08.000000000","message":"oh my god no it\u0027s not","commit_id":"7fe1246cb5726ce7902148fa482c0496a48e82d8"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7557b06ae3d0fa7899325c89bf3c4f9db3754dae","unresolved":false,"context_lines":[{"line_number":446,"context_line":""},{"line_number":447,"context_line":"        \"\"\""},{"line_number":448,"context_line":"        if not self.node_cache:"},{"line_number":449,"context_line":"            self._refresh_cache()"},{"line_number":450,"context_line":"        # Since there could be many, many instances controlled by this host,"},{"line_number":451,"context_line":"        # spawn this asynchronously so as not to stall the startup of the"},{"line_number":452,"context_line":"        # compute service."}],"source_content_type":"text/x-python","patch_set":14,"id":"ff346bd7_d33db8c4","line":449,"updated":"2017-07-26 20:51:00.000000000","message":"This explodes:\n\nhttp://logs.openstack.org/49/484949/14/check/gate-tempest-dsvm-ironic-ipa-wholedisk-bios-agent_ipmitool-tinyipa-ubuntu-xenial-nv/69b18d7/logs/screen-n-cpu.txt.gz?level\u003dTRACE\n\nIs Ironic not up yet?","commit_id":"8e77c475e1eb48703314e1b98bc9cb491027064d"}]}
