)]}'
{"glance/api/v2/images.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0b1ada2d96a7c7ef6ad7e10a94daf3cd837caa42","unresolved":true,"context_lines":[{"line_number":452,"context_line":"            # NOTE (abhishekk): If image is not present or user doesn\u0027t"},{"line_number":453,"context_line":"            # have access to the image then we need"},{"line_number":454,"context_line":"            # to return empty response to user"},{"line_number":455,"context_line":"            tasks \u003d []"},{"line_number":456,"context_line":"        else:"},{"line_number":457,"context_line":"            tasks \u003d self.db_api.tasks_get_by_image(req.context,"},{"line_number":458,"context_line":"                                                   image.image_id)"}],"source_content_type":"text/x-python","patch_set":2,"id":"16f89f1a_ae510a2f","line":455,"updated":"2021-02-12 15:55:19.000000000","message":"I believe the proper behavior here is to return 404 for this if they don\u0027t have access to the image that this is under. Also, you\u0027re doing this for a NotFound, which means I think you would get a 404 for /image/$image but a 200 for /image/$image/tasks, which would be wrong. I think in both cases here, a 404 is the right result.","commit_id":"463fa2e0af4cb7ebab3beae4fd71aa1550be8064"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"07a4f403e14995db1a900d098b88ef1171cd26ce","unresolved":false,"context_lines":[{"line_number":452,"context_line":"            # NOTE (abhishekk): If image is not present or user doesn\u0027t"},{"line_number":453,"context_line":"            # have access to the image then we need"},{"line_number":454,"context_line":"            # to return empty response to user"},{"line_number":455,"context_line":"            tasks \u003d []"},{"line_number":456,"context_line":"        else:"},{"line_number":457,"context_line":"            tasks \u003d self.db_api.tasks_get_by_image(req.context,"},{"line_number":458,"context_line":"                                                   image.image_id)"}],"source_content_type":"text/x-python","patch_set":2,"id":"fd1dc125_aea82e06","line":455,"in_reply_to":"16f89f1a_ae510a2f","updated":"2021-02-15 10:51:20.000000000","message":"Done","commit_id":"463fa2e0af4cb7ebab3beae4fd71aa1550be8064"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"70d802a58f6862138cb23d0f473a61d78335c8ad","unresolved":true,"context_lines":[{"line_number":447,"context_line":"            # NOTE (abhishekk): Just to check image is valid"},{"line_number":448,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":449,"context_line":"        except (exception.NotFound, exception.Forbidden) as e:"},{"line_number":450,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.msg)"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"        tasks \u003d self.db_api.tasks_get_by_image(req.context,"},{"line_number":453,"context_line":"                                               image.image_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"11d9e253_434ca0bf","line":450,"range":{"start_line":450,"start_character":53,"end_line":450,"end_character":58},"updated":"2021-02-15 15:15:15.000000000","message":"What is this going to look like? If it says anything like \"not authorized\" or \"access denied\" then this will leak information about the existence of the image. I\u0027m wondering if we actually would never get Forbidden after this:\n\nhttps://review.opendev.org/c/openstack/glance/+/775435\n\n...and without a bad policy, potentially never?","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"9f3d9b3af0b8a2f519463dad9f7ea1c6bcc23f10","unresolved":true,"context_lines":[{"line_number":447,"context_line":"            # NOTE (abhishekk): Just to check image is valid"},{"line_number":448,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":449,"context_line":"        except (exception.NotFound, exception.Forbidden) as e:"},{"line_number":450,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.msg)"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"        tasks \u003d self.db_api.tasks_get_by_image(req.context,"},{"line_number":453,"context_line":"                                               image.image_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"92ff7b58_5873d37e","line":450,"range":{"start_line":450,"start_character":53,"end_line":450,"end_character":58},"in_reply_to":"11d9e253_434ca0bf","updated":"2021-02-15 15:33:33.000000000","message":"will give custom message like Image \u003cimage_id\u003e not found","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2f3ec1fd1202f9624089cb71bdac574577f820cb","unresolved":true,"context_lines":[{"line_number":447,"context_line":"            # NOTE (abhishekk): Just to check image is valid"},{"line_number":448,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":449,"context_line":"        except (exception.NotFound, exception.Forbidden) as e:"},{"line_number":450,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.msg)"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"        tasks \u003d self.db_api.tasks_get_by_image(req.context,"},{"line_number":453,"context_line":"                                               image.image_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"c5929377_b2155ab0","line":450,"range":{"start_line":450,"start_character":53,"end_line":450,"end_character":58},"in_reply_to":"92ff7b58_5873d37e","updated":"2021-02-15 15:44:42.000000000","message":"What I meant is in the case of a Forbidden. Point being, I think we should not set the message to anything here and let the normal HTTPNotFound message be sent to the user so that we don\u0027t (now or in the future) expose anything other than ignorance about an image we couldn\u0027t load.","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"104659efc5e519b240e25efec064fada7d208173","unresolved":false,"context_lines":[{"line_number":447,"context_line":"            # NOTE (abhishekk): Just to check image is valid"},{"line_number":448,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":449,"context_line":"        except (exception.NotFound, exception.Forbidden) as e:"},{"line_number":450,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.msg)"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"        tasks \u003d self.db_api.tasks_get_by_image(req.context,"},{"line_number":453,"context_line":"                                               image.image_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"a997f067_3a4e2385","line":450,"range":{"start_line":450,"start_character":53,"end_line":450,"end_character":58},"in_reply_to":"c5929377_b2155ab0","updated":"2021-02-16 07:04:20.000000000","message":"Done","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"149ce3a476b4579987dce715e24b8342b6cf26e0","unresolved":true,"context_lines":[{"line_number":445,"context_line":"        image_repo \u003d self.gateway.get_repo(req.context)"},{"line_number":446,"context_line":"        try:"},{"line_number":447,"context_line":"            # NOTE (abhishekk): Just to check image is valid"},{"line_number":448,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":449,"context_line":"        except (exception.NotFound, exception.Forbidden):"},{"line_number":450,"context_line":"            raise webob.exc.HTTPNotFound()"},{"line_number":451,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"17ee13d4_54e66911","line":448,"updated":"2021-02-25 21:34:09.000000000","message":"This should be pretty straight forward to test from an RBAC perspective since we\u0027re reusing the get_image policy.\n\nOnce this lands we can add another test to the existing glance_tempest_plugin tests to make sure project-members and project-readers can view tasks for images they have access to. The policy check for get_image should short-circuit this API entirely and disallow users from snooping tasks related to another project\u0027s private image, right?\n\nShould regular end users be able to view tasks for public, community, and shared images?\n\nI might wait to add that test until this series lands though.","commit_id":"281fadc15c5e257e72514957701a5571a83d8c38"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"cf3757017561eb165ef1d9e0e1b27ae578a834e9","unresolved":true,"context_lines":[{"line_number":445,"context_line":"        image_repo \u003d self.gateway.get_repo(req.context)"},{"line_number":446,"context_line":"        try:"},{"line_number":447,"context_line":"            # NOTE (abhishekk): Just to check image is valid"},{"line_number":448,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":449,"context_line":"        except (exception.NotFound, exception.Forbidden):"},{"line_number":450,"context_line":"            raise webob.exc.HTTPNotFound()"},{"line_number":451,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"7fa2fc0b_27cea545","line":448,"in_reply_to":"17ee13d4_54e66911","updated":"2021-02-25 21:43:26.000000000","message":"\u003e Once this lands we can add another test to the existing glance_tempest_plugin tests to make sure project-members and project-readers can view tasks for images they have access to. The policy check for get_image should short-circuit this API entirely and disallow users from snooping tasks related to another project\u0027s private image, right?\n\nYup, that\u0027s pretty much the only reason to do the get here, and why we\u0027re raising NotFound for Forbidden on L450.\n\n\u003e Should regular end users be able to view tasks for public, community, and shared images?\n\nYeah, they won\u0027t be interesting to a normal user, but there\u0027s no harm in them seeing them. In general once an image has been around for a couple days the tasks expire anyway.","commit_id":"281fadc15c5e257e72514957701a5571a83d8c38"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"72b15a97e42e4be3dcf26add63e69d51e5dcc064","unresolved":false,"context_lines":[{"line_number":445,"context_line":"        image_repo \u003d self.gateway.get_repo(req.context)"},{"line_number":446,"context_line":"        try:"},{"line_number":447,"context_line":"            # NOTE (abhishekk): Just to check image is valid"},{"line_number":448,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":449,"context_line":"        except (exception.NotFound, exception.Forbidden):"},{"line_number":450,"context_line":"            raise webob.exc.HTTPNotFound()"},{"line_number":451,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"47c74ac4_88cda8be","line":448,"in_reply_to":"7fa2fc0b_27cea545","updated":"2021-02-26 02:49:31.000000000","message":"Ack","commit_id":"281fadc15c5e257e72514957701a5571a83d8c38"}],"glance/db/sqlalchemy/api.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0b1ada2d96a7c7ef6ad7e10a94daf3cd837caa42","unresolved":true,"context_lines":[{"line_number":1671,"context_line":"    ).filter_by(image_id\u003dimage_id)"},{"line_number":1672,"context_line":""},{"line_number":1673,"context_line":"    expires_at \u003d models.Task.expires_at"},{"line_number":1674,"context_line":"    query \u003d query.filter(expires_at \u003e\u003d timeutils.utcnow())"},{"line_number":1675,"context_line":""},{"line_number":1676,"context_line":"    if not context.is_admin and context.owner is not None:"},{"line_number":1677,"context_line":"        query \u003d query.filter(models.Task.owner \u003d\u003d context.owner)"}],"source_content_type":"text/x-python","patch_set":2,"id":"f045f81c_8d08d5db","line":1674,"updated":"2021-02-12 15:55:19.000000000","message":"I think there was some question about how this gets set or incremented or something, so most of the below are notes for myself on how this works, in case anyone else is fuzzy on it. Looks like we only set this when the task fails or succeeds:\n\nhttp://github.com/openstack/glance/blob/2c893fbd80d0241fad2515221b61266ced12f92d/glance/domain/__init__.py#L437-L437\n\nfurther supported by:\n\nhttp://github.com/openstack/glance/blob/2c893fbd80d0241fad2515221b61266ced12f92d/glance/domain/__init__.py#L472-L474\n\nand that TTL comes from now+CONF at the time of task object instantiation:\n\nhttp://github.com/openstack/glance/blob/2c893fbd80d0241fad2515221b61266ced12f92d/glance/domain/__init__.py#L373-L376\n\nAll of that seems fine, except that presumably we could have some tasks that get created and then never actually change state, such as  would be the case if we start an import and then power off the worker node.\n\nLooks like the task scrub would also never clean up these things because they would have no expires_at:\n\nhttp://github.com/openstack/glance/blob/2c893fbd80d0241fad2515221b61266ced12f92d/glance/db/sqlalchemy/api.py#L1672-L1684\n\nNow, that\u0027s an existing problem that we have today, so nothing new. However, exposing this to users means that more people might notice and/or be confused by it. It seems clear, however, that we should at *least* be calling _task_soft_delete() in this method to make sure that legit complete/failed tasks *do* get scrubbed, or just use task_get_all() internally here with our own set of crafted filters.\n\nHowever, I also wonder if it might be good to also add a filter of:\n\n query.filter(updated_at \u003c\u003d (timeutils.utcnow() + \n                             CONF.task_time_to_live))\n\nWe could also double the CONF value just to make sure there\u0027s plenty of time for it to continue being acted upon, but so that we will eventually stop showing those tasks to the user.","commit_id":"463fa2e0af4cb7ebab3beae4fd71aa1550be8064"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"07a4f403e14995db1a900d098b88ef1171cd26ce","unresolved":true,"context_lines":[{"line_number":1671,"context_line":"    ).filter_by(image_id\u003dimage_id)"},{"line_number":1672,"context_line":""},{"line_number":1673,"context_line":"    expires_at \u003d models.Task.expires_at"},{"line_number":1674,"context_line":"    query \u003d query.filter(expires_at \u003e\u003d timeutils.utcnow())"},{"line_number":1675,"context_line":""},{"line_number":1676,"context_line":"    if not context.is_admin and context.owner is not None:"},{"line_number":1677,"context_line":"        query \u003d query.filter(models.Task.owner \u003d\u003d context.owner)"}],"source_content_type":"text/x-python","patch_set":2,"id":"193d396f_aea2386c","line":1674,"in_reply_to":"f045f81c_8d08d5db","updated":"2021-02-15 10:51:20.000000000","message":"Using _task_soft_delete instead of calling task_get_all and I also liked the suggestion of using additional filter.","commit_id":"463fa2e0af4cb7ebab3beae4fd71aa1550be8064"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"70d802a58f6862138cb23d0f473a61d78335c8ad","unresolved":true,"context_lines":[{"line_number":1677,"context_line":"    updated_at \u003d models.Task.updated_at"},{"line_number":1678,"context_line":"    query.filter("},{"line_number":1679,"context_line":"        updated_at \u003c\u003d (timeutils.utcnow() +"},{"line_number":1680,"context_line":"                       datetime.timedelta(hours\u003dCONF.task.task_time_to_live)))"},{"line_number":1681,"context_line":""},{"line_number":1682,"context_line":"    if not context.is_admin and context.owner is not None:"},{"line_number":1683,"context_line":"        query \u003d query.filter(models.Task.owner \u003d\u003d context.owner)"}],"source_content_type":"text/x-python","patch_set":3,"id":"678aa546_08cadac4","line":1680,"updated":"2021-02-15 15:15:15.000000000","message":"Yeah, I think this makes sense. As mentioned before, I can see doubling the time period for this belt-and-suspenders check, but I expect the default is so long that it would basically never matter.","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"883995dcfb337ceb0a7646dda2d33eb58b39c18d","unresolved":true,"context_lines":[{"line_number":1675,"context_line":"    expires_at \u003d models.Task.expires_at"},{"line_number":1676,"context_line":"    query \u003d query.filter(expires_at \u003e\u003d timeutils.utcnow())"},{"line_number":1677,"context_line":"    updated_at \u003d models.Task.updated_at"},{"line_number":1678,"context_line":"    query.filter("},{"line_number":1679,"context_line":"        updated_at \u003c\u003d (timeutils.utcnow() +"},{"line_number":1680,"context_line":"                       datetime.timedelta(hours\u003dCONF.task.task_time_to_live)))"},{"line_number":1681,"context_line":""},{"line_number":1682,"context_line":"    if not context.is_admin and context.owner is not None:"},{"line_number":1683,"context_line":"        query \u003d query.filter(models.Task.owner \u003d\u003d context.owner)"}],"source_content_type":"text/x-python","patch_set":4,"id":"4f3c1183_a529602d","line":1680,"range":{"start_line":1678,"start_character":0,"end_line":1680,"end_character":78},"updated":"2021-02-16 12:44:21.000000000","message":"I think this is fine.  At 1669, expired tasks in a final state are deleted, and here we make sure that old tasks that were in suspension don\u0027t clog up the display and confuse the user, but they\u0027ll still be available to the admin for troubleshooting purposes.","commit_id":"9b1ba2b2d6bd6a1cf7ecd88224587ccb33ac3e7a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"881c872733b8d0d890a45718a2908b1d9f984cbb","unresolved":true,"context_lines":[{"line_number":1662,"context_line":""},{"line_number":1663,"context_line":""},{"line_number":1664,"context_line":"def tasks_get_by_image(context, image_id, session\u003dNone,"},{"line_number":1665,"context_line":"                       force_show_deleted\u003dFalse):"},{"line_number":1666,"context_line":"    \"\"\"Fetch all tasks associated with image_id\"\"\""},{"line_number":1667,"context_line":"    tasks \u003d []"},{"line_number":1668,"context_line":"    session \u003d session or get_session()"}],"source_content_type":"text/x-python","patch_set":6,"id":"37860430_5abf4489","line":1665,"range":{"start_line":1665,"start_character":23,"end_line":1665,"end_character":47},"updated":"2021-02-19 20:00:54.000000000","message":"Also just noticed, this does not seem to be used. Assume we can drop it?","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"2678f04352e59330b0c9354d7eeab6fd15e0c19d","unresolved":true,"context_lines":[{"line_number":1662,"context_line":""},{"line_number":1663,"context_line":""},{"line_number":1664,"context_line":"def tasks_get_by_image(context, image_id, session\u003dNone,"},{"line_number":1665,"context_line":"                       force_show_deleted\u003dFalse):"},{"line_number":1666,"context_line":"    \"\"\"Fetch all tasks associated with image_id\"\"\""},{"line_number":1667,"context_line":"    tasks \u003d []"},{"line_number":1668,"context_line":"    session \u003d session or get_session()"}],"source_content_type":"text/x-python","patch_set":6,"id":"a527c4d9_dcf056c4","line":1665,"range":{"start_line":1665,"start_character":23,"end_line":1665,"end_character":47},"in_reply_to":"37860430_5abf4489","updated":"2021-02-22 05:02:03.000000000","message":"Yes, we can","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"881c872733b8d0d890a45718a2908b1d9f984cbb","unresolved":true,"context_lines":[{"line_number":1680,"context_line":"                       datetime.timedelta(hours\u003dCONF.task.task_time_to_live)))"},{"line_number":1681,"context_line":""},{"line_number":1682,"context_line":"    if not context.is_admin and context.owner is not None:"},{"line_number":1683,"context_line":"        query \u003d query.filter(models.Task.owner \u003d\u003d context.owner)"},{"line_number":1684,"context_line":""},{"line_number":1685,"context_line":"    if not force_show_deleted and not context.can_see_deleted:"},{"line_number":1686,"context_line":"        query \u003d query.filter_by(deleted\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":6,"id":"c8785605_febb51a1","line":1683,"updated":"2021-02-19 20:00:54.000000000","message":"Is this redundant, given the check for is_task_visible() below?","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"2678f04352e59330b0c9354d7eeab6fd15e0c19d","unresolved":true,"context_lines":[{"line_number":1680,"context_line":"                       datetime.timedelta(hours\u003dCONF.task.task_time_to_live)))"},{"line_number":1681,"context_line":""},{"line_number":1682,"context_line":"    if not context.is_admin and context.owner is not None:"},{"line_number":1683,"context_line":"        query \u003d query.filter(models.Task.owner \u003d\u003d context.owner)"},{"line_number":1684,"context_line":""},{"line_number":1685,"context_line":"    if not force_show_deleted and not context.can_see_deleted:"},{"line_number":1686,"context_line":"        query \u003d query.filter_by(deleted\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":6,"id":"10854801_299ff63f","line":1683,"in_reply_to":"c8785605_febb51a1","updated":"2021-02-22 05:02:03.000000000","message":"Yes, this is redundant","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"3a510f38df63df1c8fe89f3d16f188fd55e2b08d","unresolved":true,"context_lines":[{"line_number":1698,"context_line":"            continue"},{"line_number":1699,"context_line":"        tasks.append(_task_format(task_ref, task_ref.info))"},{"line_number":1700,"context_line":""},{"line_number":1701,"context_line":"    return tasks"},{"line_number":1702,"context_line":""},{"line_number":1703,"context_line":""},{"line_number":1704,"context_line":"def task_delete(context, task_id, session\u003dNone):"}],"source_content_type":"text/x-python","patch_set":6,"id":"ff7aecbc_4efed14a","line":1701,"updated":"2021-02-19 19:33:45.000000000","message":"Er, I just realized this isn\u0027t tested directly. I thought I pointed that out earlier, but don\u0027t see it so gerrit must have eaten it.","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"f9d9d2b22905cb8dd972d9e1d77ef9a38ae84adb","unresolved":true,"context_lines":[{"line_number":1698,"context_line":"            continue"},{"line_number":1699,"context_line":"        tasks.append(_task_format(task_ref, task_ref.info))"},{"line_number":1700,"context_line":""},{"line_number":1701,"context_line":"    return tasks"},{"line_number":1702,"context_line":""},{"line_number":1703,"context_line":""},{"line_number":1704,"context_line":"def task_delete(context, task_id, session\u003dNone):"}],"source_content_type":"text/x-python","patch_set":6,"id":"94eeb6d9_b5110db6","line":1701,"in_reply_to":"ff7aecbc_4efed14a","updated":"2021-02-22 05:21:27.000000000","message":"Sad to say but we have 0 coverage for this file, may be because for unit tests we are using db/simple/api.py","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"}],"glance/tests/functional/v2/test_images.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"70d802a58f6862138cb23d0f473a61d78335c8ad","unresolved":true,"context_lines":[{"line_number":5475,"context_line":"            self.assertIn(\u0027image_id\u0027, task)"},{"line_number":5476,"context_line":"            self.assertIn(\u0027request_id\u0027, task)"},{"line_number":5477,"context_line":"            self.assertIn(\u0027user_id\u0027, task)"},{"line_number":5478,"context_line":""},{"line_number":5479,"context_line":"        # Copy newly created image to file2 and file3 stores"},{"line_number":5480,"context_line":"        path \u003d self._url(\u0027/v2/images/%s/import\u0027 % image_id)"},{"line_number":5481,"context_line":"        headers \u003d self._headers({"}],"source_content_type":"text/x-python","patch_set":3,"id":"47be4da8_814b5b6a","line":5478,"updated":"2021-02-15 15:15:15.000000000","message":"I think it would be good to validate these values, which I think should be easy for these regular functional tests since we have the response right?","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"9f3d9b3af0b8a2f519463dad9f7ea1c6bcc23f10","unresolved":true,"context_lines":[{"line_number":5475,"context_line":"            self.assertIn(\u0027image_id\u0027, task)"},{"line_number":5476,"context_line":"            self.assertIn(\u0027request_id\u0027, task)"},{"line_number":5477,"context_line":"            self.assertIn(\u0027user_id\u0027, task)"},{"line_number":5478,"context_line":""},{"line_number":5479,"context_line":"        # Copy newly created image to file2 and file3 stores"},{"line_number":5480,"context_line":"        path \u003d self._url(\u0027/v2/images/%s/import\u0027 % image_id)"},{"line_number":5481,"context_line":"        headers \u003d self._headers({"}],"source_content_type":"text/x-python","patch_set":3,"id":"1d206d3c_ad5ca096","line":5478,"in_reply_to":"47be4da8_814b5b6a","updated":"2021-02-15 15:33:33.000000000","message":"will find out the way to validate request_id and user_id","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"41eb15efa3c1d3d43e26bfc7dac82ddc6327097a","unresolved":true,"context_lines":[{"line_number":5477,"context_line":"            user_id \u003d response.request.headers.get("},{"line_number":5478,"context_line":"                \u0027X-User-Id\u0027)"},{"line_number":5479,"context_line":"            self.assertEqual(user_id, task[\u0027user_id\u0027])"},{"line_number":5480,"context_line":"            self.assertEqual(import_reqid, task[\u0027request_id\u0027])"},{"line_number":5481,"context_line":""},{"line_number":5482,"context_line":"        # Copy newly created image to file2 and file3 stores"},{"line_number":5483,"context_line":"        path \u003d self._url(\u0027/v2/images/%s/import\u0027 % image_id)"}],"source_content_type":"text/x-python","patch_set":6,"id":"8e9be274_c474c239","line":5480,"updated":"2021-02-19 19:31:36.000000000","message":"Abhi, I updated this for you to grab and validate the request-id. The tempest test was already validating this, so I knew it worked, but...nice to see it here too :)","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"f9d9d2b22905cb8dd972d9e1d77ef9a38ae84adb","unresolved":true,"context_lines":[{"line_number":5477,"context_line":"            user_id \u003d response.request.headers.get("},{"line_number":5478,"context_line":"                \u0027X-User-Id\u0027)"},{"line_number":5479,"context_line":"            self.assertEqual(user_id, task[\u0027user_id\u0027])"},{"line_number":5480,"context_line":"            self.assertEqual(import_reqid, task[\u0027request_id\u0027])"},{"line_number":5481,"context_line":""},{"line_number":5482,"context_line":"        # Copy newly created image to file2 and file3 stores"},{"line_number":5483,"context_line":"        path \u003d self._url(\u0027/v2/images/%s/import\u0027 % image_id)"}],"source_content_type":"text/x-python","patch_set":6,"id":"0471248c_110b2aac","line":5480,"in_reply_to":"8e9be274_c474c239","updated":"2021-02-22 05:21:27.000000000","message":"Thank you :D","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"41eb15efa3c1d3d43e26bfc7dac82ddc6327097a","unresolved":true,"context_lines":[{"line_number":5523,"context_line":"            user_id \u003d response.request.headers.get("},{"line_number":5524,"context_line":"                \u0027X-User-Id\u0027)"},{"line_number":5525,"context_line":"            self.assertEqual(user_id, task[\u0027user_id\u0027])"},{"line_number":5526,"context_line":"            self.assertEqual(expected_reqids.pop(), task[\u0027request_id\u0027])"},{"line_number":5527,"context_line":""},{"line_number":5528,"context_line":"        # Deleting image should work"},{"line_number":5529,"context_line":"        path \u003d self._url(\u0027/v2/images/%s\u0027 % image_id)"}],"source_content_type":"text/x-python","patch_set":6,"id":"6f0ea003_18c0dc2b","line":5526,"updated":"2021-02-19 19:31:36.000000000","message":"Same.","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"f9d9d2b22905cb8dd972d9e1d77ef9a38ae84adb","unresolved":true,"context_lines":[{"line_number":5523,"context_line":"            user_id \u003d response.request.headers.get("},{"line_number":5524,"context_line":"                \u0027X-User-Id\u0027)"},{"line_number":5525,"context_line":"            self.assertEqual(user_id, task[\u0027user_id\u0027])"},{"line_number":5526,"context_line":"            self.assertEqual(expected_reqids.pop(), task[\u0027request_id\u0027])"},{"line_number":5527,"context_line":""},{"line_number":5528,"context_line":"        # Deleting image should work"},{"line_number":5529,"context_line":"        path \u003d self._url(\u0027/v2/images/%s\u0027 % image_id)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9145d90d_de133aad","line":5526,"in_reply_to":"6f0ea003_18c0dc2b","updated":"2021-02-22 05:21:27.000000000","message":"Thank you","commit_id":"d94e84e4e3df07b0258ec20524fb8c2f64e253a0"}],"glance/tests/unit/v2/test_images_resource.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"70d802a58f6862138cb23d0f473a61d78335c8ad","unresolved":true,"context_lines":[{"line_number":759,"context_line":"    def test_get_task_info(self):"},{"line_number":760,"context_line":"        request \u003d unit_test_utils.get_fake_request()"},{"line_number":761,"context_line":"        output \u003d self.controller.get_task_info(request, image_id\u003dUUID1)"},{"line_number":762,"context_line":"        self.assertEqual(2, len(output[\u0027tasks\u0027]))"},{"line_number":763,"context_line":""},{"line_number":764,"context_line":"    def test_get_task_info_no_tasks(self):"},{"line_number":765,"context_line":"        request \u003d unit_test_utils.get_fake_request()"}],"source_content_type":"text/x-python","patch_set":3,"id":"f04bbf3b_c8346623","line":762,"updated":"2021-02-15 15:15:15.000000000","message":"We should be able to do better than this here, since we are controlling the task structures.\n\nAlso, I think it would be good to make sure that we have at least one task structure that was created without these values to test that the view is consistent and doesn\u0027t 500 or something. If I create an image just before an upgrade, then post-upgrade I could hit this /tasks api, but the tasks will have null fields in the database for the new values. We should test that explicitly to make sure it works and behaves like we expect.","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"1d2aee6c32af55b21a5f55a936a6da6555a5fa8b","unresolved":true,"context_lines":[{"line_number":759,"context_line":"    def test_get_task_info(self):"},{"line_number":760,"context_line":"        request \u003d unit_test_utils.get_fake_request()"},{"line_number":761,"context_line":"        output \u003d self.controller.get_task_info(request, image_id\u003dUUID1)"},{"line_number":762,"context_line":"        self.assertEqual(2, len(output[\u0027tasks\u0027]))"},{"line_number":763,"context_line":""},{"line_number":764,"context_line":"    def test_get_task_info_no_tasks(self):"},{"line_number":765,"context_line":"        request \u003d unit_test_utils.get_fake_request()"}],"source_content_type":"text/x-python","patch_set":3,"id":"780a97dc_7834839b","line":762,"in_reply_to":"de7afd62_218bb633","updated":"2021-02-16 14:35:29.000000000","message":"The test I want can only be done in this patch, because it needs to use this API :)\n\nBut yes, that\u0027s what I mean - make sure that the API handles the tasks with None for those fields. I know you\u0027re filtering for them, but we should have a test that runs in the presence of tasks with None for those fields and make sure the API doesn\u0027t choke.","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"104659efc5e519b240e25efec064fada7d208173","unresolved":true,"context_lines":[{"line_number":759,"context_line":"    def test_get_task_info(self):"},{"line_number":760,"context_line":"        request \u003d unit_test_utils.get_fake_request()"},{"line_number":761,"context_line":"        output \u003d self.controller.get_task_info(request, image_id\u003dUUID1)"},{"line_number":762,"context_line":"        self.assertEqual(2, len(output[\u0027tasks\u0027]))"},{"line_number":763,"context_line":""},{"line_number":764,"context_line":"    def test_get_task_info_no_tasks(self):"},{"line_number":765,"context_line":"        request \u003d unit_test_utils.get_fake_request()"}],"source_content_type":"text/x-python","patch_set":3,"id":"de7afd62_218bb633","line":762,"in_reply_to":"f04bbf3b_c8346623","updated":"2021-02-16 07:04:20.000000000","message":"If you create an image before upgrade then after post upgrade when you hit this API you will not get the pre upgrade task record in the result as we are getting tasks filtered by image_id.\n\nThe test you suggesting could be added in previous patchset where we are actually utilizing these new fields.","commit_id":"9d959c7b4a41ddabf0e9c93748dba96531b7504a"}]}
