)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"c7d581caa4f81db30e88048f6aa76eb881d2963b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"e3d6d65b_a0e94600","updated":"2026-08-04 05:49:53.000000000","message":"recheck","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"a11486160d81473109d0c6650706e7c2a43aade5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"253df239_c6c89987","updated":"2026-08-06 06:50:52.000000000","message":"recheck","commit_id":"e017b31f620f40ab572561d7e1ebe0d21dbbaa02"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"736e5e73347e6175f63af74d2a6943429f18729d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"7d74299e_2f12afad","updated":"2026-08-06 07:07:11.000000000","message":"recheck","commit_id":"e017b31f620f40ab572561d7e1ebe0d21dbbaa02"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"5003a44f721b83b85038cde4809b6162255a7d60","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"31c78970_b117a7ed","updated":"2026-08-07 04:52:03.000000000","message":"recheck","commit_id":"9b4ef040548a553411dbfb85acda998945ded1f6"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"9e54b8754bc4a0a2174b5eb7ae46042b7bf8e183","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"caa2e53d_24b77aa8","updated":"2026-08-07 03:03:03.000000000","message":"recheck","commit_id":"9b4ef040548a553411dbfb85acda998945ded1f6"}],"api-ref/source/instances.inc":[{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":102,"context_line":"The database service can only be access within the tenant network, unless the"},{"line_number":103,"context_line":"``access`` parameter is defined."},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"If a configuration group is supplied for a ``mysql``, ``mariadb`` or"},{"line_number":106,"context_line":"``postgresql`` instance, Trove validates its values with the database engine"},{"line_number":107,"context_line":"before applying them. Instance creation is asynchronous. If validation fails,"},{"line_number":108,"context_line":"the instance enters the ``ERROR`` state and the ``fault`` information contains"}],"source_content_type":"text/x-c++src","patch_set":10,"id":"5c83c24a_9ae1327b","line":105,"updated":"2026-08-04 13:25:10.000000000","message":"I think we don\u0027t need a list of datastores here. Otherwise, we should maintain this list in the future; it\u0027s very complicated for documentation.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":102,"context_line":"The database service can only be access within the tenant network, unless the"},{"line_number":103,"context_line":"``access`` parameter is defined."},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"If a configuration group is supplied for a ``mysql``, ``mariadb`` or"},{"line_number":106,"context_line":"``postgresql`` instance, Trove validates its values with the database engine"},{"line_number":107,"context_line":"before applying them. Instance creation is asynchronous. If validation fails,"},{"line_number":108,"context_line":"the instance enters the ``ERROR`` state and the ``fault`` information contains"}],"source_content_type":"text/x-c++src","patch_set":10,"id":"09342718_a2ae2b6d","line":105,"in_reply_to":"5c83c24a_9ae1327b","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":332,"context_line":""},{"line_number":333,"context_line":"Attach a configuration group for an instance."},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"For ``mysql``, ``mariadb`` and ``postgresql`` instances, Trove validates the"},{"line_number":336,"context_line":"configuration group values with the database engine before applying them. If"},{"line_number":337,"context_line":"validation fails, Trove returns a ``422`` response and the instance continues"},{"line_number":338,"context_line":"to use its previous configuration."}],"source_content_type":"text/x-c++src","patch_set":10,"id":"6f85259a_737296a4","line":335,"updated":"2026-08-04 13:25:10.000000000","message":"Ditto","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":332,"context_line":""},{"line_number":333,"context_line":"Attach a configuration group for an instance."},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"For ``mysql``, ``mariadb`` and ``postgresql`` instances, Trove validates the"},{"line_number":336,"context_line":"configuration group values with the database engine before applying them. If"},{"line_number":337,"context_line":"validation fails, Trove returns a ``422`` response and the instance continues"},{"line_number":338,"context_line":"to use its previous configuration."}],"source_content_type":"text/x-c++src","patch_set":10,"id":"7449acc7_da0c2c13","line":335,"in_reply_to":"6f85259a_737296a4","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":337,"context_line":"validation fails, Trove returns a ``422`` response and the instance continues"},{"line_number":338,"context_line":"to use its previous configuration."},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"Configuration validation before attachment requires guest version ``1.3`` or"},{"line_number":341,"context_line":"later. If the guest does not support this version, Trove rejects the request."},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"Normal response codes: 202"}],"source_content_type":"text/x-c++src","patch_set":10,"id":"2fedbc20_337079a7","line":340,"updated":"2026-08-04 13:25:10.000000000","message":"IMO we don\u0027t need to specify this in the api-ref though. If control plane supports this feature, it may use it. If it\u0027s not, it\u0027s not.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":337,"context_line":"validation fails, Trove returns a ``422`` response and the instance continues"},{"line_number":338,"context_line":"to use its previous configuration."},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"Configuration validation before attachment requires guest version ``1.3`` or"},{"line_number":341,"context_line":"later. If the guest does not support this version, Trove rejects the request."},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"Normal response codes: 202"}],"source_content_type":"text/x-c++src","patch_set":10,"id":"f0c7ec88_45524058","line":340,"in_reply_to":"2fedbc20_337079a7","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":342,"context_line":""},{"line_number":343,"context_line":"Normal response codes: 202"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"Error response codes: badRequest(400), unprocessableEntity(422),"},{"line_number":346,"context_line":"internalServerError(500)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"Request"}],"source_content_type":"text/x-c++src","patch_set":10,"id":"44e9ce4e_fb948c65","line":345,"updated":"2026-08-04 13:25:10.000000000","message":"I don\u0027t see the definition of Error response codes anywhere in the api-ref. I think it\u0027s unnecessary; that means any code except 202 should be considered as a error.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":342,"context_line":""},{"line_number":343,"context_line":"Normal response codes: 202"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"Error response codes: badRequest(400), unprocessableEntity(422),"},{"line_number":346,"context_line":"internalServerError(500)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"Request"}],"source_content_type":"text/x-c++src","patch_set":10,"id":"26989dfe_2d4555ba","line":345,"in_reply_to":"44e9ce4e_fb948c65","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"releasenotes/notes/config-params-validation-7d2a3f9c0b1e5a48.yaml":[{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Configuration groups for ``mysql``, ``mariadb`` and ``postgresql`` are now"},{"line_number":5,"context_line":"    validated with the database engine before they are attached to an existing"},{"line_number":6,"context_line":"    instance or applied while creating a new instance. An invalid attach"},{"line_number":7,"context_line":"    request returns HTTP 422 and leaves the instance configuration unchanged."}],"source_content_type":"text/x-yaml","patch_set":10,"id":"f3d0c1a4_6a7ce29e","line":4,"updated":"2026-08-04 13:25:10.000000000","message":"ditto (I still have a hope to add KeyDB and Valkey in the current release 😄)","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Configuration groups for ``mysql``, ``mariadb`` and ``postgresql`` are now"},{"line_number":5,"context_line":"    validated with the database engine before they are attached to an existing"},{"line_number":6,"context_line":"    instance or applied while creating a new instance. An invalid attach"},{"line_number":7,"context_line":"    request returns HTTP 422 and leaves the instance configuration unchanged."}],"source_content_type":"text/x-yaml","patch_set":10,"id":"8aeca3e2_533eaea2","line":4,"in_reply_to":"f3d0c1a4_6a7ce29e","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"trove/guestagent/api.py":[{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":90,"context_line":"                              serializer\u003dserializer)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _call(self, method_name, timeout_sec, version,"},{"line_number":93,"context_line":"              remote_error_map\u003dNone, **kwargs):"},{"line_number":94,"context_line":"        LOG.debug(\"Calling %(name)s with timeout %(timeout)s\","},{"line_number":95,"context_line":"                  {\u0027name\u0027: method_name, \u0027timeout\u0027: timeout_sec})"},{"line_number":96,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"7c8dffc8_27eece8c","line":93,"updated":"2026-08-04 13:25:10.000000000","message":"Oh, I see what\u0027s going on here.\nWe\u0027re trying to use inside the Guest agent `trove.common.exceptions`, which are intended for the control plane only.\nThat\u0027s why we need to modify this `_call` method, and it looks wrong.\n\nIMO, if we decide to use common exceptions for both control plane and guest, we should do a big refactoring in a different task.\nLet\u0027s switch to a simple GuestError or TroveError, or BadRequest, and remove this unnecessary refactoring, please? )","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                              serializer\u003dserializer)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _call(self, method_name, timeout_sec, version,"},{"line_number":93,"context_line":"              remote_error_map\u003dNone, **kwargs):"},{"line_number":94,"context_line":"        LOG.debug(\"Calling %(name)s with timeout %(timeout)s\","},{"line_number":95,"context_line":"                  {\u0027name\u0027: method_name, \u0027timeout\u0027: timeout_sec})"},{"line_number":96,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"d5239aeb_8d7a6a39","line":93,"in_reply_to":"7c8dffc8_27eece8c","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"trove/guestagent/datastore/manager.py":[{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":444,"context_line":"    def validate_configuration(self, context, overrides):"},{"line_number":445,"context_line":"        \"\"\"Validate configuration without changing the live instance.\"\"\""},{"line_number":446,"context_line":"        LOG.info(\"Validating configuration overrides on instance.\")"},{"line_number":447,"context_line":"        self.app.validate_overrides("},{"line_number":448,"context_line":"            overrides, CONF.datastore_version)"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"    #################"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5cbb05_c30b0586","line":447,"updated":"2026-08-04 13:25:10.000000000","message":"We can check here that self.app supports the validation method and throw the DatastoreOperationNotSupported if it\u0027s not.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":444,"context_line":"    def validate_configuration(self, context, overrides):"},{"line_number":445,"context_line":"        \"\"\"Validate configuration without changing the live instance.\"\"\""},{"line_number":446,"context_line":"        LOG.info(\"Validating configuration overrides on instance.\")"},{"line_number":447,"context_line":"        self.app.validate_overrides("},{"line_number":448,"context_line":"            overrides, CONF.datastore_version)"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"    #################"}],"source_content_type":"text/x-python","patch_set":10,"id":"c5f6e7db_d87e7f35","line":447,"in_reply_to":"7a5cbb05_c30b0586","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"trove/guestagent/datastore/mysql_common/validator.py":[{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":27,"context_line":"class MySQLCommonValidator(Validator):"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def __init__(self, docker_client, uid, gid, datastore_manager):"},{"line_number":30,"context_line":"        super().__init__(docker_client)"},{"line_number":31,"context_line":"        self.uid \u003d uid"},{"line_number":32,"context_line":"        self.gid \u003d gid"},{"line_number":33,"context_line":"        self.datastore_manager \u003d datastore_manager"}],"source_content_type":"text/x-python","patch_set":10,"id":"98e30dbe_a76f887e","line":30,"updated":"2026-08-04 13:25:10.000000000","message":"Usually we do like this:\n`super(MySQLCommonValidator, self)`\nI\u0027m not sure if it\u0027s critical, though.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":27,"context_line":"class MySQLCommonValidator(Validator):"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def __init__(self, docker_client, uid, gid, datastore_manager):"},{"line_number":30,"context_line":"        super().__init__(docker_client)"},{"line_number":31,"context_line":"        self.uid \u003d uid"},{"line_number":32,"context_line":"        self.gid \u003d gid"},{"line_number":33,"context_line":"        self.datastore_manager \u003d datastore_manager"}],"source_content_type":"text/x-python","patch_set":10,"id":"81ebc3e9_da502699","line":30,"in_reply_to":"98e30dbe_a76f887e","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":33,"context_line":"        self.datastore_manager \u003d datastore_manager"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @property"},{"line_number":36,"context_line":"    def datastore_name(self):"},{"line_number":37,"context_line":"        return self.datastore_manager"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def prepare_candidate(self, work_dir, overrides):"}],"source_content_type":"text/x-python","patch_set":10,"id":"403173b9_e5dd968d","line":36,"updated":"2026-08-04 13:25:10.000000000","message":"This property is used in the parent `Validator` class, but in this class it\u0027s also referenced as `datastore_manager`, which imo isn\u0027t correct. Please replace `datastore_manager` with `datastore_name` in this class to eliminate ambiguity.\nProbably it\u0027s better to pass datastore_name into the parent\u0027s constructor and remove this property method definition here altogether.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        self.datastore_manager \u003d datastore_manager"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @property"},{"line_number":36,"context_line":"    def datastore_name(self):"},{"line_number":37,"context_line":"        return self.datastore_manager"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def prepare_candidate(self, work_dir, overrides):"}],"source_content_type":"text/x-python","patch_set":10,"id":"442eab0a_0a97a445","line":36,"in_reply_to":"403173b9_e5dd968d","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"trove/guestagent/datastore/validator.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"VALIDATION_CONTAINER_PREFIX \u003d \"trove-config-validation\""},{"line_number":31,"context_line":"VALIDATION_LABEL \u003d \"com.openstack.trove.configuration-validation\""},{"line_number":32,"context_line":"SECRET_PATTERN \u003d re.compile(r\"(?i)(password|passwd|secret|token)\\s*[\u003d:]\\s*[^\\s]+\")"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"class ValidationContainerRunner:"}],"source_content_type":"text/x-python","patch_set":2,"id":"b6c52efa_f83865e3","line":32,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (82 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":34,"context_line":")"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class ValidationContainerRunner:"},{"line_number":38,"context_line":"    \"\"\"Run one isolated database configuration parser.\"\"\""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def __init__(self, docker_client):"}],"source_content_type":"text/x-python","patch_set":10,"id":"a28c0c95_20d85154","line":37,"updated":"2026-08-04 13:25:10.000000000","message":"I don\u0027t see that `ValidationContainerRunner` is used anywhere except this module, and considering the code, I don\u0027t see that it is required to be a separate class. Maybe we can combine it with the `Validator` class instead? )\n\nThis also would allow managers to override some methods of this class in the future, if necessary.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":34,"context_line":")"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class ValidationContainerRunner:"},{"line_number":38,"context_line":"    \"\"\"Run one isolated database configuration parser.\"\"\""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def __init__(self, docker_client):"}],"source_content_type":"text/x-python","patch_set":10,"id":"aa3c1dc3_00efef2c","line":37,"in_reply_to":"a28c0c95_20d85154","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":89,"context_line":"                        \"Validation command exited with code %s\" % exit_code,"},{"line_number":90,"context_line":"                    ),"},{"line_number":91,"context_line":"                )"},{"line_number":92,"context_line":"            time.sleep(CONF.state_change_poll_time)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        raise exception.ConfigurationValidationExecutionError("},{"line_number":95,"context_line":"            datastore\u003ddatastore,"}],"source_content_type":"text/x-python","patch_set":10,"id":"01f47623_467183be","line":92,"updated":"2026-08-04 13:25:10.000000000","message":"Imo we should use `utils.poll_until()` instead of plain `time.sleep`. Please take a look at different parts of the code and take a look at how it\u0027s implemented. We should use the same style in any part of the codebase.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                        \"Validation command exited with code %s\" % exit_code,"},{"line_number":90,"context_line":"                    ),"},{"line_number":91,"context_line":"                )"},{"line_number":92,"context_line":"            time.sleep(CONF.state_change_poll_time)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        raise exception.ConfigurationValidationExecutionError("},{"line_number":95,"context_line":"            datastore\u003ddatastore,"}],"source_content_type":"text/x-python","patch_set":10,"id":"3e53012a_178b35c2","line":92,"in_reply_to":"01f47623_467183be","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":110,"context_line":"            return []"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    @staticmethod"},{"line_number":113,"context_line":"    def _safe_reason(logs, fallback):"},{"line_number":114,"context_line":"        fallback_reason \u003d SECRET_PATTERN.sub(r\"\\1\u003d\u003credacted\u003e\", fallback)"},{"line_number":115,"context_line":"        redacted_lines \u003d []"},{"line_number":116,"context_line":"        for line in reversed(logs):"}],"source_content_type":"text/x-python","patch_set":10,"id":"2721b13c_b45b264c","line":113,"updated":"2026-08-04 13:25:10.000000000","message":"Please take a look at `strutils.mask_password` in `oslo.utils` package. Masking a password is a common task, and we can utilize an existing functionality instead of creating a new one.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":110,"context_line":"            return []"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    @staticmethod"},{"line_number":113,"context_line":"    def _safe_reason(logs, fallback):"},{"line_number":114,"context_line":"        fallback_reason \u003d SECRET_PATTERN.sub(r\"\\1\u003d\u003credacted\u003e\", fallback)"},{"line_number":115,"context_line":"        redacted_lines \u003d []"},{"line_number":116,"context_line":"        for line in reversed(logs):"}],"source_content_type":"text/x-python","patch_set":10,"id":"44be183f_67471dea","line":113,"in_reply_to":"2721b13c_b45b264c","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"trove/instance/models.py":[{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":70,"context_line":""},{"line_number":71,"context_line":"CLOUDINIT_HEADER \u003d \"#cloud-config\\n\""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"CONFIGURATION_VALIDATION_DATASTORES \u003d frozenset({"},{"line_number":74,"context_line":"    \"mariadb\", \"mysql\", \"postgresql\","},{"line_number":75,"context_line":"})"},{"line_number":76,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"aff5637f_f8b773f1","line":73,"updated":"2026-08-04 13:25:10.000000000","message":"This should not be hardcoded here also. If some datastore manager doesn\u0027t implement the `validate_configuration` method, it should just throw an exception from the guest agent.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":70,"context_line":""},{"line_number":71,"context_line":"CLOUDINIT_HEADER \u003d \"#cloud-config\\n\""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"CONFIGURATION_VALIDATION_DATASTORES \u003d frozenset({"},{"line_number":74,"context_line":"    \"mariadb\", \"mysql\", \"postgresql\","},{"line_number":75,"context_line":"})"},{"line_number":76,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"907d0e94_606e9cd2","line":73,"in_reply_to":"aff5637f_f8b773f1","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"trove/taskmanager/models.py":[{"author":{"_account_id":36080,"name":"Erkin Mussurmankulov","display_name":"Eric","email":"erkin.mussurmankulov@ps.kz","username":"mongoose404","status":"PS Cloud services employee"},"change_message_id":"e01f97b6cf392016e730b17ba424667449862b8b","unresolved":true,"context_lines":[{"line_number":487,"context_line":"            error_details \u003d traceback.format_exc()"},{"line_number":488,"context_line":"        finally:"},{"line_number":489,"context_line":"            if error_message:"},{"line_number":490,"context_line":"                if self._configuration_validation_fault_exists():"},{"line_number":491,"context_line":"                    LOG.debug("},{"line_number":492,"context_line":"                        \"Preserving configuration validation fault for \""},{"line_number":493,"context_line":"                        \"instance %s.\", self.id)"}],"source_content_type":"text/x-python","patch_set":10,"id":"ee2fcc57_e5b8ef18","line":490,"updated":"2026-08-04 13:25:10.000000000","message":"This code and the whole helper looks ugly (also, this helper isn\u0027t used anywhere else).\nMaybe we can just override the `error_message` above with the Validation fault message? Or maybe we don\u0027t need to do anything here, except just catch `GuestError` with the error message that validation failed?\nI would prefer to make it simpler, if it\u0027s possible.","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"},{"author":{"_account_id":39300,"name":"Olessya Khussainova","display_name":"Olessya Khussainova","email":"olessya.khussainova@ps.kz","username":"Cellofun"},"change_message_id":"ba96d05b2164ba212a63209d16efada8b877709c","unresolved":false,"context_lines":[{"line_number":487,"context_line":"            error_details \u003d traceback.format_exc()"},{"line_number":488,"context_line":"        finally:"},{"line_number":489,"context_line":"            if error_message:"},{"line_number":490,"context_line":"                if self._configuration_validation_fault_exists():"},{"line_number":491,"context_line":"                    LOG.debug("},{"line_number":492,"context_line":"                        \"Preserving configuration validation fault for \""},{"line_number":493,"context_line":"                        \"instance %s.\", self.id)"}],"source_content_type":"text/x-python","patch_set":10,"id":"97b0d5d2_daa209c7","line":490,"in_reply_to":"ee2fcc57_e5b8ef18","updated":"2026-08-06 08:36:39.000000000","message":"Done","commit_id":"fdf33a110906ae7dbf479f7c685e4ab678d46588"}],"trove/tests/unittests/guestagent/datastore/test_validator.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from trove.common import exception"},{"line_number":19,"context_line":"from trove.guestagent.datastore import validator"},{"line_number":20,"context_line":"from trove.guestagent.datastore.mysql_common import validator as mysql_validator"},{"line_number":21,"context_line":"from trove.guestagent.datastore.postgres import validator as pg_validator"},{"line_number":22,"context_line":"from trove.tests.unittests import trove_testtools"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1ef4c788_1c5755a7","line":20,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (80 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from trove.common import exception"},{"line_number":19,"context_line":"from trove.guestagent.datastore import validator"},{"line_number":20,"context_line":"from trove.guestagent.datastore.mysql_common import validator as mysql_validator"},{"line_number":21,"context_line":"from trove.guestagent.datastore.postgres import validator as pg_validator"},{"line_number":22,"context_line":"from trove.tests.unittests import trove_testtools"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"6c72c833_a1749987","line":20,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: H306: imports not in alphabetical order (trove.guestagent.datastore.validator, trove.guestagent.datastore.mysql_common.validator)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        self.container.remove.assert_called_once_with(force\u003dTrue)"},{"line_number":40,"context_line":"        args \u003d self.client.containers.run.call_args.kwargs"},{"line_number":41,"context_line":"        self.assertTrue(args[\"name\"].startswith(validator.VALIDATION_CONTAINER_PREFIX))"},{"line_number":42,"context_line":"        self.assertEqual(\"none\", args[\"network_mode\"])"},{"line_number":43,"context_line":"        self.assertEqual({\"Name\": \"no\"}, args[\"restart_policy\"])"},{"line_number":44,"context_line":"        self.client.containers.get.assert_not_called()"}],"source_content_type":"text/x-python","patch_set":2,"id":"2ae493ce_6eb5f188","line":41,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (87 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def test_failed_parser_returns_redacted_engine_reason(self):"},{"line_number":47,"context_line":"        self.container.attrs \u003d {\"State\": {\"Status\": \"exited\", \"ExitCode\": 2}}"},{"line_number":48,"context_line":"        self.container.logs.return_value \u003d b\"invalid option: password\u003ddo-not-expose\""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        error \u003d self.assertRaises("},{"line_number":51,"context_line":"            exception.ConfigurationValidationError,"}],"source_content_type":"text/x-python","patch_set":2,"id":"7dea3f74_e5f0c4b0","line":48,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (84 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        overrides \u003d {\"max_connections\": 10}"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        with tempfile.TemporaryDirectory() as work_dir:"},{"line_number":102,"context_line":"            run_args \u003d validator_instance.prepare_candidate(work_dir, overrides)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        copy.assert_called_once_with("},{"line_number":105,"context_line":"            \"/etc/mysql\", mock.ANY, preserve\u003dTrue, recursive\u003dTrue, as_root\u003dTrue"}],"source_content_type":"text/x-python","patch_set":2,"id":"d43c2edd_c0f2d601","line":102,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (80 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":115,"context_line":"    @mock.patch.object(mysql_validator.configuration, \"ConfigurationManager\")"},{"line_number":116,"context_line":"    @mock.patch.object(mysql_validator.operating_system, \"copy\")"},{"line_number":117,"context_line":"    @mock.patch.object(mysql_validator.operating_system, \"chown\")"},{"line_number":118,"context_line":"    def test_mariadb_candidate_uses_mariadbd_parser(self, chown, copy, manager_class):"},{"line_number":119,"context_line":"        validator_instance \u003d mysql_validator.MySQLCommonValidator("},{"line_number":120,"context_line":"            mock.MagicMock(), 1001, 1001, \"mariadb\""},{"line_number":121,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":2,"id":"7255ab48_94b8663b","line":118,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (86 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        overrides \u003d {\"max_connections\": 10}"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        with tempfile.TemporaryDirectory() as work_dir:"},{"line_number":144,"context_line":"            run_args \u003d validator_instance.prepare_candidate(work_dir, overrides)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        copy.assert_called_once_with("},{"line_number":147,"context_line":"            \"/etc/postgresql\", mock.ANY, preserve\u003dTrue, recursive\u003dTrue, as_root\u003dTrue"}],"source_content_type":"text/x-python","patch_set":2,"id":"b6e5e679_3970c222","line":144,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (80 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"7ed72fe2364a65428d45ad27622f3f7105f6a45a","unresolved":false,"context_lines":[{"line_number":144,"context_line":"            run_args \u003d validator_instance.prepare_candidate(work_dir, overrides)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        copy.assert_called_once_with("},{"line_number":147,"context_line":"            \"/etc/postgresql\", mock.ANY, preserve\u003dTrue, recursive\u003dTrue, as_root\u003dTrue"},{"line_number":148,"context_line":"        )"},{"line_number":149,"context_line":"        manager_class.return_value.apply_user_override.assert_called_once_with("},{"line_number":150,"context_line":"            overrides"}],"source_content_type":"text/x-python","patch_set":2,"id":"903b4863_6ad59901","line":147,"updated":"2026-07-29 15:04:03.000000000","message":"pep8: E501 line too long (84 \u003e 79 characters)","commit_id":"39aab4aaf595dc868d46c07ad946917cbbc6ad40"}],"trove/tests/unittests/guestagent/test_api.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"86d4ef3171d1f88c21b2e70e34ff91031cff3b37","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        self.assertIs("},{"line_number":94,"context_line":"            exception.ConfigurationValidationError, type(error.exception))"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"dbf8ba6d_b54e1229","line":95,"updated":"2026-08-03 14:07:54.000000000","message":"pep8: W391 blank line at end of file","commit_id":"f5a3d761a621c5e248357832c028d2ad39334210"}]}
