)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":14525,"name":"Vasyl Saienko","email":"vsaienko@mirantis.com","username":"vsaienko"},"change_message_id":"06b85947b86df2916eb4be5075565c5a137b2ad0","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Improve conductor driver validation at startup"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This changes the driver loading validation in the conductor"},{"line_number":10,"context_line":"startup to check for at least one classic *or* dynamic driver."},{"line_number":11,"context_line":"Previously the conductor would fail to start if no classic drivers"},{"line_number":12,"context_line":"were loaded. This allows the conductor to use only dynamic"},{"line_number":13,"context_line":"drivers, without loading any classic drivers."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a461143_6963a542","line":10,"updated":"2017-01-31 08:19:41.000000000","message":"Looks like we need a release note as it is visible to user (administrator)","commit_id":"39b5aadd63da85343c601c4b70fa527e91a7c3b8"}],"ironic/common/exception.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6f6f248918e5ced025e6feb6adf019c43c53f9a9","unresolved":false,"context_lines":[{"line_number":418,"context_line":""},{"line_number":419,"context_line":"class DriverNameConflict(IronicException):"},{"line_number":420,"context_line":"    _msg_fmt \u003d _(\"Classic and dynamic drivers \u0027%(names)s\u0027 cannot have the \""},{"line_number":421,"context_line":"                 \"same name.\")"},{"line_number":422,"context_line":""},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"class NoDriversLoaded(IronicException):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_00bf44aa","line":421,"updated":"2017-01-31 14:08:39.000000000","message":"nit: I\u0027d prefer we stop creating single-purpose exceptions that are never exposed to users, and e.g. use RuntimeError instead.","commit_id":"1092ebfe0c9fafb6bb33fbca1a902421c5a1a50c"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"8af94210982c4490dd3aa0cfe80666dddeeec079","unresolved":false,"context_lines":[{"line_number":418,"context_line":""},{"line_number":419,"context_line":"class DriverNameConflict(IronicException):"},{"line_number":420,"context_line":"    _msg_fmt \u003d _(\"Classic and dynamic drivers \u0027%(names)s\u0027 cannot have the \""},{"line_number":421,"context_line":"                 \"same name.\")"},{"line_number":422,"context_line":""},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"class NoDriversLoaded(IronicException):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_b2615b07","line":421,"in_reply_to":"3a461143_008e64cf","updated":"2017-01-31 17:33:14.000000000","message":"I tend to agree but yeah let\u0027s start this at another time, not right before freeze.","commit_id":"1092ebfe0c9fafb6bb33fbca1a902421c5a1a50c"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"21d98f4f9d0723febcb72b2f98b924e8b20de52e","unresolved":false,"context_lines":[{"line_number":418,"context_line":""},{"line_number":419,"context_line":"class DriverNameConflict(IronicException):"},{"line_number":420,"context_line":"    _msg_fmt \u003d _(\"Classic and dynamic drivers \u0027%(names)s\u0027 cannot have the \""},{"line_number":421,"context_line":"                 \"same name.\")"},{"line_number":422,"context_line":""},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"class NoDriversLoaded(IronicException):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_008e64cf","line":421,"in_reply_to":"3a461143_00bf44aa","updated":"2017-01-31 14:14:24.000000000","message":"I think we\u0027re already a bit too far down the road to change that direction just this moment, but does kind of make sense to abandon it since our coding style seems to rarely use the message formatting provided by single purpose exceptions.  I\u0027m going to add to the PTG etherpad since it is a relevant topic to do with velocity.","commit_id":"1092ebfe0c9fafb6bb33fbca1a902421c5a1a50c"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6f6f248918e5ced025e6feb6adf019c43c53f9a9","unresolved":false,"context_lines":[{"line_number":423,"context_line":""},{"line_number":424,"context_line":"class NoDriversLoaded(IronicException):"},{"line_number":425,"context_line":"    _msg_fmt \u003d _(\"Conductor %(conductor)s cannot be started \""},{"line_number":426,"context_line":"                 \"because no drivers were loaded.\")"},{"line_number":427,"context_line":""},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"class ConductorNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_20e0c0cc","line":426,"updated":"2017-01-31 14:08:39.000000000","message":"... though we\u0027ve been already doing that","commit_id":"1092ebfe0c9fafb6bb33fbca1a902421c5a1a50c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"563c54459cce0351f35ec1674876b5b7836e851c","unresolved":false,"context_lines":[{"line_number":418,"context_line":""},{"line_number":419,"context_line":"class DriverNameConflict(IronicException):"},{"line_number":420,"context_line":"    _msg_fmt \u003d _(\"Classic and dynamic drivers \u0027%(names)s\u0027 cannot have the \""},{"line_number":421,"context_line":"                 \"same name.\")"},{"line_number":422,"context_line":""},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"class NoDriversLoaded(IronicException):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_9b239bbc","line":421,"updated":"2017-01-31 19:30:47.000000000","message":"how about \"Classic and dynamic drivers cannot have the same names \u0027foobar\u0027\"?","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ec78f7286c119022586181ccdc720c5d42f4ba27","unresolved":false,"context_lines":[{"line_number":418,"context_line":""},{"line_number":419,"context_line":"class DriverNameConflict(IronicException):"},{"line_number":420,"context_line":"    _msg_fmt \u003d _(\"Classic and dynamic drivers \u0027%(names)s\u0027 cannot have the \""},{"line_number":421,"context_line":"                 \"same name.\")"},{"line_number":422,"context_line":""},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"class NoDriversLoaded(IronicException):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_588823c7","line":421,"in_reply_to":"3a461143_9b239bbc","updated":"2017-02-01 22:25:56.000000000","message":"Good idea, done","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"}],"ironic/conductor/base_manager.py":[{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"fa51ba67a3409cc8a6aeff700c0b946b7d6d8028","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                LOG.error(_LE(\u0027Failed to register hardware types\u0027))"},{"line_number":157,"context_line":"                self.del_host()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        # TODO(jroll) validate here that at least one driver OR"},{"line_number":160,"context_line":"        # hardware type is loaded. If not, call del_host and raise"},{"line_number":161,"context_line":"        # NoDriversLoaded."},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_bd40bda6","line":159,"updated":"2017-01-27 15:00:23.000000000","message":"Seems like this TODO is done.","commit_id":"d2ed95aee855d357807cd6587b3c7fa97fda3f9d"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"d17e25cd444b7c10bfd6716c9940eae823c0916b","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                LOG.error(_LE(\u0027Failed to register hardware types\u0027))"},{"line_number":157,"context_line":"                self.del_host()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        # TODO(jroll) validate here that at least one driver OR"},{"line_number":160,"context_line":"        # hardware type is loaded. If not, call del_host and raise"},{"line_number":161,"context_line":"        # NoDriversLoaded."},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_03225200","line":159,"in_reply_to":"3a461143_bd40bda6","updated":"2017-01-27 15:41:57.000000000","message":"Oops, thanks","commit_id":"d2ed95aee855d357807cd6587b3c7fa97fda3f9d"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"cf46b03dbb6945718ae419fe99caf192a1eab04e","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        :raises: NoDriversLoaded when no drivers are enabled on the conductor."},{"line_number":61,"context_line":"        :raises: DriverNotFound if a driver is enabled that does not exist."},{"line_number":62,"context_line":"        :raises: DriverLoadError if an enabled driver cannot be loaded."},{"line_number":63,"context_line":"        :raises: DriverNameConflict if a classic driver and a dynamic driver"},{"line_number":64,"context_line":"                 are both enabled and have the same name."},{"line_number":65,"context_line":"        \"\"\""},{"line_number":66,"context_line":"        if self._started:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_072dbafd","line":63,"updated":"2017-01-30 19:54:34.000000000","message":"I guess this means that my comment about precedence on https://review.openstack.org/#/c/417970/ doesn\u0027t matter, since no classic and dynamic drivers may have the same name and be enabled.","commit_id":"c4dcc228e48a97850406abc48b7f8701b13f1aff"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"260af39a468d4404f6008bd6974f9dc90369d53b","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        :raises: NoDriversLoaded when no drivers are enabled on the conductor."},{"line_number":61,"context_line":"        :raises: DriverNotFound if a driver is enabled that does not exist."},{"line_number":62,"context_line":"        :raises: DriverLoadError if an enabled driver cannot be loaded."},{"line_number":63,"context_line":"        :raises: DriverNameConflict if a classic driver and a dynamic driver"},{"line_number":64,"context_line":"                 are both enabled and have the same name."},{"line_number":65,"context_line":"        \"\"\""},{"line_number":66,"context_line":"        if self._started:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_8d40e835","line":63,"in_reply_to":"3a461143_072dbafd","updated":"2017-01-30 21:57:14.000000000","message":":)","commit_id":"c4dcc228e48a97850406abc48b7f8701b13f1aff"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"cf46b03dbb6945718ae419fe99caf192a1eab04e","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        name_clashes \u003d set(driver_names).intersection(hardware_type_names)"},{"line_number":172,"context_line":"        if name_clashes:"},{"line_number":173,"context_line":"            name_clashes \u003d \u0027, \u0027.join(name_clashes)"},{"line_number":174,"context_line":"            msg \u003d _LE(\"Conductor %(host)s cannot be started because there is \""},{"line_number":175,"context_line":"                      \"one or more name conflicts between classic drivers and \""},{"line_number":176,"context_line":"                      \"dynamic drivers (%(names)s). Check any external driver \""},{"line_number":177,"context_line":"                      \"plugins and the \u0027enabled_drivers\u0027 and \""}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_25d5841b","line":174,"range":{"start_line":174,"start_character":74,"end_line":174,"end_character":76},"updated":"2017-01-30 19:54:34.000000000","message":"nit: s/is/are","commit_id":"c4dcc228e48a97850406abc48b7f8701b13f1aff"},{"author":{"_account_id":19593,"name":"Anup Navare","email":"anup.d.navare@intel.com","username":"anup"},"change_message_id":"a7d204ca2c30caff4640046bb9f379191f31d7ee","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        # beginning, and failures prevent the conductor from starting."},{"line_number":90,"context_line":"        drivers \u003d driver_factory.drivers()"},{"line_number":91,"context_line":"        driver_factory.NetworkInterfaceFactory()"},{"line_number":92,"context_line":"        driver_factory.StorageInterfaceFactory()"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        # NOTE(jroll) this is passed to the dbapi, which requires a list, not"},{"line_number":95,"context_line":"        # a generator (which keys() returns in py3)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_d73d16c5","line":92,"updated":"2017-01-31 01:15:30.000000000","message":"I am not sure, but should it be good to still check if \u0027drivers\u0027 object is empty or not? I mean drivers.values() has been used at 107 so result would be different in case it\u0027s empty. Please correct me if wrong","commit_id":"39b5aadd63da85343c601c4b70fa527e91a7c3b8"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"d2d1f6956552dfb338e3f02c4c06977add2aa7f3","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        # beginning, and failures prevent the conductor from starting."},{"line_number":90,"context_line":"        drivers \u003d driver_factory.drivers()"},{"line_number":91,"context_line":"        driver_factory.NetworkInterfaceFactory()"},{"line_number":92,"context_line":"        driver_factory.StorageInterfaceFactory()"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        # NOTE(jroll) this is passed to the dbapi, which requires a list, not"},{"line_number":95,"context_line":"        # a generator (which keys() returns in py3)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_0f177e48","line":92,"in_reply_to":"3a461143_d73d16c5","updated":"2017-01-31 10:31:53.000000000","message":"It\u0027s fine, we only use it there to load tasks for any loaded drivers. Since there are no drivers loaded, we don\u0027t load any tasks, it\u0027s all good :)","commit_id":"39b5aadd63da85343c601c4b70fa527e91a7c3b8"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"6f6f248918e5ced025e6feb6adf019c43c53f9a9","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                      \"dynamic drivers (%(names)s). Check any external driver \""},{"line_number":177,"context_line":"                      \"plugins and the \u0027enabled_drivers\u0027 and \""},{"line_number":178,"context_line":"                      \"\u0027enabled_hardware_types\u0027 config options.\")"},{"line_number":179,"context_line":"            LOG.error(msg, host\u003dself.host, names\u003dname_clashes)"},{"line_number":180,"context_line":"            self.del_host()"},{"line_number":181,"context_line":"            raise exception.DriverNameConflict(names\u003dname_clashes)"},{"line_number":182,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_40e30cd9","line":179,"updated":"2017-01-31 14:08:39.000000000","message":"passing formatting arguments does not work this way, you should pass a dict {\u0027host\u0027: .., \u0027names\u0027: ..}, otherwise it\u0027s passed as (ignored) parameters to the logging system","commit_id":"1092ebfe0c9fafb6bb33fbca1a902421c5a1a50c"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"8af94210982c4490dd3aa0cfe80666dddeeec079","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                      \"dynamic drivers (%(names)s). Check any external driver \""},{"line_number":177,"context_line":"                      \"plugins and the \u0027enabled_drivers\u0027 and \""},{"line_number":178,"context_line":"                      \"\u0027enabled_hardware_types\u0027 config options.\")"},{"line_number":179,"context_line":"            LOG.error(msg, host\u003dself.host, names\u003dname_clashes)"},{"line_number":180,"context_line":"            self.del_host()"},{"line_number":181,"context_line":"            raise exception.DriverNameConflict(names\u003dname_clashes)"},{"line_number":182,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_d27507cb","line":179,"in_reply_to":"3a461143_00ed84b6","updated":"2017-01-31 17:33:14.000000000","message":"Oops, done","commit_id":"1092ebfe0c9fafb6bb33fbca1a902421c5a1a50c"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"21d98f4f9d0723febcb72b2f98b924e8b20de52e","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                      \"dynamic drivers (%(names)s). Check any external driver \""},{"line_number":177,"context_line":"                      \"plugins and the \u0027enabled_drivers\u0027 and \""},{"line_number":178,"context_line":"                      \"\u0027enabled_hardware_types\u0027 config options.\")"},{"line_number":179,"context_line":"            LOG.error(msg, host\u003dself.host, names\u003dname_clashes)"},{"line_number":180,"context_line":"            self.del_host()"},{"line_number":181,"context_line":"            raise exception.DriverNameConflict(names\u003dname_clashes)"},{"line_number":182,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_00ed84b6","line":179,"in_reply_to":"3a461143_40e30cd9","updated":"2017-01-31 14:14:24.000000000","message":"++","commit_id":"1092ebfe0c9fafb6bb33fbca1a902421c5a1a50c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"563c54459cce0351f35ec1674876b5b7836e851c","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                LOG.error(_LE(\u0027Failed to register hardware types\u0027))"},{"line_number":157,"context_line":"                self.del_host()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        # check that at least one driver is loaded, whether classic or dynamic"},{"line_number":160,"context_line":"        if not driver_names and not hardware_type_names:"},{"line_number":161,"context_line":"            msg \u003d _LE(\"Conductor %s cannot be started because no drivers \""},{"line_number":162,"context_line":"                      \"were loaded. This could be because no classic drivers \""}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_2cd6ef4e","line":159,"updated":"2017-01-31 19:30:47.000000000","message":"I\u0027d actually prefer to do these checks before the conductor is registered into the db. I\u0027m not sure why, except that we can do this before and I am wondering whether start/register the conductor and then stop it could cause some corner cases of \u003csomething-i-don-t-know-but-why-chance-it\u003e. Once it is registered, it is in the hash ring, right? Could an incoming request get that topic/conductor before the conductor is removed?","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"d9ac2ddd1ee6c0bd32b7e95d073c88b06e540215","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                LOG.error(_LE(\u0027Failed to register hardware types\u0027))"},{"line_number":157,"context_line":"                self.del_host()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        # check that at least one driver is loaded, whether classic or dynamic"},{"line_number":160,"context_line":"        if not driver_names and not hardware_type_names:"},{"line_number":161,"context_line":"            msg \u003d _LE(\"Conductor %s cannot be started because no drivers \""},{"line_number":162,"context_line":"                      \"were loaded. This could be because no classic drivers \""}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_82c88756","line":159,"in_reply_to":"3a461143_2cd6ef4e","updated":"2017-01-31 21:45:10.000000000","message":"I\u0027m +1 to moving this check up, especially since that was the behavior before this patch (verifying at least 1 driver was loaded before conductor registration)","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ec78f7286c119022586181ccdc720c5d42f4ba27","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                LOG.error(_LE(\u0027Failed to register hardware types\u0027))"},{"line_number":157,"context_line":"                self.del_host()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        # check that at least one driver is loaded, whether classic or dynamic"},{"line_number":160,"context_line":"        if not driver_names and not hardware_type_names:"},{"line_number":161,"context_line":"            msg \u003d _LE(\"Conductor %s cannot be started because no drivers \""},{"line_number":162,"context_line":"                      \"were loaded. This could be because no classic drivers \""}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_387197e1","line":159,"in_reply_to":"3a461143_82c88756","updated":"2017-02-01 22:25:56.000000000","message":"That\u0027s a good point, I\u0027ll do that. Thanks.\n\nFor the record, the drivers get in the hash ring when they\u0027re registered in the database, so we could get a request.\n\nThis also saves a del_host() call because we aren\u0027t registered yet :D","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"563c54459cce0351f35ec1674876b5b7836e851c","unresolved":false,"context_lines":[{"line_number":161,"context_line":"            msg \u003d _LE(\"Conductor %s cannot be started because no drivers \""},{"line_number":162,"context_line":"                      \"were loaded. This could be because no classic drivers \""},{"line_number":163,"context_line":"                      \"were specified in the \u0027enabled_drivers\u0027 config option \""},{"line_number":164,"context_line":"                      \"and no dynamic drivers were specified in the \""},{"line_number":165,"context_line":"                      \"\u0027enabled_hardware_types\u0027 config option.\")"},{"line_number":166,"context_line":"            LOG.error(msg, self.host)"},{"line_number":167,"context_line":"            self.del_host()"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_2ca18ff8","line":164,"updated":"2017-01-31 19:30:47.000000000","message":"nit s/and/or/","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ec78f7286c119022586181ccdc720c5d42f4ba27","unresolved":false,"context_lines":[{"line_number":161,"context_line":"            msg \u003d _LE(\"Conductor %s cannot be started because no drivers \""},{"line_number":162,"context_line":"                      \"were loaded. This could be because no classic drivers \""},{"line_number":163,"context_line":"                      \"were specified in the \u0027enabled_drivers\u0027 config option \""},{"line_number":164,"context_line":"                      \"and no dynamic drivers were specified in the \""},{"line_number":165,"context_line":"                      \"\u0027enabled_hardware_types\u0027 config option.\")"},{"line_number":166,"context_line":"            LOG.error(msg, self.host)"},{"line_number":167,"context_line":"            self.del_host()"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_587663d9","line":164,"in_reply_to":"3a461143_2ca18ff8","updated":"2017-02-01 22:25:56.000000000","message":"Well, this will only happen if *both* configs were empty, so I think and is appropriate, no?","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6d4054285e07504c3f512fadaa199a371146730d","unresolved":false,"context_lines":[{"line_number":161,"context_line":"            msg \u003d _LE(\"Conductor %s cannot be started because no drivers \""},{"line_number":162,"context_line":"                      \"were loaded. This could be because no classic drivers \""},{"line_number":163,"context_line":"                      \"were specified in the \u0027enabled_drivers\u0027 config option \""},{"line_number":164,"context_line":"                      \"and no dynamic drivers were specified in the \""},{"line_number":165,"context_line":"                      \"\u0027enabled_hardware_types\u0027 config option.\")"},{"line_number":166,"context_line":"            LOG.error(msg, self.host)"},{"line_number":167,"context_line":"            self.del_host()"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_42581857","line":164,"in_reply_to":"3a461143_587663d9","updated":"2017-02-02 14:16:01.000000000","message":"Oh yes, you\u0027re right. I interpreted that as \u0027to fix it you should do one of the following\u0027 but that\u0027s not what the msg is about.","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"563c54459cce0351f35ec1674876b5b7836e851c","unresolved":false,"context_lines":[{"line_number":270,"context_line":"        # first unregister, in case we have cruft laying around"},{"line_number":271,"context_line":"        self.conductor.unregister_all_hardware_interfaces()"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        hardware_types \u003d driver_factory.hardware_types()"},{"line_number":274,"context_line":"        for ht_name, ht in hardware_types.items():"},{"line_number":275,"context_line":"            interface_map \u003d driver_factory.enabled_supported_interfaces(ht)"},{"line_number":276,"context_line":"            for interface_type, interface_names in interface_map.items():"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_ec2ea78a","line":273,"updated":"2017-01-31 19:30:47.000000000","message":"my preference would be to pull this code out of here and do it earlier in the conductor\u0027s init, before we actually register the conductor.\n\nAnd then pass hardware_type(_names) to this method.","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ec78f7286c119022586181ccdc720c5d42f4ba27","unresolved":false,"context_lines":[{"line_number":270,"context_line":"        # first unregister, in case we have cruft laying around"},{"line_number":271,"context_line":"        self.conductor.unregister_all_hardware_interfaces()"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        hardware_types \u003d driver_factory.hardware_types()"},{"line_number":274,"context_line":"        for ht_name, ht in hardware_types.items():"},{"line_number":275,"context_line":"            interface_map \u003d driver_factory.enabled_supported_interfaces(ht)"},{"line_number":276,"context_line":"            for interface_type, interface_names in interface_map.items():"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_b347684a","line":273,"in_reply_to":"3a461143_ec2ea78a","updated":"2017-02-01 22:25:56.000000000","message":"Yeah, I prefer that as well, nice catch.","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"}],"ironic/tests/unit/conductor/test_base_manager.py":[{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"8b4061cde73ef79d9c3dd8c719ca897bd866cf23","unresolved":false,"context_lines":[{"line_number":174,"context_line":"    @mock.patch.object(base_manager, \u0027LOG\u0027)"},{"line_number":175,"context_line":"    @mock.patch.object(base_manager.BaseConductorManager, \u0027del_host\u0027)"},{"line_number":176,"context_line":"    @mock.patch.object(driver_factory, \u0027DriverFactory\u0027)"},{"line_number":177,"context_line":"    def test_starts_with_only_classic_drivers(self, df_mock, del_mock,"},{"line_number":178,"context_line":"                                              log_mock):"},{"line_number":179,"context_line":"        driver_factory_mock \u003d mock.MagicMock(names\u003d[])"},{"line_number":180,"context_line":"        df_mock.return_value \u003d driver_factory_mock"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_a4fa61bb","line":177,"updated":"2017-01-27 17:50:49.000000000","message":"This confuses me. The title seems to imply that there is a classic driver set. But L179 seems to provide an empty list.\n\nAnd if I comment out L176 and edit the rest the test still passes.","commit_id":"c4dcc228e48a97850406abc48b7f8701b13f1aff"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"260af39a468d4404f6008bd6974f9dc90369d53b","unresolved":false,"context_lines":[{"line_number":174,"context_line":"    @mock.patch.object(base_manager, \u0027LOG\u0027)"},{"line_number":175,"context_line":"    @mock.patch.object(base_manager.BaseConductorManager, \u0027del_host\u0027)"},{"line_number":176,"context_line":"    @mock.patch.object(driver_factory, \u0027DriverFactory\u0027)"},{"line_number":177,"context_line":"    def test_starts_with_only_classic_drivers(self, df_mock, del_mock,"},{"line_number":178,"context_line":"                                              log_mock):"},{"line_number":179,"context_line":"        driver_factory_mock \u003d mock.MagicMock(names\u003d[])"},{"line_number":180,"context_line":"        df_mock.return_value \u003d driver_factory_mock"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_4d5a802b","line":177,"in_reply_to":"3a461143_67b91e79","updated":"2017-01-30 21:57:14.000000000","message":"Yeah, I have these two backwards. This one is testing with only dynamic drivers, the other only with classic. Will fix.","commit_id":"c4dcc228e48a97850406abc48b7f8701b13f1aff"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"cf46b03dbb6945718ae419fe99caf192a1eab04e","unresolved":false,"context_lines":[{"line_number":174,"context_line":"    @mock.patch.object(base_manager, \u0027LOG\u0027)"},{"line_number":175,"context_line":"    @mock.patch.object(base_manager.BaseConductorManager, \u0027del_host\u0027)"},{"line_number":176,"context_line":"    @mock.patch.object(driver_factory, \u0027DriverFactory\u0027)"},{"line_number":177,"context_line":"    def test_starts_with_only_classic_drivers(self, df_mock, del_mock,"},{"line_number":178,"context_line":"                                              log_mock):"},{"line_number":179,"context_line":"        driver_factory_mock \u003d mock.MagicMock(names\u003d[])"},{"line_number":180,"context_line":"        df_mock.return_value \u003d driver_factory_mock"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_67b91e79","line":177,"in_reply_to":"3a461143_a4fa61bb","updated":"2017-01-30 19:54:34.000000000","message":"Some no-op drivers are probably loaded by default when L176 is commented out?\n\n+1 about the empty list though, that doesn\u0027t make sense to me.\n\nI think this might be passing because HTFactory isn\u0027t mocked here, and the below is passing because DriverFactory isn\u0027t mocked properly?","commit_id":"c4dcc228e48a97850406abc48b7f8701b13f1aff"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"8b4061cde73ef79d9c3dd8c719ca897bd866cf23","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    @mock.patch.object(base_manager, \u0027LOG\u0027)"},{"line_number":187,"context_line":"    @mock.patch.object(base_manager.BaseConductorManager, \u0027del_host\u0027)"},{"line_number":188,"context_line":"    @mock.patch.object(driver_factory, \u0027HardwareTypesFactory\u0027)"},{"line_number":189,"context_line":"    def test_starts_with_only_dynamic_drivers(self, ht_mock, del_mock,"},{"line_number":190,"context_line":"                                              log_mock):"},{"line_number":191,"context_line":"        driver_factory_mock \u003d mock.MagicMock(names\u003d[])"},{"line_number":192,"context_line":"        ht_mock.return_value \u003d driver_factory_mock"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_64279964","line":189,"updated":"2017-01-27 17:50:49.000000000","message":"Same as comment on L177","commit_id":"c4dcc228e48a97850406abc48b7f8701b13f1aff"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"aa049a307b5b56b691abb2e176c7f12129a0ca7d","unresolved":false,"context_lines":[{"line_number":173,"context_line":"        ht_mock.assert_called_once_with()"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    @mock.patch.object(base_manager, \u0027LOG\u0027)"},{"line_number":176,"context_line":"    @mock.patch.object(base_manager.BaseConductorManager, \u0027del_host\u0027)"},{"line_number":177,"context_line":"    @mock.patch.object(driver_factory, \u0027DriverFactory\u0027)"},{"line_number":178,"context_line":"    def test_starts_with_only_dynamic_drivers(self, df_mock, del_mock,"},{"line_number":179,"context_line":"                                              log_mock):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_1749f78e","line":176,"updated":"2017-02-02 11:05:25.000000000","message":"Doesn\u0027t make much sense to have this anymore :)","commit_id":"0071c7e1ec991b8b150168216133390b854c759f"}],"releasenotes/notes/dynamic-driver-conductor-startup-validation-2d56d6ebe748a6bb.yaml":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"563c54459cce0351f35ec1674876b5b7836e851c","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The conductor process no longer requires at least one classic driver"},{"line_number":4,"context_line":"    to start. Instead, it requires one classic driver *or* one dynamic"},{"line_number":5,"context_line":"    driver."},{"line_number":6,"context_line":"upgrade:"},{"line_number":7,"context_line":"  - The conductor process will now refuse to start if a dynamic driver and"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"3a461143_ac93bf59","line":4,"updated":"2017-01-31 19:30:47.000000000","message":"nit, s/one/at least one/","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ec78f7286c119022586181ccdc720c5d42f4ba27","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The conductor process no longer requires at least one classic driver"},{"line_number":4,"context_line":"    to start. Instead, it requires one classic driver *or* one dynamic"},{"line_number":5,"context_line":"    driver."},{"line_number":6,"context_line":"upgrade:"},{"line_number":7,"context_line":"  - The conductor process will now refuse to start if a dynamic driver and"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"3a461143_137bdc7c","line":4,"in_reply_to":"3a461143_ac93bf59","updated":"2017-02-01 22:25:56.000000000","message":"Done","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"563c54459cce0351f35ec1674876b5b7836e851c","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    to start. Instead, it requires one classic driver *or* one dynamic"},{"line_number":5,"context_line":"    driver."},{"line_number":6,"context_line":"upgrade:"},{"line_number":7,"context_line":"  - The conductor process will now refuse to start if a dynamic driver and"},{"line_number":8,"context_line":"    a classic driver with the same name are both enabled."}],"source_content_type":"text/x-yaml","patch_set":7,"id":"3a461143_cc756b32","line":7,"updated":"2017-01-31 19:30:47.000000000","message":"nit: s/now//\n\n\u0027refuse\u0027 makes it seem like the conductor is alive :)","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ec78f7286c119022586181ccdc720c5d42f4ba27","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    to start. Instead, it requires one classic driver *or* one dynamic"},{"line_number":5,"context_line":"    driver."},{"line_number":6,"context_line":"upgrade:"},{"line_number":7,"context_line":"  - The conductor process will now refuse to start if a dynamic driver and"},{"line_number":8,"context_line":"    a classic driver with the same name are both enabled."}],"source_content_type":"text/x-yaml","patch_set":7,"id":"3a461143_3380d846","line":7,"in_reply_to":"3a461143_cc756b32","updated":"2017-02-01 22:25:56.000000000","message":"Done","commit_id":"01d53788f1644d313aa344a8fdc1d13e99607ba6"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"a0212f63707a499e525ce4464c3bb9b70a6d4fba","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The conductor process no longer requires at least one classic driver"},{"line_number":4,"context_line":"    to start. Instead, it requires at least one classic driver *or* at least"},{"line_number":5,"context_line":"    one dynamic driver."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"3a461143_57fd3f6d","line":2,"updated":"2017-02-02 10:49:26.000000000","message":"Not sure that it\u0027s a feature, looks like a fix.","commit_id":"0071c7e1ec991b8b150168216133390b854c759f"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"c957b548e52981ac6b3707216ae3a482186895f1","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    one dynamic driver."},{"line_number":6,"context_line":"upgrade:"},{"line_number":7,"context_line":"  - The conductor process will refuse to start if a dynamic driver and"},{"line_number":8,"context_line":"    a classic driver with the same name are both enabled."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"3a461143_17b9f7ec","line":8,"updated":"2017-02-02 10:43:07.000000000","message":"nit: this is not an upgrade concern IMO as hardware types did not exist in any previous release","commit_id":"0071c7e1ec991b8b150168216133390b854c759f"}]}
