)]}'
{"nova/conductor/tasks/cross_cell_migrate.py":[{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"f46674060d27a62108b344403bc2ffa675e22ec3","unresolved":false,"context_lines":[{"line_number":290,"context_line":"        migrations \u003d objects.MigrationList.get_by_filters("},{"line_number":291,"context_line":"            self.context, filters\u003d{\u0027instance_uuid\u0027: self.instance.uuid})"},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"        inst \u003d _clone_creatable_object(cctxt, self.instance)"},{"line_number":294,"context_line":"        inst.create()"},{"line_number":295,"context_line":""},{"line_number":296,"context_line":"        # Do the same dance for the other instance-related records."},{"line_number":297,"context_line":"        for bdm in bdms:"}],"source_content_type":"text/x-python","patch_set":2,"id":"bfdaf3ff_8b02ac08","line":294,"range":{"start_line":293,"start_character":8,"end_line":294,"end_character":21},"updated":"2019-01-16 02:05:41.000000000","message":"will this preserve the instance.created_at time from the original record? Huawei Public cloud seems care about this alot, they do not want user to know that the instance have changed databases, and, it might cause some problem for outside monitoring system.","commit_id":"e3f27d963b81ef163c4847599cc757fe7a447d62"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"fc96bd100ca713d4ccaf5566ce618cf2d0edf18a","unresolved":false,"context_lines":[{"line_number":296,"context_line":"        migrations \u003d objects.MigrationList.get_by_filters("},{"line_number":297,"context_line":"            self.context, filters\u003d{\u0027instance_uuid\u0027: self.instance.uuid})"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"        inst \u003d _clone_creatable_object(cctxt, self.instance)"},{"line_number":300,"context_line":"        inst.create()"},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"        # Do the same dance for the other instance-related records."},{"line_number":303,"context_line":"        for bdm in bdms:"}],"source_content_type":"text/x-python","patch_set":3,"id":"bfdaf3ff_671c5812","line":300,"range":{"start_line":299,"start_character":8,"end_line":300,"end_character":21},"updated":"2019-01-16 07:30:05.000000000","message":"will this preserve the instance.created_at time from the original record? Huawei Public cloud seems care about this alot, they do not want user to know that the instance have changed databases, and, it might cause some problem for outside monitoring system.","commit_id":"4cbb3d4444a720f7709556448e6f3ab7245ce19f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"11ca0b59913030c71e3c00a93dce339fff7cda4c","unresolved":false,"context_lines":[{"line_number":296,"context_line":"        migrations \u003d objects.MigrationList.get_by_filters("},{"line_number":297,"context_line":"            self.context, filters\u003d{\u0027instance_uuid\u0027: self.instance.uuid})"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"        inst \u003d _clone_creatable_object(cctxt, self.instance)"},{"line_number":300,"context_line":"        inst.create()"},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"        # Do the same dance for the other instance-related records."},{"line_number":303,"context_line":"        for bdm in bdms:"}],"source_content_type":"text/x-python","patch_set":3,"id":"bfdaf3ff_7a9929c2","line":300,"range":{"start_line":299,"start_character":8,"end_line":300,"end_character":21},"in_reply_to":"bfdaf3ff_671c5812","updated":"2019-01-17 17:14:11.000000000","message":"Hmm, I believe created_at is automatically assigned on a new record if not set:\n\nhttps://github.com/openstack/oslo.db/blob/4.43.0/oslo_db/sqlalchemy/models.py#L138\n\nBut that\u0027s the default. I believe updated_at could get updated on the insert (not sure though, also not sure it matters), but I *think* created_at shouldn\u0027t change if it\u0027s provided - I will add an assertion to my test case though.","commit_id":"4cbb3d4444a720f7709556448e6f3ab7245ce19f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5fe8324fc4f60e15ca405df9bbb88480eaa53262","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        if tags:"},{"line_number":111,"context_line":"            primitive_tags \u003d [tag.tag for tag in tags]"},{"line_number":112,"context_line":"            objects.TagList.create(self.tgt_ctx, inst.uuid, primitive_tags)"},{"line_number":113,"context_line":"        for pci_device in pci_devices:"},{"line_number":114,"context_line":"            pci_device \u003d self._clone_creatable_object(pci_device)"},{"line_number":115,"context_line":"            # FIXME(mriedem): PciDevice.compute_node_id is likely going to"},{"line_number":116,"context_line":"            # point at the wrong compute node (and might be missing) so this"},{"line_number":117,"context_line":"            # needs investigation. Will the DB API create the record if the"},{"line_number":118,"context_line":"            # compute_node_id is not found in the target DB? Worse, will we"},{"line_number":119,"context_line":"            # update a pci device record in the target cell DB by address and"},{"line_number":120,"context_line":"            # change its instance_uuid / status?"},{"line_number":121,"context_line":"            pci_device.save()"},{"line_number":122,"context_line":"        for action in actions:"},{"line_number":123,"context_line":"            new_action \u003d self._clone_creatable_object(action)"},{"line_number":124,"context_line":"            new_action.create()"}],"source_content_type":"text/x-python","patch_set":5,"id":"9fdfeff1_7dc97976","line":121,"range":{"start_line":113,"start_character":8,"end_line":121,"end_character":29},"updated":"2019-01-22 15:22:52.000000000","message":"I don\u0027t think we actually need to copy these over:\n\nhttp://lists.openstack.org/pipermail/openstack-discuss/2019-January/001959.html\n\nSince PciDevice is both an inventory record of a PCI device on a compute node in the source cell and optionally it\u0027s allocation for a given instance. We just need to make sure pci_requests are copied over to the target cell DB so that the RT.resize_claim will properly claim PciDevice(s) on the target compute node in the target cell.","commit_id":"d0c715524e3fb57e17b5660da11437de9334c166"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"14e2c60f819fdb52ed5343c7d51bbbaf182c285a","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        inst.hidden \u003d True"},{"line_number":132,"context_line":"        # db.instance_create cannot handle some fields which might be loaded on"},{"line_number":133,"context_line":"        # the instance object, so reset those here and explicitly create the"},{"line_number":134,"context_line":"        # ones we care about (like tags) below. Things like pci_devices and"},{"line_number":135,"context_line":"        # services will not make sense in the target DB so we omit those as"},{"line_number":136,"context_line":"        # well."},{"line_number":137,"context_line":"        # TODO(mriedem): Determine if we care about copying faults over to the"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_13c46390","line":134,"range":{"start_line":134,"start_character":29,"end_line":134,"end_character":40},"updated":"2019-01-29 21:24:00.000000000","message":"We could make db.instance_create handle tags:\n\nhttps://review.openstack.org/#/c/484170/4/nova/db/sqlalchemy/api.py@1811","commit_id":"529aa7f21aa3f8c0887c661fbc96fb005a6123b4"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"8ecd82d2e9c54b3f0151b014a04c43e1e38dac7b","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        inst.hidden \u003d True"},{"line_number":132,"context_line":"        # db.instance_create cannot handle some fields which might be loaded on"},{"line_number":133,"context_line":"        # the instance object, so reset those here and explicitly create the"},{"line_number":134,"context_line":"        # ones we care about (like tags) below. Things like pci_devices and"},{"line_number":135,"context_line":"        # services will not make sense in the target DB so we omit those as"},{"line_number":136,"context_line":"        # well."},{"line_number":137,"context_line":"        # TODO(mriedem): Determine if we care about copying faults over to the"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_703a80cc","line":134,"range":{"start_line":134,"start_character":29,"end_line":134,"end_character":40},"in_reply_to":"9fdfeff1_13c46390","updated":"2019-01-29 23:11:16.000000000","message":"I added a FIXME in the test since we can deal with that later.","commit_id":"529aa7f21aa3f8c0887c661fbc96fb005a6123b4"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"e28ae5464654d62e730ab43cfe882b619b443a77","unresolved":false,"context_lines":[{"line_number":81,"context_line":"            # would be wrong for a live-migration or evacuation."},{"line_number":82,"context_line":"            migration.migration_type \u003d ("},{"line_number":83,"context_line":"                migration_obj.determine_migration_type(migration))"},{"line_number":84,"context_line":"            # If this is the active migration for this operation, create the"},{"line_number":85,"context_line":"            # Migration record in the target cell with cross_cell_move\u003dTrue."},{"line_number":86,"context_line":"            active_migration \u003d self.migration.uuid \u003d\u003d migration.uuid"},{"line_number":87,"context_line":"            if active_migration:"},{"line_number":88,"context_line":"                migration.cross_cell_move \u003d True"},{"line_number":89,"context_line":"            migration.create()"},{"line_number":90,"context_line":"            if active_migration:"},{"line_number":91,"context_line":"                # Save this off so subsequent tasks don\u0027t need to look it up."}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_f4af00e0","line":88,"range":{"start_line":84,"start_character":12,"end_line":88,"end_character":48},"updated":"2019-02-18 03:16:27.000000000","message":"won\u0027t clone_create_object handle this? I mean the active_migration in the source cell should already have cross_cell_move\u003dTrue set?","commit_id":"896abc33bec9ce37716314e7dd063c8574b2c9e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7eb05f1f2b4b79bf5e3bf330ca6650ce1bbb53e7","unresolved":false,"context_lines":[{"line_number":81,"context_line":"            # would be wrong for a live-migration or evacuation."},{"line_number":82,"context_line":"            migration.migration_type \u003d ("},{"line_number":83,"context_line":"                migration_obj.determine_migration_type(migration))"},{"line_number":84,"context_line":"            # If this is the active migration for this operation, create the"},{"line_number":85,"context_line":"            # Migration record in the target cell with cross_cell_move\u003dTrue."},{"line_number":86,"context_line":"            active_migration \u003d self.migration.uuid \u003d\u003d migration.uuid"},{"line_number":87,"context_line":"            if active_migration:"},{"line_number":88,"context_line":"                migration.cross_cell_move \u003d True"},{"line_number":89,"context_line":"            migration.create()"},{"line_number":90,"context_line":"            if active_migration:"},{"line_number":91,"context_line":"                # Save this off so subsequent tasks don\u0027t need to look it up."}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_235462fe","line":88,"range":{"start_line":84,"start_character":12,"end_line":88,"end_character":48},"in_reply_to":"9fdfeff1_126acaec","updated":"2019-02-18 17:29:00.000000000","message":"Done","commit_id":"896abc33bec9ce37716314e7dd063c8574b2c9e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"0f9d4e339bfd66b2125b4ed69e32eec6a0428f39","unresolved":false,"context_lines":[{"line_number":81,"context_line":"            # would be wrong for a live-migration or evacuation."},{"line_number":82,"context_line":"            migration.migration_type \u003d ("},{"line_number":83,"context_line":"                migration_obj.determine_migration_type(migration))"},{"line_number":84,"context_line":"            # If this is the active migration for this operation, create the"},{"line_number":85,"context_line":"            # Migration record in the target cell with cross_cell_move\u003dTrue."},{"line_number":86,"context_line":"            active_migration \u003d self.migration.uuid \u003d\u003d migration.uuid"},{"line_number":87,"context_line":"            if active_migration:"},{"line_number":88,"context_line":"                migration.cross_cell_move \u003d True"},{"line_number":89,"context_line":"            migration.create()"},{"line_number":90,"context_line":"            if active_migration:"},{"line_number":91,"context_line":"                # Save this off so subsequent tasks don\u0027t need to look it up."}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_126acaec","line":88,"range":{"start_line":84,"start_character":12,"end_line":88,"end_character":48},"in_reply_to":"9fdfeff1_f4af00e0","updated":"2019-02-18 16:05:45.000000000","message":"We don\u0027t, that\u0027s why I have the TODO here:\n\nhttps://review.openstack.org/#/c/627890/18/nova/conductor/tasks/cross_cell_migrate.py@523","commit_id":"896abc33bec9ce37716314e7dd063c8574b2c9e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1c09f51bfd24dd2ffc00b68a0b4321bc456eb57d","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        target_cell_migration \u003d None"},{"line_number":79,"context_line":"        for migration in migrations:"},{"line_number":80,"context_line":"            migration \u003d clone_creatable_object(self.tgt_ctx, migration)"},{"line_number":81,"context_line":"            # FIXME(mriedem): Why isn\u0027t the migration_type field already set?"},{"line_number":82,"context_line":"            # determine_migration_type only returns resize or migration, which"},{"line_number":83,"context_line":"            # would be wrong for a live-migration or evacuation."},{"line_number":84,"context_line":"            migration.migration_type \u003d ("},{"line_number":85,"context_line":"                migration_obj.determine_migration_type(migration))"},{"line_number":86,"context_line":"            migration.create()"}],"source_content_type":"text/x-python","patch_set":15,"id":"9fdfeff1_da541e01","line":83,"range":{"start_line":81,"start_character":12,"end_line":83,"end_character":64},"updated":"2019-02-20 21:36:03.000000000","message":"Apparently this is no longer an issue.","commit_id":"0d69cacbc003b533bb91453972c40c34e4aae0a2"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a4a2ccf9fbf956723b2bb7792d2e0f8f2cadd2d0","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        target_cell_migration \u003d None"},{"line_number":79,"context_line":"        for migration in migrations:"},{"line_number":80,"context_line":"            migration \u003d clone_creatable_object(self.tgt_ctx, migration)"},{"line_number":81,"context_line":"            # FIXME(mriedem): Why isn\u0027t the migration_type field already set?"},{"line_number":82,"context_line":"            # determine_migration_type only returns resize or migration, which"},{"line_number":83,"context_line":"            # would be wrong for a live-migration or evacuation."},{"line_number":84,"context_line":"            migration.migration_type \u003d ("},{"line_number":85,"context_line":"                migration_obj.determine_migration_type(migration))"},{"line_number":86,"context_line":"            migration.create()"}],"source_content_type":"text/x-python","patch_set":15,"id":"9fdfeff1_d0eb36da","line":83,"range":{"start_line":81,"start_character":12,"end_line":83,"end_character":64},"in_reply_to":"9fdfeff1_da541e01","updated":"2019-02-26 18:36:26.000000000","message":"Done","commit_id":"0d69cacbc003b533bb91453972c40c34e4aae0a2"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"864ce2458a34492bd87e2357aefa23c229f6c722","unresolved":false,"context_lines":[{"line_number":151,"context_line":"        # Do the same dance for the other instance-related records."},{"line_number":152,"context_line":"        for bdm in bdms:"},{"line_number":153,"context_line":"            bdm \u003d clone_creatable_object(self.tgt_ctx, bdm)"},{"line_number":154,"context_line":"            # FIXME(mriedem): Why isn\u0027t the instance_uuid field already set?"},{"line_number":155,"context_line":"            bdm.instance_uuid \u003d inst.uuid"},{"line_number":156,"context_line":"            bdm.create()"},{"line_number":157,"context_line":"        for vif in vifs:"},{"line_number":158,"context_line":"            vif \u003d clone_creatable_object(self.tgt_ctx, vif)"}],"source_content_type":"text/x-python","patch_set":15,"id":"9fdfeff1_756d9c01","line":155,"range":{"start_line":154,"start_character":12,"end_line":155,"end_character":41},"updated":"2019-02-26 18:08:48.000000000","message":"Nor is this.","commit_id":"0d69cacbc003b533bb91453972c40c34e4aae0a2"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a4a2ccf9fbf956723b2bb7792d2e0f8f2cadd2d0","unresolved":false,"context_lines":[{"line_number":151,"context_line":"        # Do the same dance for the other instance-related records."},{"line_number":152,"context_line":"        for bdm in bdms:"},{"line_number":153,"context_line":"            bdm \u003d clone_creatable_object(self.tgt_ctx, bdm)"},{"line_number":154,"context_line":"            # FIXME(mriedem): Why isn\u0027t the instance_uuid field already set?"},{"line_number":155,"context_line":"            bdm.instance_uuid \u003d inst.uuid"},{"line_number":156,"context_line":"            bdm.create()"},{"line_number":157,"context_line":"        for vif in vifs:"},{"line_number":158,"context_line":"            vif \u003d clone_creatable_object(self.tgt_ctx, vif)"}],"source_content_type":"text/x-python","patch_set":15,"id":"9fdfeff1_f0e8badf","line":155,"range":{"start_line":154,"start_character":12,"end_line":155,"end_character":41},"in_reply_to":"9fdfeff1_756d9c01","updated":"2019-02-26 18:36:26.000000000","message":"Done","commit_id":"0d69cacbc003b533bb91453972c40c34e4aae0a2"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e8106a948857783af6da239f96db5f1e4bcfc0f2","unresolved":false,"context_lines":[{"line_number":138,"context_line":"        # different cells, listing servers out of the API will filter out the"},{"line_number":139,"context_line":"        # hidden one."},{"line_number":140,"context_line":"        inst.hidden \u003d True"},{"line_number":141,"context_line":"        inst.create()"},{"line_number":142,"context_line":"        self._target_cell_instance \u003d inst  # keep track of this for rollbacks"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        # Do the same dance for the other instance-related records."}],"source_content_type":"text/x-python","patch_set":20,"id":"5fc1f717_0e110754","line":141,"updated":"2019-04-03 01:51:37.000000000","message":"This is failing in devstack testing when we resize, revert, then resize again because while the instance is deleted it\u0027s only soft-deleted, so the uuid unique constraint is still around and causes a failure on the 2nd resize attempt.","commit_id":"f5a08b57a410bf954415622f7bcda0b3b119e502"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2d320556f35b63f86439719cb263f4f149640155","unresolved":false,"context_lines":[{"line_number":138,"context_line":"        # different cells, listing servers out of the API will filter out the"},{"line_number":139,"context_line":"        # hidden one."},{"line_number":140,"context_line":"        inst.hidden \u003d True"},{"line_number":141,"context_line":"        inst.create()"},{"line_number":142,"context_line":"        self._target_cell_instance \u003d inst  # keep track of this for rollbacks"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        # Do the same dance for the other instance-related records."}],"source_content_type":"text/x-python","patch_set":20,"id":"5fc1f717_ce61bfd5","line":141,"in_reply_to":"5fc1f717_0e110754","updated":"2019-04-03 02:01:16.000000000","message":"Related https://review.openstack.org/#/c/570202/","commit_id":"f5a08b57a410bf954415622f7bcda0b3b119e502"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e44358a7409aa7ae44394f941bce547972de9d3b","unresolved":false,"context_lines":[{"line_number":174,"context_line":"            LOG.debug(\u0027Destroying instance from target cell: %s\u0027,"},{"line_number":175,"context_line":"                      self.tgt_ctx.cell_uuid,"},{"line_number":176,"context_line":"                      instance\u003dself._target_cell_instance)"},{"line_number":177,"context_line":"            self._target_cell_instance.destroy()"}],"source_content_type":"text/x-python","patch_set":20,"id":"5fc1f717_a2b8f610","line":177,"updated":"2019-04-03 19:08:44.000000000","message":"Added a TODO for hard destroy here.","commit_id":"f5a08b57a410bf954415622f7bcda0b3b119e502"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c1b3dc0ddfe5f0967d9d97711ce54597ebe64ae0","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                target_cell_migration \u003d migration"},{"line_number":84,"context_line":"        return target_cell_migration"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _execute(self):"},{"line_number":87,"context_line":"        \"\"\"Creates the instance and its related records in the target cell"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        Instance.pci_devices are not copied over since those records are"}],"source_content_type":"text/x-python","patch_set":27,"id":"ffb9cba7_5a50f65d","line":86,"updated":"2019-04-26 02:00:01.000000000","message":"We can do all of the creates in here with a single transaction following this: https://review.opendev.org/#/c/586742/","commit_id":"b46bea494e9bfa2491e29307c9a2ff28355d9f2e"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3ad037f4aa77be786e8fc1202b60e55a1510526a","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                target_cell_migration \u003d migration"},{"line_number":84,"context_line":"        return target_cell_migration"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _execute(self):"},{"line_number":87,"context_line":"        \"\"\"Creates the instance and its related records in the target cell"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        Instance.pci_devices are not copied over since those records are"}],"source_content_type":"text/x-python","patch_set":27,"id":"dfbec78f_5bb47935","line":86,"in_reply_to":"ffb9cba7_5a50f65d","updated":"2019-05-09 20:25:07.000000000","message":"Maybe I\u0027ll just make this a TODO for now since I\u0027m having some issues getting it to work and it\u0027s low priority it seems since once the instance record is created in the target cell db the rollback will clean everything else up. A single transaction would be more fail-safe but probably not urgent.","commit_id":"b46bea494e9bfa2491e29307c9a2ff28355d9f2e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"0f441cd59f904e0d511e2e049a551191f38578e5","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    This is necessary before the object is created in a new cell."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    :param ctxt: cell-targeted nova auth request context to set on the clone"},{"line_number":28,"context_line":"    :param obj: the object to re-target"},{"line_number":29,"context_line":"    :param delete_fields: list of fields to delete from the new object;"},{"line_number":30,"context_line":"        note that the ``id`` field is always deleted"},{"line_number":31,"context_line":"    :returns: Cloned version of ``obj`` with all set fields marked as"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_3823f507","line":28,"range":{"start_line":28,"start_character":16,"end_line":28,"end_character":26},"updated":"2019-06-05 12:09:35.000000000","message":"I guess it needs to be an oslo versioned object so obj_clone exists when called at L39","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f5b1a9ccbb13a7b51882d659f6a069ecbdf625eb","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    This is necessary before the object is created in a new cell."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    :param ctxt: cell-targeted nova auth request context to set on the clone"},{"line_number":28,"context_line":"    :param obj: the object to re-target"},{"line_number":29,"context_line":"    :param delete_fields: list of fields to delete from the new object;"},{"line_number":30,"context_line":"        note that the ``id`` field is always deleted"},{"line_number":31,"context_line":"    :returns: Cloned version of ``obj`` with all set fields marked as"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_de9caf0f","line":28,"range":{"start_line":28,"start_character":16,"end_line":28,"end_character":26},"in_reply_to":"9fb8cfa7_3823f507","updated":"2019-06-10 19:38:10.000000000","message":"Correct.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"0f441cd59f904e0d511e2e049a551191f38578e5","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            if field in delete_fields:"},{"line_number":44,"context_line":"                delattr(new_obj, field)"},{"line_number":45,"context_line":"            else:"},{"line_number":46,"context_line":"                setattr(new_obj, field, getattr(obj, field))"},{"line_number":47,"context_line":"    return new_obj"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_78116dac","line":46,"updated":"2019-06-05 12:09:35.000000000","message":"obj_clone() [1] already setting the fields isn\u0027t it?\n\n[1]https://github.com/openstack/oslo.versionedobjects/blob/d46aea7e3c0411956f0b7afdcf08a7ae4500cdd9/oslo_versionedobjects/base.py#L417","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f5b1a9ccbb13a7b51882d659f6a069ecbdf625eb","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            if field in delete_fields:"},{"line_number":44,"context_line":"                delattr(new_obj, field)"},{"line_number":45,"context_line":"            else:"},{"line_number":46,"context_line":"                setattr(new_obj, field, getattr(obj, field))"},{"line_number":47,"context_line":"    return new_obj"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_7e7b43bd","line":46,"in_reply_to":"9fb8cfa7_78116dac","updated":"2019-06-10 19:38:10.000000000","message":"You\u0027re right. It will only do it for loaded fields:\n\nhttps://github.com/openstack/oslo.versionedobjects/blob/d46aea7e3c0411956f0b7afdcf08a7ae4500cdd9/oslo_versionedobjects/base.py#L434\n\nBut so does my method (L42). I can\u0027t remember if I needed this for some specific reason, so I\u0027ll remove it and see if anything breaks.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7d5c969e21b5b882088f8aa1f36f1f14bb4f5fd9","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            if field in delete_fields:"},{"line_number":44,"context_line":"                delattr(new_obj, field)"},{"line_number":45,"context_line":"            else:"},{"line_number":46,"context_line":"                setattr(new_obj, field, getattr(obj, field))"},{"line_number":47,"context_line":"    return new_obj"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_f23d272b","line":46,"in_reply_to":"9fb8cfa7_7e7b43bd","updated":"2019-06-10 20:16:13.000000000","message":"OK I think I see why - obj_clone copies the set of _changed_fields during the clone, but we need to dirty all of the fields since the cloned object is going to be used to create new records and most (if not all) of our object code checks the changed fields when passing values to the DB to insert, e.g.:\n\nhttps://github.com/openstack/nova/blob/1316c1c2850d2f966f335b628f7f5fe88cef611c/nova/objects/block_device.py#L205\n\nI commented out the setattr and tests fail with something like this:\n\nnova.tests.unit.conductor.tasks.test_cross_cell_migrate.TargetDBSetupTaskTestCase.test_execute_and_rollback\n-----------------------------------------------------------------------------------------------------------\n\nCaptured traceback:\n~~~~~~~~~~~~~~~~~~~\n    b\u0027Traceback (most recent call last):\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/tests/unit/conductor/tasks/test_cross_cell_migrate.py\", line 227, in test_execute_and_rollback\u0027\n    b\u0027    target_cell_instance \u003d task.execute()[0]\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/conductor/tasks/base.py\", line 27, in wrap\u0027\n    b\u0027    self.rollback()\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/oslo_utils/excutils.py\", line 220, in __exit__\u0027\n    b\u0027    self.force_reraise()\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/oslo_utils/excutils.py\", line 196, in force_reraise\u0027\n    b\u0027    six.reraise(self.type_, self.value, self.tb)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/six.py\", line 693, in reraise\u0027\n    b\u0027    raise value\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/conductor/tasks/base.py\", line 24, in wrap\u0027\n    b\u0027    return original(self)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/conductor/tasks/base.py\", line 42, in execute\u0027\n    b\u0027    return self._execute()\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/conductor/tasks/cross_cell_migrate.py\", line 151, in _execute\u0027\n    b\u0027    bdm.create()\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/oslo_versionedobjects/base.py\", line 226, in wrapper\u0027\n    b\u0027    return fn(self, *args, **kwargs)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/objects/block_device.py\", line 221, in create\u0027\n    b\u0027    self._create(self._context)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/objects/block_device.py\", line 217, in _create\u0027\n    b\u0027    self._from_db_object(context, self, db_bdm)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/nova/objects/block_device.py\", line 177, in _from_db_object\u0027\n    b\u0027    block_device_obj[key] \u003d db_block_device[key]\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/oslo_versionedobjects/base.py\", line 777, in __setitem__\u0027\n    b\u0027    setattr(self, name, value)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/oslo_versionedobjects/base.py\", line 72, in setter\u0027\n    b\u0027    field_value \u003d field.coerce(self, name, value)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/oslo_versionedobjects/fields.py\", line 207, in coerce\u0027\n    b\u0027    return self._null(obj, attr)\u0027\n    b\u0027  File \"/home/osboxes/git/nova/.tox/py36/lib/python3.6/site-packages/oslo_versionedobjects/fields.py\", line 185, in _null\u0027\n    b\u0027    raise ValueError(_(\"Field `%s\\\u0027 cannot be None\") % attr)\u0027\n    b\"ValueError: Field `instance_uuid\u0027 cannot be None\"\n    b\u0027\u0027\n\nEven though the method docstring mentions we dirty the fields maybe that was lost here, so I can add another inline comment on the code to make it extra clear.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4abad8da4df204e7724097dfc854c106f680b704","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            if field in delete_fields:"},{"line_number":44,"context_line":"                delattr(new_obj, field)"},{"line_number":45,"context_line":"            else:"},{"line_number":46,"context_line":"                setattr(new_obj, field, getattr(obj, field))"},{"line_number":47,"context_line":"    return new_obj"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_c029f236","line":46,"in_reply_to":"9fb8cfa7_f23d272b","updated":"2019-06-13 13:09:21.000000000","message":"Thanks for the explanation.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"0f441cd59f904e0d511e2e049a551191f38578e5","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        :param target_cell_context: target-cell targeted auth RequestContext"},{"line_number":63,"context_line":"        \"\"\""},{"line_number":64,"context_line":"        super(TargetDBSetupTask, self).__init__(context, instance)"},{"line_number":65,"context_line":"        self.tgt_ctx \u003d target_cell_context"},{"line_number":66,"context_line":"        self.migration \u003d migration"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        self._target_cell_instance \u003d None"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_388455b1","line":65,"range":{"start_line":65,"start_character":13,"end_line":65,"end_character":16},"updated":"2019-06-05 12:09:35.000000000","message":"nit: I don\u0027t think this is a common abbrev in our code. Can we write out \u0027target_ctx\u0027 ?","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f5b1a9ccbb13a7b51882d659f6a069ecbdf625eb","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        :param target_cell_context: target-cell targeted auth RequestContext"},{"line_number":63,"context_line":"        \"\"\""},{"line_number":64,"context_line":"        super(TargetDBSetupTask, self).__init__(context, instance)"},{"line_number":65,"context_line":"        self.tgt_ctx \u003d target_cell_context"},{"line_number":66,"context_line":"        self.migration \u003d migration"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        self._target_cell_instance \u003d None"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_3e538b41","line":65,"range":{"start_line":65,"start_character":13,"end_line":65,"end_character":16},"in_reply_to":"9fb8cfa7_388455b1","updated":"2019-06-10 19:38:10.000000000","message":"Sure.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"0f441cd59f904e0d511e2e049a551191f38578e5","unresolved":false,"context_lines":[{"line_number":80,"context_line":"            migration.create()"},{"line_number":81,"context_line":"            if self.migration.uuid \u003d\u003d migration.uuid:"},{"line_number":82,"context_line":"                # Save this off so subsequent tasks don\u0027t need to look it up."},{"line_number":83,"context_line":"                target_cell_migration \u003d migration"},{"line_number":84,"context_line":"        return target_cell_migration"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _execute(self):"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_a3d33a38","line":83,"updated":"2019-06-05 12:09:35.000000000","message":"I was confused first so just to be sure: Will there be always a migration where the uuids match (the active migration)?","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f5b1a9ccbb13a7b51882d659f6a069ecbdf625eb","unresolved":false,"context_lines":[{"line_number":80,"context_line":"            migration.create()"},{"line_number":81,"context_line":"            if self.migration.uuid \u003d\u003d migration.uuid:"},{"line_number":82,"context_line":"                # Save this off so subsequent tasks don\u0027t need to look it up."},{"line_number":83,"context_line":"                target_cell_migration \u003d migration"},{"line_number":84,"context_line":"        return target_cell_migration"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _execute(self):"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_fe165355","line":83,"in_reply_to":"9fb8cfa7_a3d33a38","updated":"2019-06-10 19:38:10.000000000","message":"Yeah the migration record is created in the source cell DB when the migration starts, e.g.:\n\nhttps://github.com/openstack/nova/blob/1316c1c2850d2f966f335b628f7f5fe88cef611c/nova/conductor/tasks/migrate.py#L152\n\nSo here we\u0027re copying that and creating it in the target cell DB. Since the new migration record in the target cell DB will have a different id (or could), everything that needs to access the migration uniquely needs to do it via the migration uuid. That comes into play a bit later here:\n\nhttps://review.opendev.org/#/c/636224/29/nova/compute/api.py\n\nThere is also some related work done during the prep-at-dest work here:\n\nhttps://review.opendev.org/#/c/627890/41/nova/conductor/tasks/cross_cell_migrate.py@502","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"0f441cd59f904e0d511e2e049a551191f38578e5","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        return target_cell_migration"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _execute(self):"},{"line_number":87,"context_line":"        \"\"\"Creates the instance and its related records in the target cell"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        Instance.pci_devices are not copied over since those records are"},{"line_number":90,"context_line":"        tightly coupled to the compute_nodes records and are meant to track"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_c39e6eb7","line":87,"updated":"2019-06-05 12:09:35.000000000","message":"Do we have any insurance that the instance data does not change in the source cell while we are doing the copy?\n\nAn extreme edge case example: While / After we are creating the copy somebody deletes the port in neutron bound to this instance. Neutron will send os-external-event that is routed to the source compute and the vif is detached from the running instance and deleted. So the data we read from L114 become stale.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4abad8da4df204e7724097dfc854c106f680b704","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        return target_cell_migration"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _execute(self):"},{"line_number":87,"context_line":"        \"\"\"Creates the instance and its related records in the target cell"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        Instance.pci_devices are not copied over since those records are"},{"line_number":90,"context_line":"        tightly coupled to the compute_nodes records and are meant to track"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_a0db9e4c","line":87,"in_reply_to":"9fb8cfa7_524f536a","updated":"2019-06-13 13:09:21.000000000","message":"OK, non-None task_state helps with the majority of the cases. And I agree that my example was extreme.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f5b1a9ccbb13a7b51882d659f6a069ecbdf625eb","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        return target_cell_migration"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def _execute(self):"},{"line_number":87,"context_line":"        \"\"\"Creates the instance and its related records in the target cell"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        Instance.pci_devices are not copied over since those records are"},{"line_number":90,"context_line":"        tightly coupled to the compute_nodes records and are meant to track"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_524f536a","line":87,"in_reply_to":"9fb8cfa7_c39e6eb7","updated":"2019-06-10 19:38:10.000000000","message":"\u003e Do we have any insurance that the instance data does not change in\n \u003e the source cell while we are doing the copy?\n\nA non-None task_state is about the most insurance we can get anywhere in nova that when we\u0027re doing something on an instance, another task can\u0027t be changing it concurrently.\n\n \u003e An extreme edge case example: While / After we are creating the\n \u003e copy somebody deletes the port in neutron bound to this instance.\n \u003e Neutron will send os-external-event that is routed to the source\n \u003e compute and the vif is detached from the running instance and\n \u003e deleted. So the data we read from L114 become stale.\n\nSure, like you say that\u0027s extreme, but could happen in a tight window. However, I\u0027d argue that\u0027s already a problem for *any* move operation we have where we\u0027ve pulled the network info cache data at t0, it changes on another thread at t1, and then we use the data from t0 at t2 and there is an issue.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d6f082e36e1705b2e5841f65162ff46ea809d91","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        \"changed\" so they will be persisted on a subsequent"},{"line_number":33,"context_line":"        ``obj.create()`` call."},{"line_number":34,"context_line":"    \"\"\""},{"line_number":35,"context_line":"    if delete_fields is None:"},{"line_number":36,"context_line":"        delete_fields \u003d []"},{"line_number":37,"context_line":"    if \u0027id\u0027 not in delete_fields:"},{"line_number":38,"context_line":"        delete_fields.append(\u0027id\u0027)"}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_a23ed9b6","line":35,"range":{"start_line":35,"start_character":3,"end_line":35,"end_character":29},"updated":"2019-08-09 16:40:12.000000000","message":"if not delete_fields:","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"04800f2efd7782b9e114ec64b95698946cf15341","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        \"changed\" so they will be persisted on a subsequent"},{"line_number":33,"context_line":"        ``obj.create()`` call."},{"line_number":34,"context_line":"    \"\"\""},{"line_number":35,"context_line":"    if delete_fields is None:"},{"line_number":36,"context_line":"        delete_fields \u003d []"},{"line_number":37,"context_line":"    if \u0027id\u0027 not in delete_fields:"},{"line_number":38,"context_line":"        delete_fields.append(\u0027id\u0027)"}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_4189f823","line":35,"range":{"start_line":35,"start_character":3,"end_line":35,"end_character":29},"in_reply_to":"7faddb67_a23ed9b6","updated":"2019-08-13 11:58:52.000000000","message":"Well, if delete_fields is [] that would be true and we\u0027d just set it to [] again.","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d6f082e36e1705b2e5841f65162ff46ea809d91","unresolved":false,"context_lines":[{"line_number":113,"context_line":"        # Similarly, expired console auth tokens will be automatically cleaned"},{"line_number":114,"context_line":"        # from the source cell."},{"line_number":115,"context_line":"        bdms \u003d self.instance.get_bdms()"},{"line_number":116,"context_line":"        vifs \u003d objects.VirtualInterfaceList.get_by_instance_uuid("},{"line_number":117,"context_line":"            self.context, self.instance.uuid)"},{"line_number":118,"context_line":"        tags \u003d self.instance.tags"},{"line_number":119,"context_line":"        # We copy instance actions to preserve the history of the instance"},{"line_number":120,"context_line":"        # in case the resize is confirmed."}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_0281ed4a","line":117,"range":{"start_line":116,"start_character":0,"end_line":117,"end_character":45},"updated":"2019-08-09 16:40:12.000000000","message":"sidenote: We should probably have a \u0027get_vifs\u0027 property on \u0027Instance\u0027","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"}],"nova/tests/unit/conductor/tasks/test_cross_cell_migrate.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"65f7741518bc2473d181f154af53480e613cabdc","unresolved":false,"context_lines":[{"line_number":107,"context_line":"        target_cell_instance \u003d task.execute()"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        # The instance in the target cell should be hidden."},{"line_number":110,"context_line":"        self.assertTrue(target_cell_instance.hidden,"},{"line_number":111,"context_line":"                        \u0027Target cell instance should be hidden\u0027)"},{"line_number":112,"context_line":"        # TODO(mriedem): Assert that the various records created in"},{"line_number":113,"context_line":"        # _create_instance_data are found in the target cell database."}],"source_content_type":"text/x-python","patch_set":4,"id":"bfdaf3ff_faeaf90c","line":110,"updated":"2019-01-17 17:28:55.000000000","message":"Assert that the target cell instance created_at is the same as the source cell instance. In fact, we can probably use an object comparison method and just ignore the id and hidden fields since everything else should be the same. nova.tests.unit.objects.test_objects.compare_obj could be used, but needs some tweaks.","commit_id":"05266b806e0f8e4a41eedf94e7522db5c201a1a4"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"595b20f112a7cbc8e747c2ccdeac88503834a846","unresolved":false,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        objects.TagList.create(self.source_context, inst.uuid, [\u0027test\u0027])"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        # TODO(mriedem): Test instance.pci_devices"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        objects.InstanceAction().action_start("},{"line_number":93,"context_line":"            self.source_context, inst.uuid, \u0027resize\u0027, want_result\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9fdfeff1_1d894d22","line":90,"updated":"2019-01-22 15:23:48.000000000","message":"Also need to test things like instance.numa_topology and trusted_certs - really everything in INSTANCE_OPTIONAL_ATTRS.","commit_id":"d0c715524e3fb57e17b5660da11437de9334c166"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"0f441cd59f904e0d511e2e049a551191f38578e5","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        inst \u003d fake_instance.fake_instance_obj("},{"line_number":90,"context_line":"            self.source_context, reset_changes\u003dFalse, **updates)"},{"line_number":91,"context_line":"        delattr(inst, \u0027id\u0027)  # cannot create an instance with an id set"},{"line_number":92,"context_line":"        # Now we have to dirty all of the fields because fake_instance_obj"},{"line_number":93,"context_line":"        # uses Instance._from_db_object to create the Instance object we have"},{"line_number":94,"context_line":"        # but _from_db_object calls obj_reset_changes() which resets all of"},{"line_number":95,"context_line":"        # the fields that were on the object, including the basic stuff like"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_e3f3729d","line":92,"updated":"2019-06-05 12:09:35.000000000","message":"you added reset_changes\u003dFalse so I assume fake_instance_obj keep the instance obj dirty.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7d5c969e21b5b882088f8aa1f36f1f14bb4f5fd9","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        inst \u003d fake_instance.fake_instance_obj("},{"line_number":90,"context_line":"            self.source_context, reset_changes\u003dFalse, **updates)"},{"line_number":91,"context_line":"        delattr(inst, \u0027id\u0027)  # cannot create an instance with an id set"},{"line_number":92,"context_line":"        # Now we have to dirty all of the fields because fake_instance_obj"},{"line_number":93,"context_line":"        # uses Instance._from_db_object to create the Instance object we have"},{"line_number":94,"context_line":"        # but _from_db_object calls obj_reset_changes() which resets all of"},{"line_number":95,"context_line":"        # the fields that were on the object, including the basic stuff like"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_f2d9a7f2","line":92,"in_reply_to":"9fb8cfa7_92b62b3e","updated":"2019-06-10 20:16:13.000000000","message":"Note I had to do something similar later here:\n\nhttps://review.opendev.org/#/c/635646/31/nova/tests/unit/conductor/tasks/test_cross_cell_migrate.py@908\n\nMaybe the reset_changes kwarg on fake_instance_obj should actually be something called make_creatable.\n\nAnyway, I removed the reset_changes change and the test passes either way so I\u0027ll undo the reset_changes kwarg on fake_instance_obj and leave a TODO to move this into fake_instance_obj with a make_creatable kwarg.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f5b1a9ccbb13a7b51882d659f6a069ecbdf625eb","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        inst \u003d fake_instance.fake_instance_obj("},{"line_number":90,"context_line":"            self.source_context, reset_changes\u003dFalse, **updates)"},{"line_number":91,"context_line":"        delattr(inst, \u0027id\u0027)  # cannot create an instance with an id set"},{"line_number":92,"context_line":"        # Now we have to dirty all of the fields because fake_instance_obj"},{"line_number":93,"context_line":"        # uses Instance._from_db_object to create the Instance object we have"},{"line_number":94,"context_line":"        # but _from_db_object calls obj_reset_changes() which resets all of"},{"line_number":95,"context_line":"        # the fields that were on the object, including the basic stuff like"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_92b62b3e","line":92,"in_reply_to":"9fb8cfa7_e3f3729d","updated":"2019-06-10 19:38:10.000000000","message":"Hmm, you\u0027re right. I remember having to do some gymnastics to make this all work and looking at it now the reset_changes change to fake_instance_obj is likely unnecessary because it happens too late for some things, e.g. instance.host (as mentioned in this comment). I needed the new instance record to have host set to correlate to the services record above. The reset_changes change to fake_instance_obj will just leave some object fields dirty like flavor, but this code below on L99 should dirty that anyway.\n\nI will try removing the reset_changes change and see if it makes any difference.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4abad8da4df204e7724097dfc854c106f680b704","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        inst \u003d fake_instance.fake_instance_obj("},{"line_number":90,"context_line":"            self.source_context, reset_changes\u003dFalse, **updates)"},{"line_number":91,"context_line":"        delattr(inst, \u0027id\u0027)  # cannot create an instance with an id set"},{"line_number":92,"context_line":"        # Now we have to dirty all of the fields because fake_instance_obj"},{"line_number":93,"context_line":"        # uses Instance._from_db_object to create the Instance object we have"},{"line_number":94,"context_line":"        # but _from_db_object calls obj_reset_changes() which resets all of"},{"line_number":95,"context_line":"        # the fields that were on the object, including the basic stuff like"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_20c80e72","line":92,"in_reply_to":"9fb8cfa7_f2d9a7f2","updated":"2019-06-13 13:09:21.000000000","message":"Cool.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f5b1a9ccbb13a7b51882d659f6a069ecbdf625eb","unresolved":false,"context_lines":[{"line_number":112,"context_line":"        inst.device_metadata \u003d ("},{"line_number":113,"context_line":"            test_instance_device_metadata.get_fake_obj_device_metadata("},{"line_number":114,"context_line":"                self.source_context))"},{"line_number":115,"context_line":"        # FIXME(mriedem): db.instance_create does not handle tags"},{"line_number":116,"context_line":"        inst.obj_reset_changes([\u0027tags\u0027])"},{"line_number":117,"context_line":"        inst.create()"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        bdm \u003d {"}],"source_content_type":"text/x-python","patch_set":36,"id":"9fb8cfa7_52867368","line":116,"range":{"start_line":115,"start_character":8,"end_line":116,"end_character":40},"updated":"2019-06-10 19:38:10.000000000","message":"This also adds to the confusion.","commit_id":"95b869bc409d2c92ad2972649610b6cb3624e263"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d6f082e36e1705b2e5841f65162ff46ea809d91","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        # but _from_db_object calls obj_reset_changes() which resets all of"},{"line_number":94,"context_line":"        # the fields that were on the object, including the basic stuff like"},{"line_number":95,"context_line":"        # the \u0027host\u0027 field, which means those fields don\u0027t get set in the DB."},{"line_number":96,"context_line":"        # TODO(mriedem): This should live in fake_instance_obj with a"},{"line_number":97,"context_line":"        # make_creatable kwarg."},{"line_number":98,"context_line":"        for field in inst.obj_fields:"},{"line_number":99,"context_line":"            if field in inst:"},{"line_number":100,"context_line":"                setattr(inst, field, getattr(inst, field))"}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_62a9c122","line":97,"range":{"start_line":96,"start_character":0,"end_line":97,"end_character":31},"updated":"2019-08-09 16:40:12.000000000","message":"++","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d6f082e36e1705b2e5841f65162ff46ea809d91","unresolved":false,"context_lines":[{"line_number":105,"context_line":"            objects.InstancePCIRequest("},{"line_number":106,"context_line":"                **test_instance_pci_requests.fake_pci_requests[0])])"},{"line_number":107,"context_line":"        inst.numa_topology \u003d objects.InstanceNUMATopology("},{"line_number":108,"context_line":"            cells\u003dtest_instance_numa_topology.fake_obj_numa_topology.cells)"},{"line_number":109,"context_line":"        inst.trusted_certs \u003d objects.TrustedCerts(ids\u003d[uuids.cert])"},{"line_number":110,"context_line":"        inst.vcpu_model \u003d test_vcpu_model.fake_vcpumodel"},{"line_number":111,"context_line":"        inst.keypairs \u003d objects.KeyPairList(objects\u003d["}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_c27195e0","line":108,"range":{"start_line":108,"start_character":68,"end_line":108,"end_character":74},"updated":"2019-08-09 16:40:12.000000000","message":"Should be be cloning this to make sure we don\u0027t mess with global state? Maybe it\u0027d be easier just define an absolute minimal object here?","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"04800f2efd7782b9e114ec64b95698946cf15341","unresolved":false,"context_lines":[{"line_number":105,"context_line":"            objects.InstancePCIRequest("},{"line_number":106,"context_line":"                **test_instance_pci_requests.fake_pci_requests[0])])"},{"line_number":107,"context_line":"        inst.numa_topology \u003d objects.InstanceNUMATopology("},{"line_number":108,"context_line":"            cells\u003dtest_instance_numa_topology.fake_obj_numa_topology.cells)"},{"line_number":109,"context_line":"        inst.trusted_certs \u003d objects.TrustedCerts(ids\u003d[uuids.cert])"},{"line_number":110,"context_line":"        inst.vcpu_model \u003d test_vcpu_model.fake_vcpumodel"},{"line_number":111,"context_line":"        inst.keypairs \u003d objects.KeyPairList(objects\u003d["}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_a171cc46","line":108,"range":{"start_line":108,"start_character":68,"end_line":108,"end_character":74},"in_reply_to":"7faddb67_c27195e0","updated":"2019-08-13 11:58:52.000000000","message":"I\u0027m pretty sure I just copied this from elsewhere. The test isn\u0027t modifying the fake numa topology object nor is it asserting anything specific about it, just that the version in the source db matches the version in the target db, minus fields that can change (id).","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d6f082e36e1705b2e5841f65162ff46ea809d91","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            self.source_context, inst.uuid, \u0027resize\u0027, want_result\u003dFalse)"},{"line_number":156,"context_line":"        objects.InstanceActionEvent().event_start("},{"line_number":157,"context_line":"            self.source_context, inst.uuid, \u0027migrate_server\u0027,"},{"line_number":158,"context_line":"            want_result\u003dFalse)"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"        # Create a fake migration for the cross-cell resize operation."},{"line_number":161,"context_line":"        migration \u003d objects.Migration("}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_222f49a8","line":158,"updated":"2019-08-09 16:40:12.000000000","message":"Good lord that was a lot of data...","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"834150cffbdfb9bea3d3ec8bf70c08616ff7f7b5","unresolved":false,"context_lines":[{"line_number":233,"context_line":"        # Assert that the various records created in _create_instance_data are"},{"line_number":234,"context_line":"        # found in the target cell database. We ignore \u0027hidden\u0027 because the"},{"line_number":235,"context_line":"        # values are explicitly different between source and target DB. The"},{"line_number":236,"context_line":"        # pci_devices/services/tags fields are not set on the target instance"},{"line_number":237,"context_line":"        # during TargetDBSetupTask.execute so we ignore those here and verify"},{"line_number":238,"context_line":"        # them below."},{"line_number":239,"context_line":"        ignored_keys \u003d [\u0027hidden\u0027, \u0027pci_devices\u0027, \u0027services\u0027, \u0027tags\u0027]"},{"line_number":240,"context_line":"        self._compare_objs(source_cell_instance, target_cell_instance,"}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_b991049d","line":237,"range":{"start_line":236,"start_character":10,"end_line":237,"end_character":42},"updated":"2019-08-13 14:23:03.000000000","message":"nit: tags are different they are set during the TargetDBSetupTask.execute() while pci_devices and services are really ignored.","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"0ae2b56b07161a79c9cd4e714f6252028bbecdee","unresolved":false,"context_lines":[{"line_number":233,"context_line":"        # Assert that the various records created in _create_instance_data are"},{"line_number":234,"context_line":"        # found in the target cell database. We ignore \u0027hidden\u0027 because the"},{"line_number":235,"context_line":"        # values are explicitly different between source and target DB. The"},{"line_number":236,"context_line":"        # pci_devices/services/tags fields are not set on the target instance"},{"line_number":237,"context_line":"        # during TargetDBSetupTask.execute so we ignore those here and verify"},{"line_number":238,"context_line":"        # them below."},{"line_number":239,"context_line":"        ignored_keys \u003d [\u0027hidden\u0027, \u0027pci_devices\u0027, \u0027services\u0027, \u0027tags\u0027]"},{"line_number":240,"context_line":"        self._compare_objs(source_cell_instance, target_cell_instance,"}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_b23a79c1","line":237,"range":{"start_line":236,"start_character":10,"end_line":237,"end_character":42},"in_reply_to":"7faddb67_9c3af6ca","updated":"2019-08-13 16:02:22.000000000","message":"Done: https://review.opendev.org/676228","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f71768091f5f97b4c448fc10d012fedeeb772d04","unresolved":false,"context_lines":[{"line_number":233,"context_line":"        # Assert that the various records created in _create_instance_data are"},{"line_number":234,"context_line":"        # found in the target cell database. We ignore \u0027hidden\u0027 because the"},{"line_number":235,"context_line":"        # values are explicitly different between source and target DB. The"},{"line_number":236,"context_line":"        # pci_devices/services/tags fields are not set on the target instance"},{"line_number":237,"context_line":"        # during TargetDBSetupTask.execute so we ignore those here and verify"},{"line_number":238,"context_line":"        # them below."},{"line_number":239,"context_line":"        ignored_keys \u003d [\u0027hidden\u0027, \u0027pci_devices\u0027, \u0027services\u0027, \u0027tags\u0027]"},{"line_number":240,"context_line":"        self._compare_objs(source_cell_instance, target_cell_instance,"}],"source_content_type":"text/x-python","patch_set":47,"id":"7faddb67_9c3af6ca","line":237,"range":{"start_line":236,"start_character":10,"end_line":237,"end_character":42},"in_reply_to":"7faddb67_b991049d","updated":"2019-08-13 14:48:05.000000000","message":"Ack, I can fix this comment in a follow up. At least tags are verified below.","commit_id":"dec1d56f258572da3d96091c611d350d5de3d513"}]}
