)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9976,"name":"Ronelle Landy","email":"rlandy@redhat.com","username":"rlandy"},"change_message_id":"4d730fa0a77d18c7f178ff53e0927b4a18a8c1d7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"95b32b3e_ad099d19","updated":"2026-06-24 12:35:54.000000000","message":"reviewing code and full test run","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":9976,"name":"Ronelle Landy","email":"rlandy@redhat.com","username":"rlandy"},"change_message_id":"8d7cf650b7c8407a0f520fcc67ff130727bd5aa3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"266ee020_aebc3b06","updated":"2026-06-25 07:08:36.000000000","message":"After talking with Chandan - will cut this change down to just the V1 removal and resubmit","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"159e465131b1ba709b04f1ff5b6cee5dc3b3239c","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":2,"id":"089c8b4a_a3712f67","updated":"2026-06-24 15:40:11.000000000","message":"this si not moving the the correct direction\n\nwe do not want this to be self contained we want it to use the sdk\n\nthe goal for this cycle was to remove the dead code (v1 api), freeze freestanding  cyborg client cli and then next cycle either port the osc plugin ito osc or delete all code form this repo that is not the osc plugin.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/osc/plugin.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"DEFAULT_ACCELERATOR_API_VERSION \u003d \u00272.3\u0027"},{"line_number":25,"context_line":"API_VERSION_OPTION \u003d \u0027os_accelerator_api_version\u0027"},{"line_number":26,"context_line":"API_NAME \u003d \u0027accelerator\u0027"},{"line_number":27,"context_line":"CURRENT_API_VERSION \u003d \u00272\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"79a9615d_d87e47f9","line":24,"updated":"2026-06-24 13:39:34.000000000","message":"DEFAULT_ACCELERATOR_API_VERSION is set to \u00272.3\u0027 but CURRENT_API_VERSION is \u00272\u0027 and the AcceleratorProxy version parameter also defaults to \u00272\u0027, creating a version string inconsistency\n\n**Severity**: WARNING | **Confidence**: 0.7\n\n**Impact**: Users may pass --os-accelerator-api-version 2.3 but the client always creates a version\u003d\u00272\u0027 adapter, ignoring the microversion. API features requiring version 2.1+ (like project_id binding) may not be requested correctly.\n\n**Suggestion**:\nPass the parsed API version from instance._api_version to AcceleratorProxy instead of hardcoding CURRENT_API_VERSION. This ensures the adapter uses the correct microversion when the user specifies one.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"159e465131b1ba709b04f1ff5b6cee5dc3b3239c","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"DEFAULT_ACCELERATOR_API_VERSION \u003d \u00272.3\u0027"},{"line_number":25,"context_line":"API_VERSION_OPTION \u003d \u0027os_accelerator_api_version\u0027"},{"line_number":26,"context_line":"API_NAME \u003d \u0027accelerator\u0027"},{"line_number":27,"context_line":"CURRENT_API_VERSION \u003d \u00272\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"532bae4b_c4169d11","line":24,"in_reply_to":"79a9615d_d87e47f9","updated":"2026-06-24 15:40:11.000000000","message":"DEFAULT_ACCELERATOR_API_VERSION proably shoudl be \n\nMAX_ACCELERATOR_API_VERSION\nand\nCURRENT_API_VERSION \u003d \u00272\u0027\nshould likely be \nCURRENT_MAJOR_API_VERSION \u003d \u00272\u0027\n\nbut that could be doen in a followup\n\ni think next cycel we are going to eol this deliverabel adn work to fully upstream the cybrog supprot directly into osc but doing this cleanup now is still valueable","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/osc/v2/accelerator_request.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":275,"context_line":"            properties.extend(utils.args_array_to_patch(\u0027add\u0027, device_rp_uuid))"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        if properties:"},{"line_number":278,"context_line":"            acc_client.update_accelerator_request("},{"line_number":279,"context_line":"                parsed_args.accelerator_request, properties)"},{"line_number":280,"context_line":"            return _show_accelerator_request(acc_client,"},{"line_number":281,"context_line":"                                             parsed_args.accelerator_request)"}],"source_content_type":"text/x-python","patch_set":2,"id":"00509b2a_adb9bd0d","line":278,"updated":"2026-06-24 13:39:34.000000000","message":"OSC bind/unbind accelerator request commands pass a JSON patch list as **attrs to update_accelerator_request, but the proxy method forwards it as JSON body directly, mismatching the old openstacksdk proxy semantics\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: The \u0027openstack accelerator arq bind\u0027 and \u0027arq unbind\u0027 commands may send incorrect request bodies to the API, causing bind/unbind operations to fail\n\n**Priority**: Before merge\n**Why This Matters**: BindAcceleratorRequest builds a JSON patch list via args_array_to_patch and calls update_accelerator_request(uuid, properties). AcceleratorProxy forwards attrs as a plain JSON body. The Cyborg API expects a JSON patch array format for ARQ updates, which may not match what the proxy sends.\n\n**Recommendation**:\nVerify the Cyborg v2 API expects the JSON patch array format. If so, update_accelerator_request should pass the list as the json body. If the API expects key-value pairs, the OSC modules need to be updated to match.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"159e465131b1ba709b04f1ff5b6cee5dc3b3239c","unresolved":true,"context_lines":[{"line_number":275,"context_line":"            properties.extend(utils.args_array_to_patch(\u0027add\u0027, device_rp_uuid))"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        if properties:"},{"line_number":278,"context_line":"            acc_client.update_accelerator_request("},{"line_number":279,"context_line":"                parsed_args.accelerator_request, properties)"},{"line_number":280,"context_line":"            return _show_accelerator_request(acc_client,"},{"line_number":281,"context_line":"                                             parsed_args.accelerator_request)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ae964b52_ce8e50b7","line":278,"in_reply_to":"00509b2a_adb9bd0d","updated":"2026-06-24 15:40:11.000000000","message":"yes... os i was talking to stephen baout the sdk and i belive htey hack around this internally\n\nit was a painpoint that i was hoping to adres by changing hte cyborg api next cycle to use put with a json body and remove patch entrily.\n\nhttps://github.com/openstack/openstacksdk/blob/3913e1b4734487359bc5aefe2ab71191d2ada949/openstack/accelerator/v2/accelerator_request.py#L56-L118\n\nwhenever the sdk need to provide overeid function like that it means that the service api is not conforming to the normal openstack patterns\n\ni have not fully traced though the code to confirm its comments but we shoudl validate this","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/osc/v2/attribute.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"159e465131b1ba709b04f1ff5b6cee5dc3b3239c","unresolved":true,"context_lines":[{"line_number":129,"context_line":"            try:"},{"line_number":130,"context_line":"                acc_client.delete_attribute(uuid, False)"},{"line_number":131,"context_line":"                print(_(\u0027Deleted attribute %s\u0027) % uuid)"},{"line_number":132,"context_line":"            except exc.ResourceNotFound:"},{"line_number":133,"context_line":"                raise exc.CommandError(_(\u0027Attribute %s not found\u0027) % uuid)"},{"line_number":134,"context_line":"            except exc.ClientException as e:"},{"line_number":135,"context_line":"                failures.append(_(\"Failed to delete attribute \\"}],"source_content_type":"text/x-python","patch_set":2,"id":"0553f8a0_e63add33","line":132,"range":{"start_line":132,"start_character":19,"end_line":132,"end_character":40},"updated":"2026-06-24 15:40:11.000000000","message":"unless you are doing the convertion from the sdk ection in acc_client this does not look correct\n\nthese try except blocks are there to convert the sdk excption into our internal ones.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/osc/v2/deployable.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":157,"context_line":"        try:"},{"line_number":158,"context_line":"            image_client.get(image_uuid)"},{"line_number":159,"context_line":"        except exc.ResourceNotFound:"},{"line_number":160,"context_line":"            raise exc.CommandError(_(\u0027image not found: %s\u0027) % image_uuid)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"        program_info \u003d [{\u0027path\u0027: \u0027/program\u0027,"},{"line_number":163,"context_line":"                         \u0027value\u0027: [{\u0027image_uuid\u0027: image_uuid}],"}],"source_content_type":"text/x-python","patch_set":1,"id":"3495db0e_7191ab49","line":160,"updated":"2026-06-24 12:54:24.000000000","message":"deployable.py:160 catches exc.ResourceNotFound (cyborgclient exception) for image_client.get(image_uuid), but image_client is the openstacksdk glance proxy (self.app.client_manager.image) which raises openstack.exceptions.ResourceNotFound — a different class. The except clause will never match.\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: When the image UUID does not exist, the \u0027openstack accelerator deployable program\u0027 command crashes with an unhandled openstacksdk exception instead of the friendly \u0027image not found\u0027 error.\n\n**Priority**: Before merge\n**Why This Matters**: This is a behavioral regression: the old code caught sdk_exc.ResourceNotFound which correctly matched the glance proxy exception. The migration to exc.ResourceNotFound broke this because the glance proxy still raises openstacksdk exceptions.\n\n**Recommendation**:\nCatch both exception types for the image client call. Since the image client is provided by openstacksdk via OSC, import openstack.exceptions for this specific catch, or restructure to validate the image UUID differently.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        \u0027data\u0027: utils.json_formatter,"},{"line_number":119,"context_line":"    }"},{"line_number":120,"context_line":"    data \u003d deployable.to_dict()"},{"line_number":121,"context_line":"    data[\u0027uuid\u0027] \u003d data.pop(\u0027id\u0027, uuid)"},{"line_number":122,"context_line":"    return columns, oscutils.get_dict_properties(data, columns,"},{"line_number":123,"context_line":"                                                 formatters\u003dformatters)"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"f62a5ac7_34b8a5ac","line":121,"updated":"2026-06-24 13:39:34.000000000","message":"Deployable list columns mismatch: column_headers use \u0027uuid\u0027 but columns map to \u0027id\u0027 field, and the ShowDeployable function manually renames id to uuid via data.pop, indicating inconsistent API field naming\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: If the Cyborg API returns \u0027uuid\u0027 directly in newer versions, the manual rename will use the fallback uuid parameter instead of the actual value, showing incorrect data\n\n**Suggestion**:\nVerify the Cyborg v2 API returns \u0027id\u0027 for deployables. If it now returns \u0027uuid\u0027, remove the data.pop(\u0027id\u0027, uuid) workaround and update the columns mapping. This was likely inherited from the openstacksdk proxy which handled field mapping differently.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":162,"context_line":"        program_info \u003d [{\u0027path\u0027: \u0027/program\u0027,"},{"line_number":163,"context_line":"                         \u0027value\u0027: [{\u0027image_uuid\u0027: image_uuid}],"},{"line_number":164,"context_line":"                         \u0027op\u0027: \u0027replace\u0027}]"},{"line_number":165,"context_line":"        acc_client.program(dep_uuid, program_info)"},{"line_number":166,"context_line":"        return _show_deployable(acc_client, dep_uuid)"}],"source_content_type":"text/x-python","patch_set":2,"id":"d15e17e8_5eae30cb","line":165,"updated":"2026-06-24 13:39:34.000000000","message":"OSC deployable program() call passes a JSON patch list as the second argument, but AcceleratorProxy.program() expects an image_uuid string, causing incorrect API request payload and likely API failure\n\n**Severity**: CRITICAL | **Confidence**: 0.9\n\n**Risk**: The \u0027openstack accelerator deployable program\u0027 command will send malformed data to the Cyborg API, causing a 400 Bad Request or unexpected behavior\n\n**Priority**: Immediate\n**Why This Matters**: deployable.py:165 calls program(dep_uuid, program_info) where program_info is a JSON patch list. But AcceleratorProxy.program() sends {\u0027image_uuid\u0027: image_uuid} as a simple PATCH body. The old openstacksdk proxy accepted the raw patch body; the new proxy wraps it differently, breaking the command.\n\n**Recommendation**:\nUpdate AcceleratorProxy.program() to accept and forward the raw JSON patch body, or change the OSC deployable module to extract image_uuid from program_info and pass it directly to the new signature. The method semantics must match how callers use it.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/osc/v2/device_profile.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    def take_action(self, parsed_args):"},{"line_number":57,"context_line":"        acc_client \u003d self.app.client_manager.accelerator"},{"line_number":58,"context_line":"        if parsed_args.detail:"},{"line_number":59,"context_line":"            self.column_headers +\u003d self.detail_cols"},{"line_number":60,"context_line":"            self.columns +\u003d self.detail_cols"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        data \u003d acc_client.device_profiles()"}],"source_content_type":"text/x-python","patch_set":2,"id":"d36552b2_9bec4cee","line":59,"updated":"2026-06-24 13:39:34.000000000","message":"ListDeviceProfile and ListAttribute mutate class-level column_headers and columns attributes in take_action via +\u003d, which persists state across invocations in long-running processes\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Using instance-local copies prevents --long detail columns from accumulating across multiple calls in the same process, which matters for programmatic use or test runs\n\n**Recommendation**:\nChange self.column_headers +\u003d to create local variables instead of mutating class attributes. For example: local_headers \u003d self.column_headers + self.detail_cols when detail is set.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":101,"context_line":"            \u0027description\u0027: parsed_args.description"},{"line_number":102,"context_line":"        }"},{"line_number":103,"context_line":"        device_profile \u003d acc_client.create_device_profile(**attrs)"},{"line_number":104,"context_line":"        return _show_device_profile(acc_client, device_profile.uuid)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"class DeleteDeviceProfile(command.Command):"}],"source_content_type":"text/x-python","patch_set":2,"id":"933aaf18_012ece7e","line":104,"updated":"2026-06-24 13:39:34.000000000","message":"CreateDeviceProfile passes device_profile.uuid to _show_device_profile, but the AcceleratorProxy.create_device_profile returns a DeviceProfile resource that may not have a uuid attribute if the API response uses a different key\n\n**Severity**: WARNING | **Confidence**: 0.7\n\n**Impact**: If the API response field names don\u0027t match expectations, the create command will fail with AttributeError when trying to access .uuid on the returned resource\n\n**Suggestion**:\nVerify that the Cyborg v2 API \u0027POST /device_profiles\u0027 response includes a \u0027uuid\u0027 field. Since the Resource base class uses setattr from data keys, .uuid will only exist if the API returns it. Add a fallback or verify against the API spec.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        failures \u003d []"},{"line_number":129,"context_line":"        for uuid in parsed_args.device_profiles:"},{"line_number":130,"context_line":"            try:"},{"line_number":131,"context_line":"                acc_client.delete_device_profile(uuid, False)"},{"line_number":132,"context_line":"                print(_(\u0027Deleted device_profile %s\u0027) % uuid)"},{"line_number":133,"context_line":"            except exc.ResourceNotFound:"},{"line_number":134,"context_line":"                raise exc.CommandError(_(\u0027device_profile %s not found\u0027) % uuid)"}],"source_content_type":"text/x-python","patch_set":2,"id":"e522c7c4_5251c9c9","line":131,"updated":"2026-06-24 13:39:34.000000000","message":"OSC delete commands call AcceleratorProxy delete methods with a second positional argument (False) that the proxy methods do not accept, causing TypeError at runtime for delete device_profile, attribute, and accelerator_request\n\n**Severity**: CRITICAL | **Confidence**: 1.0\n\n**Risk**: All \u0027openstack accelerator device profile delete\u0027, \u0027accelerator device attribute delete\u0027, and \u0027accelerator arq delete\u0027 commands will crash with TypeError instead of deleting resources\n\n**Priority**: Immediate\n**Why This Matters**: User-facing runtime failure. The old openstacksdk proxy accepted an ignore_missing boolean; the new AcceleratorProxy delete methods take only one arg. Calling delete_device_profile(uuid, False) raises TypeError. Same issue in attribute.py:130 and accelerator_request.py:159.\n\n**Recommendation**:\nEither add an ignore_missing\u003dFalse parameter to AcceleratorProxy delete methods (matching the old openstacksdk signature), or remove the extra \u0027False\u0027 argument from the three OSC call sites: device_profile.py:131, attribute.py:130, accelerator_request.py:159.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":178,"context_line":"    except exc.ResourceNotFound:"},{"line_number":179,"context_line":"        raise exc.CommandError(_(\u0027device_profile %s not found\u0027) % name_or_uuid)"},{"line_number":180,"context_line":"    except exc.HttpException as e:"},{"line_number":181,"context_line":"        raise exc.NotAcceptable(message\u003de.details)"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    formatters \u003d {\u0027data\u0027: utils.json_formatter}"},{"line_number":184,"context_line":"    data \u003d device_profile.to_dict()"}],"source_content_type":"text/x-python","patch_set":2,"id":"f8063f50_70931d8e","line":181,"updated":"2026-06-24 13:39:34.000000000","message":"HttpException class added in exceptions.py lacks a \u0027details\u0027 attribute, but OSC modules device_profile.py and attribute.py access e.details, causing AttributeError when HTTP errors are caught\n\n**Severity**: CRITICAL | **Confidence**: 0.9\n\n**Risk**: When the Cyborg API returns an HTTP error (e.g., API version too low), the exception handler will crash with AttributeError instead of showing the error message to the user\n\n**Priority**: Immediate\n**Why This Matters**: device_profile.py:181 and attribute.py:178 access e.details on exc.HttpException. The new HttpException.__init__ only sets http_status and response -- no details attribute. The old openstacksdk HttpException had details. This causes unhandled AttributeError at runtime.\n\n**Recommendation**:\nAdd a \u0027details\u0027 parameter to HttpException.__init__ and store it as self.details, or change the OSC code to use an existing attribute like str(e) or e.http_status instead of e.details.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/tests/unit/osc/v2/test_deployable.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"4198f0dc2bdec9a92e3e221e1a5ba232a95568fa","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from cyborgclient import exceptions as exc"},{"line_number":18,"context_line":"from cyborgclient.osc.v2 import deployable as osc_deployable"},{"line_number":19,"context_line":"from cyborgclient.tests.unit.osc.v2 import fakes as acc_fakes"},{"line_number":20,"context_line":"from cyborgclient import exceptions as sdk_exc"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestDeployable(acc_fakes.TestAccelerator):"}],"source_content_type":"text/x-python","patch_set":1,"id":"f52958eb_1dadaba6","line":20,"updated":"2026-06-24 12:45:18.000000000","message":"pep8: H306: imports not in alphabetical order (cyborgclient.tests.unit.osc.v2.fakes, cyborgclient.exceptions)","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"77adad0948147adf03ed851e2955578caa549fd3","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from cyborgclient import exceptions as exc"},{"line_number":18,"context_line":"from cyborgclient.osc.v2 import deployable as osc_deployable"},{"line_number":19,"context_line":"from cyborgclient.tests.unit.osc.v2 import fakes as acc_fakes"},{"line_number":20,"context_line":"from cyborgclient import exceptions as sdk_exc"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestDeployable(acc_fakes.TestAccelerator):"}],"source_content_type":"text/x-python","patch_set":2,"id":"dcdf4ce1_82bb1a4c","line":20,"updated":"2026-06-24 13:16:31.000000000","message":"pep8: H306: imports not in alphabetical order (cyborgclient.tests.unit.osc.v2.fakes, cyborgclient.exceptions)","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/tests/unit/osc/v2/test_device.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"4198f0dc2bdec9a92e3e221e1a5ba232a95568fa","unresolved":false,"context_lines":[{"line_number":16,"context_line":"from cyborgclient import exceptions as exc"},{"line_number":17,"context_line":"from cyborgclient.osc.v2 import device as osc_device"},{"line_number":18,"context_line":"from cyborgclient.tests.unit.osc.v2 import fakes as acc_fakes"},{"line_number":19,"context_line":"from cyborgclient import exceptions as sdk_exc"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class TestDevice(acc_fakes.TestAccelerator):"}],"source_content_type":"text/x-python","patch_set":1,"id":"e11c5ff8_0c83ba40","line":19,"updated":"2026-06-24 12:45:18.000000000","message":"pep8: H306: imports not in alphabetical order (cyborgclient.tests.unit.osc.v2.fakes, cyborgclient.exceptions)","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"77adad0948147adf03ed851e2955578caa549fd3","unresolved":false,"context_lines":[{"line_number":16,"context_line":"from cyborgclient import exceptions as exc"},{"line_number":17,"context_line":"from cyborgclient.osc.v2 import device as osc_device"},{"line_number":18,"context_line":"from cyborgclient.tests.unit.osc.v2 import fakes as acc_fakes"},{"line_number":19,"context_line":"from cyborgclient import exceptions as sdk_exc"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class TestDevice(acc_fakes.TestAccelerator):"}],"source_content_type":"text/x-python","patch_set":2,"id":"b6726c9a_84733ee6","line":19,"updated":"2026-06-24 13:16:31.000000000","message":"pep8: H306: imports not in alphabetical order (cyborgclient.tests.unit.osc.v2.fakes, cyborgclient.exceptions)","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/v2/__init__.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"159e465131b1ba709b04f1ff5b6cee5dc3b3239c","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":2,"id":"25d1d6e3_77f8ffa2","line":16,"range":{"start_line":1,"start_character":18,"end_line":16,"end_character":1},"updated":"2026-06-24 15:40:11.000000000","message":"this shoudl ideally be empty\n\nwe only do explict export for backward compatiblity or if forced to for typeing reasons \n\nby convetion we do not do that","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/v2/client.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"\"\"\"Cyborg v2 Accelerator Proxy Client.\"\"\""},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import json"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystoneauth1 import adapter"},{"line_number":18,"context_line":"from keystoneauth1 import exceptions as ksa_exc"}],"source_content_type":"text/x-python","patch_set":1,"id":"4ebb2492_587bc630","line":15,"updated":"2026-06-24 12:54:24.000000000","message":"Both \u0027import json\u0027 (line 15) and \u0027from oslo_serialization import jsonutils\u0027 (line 19) are unused in client.py. Neither module is referenced anywhere in the file body.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Unused imports trigger F401 flake8/hacking failures in OpenStack CI pep8 checks, which will block the patch from merging.\n\n**Suggestion**:\nRemove both \u0027import json\u0027 and \u0027from oslo_serialization import jsonutils\u0027 from cyborgclient/v2/client.py since neither is used.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"4198f0dc2bdec9a92e3e221e1a5ba232a95568fa","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"\"\"\"Cyborg v2 Accelerator Proxy Client.\"\"\""},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import json"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystoneauth1 import adapter"},{"line_number":18,"context_line":"from keystoneauth1 import exceptions as ksa_exc"}],"source_content_type":"text/x-python","patch_set":1,"id":"1213ac0e_795efc1b","line":15,"updated":"2026-06-24 12:45:18.000000000","message":"pep8: F401 \u0027json\u0027 imported but unused","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"4198f0dc2bdec9a92e3e221e1a5ba232a95568fa","unresolved":false,"context_lines":[{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystoneauth1 import adapter"},{"line_number":18,"context_line":"from keystoneauth1 import exceptions as ksa_exc"},{"line_number":19,"context_line":"from oslo_serialization import jsonutils"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from cyborgclient import exceptions as exc"},{"line_number":22,"context_line":"from cyborgclient.v2 import resource"}],"source_content_type":"text/x-python","patch_set":1,"id":"ac0a4077_a1cbca74","line":19,"updated":"2026-06-24 12:45:18.000000000","message":"pep8: F401 \u0027oslo_serialization.jsonutils\u0027 imported but unused","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from cyborgclient.v2 import resource"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class AcceleratorProxy(object):"},{"line_number":26,"context_line":"    \"\"\"Client for Cyborg v2 API."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    This replaces the openstacksdk accelerator proxy to make cyborgclient"}],"source_content_type":"text/x-python","patch_set":1,"id":"ab8cb95f_e0f3416b","line":25,"updated":"2026-06-24 12:54:24.000000000","message":"The test suite has no unit tests for the new AcceleratorProxy class in cyborgclient/v2/client.py. The 279-line client with 20+ methods is entirely untested at the proxy level.\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Benefit**: Direct tests for AcceleratorProxy would catch the method signature mismatches and error handling gaps identified in this review before they reach CI integration tests.\n\n**Recommendation**:\nAdd a test module (e.g. cyborgclient/tests/unit/v2/test_client.py) that mocks the adapter and tests each AcceleratorProxy method, including error paths via _handle_response. The existing OSC tests mock the client at a higher level and would not catch proxy-level bugs.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":57,"context_line":"            endpoint_override\u003dendpoint_override"},{"line_number":58,"context_line":"        )"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _handle_response(self, response):"},{"line_number":61,"context_line":"        \"\"\"Handle HTTP response and raise appropriate exceptions.\"\"\""},{"line_number":62,"context_line":"        try:"},{"line_number":63,"context_line":"            response.raise_for_status()"}],"source_content_type":"text/x-python","patch_set":1,"id":"c6796cf7_26a4ac8e","line":60,"updated":"2026-06-24 12:54:24.000000000","message":"_handle_response only catches ksa_exc.NotFound and ksa_exc.HttpError, but keystoneauth1 connection failures (ConnectFailure, ConnectTimeout, SSLError) are subclasses of ksa_exc.ClientException, not HttpError. These propagate as raw keystoneauth1 exceptions.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Connection errors surface as unhandled keystoneauth1 exceptions rather than cyborgclient ConnectionError, making error handling inconsistent for callers that catch cyborgclient exceptions.\n\n**Suggestion**:\nAdd a catch for ksa_exc.ClientException (or specific connection exceptions) in _handle_response and map them to exc.ConnectionError so all errors from the adapter are consistently wrapped.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"4198f0dc2bdec9a92e3e221e1a5ba232a95568fa","unresolved":false,"context_lines":[{"line_number":76,"context_line":"            return response.json()"},{"line_number":77,"context_line":"        return {}"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def _post(self, url, json\u003dNone, **kwargs):"},{"line_number":80,"context_line":"        \"\"\"Make a POST request.\"\"\""},{"line_number":81,"context_line":"        response \u003d self.adapter.post(url, json\u003djson, **kwargs)"},{"line_number":82,"context_line":"        self._handle_response(response)"}],"source_content_type":"text/x-python","patch_set":1,"id":"a7a5564c_29d9aaa1","line":79,"updated":"2026-06-24 12:45:18.000000000","message":"pep8: F811 redefinition of unused \u0027json\u0027 from line 15","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"4198f0dc2bdec9a92e3e221e1a5ba232a95568fa","unresolved":false,"context_lines":[{"line_number":84,"context_line":"            return response.json()"},{"line_number":85,"context_line":"        return {}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def _patch(self, url, json\u003dNone, **kwargs):"},{"line_number":88,"context_line":"        \"\"\"Make a PATCH request.\"\"\""},{"line_number":89,"context_line":"        response \u003d self.adapter.patch(url, json\u003djson, **kwargs)"},{"line_number":90,"context_line":"        self._handle_response(response)"}],"source_content_type":"text/x-python","patch_set":1,"id":"c163052d_0a1883b7","line":87,"updated":"2026-06-24 12:45:18.000000000","message":"pep8: F811 redefinition of unused \u0027json\u0027 from line 15","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":149,"context_line":"        data \u003d self._get(f\u0027/deployables/{deployable_uuid}\u0027)"},{"line_number":150,"context_line":"        return resource.Deployable(data)"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    def program(self, deployable_uuid, image_uuid):"},{"line_number":153,"context_line":"        \"\"\"Program a deployable with an image."},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        :param deployable_uuid: UUID of the deployable"}],"source_content_type":"text/x-python","patch_set":1,"id":"2a0598eb_c7b5839d","line":152,"updated":"2026-06-24 12:54:24.000000000","message":"program(self, deployable_uuid, image_uuid) wraps image_uuid as json\u003d{\u0027image_uuid\u0027: image_uuid}, but deployable.py:165 calls acc_client.program(dep_uuid, program_info) where program_info is a JSON patch list. The list is wrapped as {\u0027image_uuid\u0027: [list]} instead of being sent as the patch body.\n\n**Severity**: CRITICAL | **Confidence**: 0.9\n\n**Risk**: The \u0027openstack accelerator deployable program\u0027 command sends the wrong request body, causing the API call to fail or produce incorrect results.\n\n**Priority**: Before merge\n**Why This Matters**: The new program() method was written with an incompatible interface. The old openstacksdk proxy accepted the patch body directly. The new method must accept and forward the JSON patch operations.\n\n**Recommendation**:\nChange program() to accept the patch body directly: def program(self, deployable_uuid, patch_body): then data \u003d self._patch(f\u0027/deployables/{deployable_uuid}\u0027, json\u003dpatch_body). This matches how deployable.py:165 calls it.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":190,"context_line":"        data \u003d self._post(\u0027/device_profiles\u0027, json\u003dattrs)"},{"line_number":191,"context_line":"        return resource.DeviceProfile(data)"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"    def delete_device_profile(self, profile_uuid):"},{"line_number":194,"context_line":"        \"\"\"Delete a device profile."},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"        :param profile_uuid: UUID of the device profile"}],"source_content_type":"text/x-python","patch_set":1,"id":"64f75bea_594c3d70","line":193,"updated":"2026-06-24 12:54:24.000000000","message":"delete_device_profile(self, profile_uuid) accepts one positional arg, but device_profile.py:131 calls acc_client.delete_device_profile(uuid, False) with two. This raises TypeError at runtime for every \u0027openstack accelerator device profile delete\u0027 invocation.\n\n**Severity**: CRITICAL | **Confidence**: 0.9\n\n**Risk**: Every device profile delete CLI command fails immediately with TypeError instead of deleting the resource.\n\n**Priority**: Before merge\n**Why This Matters**: The new AcceleratorProxy method signature must match the existing OSC call sites. The openstacksdk proxy accepted (uuid, ignore_missing); the new proxy must replicate this or the call sites must be updated.\n\n**Recommendation**:\nUpdate delete_device_profile to accept an optional second parameter matching the existing call, e.g. def delete_device_profile(self, profile_uuid, ignore_missing\u003dTrue):, OR update device_profile.py:131 to call delete_device_profile(uuid) without the False argument.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        arqs_data \u003d data.get(\u0027arqs\u0027, [])"},{"line_number":227,"context_line":"        return [resource.AcceleratorRequest(a) for a in arqs_data]"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    def update_accelerator_request(self, arq_uuid, **attrs):"},{"line_number":230,"context_line":"        \"\"\"Update an accelerator request."},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        :param arq_uuid: UUID of the accelerator request"}],"source_content_type":"text/x-python","patch_set":1,"id":"89d7e208_95362d95","line":229,"updated":"2026-06-24 12:54:24.000000000","message":"update_accelerator_request(self, arq_uuid, **attrs) expects keyword arguments, but accelerator_request.py:278 and :311 call it as acc_client.update_accelerator_request(uuid, properties) where properties is a list passed as a positional arg, not as kwargs.\n\n**Severity**: CRITICAL | **Confidence**: 0.9\n\n**Risk**: Bind and unbind accelerator request commands send incorrect request bodies, causing API failures or silent data corruption.\n\n**Priority**: Before merge\n**Why This Matters**: The new method signature does not match the call sites. The OSC commands pass a JSON patch list as a positional argument, but the method expects keyword args and then wraps them as json\u003dattrs (a dict), not as the patch list.\n\n**Recommendation**:\nChange update_accelerator_request to accept the patch body as a positional parameter: def update_accelerator_request(self, arq_uuid, patch_body): then data \u003d self._patch(f\u0027/accelerator_requests/{arq_uuid}\u0027, json\u003dpatch_body).","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":236,"context_line":"        data \u003d self._patch(f\u0027/accelerator_requests/{arq_uuid}\u0027, json\u003dattrs)"},{"line_number":237,"context_line":"        return resource.AcceleratorRequest(data)"},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"    def delete_accelerator_request(self, arq_uuid):"},{"line_number":240,"context_line":"        \"\"\"Delete an accelerator request."},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"        :param arq_uuid: UUID of the accelerator request"}],"source_content_type":"text/x-python","patch_set":1,"id":"324d967a_b3ba85b8","line":239,"updated":"2026-06-24 12:54:24.000000000","message":"delete_accelerator_request(self, arq_uuid) accepts one positional arg, but accelerator_request.py:159 calls acc_client.delete_accelerator_request(uuid, False) with two. This raises TypeError at runtime for every accelerator request delete invocation.\n\n**Severity**: CRITICAL | **Confidence**: 0.9\n\n**Risk**: Every accelerator request delete CLI command fails immediately with TypeError.\n\n**Priority**: Before merge\n**Why This Matters**: The new AcceleratorProxy method signature must match the existing OSC call sites that pass (uuid, ignore_missing).\n\n**Recommendation**:\nUpdate delete_accelerator_request to accept an optional second parameter, e.g. def delete_accelerator_request(self, arq_uuid, ignore_missing\u003dTrue):, OR update accelerator_request.py:159 to call delete_accelerator_request(uuid) without the False argument.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ae73e288fcf58ab2fb2ff7e6271c6c70f05397b9","unresolved":false,"context_lines":[{"line_number":271,"context_line":"        data \u003d self._post(\u0027/attributes\u0027, json\u003dattrs)"},{"line_number":272,"context_line":"        return resource.Attribute(data)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"    def delete_attribute(self, attribute_uuid):"},{"line_number":275,"context_line":"        \"\"\"Delete an attribute."},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        :param attribute_uuid: UUID of the attribute"}],"source_content_type":"text/x-python","patch_set":1,"id":"13d17ec6_84c8575c","line":274,"updated":"2026-06-24 12:54:24.000000000","message":"delete_attribute(self, attribute_uuid) accepts one positional arg, but attribute.py:130 calls acc_client.delete_attribute(uuid, False) with two. This raises TypeError at runtime for every attribute delete invocation.\n\n**Severity**: CRITICAL | **Confidence**: 0.9\n\n**Risk**: Every attribute delete CLI command fails immediately with TypeError.\n\n**Priority**: Before merge\n**Why This Matters**: The new AcceleratorProxy method signature must match the existing OSC call sites that pass (uuid, ignore_missing).\n\n**Recommendation**:\nUpdate delete_attribute to accept an optional second parameter, e.g. def delete_attribute(self, attribute_uuid, ignore_missing\u003dTrue):, OR update attribute.py:130 to call delete_attribute(uuid) without the False argument.","commit_id":"8fbc0f3d5ea5adfe644f97c344cd6101634bea24"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"\"\"\"Cyborg v2 Accelerator Proxy Client.\"\"\""},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import json"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystoneauth1 import adapter"},{"line_number":18,"context_line":"from keystoneauth1 import exceptions as ksa_exc"}],"source_content_type":"text/x-python","patch_set":2,"id":"6054633e_2d5d61ac","line":15,"updated":"2026-06-24 13:39:34.000000000","message":"Unused imports in v2/client.py: \u0027import json\u0027 (line 15) and \u0027from oslo_serialization import jsonutils\u0027 (line 19) are never referenced in the module\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Dead imports create confusion for maintainers and will be flagged by flake8/hacking in CI, potentially blocking the gate\n\n**Suggestion**:\nRemove both \u0027import json\u0027 and \u0027from oslo_serialization import jsonutils\u0027 from cyborgclient/v2/client.py. The json keyword arguments are parameter names, not uses of the json module, and response.json() is a method call.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"77adad0948147adf03ed851e2955578caa549fd3","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"\"\"\"Cyborg v2 Accelerator Proxy Client.\"\"\""},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import json"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystoneauth1 import adapter"},{"line_number":18,"context_line":"from keystoneauth1 import exceptions as ksa_exc"}],"source_content_type":"text/x-python","patch_set":2,"id":"6b6950fc_cbe8ddf9","line":15,"updated":"2026-06-24 13:16:31.000000000","message":"pep8: F401 \u0027json\u0027 imported but unused","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"77adad0948147adf03ed851e2955578caa549fd3","unresolved":false,"context_lines":[{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystoneauth1 import adapter"},{"line_number":18,"context_line":"from keystoneauth1 import exceptions as ksa_exc"},{"line_number":19,"context_line":"from oslo_serialization import jsonutils"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from cyborgclient import exceptions as exc"},{"line_number":22,"context_line":"from cyborgclient.v2 import resource"}],"source_content_type":"text/x-python","patch_set":2,"id":"c8c8f6ea_203433a2","line":19,"updated":"2026-06-24 13:16:31.000000000","message":"pep8: F401 \u0027oslo_serialization.jsonutils\u0027 imported but unused","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"159e465131b1ba709b04f1ff5b6cee5dc3b3239c","unresolved":true,"context_lines":[{"line_number":25,"context_line":"class AcceleratorProxy(object):"},{"line_number":26,"context_line":"    \"\"\"Client for Cyborg v2 API."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    This replaces the openstacksdk accelerator proxy to make cyborgclient"},{"line_number":29,"context_line":"    self-contained."},{"line_number":30,"context_line":"    \"\"\""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    def __init__(self, session\u003dNone, service_type\u003d\u0027accelerator\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"266ef61c_7df2bb0f","line":29,"range":{"start_line":28,"start_character":0,"end_line":29,"end_character":19},"updated":"2026-06-24 15:40:11.000000000","message":"that is not a goal\n\nwe want to resue the sdk expclisviel for all api interaction.\n\ninfact in the next 6-12 months my hope is we entirly edn fo life this repo, and move all the current code into the openstack client directly.\n\nwe alrady agreed to feature freze the libary and start the deprecation and removal of it","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    def __init__(self, session\u003dNone, service_type\u003d\u0027accelerator\u0027,"},{"line_number":33,"context_line":"                 interface\u003d\u0027public\u0027, region_name\u003dNone, version\u003d\u00272\u0027,"},{"line_number":34,"context_line":"                 endpoint_override\u003dNone, **kwargs):"},{"line_number":35,"context_line":"        \"\"\"Initialize the Accelerator Proxy."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"        :param session: A keystoneauth1 session object"}],"source_content_type":"text/x-python","patch_set":2,"id":"2e45152c_64879850","line":34,"updated":"2026-06-24 13:39:34.000000000","message":"The AcceleratorProxy constructor accepts endpoint_override but never passes it to the OSC make_client function, and there is no way for users to set a custom endpoint override via CLI\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Adding endpoint_override support in make_client would enable testing against custom Cyborg API endpoints, useful for development and CI environments\n\n**Recommendation**:\nThis is acceptable for the initial implementation. Consider adding endpoint_override support to make_client in a follow-up, reading from instance._cli_options.config if present.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":57,"context_line":"            endpoint_override\u003dendpoint_override"},{"line_number":58,"context_line":"        )"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _handle_response(self, response):"},{"line_number":61,"context_line":"        \"\"\"Handle HTTP response and raise appropriate exceptions.\"\"\""},{"line_number":62,"context_line":"        try:"},{"line_number":63,"context_line":"            response.raise_for_status()"}],"source_content_type":"text/x-python","patch_set":2,"id":"76d2804d_ec3485ba","line":60,"updated":"2026-06-24 13:39:34.000000000","message":"_handle_response only catches NotFound and generic HttpError, missing specific HTTP error subclasses like Conflict, BadRequest, Unauthorized that keystoneauth1 raise_for_status may raise\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: Specific HTTP errors (400 Bad Request, 409 Conflict, 401 Unauthorized) will be re-raised as generic HttpException with potentially loss of error detail, degrading error handling quality\n\n**Priority**: Before merge\n**Why This Matters**: keystoneauth1 raise_for_status raises specific subclasses (BadRequest, Conflict, etc.). The current HttpError catch re-raises as generic exc.HttpException, losing the specific error type. OSC modules need consistent exception mapping to handle different HTTP error classes properly.\n\n**Recommendation**:\nMap specific ksa_exc subclasses to cyborgclient exceptions (e.g., BadRequest, Conflict). Also verify that ksa_exc.NotFound is what raise_for_status raises for 404 responses, since keystoneauth1 may raise ksa_exc.http.NotFound instead.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"77adad0948147adf03ed851e2955578caa549fd3","unresolved":false,"context_lines":[{"line_number":76,"context_line":"            return response.json()"},{"line_number":77,"context_line":"        return {}"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def _post(self, url, json\u003dNone, **kwargs):"},{"line_number":80,"context_line":"        \"\"\"Make a POST request.\"\"\""},{"line_number":81,"context_line":"        response \u003d self.adapter.post(url, json\u003djson, **kwargs)"},{"line_number":82,"context_line":"        self._handle_response(response)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a45f41a_7f8d6d83","line":79,"updated":"2026-06-24 13:16:31.000000000","message":"pep8: F811 redefinition of unused \u0027json\u0027 from line 15","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"77adad0948147adf03ed851e2955578caa549fd3","unresolved":false,"context_lines":[{"line_number":84,"context_line":"            return response.json()"},{"line_number":85,"context_line":"        return {}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def _patch(self, url, json\u003dNone, **kwargs):"},{"line_number":88,"context_line":"        \"\"\"Make a PATCH request.\"\"\""},{"line_number":89,"context_line":"        response \u003d self.adapter.patch(url, json\u003djson, **kwargs)"},{"line_number":90,"context_line":"        self._handle_response(response)"}],"source_content_type":"text/x-python","patch_set":2,"id":"28bff968_cc8ba928","line":87,"updated":"2026-06-24 13:16:31.000000000","message":"pep8: F811 redefinition of unused \u0027json\u0027 from line 15","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"cyborgclient/v2/resource.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":25,"context_line":"            setattr(self, key, value)"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    def to_dict(self):"},{"line_number":28,"context_line":"        \"\"\"Convert resource to dictionary.\"\"\""},{"line_number":29,"context_line":"        return self._data"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def __getitem__(self, key):"}],"source_content_type":"text/x-python","patch_set":2,"id":"b0a77327_56aa2ddc","line":28,"updated":"2026-06-24 13:39:34.000000000","message":"Resource.to_dict() returns the internal _data dict by reference, not a copy, allowing callers to accidentally mutate the resource\u0027s internal state\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: Callers that modify the dict returned by to_dict() will silently corrupt the resource object\u0027s data, potentially causing subtle bugs in OSC commands that process and display resource data\n\n**Priority**: Next sprint\n**Why This Matters**: Several OSC modules call resource.to_dict() and then modify the result (e.g., deployable.py:121 does data[\u0027uuid\u0027] \u003d data.pop(\u0027id\u0027, uuid)). Since to_dict() returns self._data directly, this mutation affects the original resource object, violating the principle of least surprise.\n\n**Recommendation**:\nReturn a copy of the dict: \u0027return dict(self._data)\u0027 or \u0027return self._data.copy()\u0027. This prevents accidental mutation of the resource\u0027s internal state.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"releasenotes/notes/drop-v1-api-c3a8b2d1e9f4a5b6.yaml":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"fa928bd8309d171948282ab15e05890457becf90","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    This includes the native \u0027cyborg\u0027 CLI command, v1 client library modules,"},{"line_number":6,"context_line":"    and legacy HTTP client code. Users should migrate to the v2 API using"},{"line_number":7,"context_line":"    OpenStack CLI commands (openstack accelerator *). The v1 API had a critical"},{"line_number":8,"context_line":"    Python 3.12+ incompatibility due to use of the removed ssl.wrap_socket()"},{"line_number":9,"context_line":"    function. Only the v2 API via OpenStack SDK is now supported."}],"source_content_type":"text/x-yaml","patch_set":2,"id":"8bbcc0e4_8f936631","line":8,"updated":"2026-06-24 13:39:34.000000000","message":"The release notes reference \u0027OpenStack SDK\u0027 for the v2 API path but the patch removes the openstacksdk dependency, creating a minor documentation inconsistency\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Correct release notes prevent user confusion about whether openstacksdk is still needed\n\n**Recommendation**:\nChange \u0027Only the v2 API via OpenStack SDK is now supported\u0027 to \u0027Only the v2 API via OpenStack CLI is now supported\u0027 since the SDK dependency has been removed and replaced with a self-contained proxy.","commit_id":"b984d500549f9f27e13e6d07ead96ac44a69d191"}],"setup.cfg":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cd551d36f8ccd225f329309377d901a9101cd92b","unresolved":true,"context_lines":[{"line_number":27,"context_line":"    cyborgclient"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"[entry_points]"},{"line_number":30,"context_line":"console_scripts \u003d"},{"line_number":31,"context_line":"    cyborg \u003d cyborgclient.shell:main"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"openstack.cli.extension \u003d"},{"line_number":34,"context_line":"    accelerator \u003d cyborgclient.osc.plugin"}],"source_content_type":"text/x-ttcn-cfg","patch_set":2,"id":"3611cb79_fd4558e1","side":"PARENT","line":31,"range":{"start_line":30,"start_character":0,"end_line":31,"end_character":36},"updated":"2026-06-24 15:53:49.000000000","message":"removing the shell entirly is something we coudl discuss or do early but i had planned to do that early next cycle so that we have a deprection release note for it.","commit_id":"745e927b8aa15096fd663a3a95b4b2f6faa7d9e4"}]}
