)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"09a1efb2_ef00e149","updated":"2025-10-10 14:29:08.000000000","message":"Hi Dan, Thank you for the inputs, I have added few inline answers. Please have a look when you get some time!","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"18ec77312fd0d95c8a6f4b4b7f11514c67ee1d0a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"1d009316_27b87598","updated":"2025-10-10 14:11:49.000000000","message":"I like the idea of being able to do this, but I\u0027m not sure who the target audience for this is. Are you thinking this is mostly a human user feature? To me, this is as (or more) useful for compute nodes to be told what stores they\u0027re close to (especially in an edge situation). To me, it seems much better to have an API that can take a list of preferred stores instead of one that requires probing with multiple calls to determine where an image is (AFAIK that\u0027s hard to determine today right?).\n\nI also think that creating a whole new download API (even if much of the code is shared) is an unnecessary expansion of the API surface. I\u0027m not sure what \"risk of breaking the existing download API\" there really is, but - can you elaborate on why you think that\u0027s better?","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"1e08ee35320062aa0bec838ede2ec35fb4449671","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"987c2c8f_7db09808","updated":"2025-12-01 14:31:16.000000000","message":"I had a chat with Abhishek in IRC this morning [0], and my current opinion is that we don\u0027t want to have this \u0027preference\u0027 or \u0027required\u0027 parameter at all.  I think we should just say that the list of stores indicates the order that will be tried if glance has to go to a store to get the image data.\n\nThe reasons are:\n1. If the cache is enabled, the data is delivered from the cache even if you only listed one store and said it was required.\n2. A request for GET images/{id}/file means \"give me the data as quick as you can\", which currently means from the cache or from a store using the weights from 2023.2.  This proposal gives a requestor a way to override the weights and specify the order they want.  But presumably if they have requested an image download, they want the image data, so glance should give it to them.\n3. If a requestor absolutely cares that if the data is not in store X then they don\u0027t want it at all, they can do an image-show to see what stores the data is in, and if it\u0027s not in the store they want, they just don\u0027t make the download request.\n4. We already have access control to images (and hence image data) via public, community, shared, and private images.  (Though I\u0027m not sure exactly why I thought it was important to mention this.)\n\n[0] https://meetings.opendev.org/irclogs/%23openstack-glance/%23openstack-glance.2025-12-01.log.html#openstack-glance.2025-12-01.log.html#t2025-12-01T13:14:01","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"9c2d5b9da14a1db263a8c65ccd7dfcec3d160651","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"66784ea2_c04dacd1","updated":"2025-11-25 14:24:30.000000000","message":"I like it, except for... \"oneof\".\n\nWhen I read: \"?stores\u003dceph,s3\u0026preference\u003doneof\", my brain thinks it means \"either ceph or s3, PERIOD\". So, basically, what \"only\" does.\n\nShould we use \"only\" and... \"besteffort\"?","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"dda354348624a22f99461f7d841e539ad735b4a5","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"93f7e098_dc85107b","in_reply_to":"08c8403f_e7f580bb","updated":"2025-11-25 17:01:38.000000000","message":"In that example, `prefer` means \"try ceph, then try s3, then try anything else\". Then `require` would mean \"try ceph, then try s3, else fail\". Just like `preference\u003donly` in the previous example.","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"72caf77c5f76087ea5c608411d880a5e293bc35a","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"7379593f_795519e8","in_reply_to":"35eee817_0f2d9637","updated":"2025-11-25 15:40:14.000000000","message":"...or we do away with providing a strategy and require something at the end of the list that means \"anything else\".. Like `stores\u003dceph,s3,@any`, with the default being implied to be `stores\u003d@any`.\n\nPersonally, I don\u0027t like long URL parameter names, so even `preference\u003d` is too long. `selection\u003dsuggest` is pretty long (and I don\u0027t think \"suggest\" means to me what it does to you in that context). Params don\u0027t need to have values either, so it could be:\n\n`stores\u003dceph,s3\u0026prefer`\n\nor\n\n`stores\u003dceph,s3\u0026require`","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"05785ab868fcdd95652258b42304e15cd816da1e","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"f9d40ecd_537eb009","in_reply_to":"66784ea2_c04dacd1","updated":"2025-11-25 14:48:44.000000000","message":"I agree with Cyril.  The \u0027oneof\u0027 doesn\u0027t really make sense because we might use one of them, or we might use the default.\n\nNobody (other than me. Erno will absolutely hate it) will like this, but instead of \u0027preference\u0027 as the parameter name, how about \u0027store-selection\u0027, and for the values use \u0027suggest\u0027 or \u0027require\u0027?","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"1bcbb391ab1f43ea365804cf2809d8c49f54a621","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"97edb919_c816c04f","in_reply_to":"69d96a66_f0fad8d6","updated":"2025-11-25 17:26:00.000000000","message":"I like \"@any\", provided we do not allow users to name a store \"@any\".\n\nJust having \"\u0026prefer\" and \"\u0026require\" is a bit confusing because in this case they refer to the same thing (the strategy used to select a store) but are not grouped together in a named parameter (which would be selection\u003dprefer or selection\u003drequire).","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e36103d2d541ae17a0519e0fd3937e66a1a5f039","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"08c8403f_e7f580bb","in_reply_to":"7379593f_795519e8","updated":"2025-11-25 16:58:12.000000000","message":"Sorry I might be misunderstood this but if;\nstores\u003dceph,s3\u0026prefer means prefer ceph first and then go for s3 then what is require?","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"a00536631c1bd3f9baf1d8c88407ebe7a5dcd7ce","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"69d96a66_f0fad8d6","in_reply_to":"93f7e098_dc85107b","updated":"2025-11-25 17:04:30.000000000","message":"Ack, thank you Dan for the example. I will wait for Cyril and Brian and then update the spec accordingly. (I hope everyone aware about the NOTE I have added about caching in the spec).","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"165f3109fcf945fa8a5e53fa26d0672435a42ee1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"7c2778d8_de7cad1d","in_reply_to":"97edb919_c816c04f","updated":"2025-12-01 15:02:59.000000000","message":"Done","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"bca6e9b079854dc8ef517ab9788d638668133ba2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"401f8657_4bc5c880","in_reply_to":"987c2c8f_7db09808","updated":"2025-12-01 14:50:06.000000000","message":"Thank you Brian for your inputs. I am going to remove preference parameter and just keep stores as per your suggestion here.","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"447e69aa9f1125199430e90b22b8936ac1cf67b1","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"35eee817_0f2d9637","in_reply_to":"f9d40ecd_537eb009","updated":"2025-11-25 14:53:05.000000000","message":"Or maybe just \"selection\", yeah. \"?stores\u003dceph,s3\u0026selection\u003dsuggest\". It is easier to understand, and will cause less confusion when debugging.","commit_id":"de9afb829fce71a588c4670ec7b9a965620b89f4"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":5,"id":"65b8c300_c9134d21","updated":"2025-12-01 15:51:08.000000000","message":"A few suggestions noted inline.","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"84f7473f_666e6f6f","updated":"2025-12-02 09:34:48.000000000","message":"hi Brian, thank you for review, made changes as per your suggestion.","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"ec7e0dbce744f388ba89a7a71b31503a95d91091","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"9c79a619_226eafc7","updated":"2025-12-02 13:48:03.000000000","message":"Thanks for the quick revision, I think this looks good!  One final thing.  Looking at the API request:\n\n```\nGET /v2/images/{image_id}/file?stores\u003dstore1,store2\n```\n\nIf I were just looking at that, I would guess that glance will try those two stores only.  I wonder whether s/stores/suggest/ to get something like this:\n\n```\nGET /v2/images/{image_id}/file?suggest\u003dstore1,store2\n```\n\nOr maybe \"hint\" instead of \"suggest\" (along the lines of Nova scheduler hints, although I think we have different behavior in that for example if the SameHostFilter is enabled in a cloud, and you use a scheduler_hint for some server_id, if the host doesn\u0027t have room, I believe the request will fail with No Valid Host, which is definitely *not* the case for us).  So maybe we should use our own word to avoid confusion.  (Let\u0027s see what Dan thinks.)","commit_id":"c14b5ccd3b5e22a6cdac09b3ba7760c9521be013"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"11466aabd0efd754de0c1bb10f3bc5a775b7db14","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"43c93e6c_5d411af6","in_reply_to":"81a2ff9a_f0735369","updated":"2025-12-02 15:39:31.000000000","message":"\u0027prefer\u0027 is short and accurate, it sounds good to me.","commit_id":"c14b5ccd3b5e22a6cdac09b3ba7760c9521be013"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"cd40fbc594746ee554cea200278b12decd577e7d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"81a2ff9a_f0735369","in_reply_to":"9c79a619_226eafc7","updated":"2025-12-02 14:35:25.000000000","message":"I think I said `prefer\u003dstore1,store2` before.. that definitely sounds better to me than \"suggest\". Indeed \"hint\" would be an option, but I dislike it for the same reason I dislike that nova uses it. The \"hint\" can be a lot of things, preference, anti-preference, random string that affects things in other ways, etc.","commit_id":"c14b5ccd3b5e22a6cdac09b3ba7760c9521be013"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"3cd3e4910b17b0ef14c1ca1d11e07df2ea83a334","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"2e231496_009e6602","updated":"2025-12-02 18:15:06.000000000","message":"Looks like a good proposal.","commit_id":"7ef5651cd1f9fbcbf7cc59530eacea3a5a0110e8"}],"specs/2026.1/approved/glance/download-from-specific-store.rst":[{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"dc8d0489cee7d7da6a47b1288eaeb9dffbf241fc","unresolved":true,"context_lines":[{"line_number":31,"context_line":"This default-store-first selection has several limitations:"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"* **No user control**: Users cannot specify which store to download from"},{"line_number":34,"context_line":"* **Performance optimization**: Users cannot choose a faster or more"},{"line_number":35,"context_line":"  geographically closer store"},{"line_number":36,"context_line":"* **Cost optimization**: Users cannot prefer cheaper storage options"},{"line_number":37,"context_line":"* **Debugging**: Operators cannot test specific stores for troubleshooting"}],"source_content_type":"text/x-rst","patch_set":1,"id":"79d37dfb_0ecbcbb8","line":34,"range":{"start_line":34,"start_character":63,"end_line":34,"end_character":64},"updated":"2025-10-07 16:04:15.000000000","message":"Remove \"more\":\n\n\"Users cannot choose a faster or geographically closer store\".","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":false,"context_lines":[{"line_number":31,"context_line":"This default-store-first selection has several limitations:"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"* **No user control**: Users cannot specify which store to download from"},{"line_number":34,"context_line":"* **Performance optimization**: Users cannot choose a faster or more"},{"line_number":35,"context_line":"  geographically closer store"},{"line_number":36,"context_line":"* **Cost optimization**: Users cannot prefer cheaper storage options"},{"line_number":37,"context_line":"* **Debugging**: Operators cannot test specific stores for troubleshooting"}],"source_content_type":"text/x-rst","patch_set":1,"id":"07525d9e_381b154a","line":34,"range":{"start_line":34,"start_character":63,"end_line":34,"end_character":64},"in_reply_to":"79d37dfb_0ecbcbb8","updated":"2025-10-10 14:29:08.000000000","message":"Acknowledged","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"18ec77312fd0d95c8a6f4b4b7f11514c67ee1d0a","unresolved":true,"context_lines":[{"line_number":39,"context_line":""},{"line_number":40,"context_line":"While the store weight mechanism (implemented in 2023.2) allows operators to"},{"line_number":41,"context_line":"configure store priorities, it only provides operator-level control and doesn\u0027t"},{"line_number":42,"context_line":"give end users the ability to choose specific stores for individual downloads."},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"Use cases include:"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"44ffd171_6718ae94","line":42,"range":{"start_line":42,"start_character":5,"end_line":42,"end_character":14},"updated":"2025-10-10 14:11:49.000000000","message":"That\u0027s true, but giving users full control over where to download from might mean they choose the most expensive (for the operator) store, especially given they don\u0027t know the backend details. Not saying that\u0027s a reason not to do this, but... if I have a local store and a remote backup one (like a mirror of everything to S3), I likely pay to get images *out*, so if the user decides to use that, it\u0027ll cost me.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"c77b0ec6d327ca2a9a15a4eb786e27c893ea04b9","unresolved":true,"context_lines":[{"line_number":39,"context_line":""},{"line_number":40,"context_line":"While the store weight mechanism (implemented in 2023.2) allows operators to"},{"line_number":41,"context_line":"configure store priorities, it only provides operator-level control and doesn\u0027t"},{"line_number":42,"context_line":"give end users the ability to choose specific stores for individual downloads."},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"Use cases include:"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"800c6a16_1b2a6f44","line":42,"range":{"start_line":42,"start_character":5,"end_line":42,"end_character":14},"in_reply_to":"44ffd171_6718ae94","updated":"2025-10-10 14:52:54.000000000","message":"this will be real concern for an operator, I think we should make this admin or service only using policy.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"60a83ebdd0d4a8c36a2abb038a9abc48b3785f7e","unresolved":true,"context_lines":[{"line_number":39,"context_line":""},{"line_number":40,"context_line":"While the store weight mechanism (implemented in 2023.2) allows operators to"},{"line_number":41,"context_line":"configure store priorities, it only provides operator-level control and doesn\u0027t"},{"line_number":42,"context_line":"give end users the ability to choose specific stores for individual downloads."},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"Use cases include:"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"856462b6_21d3656a","line":42,"range":{"start_line":42,"start_character":5,"end_line":42,"end_character":14},"in_reply_to":"800c6a16_1b2a6f44","updated":"2025-10-10 15:08:21.000000000","message":"Okay, then please state that here. Reading this initially I thought you were actually more targeting the human users, based on the wording. A policy that lets operators decide who has this power would be good I think.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"3087951f8bba800c48e8a2a35ec71442bdd40d70","unresolved":false,"context_lines":[{"line_number":39,"context_line":""},{"line_number":40,"context_line":"While the store weight mechanism (implemented in 2023.2) allows operators to"},{"line_number":41,"context_line":"configure store priorities, it only provides operator-level control and doesn\u0027t"},{"line_number":42,"context_line":"give end users the ability to choose specific stores for individual downloads."},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"Use cases include:"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"caae08c9_52d33222","line":42,"range":{"start_line":42,"start_character":5,"end_line":42,"end_character":14},"in_reply_to":"856462b6_21d3656a","updated":"2025-10-24 13:38:17.000000000","message":"Acknowledged","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"18ec77312fd0d95c8a6f4b4b7f11514c67ee1d0a","unresolved":true,"context_lines":[{"line_number":47,"context_line":"* **Cost**: Download from the cheapest storage option"},{"line_number":48,"context_line":"* **Proximity**: Download from a geographically closer store"},{"line_number":49,"context_line":"* **Testing**: Verify that specific stores are working correctly"},{"line_number":50,"context_line":"* **Load distribution**: Spread download requests across multiple stores"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"Proposed change"},{"line_number":53,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"c8921612_2b582d0c","line":50,"updated":"2025-10-10 14:11:49.000000000","message":"How do you expect users will learn about these attributes of a store in order to pick one?","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"60a83ebdd0d4a8c36a2abb038a9abc48b3785f7e","unresolved":true,"context_lines":[{"line_number":47,"context_line":"* **Cost**: Download from the cheapest storage option"},{"line_number":48,"context_line":"* **Proximity**: Download from a geographically closer store"},{"line_number":49,"context_line":"* **Testing**: Verify that specific stores are working correctly"},{"line_number":50,"context_line":"* **Load distribution**: Spread download requests across multiple stores"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"Proposed change"},{"line_number":53,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"4e5b9086_713a3eaa","line":50,"in_reply_to":"35874ec4_7fb0a93e","updated":"2025-10-10 15:08:21.000000000","message":"I think you don\u0027t need \"default\" because that\u0027s the behavior you get with no query param at all. The other two are \"only one of the ones I specified\" or \"one of the ones I specified, else fall back to default\". So maybe \"only\" and \"oneof\"?","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"3087951f8bba800c48e8a2a35ec71442bdd40d70","unresolved":false,"context_lines":[{"line_number":47,"context_line":"* **Cost**: Download from the cheapest storage option"},{"line_number":48,"context_line":"* **Proximity**: Download from a geographically closer store"},{"line_number":49,"context_line":"* **Testing**: Verify that specific stores are working correctly"},{"line_number":50,"context_line":"* **Load distribution**: Spread download requests across multiple stores"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"Proposed change"},{"line_number":53,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"dcc1e793_c21fcff7","line":50,"in_reply_to":"4e5b9086_713a3eaa","updated":"2025-10-24 13:38:17.000000000","message":"Acknowledged","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"c77b0ec6d327ca2a9a15a4eb786e27c893ea04b9","unresolved":true,"context_lines":[{"line_number":47,"context_line":"* **Cost**: Download from the cheapest storage option"},{"line_number":48,"context_line":"* **Proximity**: Download from a geographically closer store"},{"line_number":49,"context_line":"* **Testing**: Verify that specific stores are working correctly"},{"line_number":50,"context_line":"* **Load distribution**: Spread download requests across multiple stores"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"Proposed change"},{"line_number":53,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"35874ec4_7fb0a93e","line":50,"in_reply_to":"7a8eb331_922c6e57","updated":"2025-10-10 14:52:54.000000000","message":"Ack, I know this will be easy and avoid lots of duplications in glance as well as nvoa and cinder. I will rephrase the spec and resubmit it for review. I am just wondering what options we should limit for the preference like first,only,default (or any other)?","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":true,"context_lines":[{"line_number":47,"context_line":"* **Cost**: Download from the cheapest storage option"},{"line_number":48,"context_line":"* **Proximity**: Download from a geographically closer store"},{"line_number":49,"context_line":"* **Testing**: Verify that specific stores are working correctly"},{"line_number":50,"context_line":"* **Load distribution**: Spread download requests across multiple stores"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"Proposed change"},{"line_number":53,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"d0d13155_a0f423e1","line":50,"in_reply_to":"c8921612_2b582d0c","updated":"2025-10-10 14:29:08.000000000","message":"I was thinking consumers like nova or cinder can utilise this, definitely they will need to make some changes at their end for this though.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ebaddee21f290d22c42707b99ea18888c27f3378","unresolved":true,"context_lines":[{"line_number":47,"context_line":"* **Cost**: Download from the cheapest storage option"},{"line_number":48,"context_line":"* **Proximity**: Download from a geographically closer store"},{"line_number":49,"context_line":"* **Testing**: Verify that specific stores are working correctly"},{"line_number":50,"context_line":"* **Load distribution**: Spread download requests across multiple stores"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"Proposed change"},{"line_number":53,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"7a8eb331_922c6e57","line":50,"in_reply_to":"d0d13155_a0f423e1","updated":"2025-10-10 14:42:13.000000000","message":"Ack, I think it will be much easier for nova and cinder to not substantially change their existing behavior, but just provide a list of preferred stores to the existing API if configured to do so. Just MHO :)","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"dc8d0489cee7d7da6a47b1288eaeb9dffbf241fc","unresolved":true,"context_lines":[{"line_number":57,"context_line":"endpoint."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"New API call:"},{"line_number":60,"context_line":"\u0027GET /v2/stores/\u003cStoreID\u003e/\u003cImageID\u003e/file\u0027"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"The implementation will:"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"6af81719_d1fd61fc","line":60,"range":{"start_line":60,"start_character":26,"end_line":60,"end_character":27},"updated":"2025-10-07 16:04:15.000000000","message":"This is also consistent vith DELETE /v2/stores/\u003cStoreID\u003e/\u003cImageID\u003e, so that sounds good.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":true,"context_lines":[{"line_number":57,"context_line":"endpoint."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"New API call:"},{"line_number":60,"context_line":"\u0027GET /v2/stores/\u003cStoreID\u003e/\u003cImageID\u003e/file\u0027"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"The implementation will:"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"fc078195_de3fcb21","line":60,"range":{"start_line":60,"start_character":26,"end_line":60,"end_character":27},"in_reply_to":"1776506d_fad3af14","updated":"2025-10-10 14:29:08.000000000","message":"Yes, it is already available, That\u0027s why I thought we can use similar implementation.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"18ec77312fd0d95c8a6f4b4b7f11514c67ee1d0a","unresolved":true,"context_lines":[{"line_number":57,"context_line":"endpoint."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"New API call:"},{"line_number":60,"context_line":"\u0027GET /v2/stores/\u003cStoreID\u003e/\u003cImageID\u003e/file\u0027"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"The implementation will:"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"1776506d_fad3af14","line":60,"range":{"start_line":60,"start_character":26,"end_line":60,"end_character":27},"in_reply_to":"6af81719_d1fd61fc","updated":"2025-10-10 14:11:49.000000000","message":"I haven\u0027t looked, but are you saying that DELETE path already exists for removing an image from a given store?\n\nAnother option would be to just make this a query param on the existing download endpoint (so file?store\u003dSTOREID). Another benefit of this is that the user could provide a list of preferences (file?store\u003dSTORE1,STORE2) and the first one with the image wins.\n\n(edit: I see it in the alternatives below)","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"3087951f8bba800c48e8a2a35ec71442bdd40d70","unresolved":false,"context_lines":[{"line_number":57,"context_line":"endpoint."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"New API call:"},{"line_number":60,"context_line":"\u0027GET /v2/stores/\u003cStoreID\u003e/\u003cImageID\u003e/file\u0027"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"The implementation will:"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"47255a06_86e1be5a","line":60,"range":{"start_line":60,"start_character":26,"end_line":60,"end_character":27},"in_reply_to":"fc078195_de3fcb21","updated":"2025-10-24 13:38:17.000000000","message":"Done","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"18ec77312fd0d95c8a6f4b4b7f11514c67ee1d0a","unresolved":true,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"This approach keeps the existing GET /v2/images/{image_id}/file endpoint"},{"line_number":80,"context_line":"unchanged, preserving backward compatibility and avoiding any risk of"},{"line_number":81,"context_line":"accidentally affecting existing behavior."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"Alternatives"},{"line_number":84,"context_line":"------------"}],"source_content_type":"text/x-rst","patch_set":1,"id":"ae316a78_dfd37286","line":81,"updated":"2025-10-10 14:11:49.000000000","message":"But also provides a default for the \"I have no preference, just give me this image from wherever\" option right?","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"3087951f8bba800c48e8a2a35ec71442bdd40d70","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"This approach keeps the existing GET /v2/images/{image_id}/file endpoint"},{"line_number":80,"context_line":"unchanged, preserving backward compatibility and avoiding any risk of"},{"line_number":81,"context_line":"accidentally affecting existing behavior."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"Alternatives"},{"line_number":84,"context_line":"------------"}],"source_content_type":"text/x-rst","patch_set":1,"id":"64f2c8ad_01f559cb","line":81,"in_reply_to":"3799d165_c0347f04","updated":"2025-10-24 13:38:17.000000000","message":"Done","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":true,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"This approach keeps the existing GET /v2/images/{image_id}/file endpoint"},{"line_number":80,"context_line":"unchanged, preserving backward compatibility and avoiding any risk of"},{"line_number":81,"context_line":"accidentally affecting existing behavior."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"Alternatives"},{"line_number":84,"context_line":"------------"}],"source_content_type":"text/x-rst","patch_set":1,"id":"3799d165_c0347f04","line":81,"in_reply_to":"ae316a78_dfd37286","updated":"2025-10-10 14:29:08.000000000","message":"right","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"18ec77312fd0d95c8a6f4b4b7f11514c67ee1d0a","unresolved":true,"context_lines":[{"line_number":86,"context_line":"1. **Query parameter approach**: Add a `store` query parameter to the existing"},{"line_number":87,"context_line":"   GET /v2/images/{image_id}/file endpoint. This was the original approach but"},{"line_number":88,"context_line":"   risks accidentally affecting existing behavior and is less explicit about"},{"line_number":89,"context_line":"   which store is being used."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"2. **Header-based approach**: Use HTTP headers to specify the store. Headers"},{"line_number":92,"context_line":"   are less discoverable and harder to use with standard HTTP clients."}],"source_content_type":"text/x-rst","patch_set":1,"id":"710e38f8_477a29bd","line":89,"updated":"2025-10-10 14:11:49.000000000","message":"Well, surely this is going to re-use most of the internal download code anyway, right? I\u0027m not sure the \"risks accidentally affecting existing behavior\" is a good reason not to. I\u0027d counter that with \"doesn\u0027t add _another_ way to download an image that increases the API surface\".\n\nAlso.. how is it less explicit? The behavior of the query parameter can be either \"prefer this store (or these stores), else just give it to me from the first available\" -or- it could be \"give it to me from this store, else refuse\". The latter is just as explicit as the proposed implementation - it doesn\u0027t matter that it\u0027s in the path.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"c77b0ec6d327ca2a9a15a4eb786e27c893ea04b9","unresolved":true,"context_lines":[{"line_number":86,"context_line":"1. **Query parameter approach**: Add a `store` query parameter to the existing"},{"line_number":87,"context_line":"   GET /v2/images/{image_id}/file endpoint. This was the original approach but"},{"line_number":88,"context_line":"   risks accidentally affecting existing behavior and is less explicit about"},{"line_number":89,"context_line":"   which store is being used."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"2. **Header-based approach**: Use HTTP headers to specify the store. Headers"},{"line_number":92,"context_line":"   are less discoverable and harder to use with standard HTTP clients."}],"source_content_type":"text/x-rst","patch_set":1,"id":"d9e6d409_e29ba53e","line":89,"in_reply_to":"1f0727d9_7cc95ac9","updated":"2025-10-10 14:52:54.000000000","message":"May be I chose wrong word here :) \nMy only intention for this proposed solution is to follow existing design, but yes the query parameter is more convenient and with this we can make lots of enhancement.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":true,"context_lines":[{"line_number":86,"context_line":"1. **Query parameter approach**: Add a `store` query parameter to the existing"},{"line_number":87,"context_line":"   GET /v2/images/{image_id}/file endpoint. This was the original approach but"},{"line_number":88,"context_line":"   risks accidentally affecting existing behavior and is less explicit about"},{"line_number":89,"context_line":"   which store is being used."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"2. **Header-based approach**: Use HTTP headers to specify the store. Headers"},{"line_number":92,"context_line":"   are less discoverable and harder to use with standard HTTP clients."}],"source_content_type":"text/x-rst","patch_set":1,"id":"8fc7ce97_1762a017","line":89,"in_reply_to":"710e38f8_477a29bd","updated":"2025-10-10 14:29:08.000000000","message":"We already have weighing mechanism introduced for preferential download, that\u0027s why I didn\u0027t thought having any preferential option in this implementation, If you insist of having that then we can switch to having this as a primary option.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ebaddee21f290d22c42707b99ea18888c27f3378","unresolved":true,"context_lines":[{"line_number":86,"context_line":"1. **Query parameter approach**: Add a `store` query parameter to the existing"},{"line_number":87,"context_line":"   GET /v2/images/{image_id}/file endpoint. This was the original approach but"},{"line_number":88,"context_line":"   risks accidentally affecting existing behavior and is less explicit about"},{"line_number":89,"context_line":"   which store is being used."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"2. **Header-based approach**: Use HTTP headers to specify the store. Headers"},{"line_number":92,"context_line":"   are less discoverable and harder to use with standard HTTP clients."}],"source_content_type":"text/x-rst","patch_set":1,"id":"1f0727d9_7cc95ac9","line":89,"in_reply_to":"8fc7ce97_1762a017","updated":"2025-10-10 14:42:13.000000000","message":"But as you say, the weighing mechanism is static and operator-controlled. A compute node that is at an edge site has different preferences than a human user sitting in the central site. I guess it seems to me like we\u0027re identifying the need for client preference here (which I agree is important), but making enacting that preference list fairly verbose because the client has to probe all the stores they prefer, or just take the default operator-preferred ordering.\n\nAnyway, I don\u0027t \"insist\" on anything, I just wanted to know the motivation behind making this design decision as it\u0027s not what I would have chosen. I\u0027m asking to stimulate discussion (or perhaps find out that there was already some discussion had and some reasoning exposed).","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"60a83ebdd0d4a8c36a2abb038a9abc48b3785f7e","unresolved":false,"context_lines":[{"line_number":86,"context_line":"1. **Query parameter approach**: Add a `store` query parameter to the existing"},{"line_number":87,"context_line":"   GET /v2/images/{image_id}/file endpoint. This was the original approach but"},{"line_number":88,"context_line":"   risks accidentally affecting existing behavior and is less explicit about"},{"line_number":89,"context_line":"   which store is being used."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"2. **Header-based approach**: Use HTTP headers to specify the store. Headers"},{"line_number":92,"context_line":"   are less discoverable and harder to use with standard HTTP clients."}],"source_content_type":"text/x-rst","patch_set":1,"id":"9e17d6bb_114b3b4b","line":89,"in_reply_to":"d9e6d409_e29ba53e","updated":"2025-10-10 15:08:21.000000000","message":"Acknowledged","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"18ec77312fd0d95c8a6f4b4b7f11514c67ee1d0a","unresolved":true,"context_lines":[{"line_number":120,"context_line":"* **Method**: GET"},{"line_number":121,"context_line":"* **Path Parameters**:"},{"line_number":122,"context_line":"  - `store_id`: Store identifier (e.g., \"swift-store-1\", \"cinder-store-1\")"},{"line_number":123,"context_line":"  - `image_id`: Image identifier"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"**Response Codes**:"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"820574c7_159e7a65","line":123,"updated":"2025-10-10 14:11:49.000000000","message":"Just another point about the above.. with this API, let\u0027s say I\u0027m a compute node and I know I\u0027m close to the \"us-pacific\" store. If I always want to try to download from that store if the image is available, otherwise the us-atlantic, and if nothing else, the first available, I have to do something like this:\n\n1. Get /stores/us-pacific/image/file, if 404 then:\n2. Get /stores/us-atlantic/image/file, if 404, then:\n3. Get /download/file\n\nRight? IIRC, the actual stores an image is in is not easily determinable by the user, right? They may be able to list the available stores, and they may be able to see the locations (but generally not) but... how will they know where the image is available without the above probing?\n\nOn the other hand, a query param approach could look like this:\n\n1. Get /download/file?preference\u003dfirst\u0026stores\u003dus-atlantic,us-pacific\n\nWhere \"preference\u003dfirst\" says \"try the stores in the order I gave and then fall back to the first available\". Maybe something like \"preference\u003donly\" would mean \"give it to me from this store and if it\u0027s not there, 404\".","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":true,"context_lines":[{"line_number":120,"context_line":"* **Method**: GET"},{"line_number":121,"context_line":"* **Path Parameters**:"},{"line_number":122,"context_line":"  - `store_id`: Store identifier (e.g., \"swift-store-1\", \"cinder-store-1\")"},{"line_number":123,"context_line":"  - `image_id`: Image identifier"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"**Response Codes**:"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"ee56b577_eed8806b","line":123,"in_reply_to":"820574c7_159e7a65","updated":"2025-10-10 14:29:08.000000000","message":"Same as above, we can move this as a primary solution.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"3087951f8bba800c48e8a2a35ec71442bdd40d70","unresolved":false,"context_lines":[{"line_number":120,"context_line":"* **Method**: GET"},{"line_number":121,"context_line":"* **Path Parameters**:"},{"line_number":122,"context_line":"  - `store_id`: Store identifier (e.g., \"swift-store-1\", \"cinder-store-1\")"},{"line_number":123,"context_line":"  - `image_id`: Image identifier"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"**Response Codes**:"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-rst","patch_set":1,"id":"0be5e3ad_74d4826f","line":123,"in_reply_to":"ee56b577_eed8806b","updated":"2025-10-24 13:38:17.000000000","message":"Done","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"dc8d0489cee7d7da6a47b1288eaeb9dffbf241fc","unresolved":true,"context_lines":[{"line_number":252,"context_line":"4. Add comprehensive unit tests for the new endpoint"},{"line_number":253,"context_line":"5. Add functional tests to verify end-to-end behavior"},{"line_number":254,"context_line":"6. Update API documentation and user guides"},{"line_number":255,"context_line":"7. Update python-glanceclient, openstack SDK to support the new endpoint"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"Dependencies"},{"line_number":258,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"c1765354_63006004","line":255,"range":{"start_line":255,"start_character":17,"end_line":255,"end_character":29},"updated":"2025-10-07 16:04:15.000000000","message":"I think we might want to not add changes to glanceclient, since at some point we\u0027re going to freeze development.","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e59bd2b180a83d5233364206e1d793f00abde01e","unresolved":false,"context_lines":[{"line_number":252,"context_line":"4. Add comprehensive unit tests for the new endpoint"},{"line_number":253,"context_line":"5. Add functional tests to verify end-to-end behavior"},{"line_number":254,"context_line":"6. Update API documentation and user guides"},{"line_number":255,"context_line":"7. Update python-glanceclient, openstack SDK to support the new endpoint"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"Dependencies"},{"line_number":258,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":1,"id":"98a813cc_10ea167b","line":255,"range":{"start_line":255,"start_character":17,"end_line":255,"end_character":29},"in_reply_to":"c1765354_63006004","updated":"2025-10-10 14:29:08.000000000","message":"Acknowledged","commit_id":"a908cdd7ce7d78d339db6533e90f2f07528dea09"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":5,"context_line":" http://creativecommons.org/licenses/by/3.0/legalcode"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":8,"context_line":"Download Image from Specific Store"},{"line_number":9,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"https://blueprints.launchpad.net/glance/+spec/download-from-specific-store"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5426c493_1efca119","line":8,"range":{"start_line":8,"start_character":20,"end_line":8,"end_character":34},"updated":"2025-12-01 15:51:08.000000000","message":"maybe \"Suggested Stores\"","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":5,"context_line":" http://creativecommons.org/licenses/by/3.0/legalcode"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":8,"context_line":"Download Image from Specific Store"},{"line_number":9,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"https://blueprints.launchpad.net/glance/+spec/download-from-specific-store"}],"source_content_type":"text/x-rst","patch_set":5,"id":"4256d857_fef4aadb","line":8,"range":{"start_line":8,"start_character":20,"end_line":8,"end_character":34},"in_reply_to":"5426c493_1efca119","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":13,"context_line":"Right now when you download an image using GET /v2/images/{image_id}/file,"},{"line_number":14,"context_line":"Glance tries the default store first. If the image is not there, it tries"},{"line_number":15,"context_line":"other stores until it finds the image. This spec adds a way to tell Glance"},{"line_number":16,"context_line":"which stores to use. You can give a list of stores you want to try. This"},{"line_number":17,"context_line":"helps compute nodes and services like Nova and Cinder download from stores"},{"line_number":18,"context_line":"that are close to them."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"c397af0b_6a5be802","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":66},"updated":"2025-12-01 15:51:08.000000000","message":"maybe \"what ordering to use to locate the image data for a particular request.\"","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":13,"context_line":"Right now when you download an image using GET /v2/images/{image_id}/file,"},{"line_number":14,"context_line":"Glance tries the default store first. If the image is not there, it tries"},{"line_number":15,"context_line":"other stores until it finds the image. This spec adds a way to tell Glance"},{"line_number":16,"context_line":"which stores to use. You can give a list of stores you want to try. This"},{"line_number":17,"context_line":"helps compute nodes and services like Nova and Cinder download from stores"},{"line_number":18,"context_line":"that are close to them."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"68478ca3_d6d53057","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":66},"in_reply_to":"c397af0b_6a5be802","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"Add new query parameters to the existing download endpoint. This lets services"},{"line_number":65,"context_line":"give a list of stores they prefer."},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"API call:"},{"line_number":68,"context_line":"GET /v2/images/{image_id}/file?stores\u003dstore1,store2"}],"source_content_type":"text/x-rst","patch_set":5,"id":"46c1268f_1c9b618a","line":65,"range":{"start_line":65,"start_character":0,"end_line":65,"end_character":34},"updated":"2025-12-01 15:51:08.000000000","message":"how about \"suggest the ordering of stores to try.\"","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"Add new query parameters to the existing download endpoint. This lets services"},{"line_number":65,"context_line":"give a list of stores they prefer."},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"API call:"},{"line_number":68,"context_line":"GET /v2/images/{image_id}/file?stores\u003dstore1,store2"}],"source_content_type":"text/x-rst","patch_set":5,"id":"d4950131_00a1b18e","line":65,"range":{"start_line":65,"start_character":0,"end_line":65,"end_character":34},"in_reply_to":"46c1268f_1c9b618a","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":68,"context_line":"GET /v2/images/{image_id}/file?stores\u003dstore1,store2"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"How it works:"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"1. Check if the stores in the list exist and are configured"},{"line_number":73,"context_line":"2. Check if the image is in any of the listed stores"},{"line_number":74,"context_line":"3. Download from the first matching store in the list"}],"source_content_type":"text/x-rst","patch_set":5,"id":"6fd9b8ac_4bf3a057","line":71,"updated":"2025-12-01 15:51:08.000000000","message":"I suggest adding\n\n0. If caching is enabled, and the image is cached, the \u0027stores\u0027 parameter is ignored and the data is returned.","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":68,"context_line":"GET /v2/images/{image_id}/file?stores\u003dstore1,store2"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"How it works:"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"1. Check if the stores in the list exist and are configured"},{"line_number":73,"context_line":"2. Check if the image is in any of the listed stores"},{"line_number":74,"context_line":"3. Download from the first matching store in the list"}],"source_content_type":"text/x-rst","patch_set":5,"id":"f62b4709_bade5ca9","line":71,"in_reply_to":"6fd9b8ac_4bf3a057","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":70,"context_line":"How it works:"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"1. Check if the stores in the list exist and are configured"},{"line_number":73,"context_line":"2. Check if the image is in any of the listed stores"},{"line_number":74,"context_line":"3. Download from the first matching store in the list"},{"line_number":75,"context_line":"4. If image is not found in any of the listed stores, fall back to default behavior (try all stores)"},{"line_number":76,"context_line":"5. Return errors if store does not exist"}],"source_content_type":"text/x-rst","patch_set":5,"id":"531c567e_b7091463","line":73,"updated":"2025-12-01 15:51:08.000000000","message":"I don\u0027t think we do #2 any more?  If the image isn\u0027t in any of these, then we will get it out of the default store, right?","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":70,"context_line":"How it works:"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"1. Check if the stores in the list exist and are configured"},{"line_number":73,"context_line":"2. Check if the image is in any of the listed stores"},{"line_number":74,"context_line":"3. Download from the first matching store in the list"},{"line_number":75,"context_line":"4. If image is not found in any of the listed stores, fall back to default behavior (try all stores)"},{"line_number":76,"context_line":"5. Return errors if store does not exist"}],"source_content_type":"text/x-rst","patch_set":5,"id":"236f0dac_82024a08","line":73,"in_reply_to":"531c567e_b7091463","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":73,"context_line":"2. Check if the image is in any of the listed stores"},{"line_number":74,"context_line":"3. Download from the first matching store in the list"},{"line_number":75,"context_line":"4. If image is not found in any of the listed stores, fall back to default behavior (try all stores)"},{"line_number":76,"context_line":"5. Return errors if store does not exist"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"This approach is better than a new endpoint because:"},{"line_number":79,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"44fb77da_7d2bcf7f","line":76,"range":{"start_line":76,"start_character":0,"end_line":76,"end_character":40},"updated":"2025-12-01 15:51:08.000000000","message":"Didn\u0027t we already catch this situation in step #1? (I may be missing something)","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":73,"context_line":"2. Check if the image is in any of the listed stores"},{"line_number":74,"context_line":"3. Download from the first matching store in the list"},{"line_number":75,"context_line":"4. If image is not found in any of the listed stores, fall back to default behavior (try all stores)"},{"line_number":76,"context_line":"5. Return errors if store does not exist"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"This approach is better than a new endpoint because:"},{"line_number":79,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"bcf4084b_e31deb15","line":76,"range":{"start_line":76,"start_character":0,"end_line":76,"end_character":40},"in_reply_to":"44fb77da_7d2bcf7f","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":90,"context_line":"   HTTP 200 regardless of store parameters, and store selection validation (400"},{"line_number":91,"context_line":"   errors for invalid stores) will not occur for cached images."},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Policy for store selection:"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"A new policy rule \"download_from_store\" will be added to control who can use"},{"line_number":96,"context_line":"store selection parameters. The default policy will allow anyone who can"}],"source_content_type":"text/x-rst","patch_set":5,"id":"a356e823_932f7760","line":93,"range":{"start_line":93,"start_character":17,"end_line":93,"end_character":26},"updated":"2025-12-01 15:51:08.000000000","message":"s/selection/suggestion/ here and where appropriate in the next paragraph","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":90,"context_line":"   HTTP 200 regardless of store parameters, and store selection validation (400"},{"line_number":91,"context_line":"   errors for invalid stores) will not occur for cached images."},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"Policy for store selection:"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"A new policy rule \"download_from_store\" will be added to control who can use"},{"line_number":96,"context_line":"store selection parameters. The default policy will allow anyone who can"}],"source_content_type":"text/x-rst","patch_set":5,"id":"e44b18ec_d59bc545","line":93,"range":{"start_line":93,"start_character":17,"end_line":93,"end_character":26},"in_reply_to":"a356e823_932f7760","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":134,"context_line":"Response codes:"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"* 200 OK: Image downloaded"},{"line_number":137,"context_line":"* 400 Bad Request: Invalid store name or bad parameters"},{"line_number":138,"context_line":"* 403 Forbidden: User does not have permission to use this feature"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"Examples:"}],"source_content_type":"text/x-rst","patch_set":5,"id":"16ca02b6_a295eb62","line":137,"updated":"2025-12-01 15:51:08.000000000","message":"Well, you could still get a 404 (no difference from the current download API)","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":134,"context_line":"Response codes:"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"* 200 OK: Image downloaded"},{"line_number":137,"context_line":"* 400 Bad Request: Invalid store name or bad parameters"},{"line_number":138,"context_line":"* 403 Forbidden: User does not have permission to use this feature"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"Examples:"}],"source_content_type":"text/x-rst","patch_set":5,"id":"86e1f260_de5e19c2","line":137,"in_reply_to":"16ca02b6_a295eb62","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":139,"context_line":""},{"line_number":140,"context_line":"Examples:"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"Download from specific stores:"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"  curl -H \"X-Auth-Token: $TOKEN\" \\"},{"line_number":145,"context_line":"    \"http://glance-api:9292/v2/images/{image_id}/file?stores\u003dlocal-store,backup-store\""}],"source_content_type":"text/x-rst","patch_set":5,"id":"c047e86f_93f1a066","line":142,"range":{"start_line":142,"start_character":14,"end_line":142,"end_character":22},"updated":"2025-12-01 15:51:08.000000000","message":"suggested","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":139,"context_line":""},{"line_number":140,"context_line":"Examples:"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"Download from specific stores:"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"  curl -H \"X-Auth-Token: $TOKEN\" \\"},{"line_number":145,"context_line":"    \"http://glance-api:9292/v2/images/{image_id}/file?stores\u003dlocal-store,backup-store\""}],"source_content_type":"text/x-rst","patch_set":5,"id":"a4322ac4_e160befb","line":142,"range":{"start_line":142,"start_character":14,"end_line":142,"end_character":22},"in_reply_to":"c047e86f_93f1a066","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"236e47d5ee61c25ee1b393657921b7f78c264acd","unresolved":true,"context_lines":[{"line_number":283,"context_line":"References"},{"line_number":284,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"None"}],"source_content_type":"text/x-rst","patch_set":5,"id":"cf12499d_1eaaf59d","line":286,"updated":"2025-12-01 15:51:08.000000000","message":"Would be good to include either Dan\u0027s spec [0] or implementation [1] of the store weight stuff.\n\n[0] https://specs.openstack.org/openstack/glance-specs/specs/2023.2/approved/glance_store/store-weight.html\n[1] https://review.opendev.org/c/openstack/glance_store/+/885595","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"97517cbb96981f20e1b5128a53a68270e10b3f1f","unresolved":false,"context_lines":[{"line_number":283,"context_line":"References"},{"line_number":284,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"None"}],"source_content_type":"text/x-rst","patch_set":5,"id":"e4cef573_36ea54e1","line":286,"in_reply_to":"cf12499d_1eaaf59d","updated":"2025-12-02 09:34:48.000000000","message":"Done","commit_id":"7a723233bb79d1db0af4fed5366178930e55764f"}]}
