Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Markus, C) +1 to file a spec early, so we can discuss in Tokyo if needed. Thanks, dims On Fri, Aug 28, 2015 at 11:16 AM, Markus Zoeller mzoel...@de.ibm.com wrote: Markus Zoeller/Germany/IBM@IBMDE wrote on 08/19/2015 02:15:55 PM: From: Markus Zoeller/Germany/IBM@IBMDE To: OpenStack Development Mailing List \(not for usage questions\) openstack-dev@lists.openstack.org Date: 08/19/2015 02:31 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova Markus Zoeller/Germany/IBM@IBMDE wrote on 08/17/2015 09:37:09 AM: From: Markus Zoeller/Germany/IBM@IBMDE To: OpenStack Development Mailing List \(not for usage questions\) openstack-dev@lists.openstack.org Date: 08/17/2015 09:48 AM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova Michael Still mi...@stillhq.com wrote on 08/12/2015 10:08:26 PM: From: Michael Still mi...@stillhq.com To: OpenStack Development Mailing List (not for usage questions) openstack-dev@lists.openstack.org Date: 08/12/2015 10:14 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova [...] Do we see https://review.openstack.org/#/c/205154/ as a reasonable example of such centralization? If not, what needs to change there to make it an example of that centralization? I see value in having a worked example people can follow before we attempt a large number of these moves. [...] Michael For the sake of completeness: A) An example of the centralization of the config options which addresses the issues Marian mentioned in the beginning of this thread: https://review.openstack.org/#/c/214581/4 Module nova/virt/vmwareapi/imagecache.py is a good example how it should look like in the end. B) A failed (and painful) attempt to replace the global CONF with an object, which was brought up by danpb: https://review.openstack.org/#/c/218319/2 C) Enhancing oslo.config to provide more structure and information, which was brought up by myself [1][2] TODO 1) I can create the blueprint to drive A), any veto? 2) I'll discuss C) with the oslo folks 3) I lack a good solution for B). Let's talk at the next summit about it References -- [1] https://blueprints.launchpad.net/oslo.config/+spec/option-interdependencies [2] https://blueprints.launchpad.net/oslo.config/+spec/help-text-markup __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev -- Davanum Srinivas :: https://twitter.com/dims __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Markus Zoeller/Germany/IBM@IBMDE wrote on 08/19/2015 02:15:55 PM: From: Markus Zoeller/Germany/IBM@IBMDE To: OpenStack Development Mailing List \(not for usage questions\) openstack-dev@lists.openstack.org Date: 08/19/2015 02:31 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova Markus Zoeller/Germany/IBM@IBMDE wrote on 08/17/2015 09:37:09 AM: From: Markus Zoeller/Germany/IBM@IBMDE To: OpenStack Development Mailing List \(not for usage questions\) openstack-dev@lists.openstack.org Date: 08/17/2015 09:48 AM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova Michael Still mi...@stillhq.com wrote on 08/12/2015 10:08:26 PM: From: Michael Still mi...@stillhq.com To: OpenStack Development Mailing List (not for usage questions) openstack-dev@lists.openstack.org Date: 08/12/2015 10:14 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova [...] Do we see https://review.openstack.org/#/c/205154/ as a reasonable example of such centralization? If not, what needs to change there to make it an example of that centralization? I see value in having a worked example people can follow before we attempt a large number of these moves. [...] Michael For the sake of completeness: A) An example of the centralization of the config options which addresses the issues Marian mentioned in the beginning of this thread: https://review.openstack.org/#/c/214581/4 Module nova/virt/vmwareapi/imagecache.py is a good example how it should look like in the end. B) A failed (and painful) attempt to replace the global CONF with an object, which was brought up by danpb: https://review.openstack.org/#/c/218319/2 C) Enhancing oslo.config to provide more structure and information, which was brought up by myself [1][2] TODO 1) I can create the blueprint to drive A), any veto? 2) I'll discuss C) with the oslo folks 3) I lack a good solution for B). Let's talk at the next summit about it References -- [1] https://blueprints.launchpad.net/oslo.config/+spec/option-interdependencies [2] https://blueprints.launchpad.net/oslo.config/+spec/help-text-markup __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Markus Zoeller/Germany/IBM@IBMDE wrote on 08/17/2015 09:37:09 AM: From: Markus Zoeller/Germany/IBM@IBMDE To: OpenStack Development Mailing List \(not for usage questions\) openstack-dev@lists.openstack.org Date: 08/17/2015 09:48 AM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova Michael Still mi...@stillhq.com wrote on 08/12/2015 10:08:26 PM: From: Michael Still mi...@stillhq.com To: OpenStack Development Mailing List (not for usage questions) openstack-dev@lists.openstack.org Date: 08/12/2015 10:14 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova [...] Do we see https://review.openstack.org/#/c/205154/ as a reasonable example of such centralization? If not, what needs to change there to make it an example of that centralization? I see value in having a worked example people can follow before we attempt a large number of these moves. [...] Michael IIUC, this change doesn't yet meet the idea and needs to change by: * creating a module nova/conf/default.py and * move the imagecache config options to that module After this change, it wouldn't address the need to lookup which services use a specific config option. What about enhancing this to something like this: [...] Based on Michael's proposal I did another one which shows what I tried to describe in the previous mail. The example: https://review.openstack.org/#/c/214581/ Regards, Markus Zoeller (markus_z) __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Michael Still mi...@stillhq.com wrote on 08/12/2015 10:08:26 PM: From: Michael Still mi...@stillhq.com To: OpenStack Development Mailing List (not for usage questions) openstack-dev@lists.openstack.org Date: 08/12/2015 10:14 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova [...] Do we see https://review.openstack.org/#/c/205154/ as a reasonable example of such centralization? If not, what needs to change there to make it an example of that centralization? I see value in having a worked example people can follow before we attempt a large number of these moves. [...] Michael IIUC, this change doesn't yet meet the idea and needs to change by: * creating a module nova/conf/default.py and * move the imagecache config options to that module After this change, it wouldn't address the need to lookup which services use a specific config option. What about enhancing this to something like this: Add a services package to the tree structure, which would then look like this: ├── nova │ ├── conf │ │ ├── sections │ │ │ ├── default.py │ │ └── services │ │ ├── compute.py The *registration* of the config options would be done by sections (here: default.py): from oslo_config import cfg CONF = cfg.CONF imagecache_opts = [ cfg.IntOpt('image_cache_manager_interval', default=2400, help='... help text ...'), # [...] ] CONF.register_opts(imagecache_opts) The *import* of the options would be done by service (here: compute.py): from oslo_config import cfg CONF = cfg.CONF CONF.import_opt('image_cache_manager_interval', 'nova.conf.sections.default') # ... more here ... The usage via the conf.service.compute module (here: imagecache.py): import nova.conf.services.compute as cpu def __init__(self): self.remove_unused_base_images = \ cpu.CONF.remove_unused_base_images Which means we would still use global variables but would at least know which services are meant to use them and which module thinks to which service it belongs (by using its config variables). An additional checking if a module uses import_opt could result in a warning and when the restructuring is done, result in an error. I think we wouldn't have problems with cyclic dependencies this way. The generation of the sample.conf file must be changed to use the nova.conf.sections package instead of the opts.list_opts methods as soon as we are done. Scenarios: 1) A new option should be added: = register in conf.sections.section.py = import in conf.services.service.py + It's immediatley clear which service is affected by that + If someone has to import another conf.services.service.py than the already existing ones, it's immediately clear in the review. + The person who adds it, sees that we have already a lot of config options and maybe is a bit more hesitant (let me dream, ...). 2) The config.sample has to be generated = use conf.sections.*.py for the generation 3) Someone wants a nova.conf for a compute node = use conf.services.compute.py for the generation 4) An existing option should be accessible by another service = import it in conf.services.another-service.py Regards, Markus Zoeller (markus_z) __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Wed, Aug 12, 2015 at 07:20:24PM +0200, Markus Zoeller wrote: Another thing which makes it hard to understand the impact of the config options is, that it's not clear how the interdependency to other config options is. As an example, the serial_console.base_url has a dependency to DEFAULT.cert and DEFAULT.key if you want to use secured websockets (base_url=wss://...). Another one is the option serial_console.serialproxy_port. This port number must be the same as it is in serial_console.base_url. I couldn't find an explanation to this. The three questions I have with every config option: 1) which service(s) access this option? 2) what does it do? / what's the impact? 3) which other options do I need to tweek to get the described impact? Would it make sense to stage the changes? M cycle: move the config options out of the modules to another place (like the approach Sean proposed) and annotate them with the services which uses them N cycle: inject the options into the drivers and eliminate the global variables this way (like Daniel et al. proposed) The problem I see is that as long as we're using config options as global variables, figuring out which services use which options is a major non-trivial effort. Some may be easy to figure out, but with many it gets into quite call path analysis, and the usage is changing under your feet as new reviews are posted. So personally I think it would be more practical todo the reverse. ie stop using the config options as global variables, and then split up the config file so that we have a separate one for each service. ie a /etc/nova/nova-compute.conf and get rid of /etc/nova/nova.conf Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 08/13/2015 05:02 AM, Daniel P. Berrange wrote: On Wed, Aug 12, 2015 at 07:20:24PM +0200, Markus Zoeller wrote: Another thing which makes it hard to understand the impact of the config options is, that it's not clear how the interdependency to other config options is. As an example, the serial_console.base_url has a dependency to DEFAULT.cert and DEFAULT.key if you want to use secured websockets (base_url=wss://...). Another one is the option serial_console.serialproxy_port. This port number must be the same as it is in serial_console.base_url. I couldn't find an explanation to this. The three questions I have with every config option: 1) which service(s) access this option? 2) what does it do? / what's the impact? 3) which other options do I need to tweek to get the described impact? Would it make sense to stage the changes? M cycle: move the config options out of the modules to another place (like the approach Sean proposed) and annotate them with the services which uses them N cycle: inject the options into the drivers and eliminate the global variables this way (like Daniel et al. proposed) The problem I see is that as long as we're using config options as global variables, figuring out which services use which options is a major non-trivial effort. Some may be easy to figure out, but with many it gets into quite call path analysis, and the usage is changing under your feet as new reviews are posted. So personally I think it would be more practical todo the reverse. ie stop using the config options as global variables, and then split up the config file so that we have a separate one for each service. ie a /etc/nova/nova-compute.conf and get rid of /etc/nova/nova.conf Options shouldn't be popping back and forth between services that often. If they are, we're doing something else wrong. I do agree that it's a big effort to start working through this. But we have some volunteers and will on it. And in collapsing these options into a smaller number of places we're going to be touching most of them and getting to ask real questions like why is this even a thing?. Because, right now, I don't think anyone has a good handle on our configuration space. Providing that global view through such a reorganization will help us figure out next steps here. -Sean -- Sean Dague http://dague.net __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Another thing which makes it hard to understand the impact of the config options is, that it's not clear how the interdependency to other config options is. As an example, the serial_console.base_url has a dependency to DEFAULT.cert and DEFAULT.key if you want to use secured websockets (base_url=wss://...). Another one is the option serial_console.serialproxy_port. This port number must be the same as it is in serial_console.base_url. I couldn't find an explanation to this. The three questions I have with every config option: 1) which service(s) access this option? 2) what does it do? / what's the impact? 3) which other options do I need to tweek to get the described impact? Would it make sense to stage the changes? M cycle: move the config options out of the modules to another place (like the approach Sean proposed) and annotate them with the services which uses them N cycle: inject the options into the drivers and eliminate the global variables this way (like Daniel et al. proposed) Especially for new contributors like me who didn't start in any of the early releases and didn't have the change to grow with Nova and its complexity, it would really help me a lot and enable me to contribute in a better way. As a side note: The nova.flagmappings file, which gets generated when you want to build the configuration reference manual, contains 804 config options for Nova. Quite a lot I think :) Sean Dague s...@dague.net wrote on 07/27/2015 04:35:56 PM: From: Sean Dague s...@dague.net To: openstack-dev@lists.openstack.org Date: 07/27/2015 04:36 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova On 07/27/2015 10:05 AM, Daniel P. Berrange wrote: On Fri, Jul 24, 2015 at 09:48:15AM +0100, Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 08/12/2015 01:20 PM, Markus Zoeller wrote: snip The three questions I have with every config option: 1) which service(s) access this option? 2) what does it do? / what's the impact? 3) which other options do I need to tweek to get the described impact? All excellent questions that really should be answered in both the help string for the option as well as the documentation here: http://docs.openstack.org/havana/config-reference/content/list-of-compute-config-options.html Note that the above link is generated, IIRC, from the code, so increasing the details in option descriptions (help string) should show up there. Anne is that assumption correct? Would it make sense to stage the changes? M cycle: move the config options out of the modules to another place (like the approach Sean proposed) and annotate them with the services which uses them N cycle: inject the options into the drivers and eliminate the global variables this way (like Daniel et al. proposed) +1. I think the above is an excellent plan. You have my support. Best, -jay Especially for new contributors like me who didn't start in any of the early releases and didn't have the change to grow with Nova and its complexity, it would really help me a lot and enable me to contribute in a better way. As a side note: The nova.flagmappings file, which gets generated when you want to build the configuration reference manual, contains 804 config options for Nova. Quite a lot I think :) Sean Dague s...@dague.net wrote on 07/27/2015 04:35:56 PM: From: Sean Dague s...@dague.net To: openstack-dev@lists.openstack.org Date: 07/27/2015 04:36 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova On 07/27/2015 10:05 AM, Daniel P. Berrange wrote: On Fri, Jul 24, 2015 at 09:48:15AM +0100, Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. Getting rid of the global CONF
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 08/12/2015 02:23 PM, Jay Pipes wrote: On 08/12/2015 01:20 PM, Markus Zoeller wrote: snip The three questions I have with every config option: 1) which service(s) access this option? 2) what does it do? / what's the impact? 3) which other options do I need to tweek to get the described impact? All excellent questions that really should be answered in both the help string for the option as well as the documentation here: http://docs.openstack.org/havana/config-reference/content/list-of-compute-config-options.html Note that the above link is generated, IIRC, from the code, so increasing the details in option descriptions (help string) should show up there. Anne is that assumption correct? Would it make sense to stage the changes? M cycle: move the config options out of the modules to another place (like the approach Sean proposed) and annotate them with the services which uses them N cycle: inject the options into the drivers and eliminate the global variables this way (like Daniel et al. proposed) +1. I think the above is an excellent plan. You have my support. I think this is a great plan. I agree with both steps, and the order in tackling them. Thanks for taking this on. -Sean -- Sean Dague http://dague.net __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Thu, Aug 13, 2015 at 4:29 AM, Sean Dague s...@dague.net wrote: On 08/12/2015 02:23 PM, Jay Pipes wrote: On 08/12/2015 01:20 PM, Markus Zoeller wrote: snip The three questions I have with every config option: 1) which service(s) access this option? 2) what does it do? / what's the impact? 3) which other options do I need to tweek to get the described impact? All excellent questions that really should be answered in both the help string for the option as well as the documentation here: http://docs.openstack.org/havana/config-reference/content/list-of-compute-config-options.html Note that the above link is generated, IIRC, from the code, so increasing the details in option descriptions (help string) should show up there. Anne is that assumption correct? Would it make sense to stage the changes? M cycle: move the config options out of the modules to another place (like the approach Sean proposed) and annotate them with the services which uses them Do we see https://review.openstack.org/#/c/205154/ as a reasonable example of such centralization? If not, what needs to change there to make it an example of that centralization? I see value in having a worked example people can follow before we attempt a large number of these moves. N cycle: inject the options into the drivers and eliminate the global variables this way (like Daniel et al. proposed) +1. I think the above is an excellent plan. You have my support. I think this is a great plan. I agree with both steps, and the order in tackling them. Thanks for taking this on. Michael -- Rackspace Australia __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 07/24/2015 02:15 PM, Michael Still wrote: On Fri, Jul 24, 2015 at 3:55 AM, Daniel P. Berrange berra...@redhat.com mailto:berra...@redhat.com wrote: On Thu, Jul 23, 2015 at 11:57:01AM -0500, Michael Still wrote: In fact, I did an example of what I thought it would look like already: https://review.openstack.org/#/c/205154/ I welcome discussion on this, especially from people who couldn't make it to the mid-cycle. Its up to y'all if you do that on this thread or in that review. I think this kind of thing needs to have a spec proposed for it, so we can go through the details of the problem and the design considerations for it. This is especially true considering this proposal comes out of a f2f meeting where the majority of the community was not present to participate in the discussion. So, I think discussion is totally fair here -- I want to be clear that what is in the review was a worked example of what we were thinking about, not a finished product. For example, I hit circular dependancy issues which caused the proposal to change. However, we weren't trying to solve all issues with flags ever here. Specifically what we were trying to address was ops feedback that the help text for our config options was unhelpfully terse, and that docs weren't covering the finer details that ops need to understand. Adding more help text is fine, but we were working through how to avoid having hundreds of lines of help text at the start of code files. I don't personally think that passing configuration options around as arguments really buys us much apart from an annoying user interface though. We already have to declare where we use a flag (especially if we move the flag definitions out of the code). That gives us a framework to enforce the interdependencies better, which in fact we partially do already via hacking rules. I think there is also a trade off here. Config options can be close to the code they are used in, or close to other config options. And locality is going to impact things. Right now with config options being local to code we get the incentive to grow up lots of little config options to tweak everything under the sun, and they end up buried away from a global view of if that makes sense. But config is global, for better or worse, and it's an interface to our operators. Pulling it all together as an interface into a dedicated part of the code might make it simpler to keep it consistent, and realize how big a scope of the problem is of conf sprawl. Because it would be nice to get detailed help into config options, instead of randomly in our heads, or having to read the code. It would also be nice to actually do the thing that markmc propose a long time ago of categorizing config options being the ones that you expect to change, the ones that are really only for debug, the ones that open up experimental stuff, etc. -Sean -- Sean Dague http://dague.net __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Fri, Jul 24, 2015 at 09:48:15AM +0100, Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. Getting rid of the global CONF object usage in all these files trivially now solves the circular dependancy import problem, as well as improving the overall structure and isolation of our code, freeing all these methods from unexpected side-effects from global variables. Another significant downside of using CONF objects as global variables is that it is largely impossible to say which nova.conf setting is used by which service. Figuring out whether a setting affects nova-compute or nova-api or nova-conductor, or ... largely comes down to guesswork or reliance on tribal knowledge. It would make life significantly easier for both developers and administrators if we could clear this up and in fact have separate configuration files for each service, holding only the options that are relevant for that service. Such a cleanup is not going to be practical though as long as we're using global variables for config as it requires control-flow analysis find out what affects what :-( Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 07/27/2015 10:05 AM, Daniel P. Berrange wrote: On Fri, Jul 24, 2015 at 09:48:15AM +0100, Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. Getting rid of the global CONF object usage in all these files trivially now solves the circular dependancy import problem, as well as improving the overall structure and isolation of our code, freeing all these methods from unexpected side-effects from global variables. How does that address config reload on SIGHUP? It seems like that approach would break that feature. Another significant downside of using CONF objects as global variables is that it is largely impossible to say which nova.conf setting is used by which service. Figuring out whether a setting affects nova-compute or nova-api or nova-conductor, or ... largely comes down to guesswork or reliance on tribal knowledge. It would make life significantly easier for both developers and administrators if we could clear this up and in fact have separate configuration files for each service, holding only the options that are relevant for that service. Such a cleanup is not going to be practical though as long as we're using global variables for config as it requires control-flow analysis find out what affects what :-( Part of the idea that came up in the room is to annotate variables with the service they were used in, and deny access to in services they are not for. -Sean -- Sean Dague http://dague.net __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 07/24/2015 01:48 AM, Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. Getting rid of the global CONF object usage in all these files trivially now solves the circular dependancy import problem, as well as improving the overall structure and isolation of our code, freeing all these methods from unexpected side-effects from global variables. Amen to everything you say above, Daniel. I've long hated the global CONF variables. In fact, in pulling the os_vif code out of Nova [1], I made a point of removing all use of the global CONF variables. -jay [1] http://github.com/jaypipes/os_vif __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. Getting rid of the global CONF object usage in all these files trivially now solves the circular dependancy import problem, as well as improving the overall structure and isolation of our code, freeing all these methods from unexpected side-effects from global variables. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Thu, Jul 23, 2015 at 11:57:01AM -0500, Michael Still wrote: In fact, I did an example of what I thought it would look like already: https://review.openstack.org/#/c/205154/ I welcome discussion on this, especially from people who couldn't make it to the mid-cycle. Its up to y'all if you do that on this thread or in that review. I think this kind of thing needs to have a spec proposed for it, so we can go through the details of the problem and the design considerations for it. This is especially true considering this proposal comes out of a f2f meeting where the majority of the community was not present to participate in the discussion. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Excerpts from Joshua Harlow's message of 2015-07-24 09:07:13 -0700: Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. Amen to that :) The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. +1 and IMHO if some driver needs some 'funky' new parameter that isn't getting passed previously, probably the driver may be built wrong, or it's not conforming to the API that is provided (and therefore either the API needs adjustments or the driver needs to be fixed); all the above IMHO is pretty standard OOP practices and I'd like to see more of it honestly :) While it's good to share common options as much as possible, there are a lot of perfectly legitimate reasons for drivers to need different configuration options. Different backends might use different authentication mechanisms, or need different ways to specify where the thing the driver is managing actually lives. The job of the driver API layer is to hide those differences so the application doesn't have to care about them. Pushing all of the options up to be API parameters defeats the purpose of that if not all drivers use all of the options. Doug Getting rid of the global CONF object usage in all these files trivially now solves the circular dependancy import problem, as well as improving the overall structure and isolation of our code, freeing all these methods from unexpected side-effects from global variables. Regards, Daniel __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. Amen to that :) The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. +1 and IMHO if some driver needs some 'funky' new parameter that isn't getting passed previously, probably the driver may be built wrong, or it's not conforming to the API that is provided (and therefore either the API needs adjustments or the driver needs to be fixed); all the above IMHO is pretty standard OOP practices and I'd like to see more of it honestly :) Getting rid of the global CONF object usage in all these files trivially now solves the circular dependancy import problem, as well as improving the overall structure and isolation of our code, freeing all these methods from unexpected side-effects from global variables. Regards, Daniel __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Excerpts from Daniel P. Berrange's message of 2015-07-24 15:11:19 +0100: On Fri, Jul 24, 2015 at 09:56:41AM -0400, Doug Hellmann wrote: Excerpts from Daniel P. Berrange's message of 2015-07-24 09:48:15 +0100: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. We've tried to do this in a lot of places throughout Oslo. It mostly works, until you hit a driver that uses options that the other drivers don't (oslo.messaging has this problem especially). We had a ConfigFilter class in oslo.config to enforce the isolation (an option registered on a filter object is only visible to the code that owns the filter). However, that causes challenges for value interpolation. A deployer doesn't know which options are visible to each other, and has a flat file where they can clearly see all of the values together, so they expect %(foo)s to work no matter where foo is defined. Until we solve those issues, the ConfigFilter isn't really supported. The best solution we've come up with so far is to isolate the options into groups based on the driver name, and then not allow code outside of the driver to access those options for any reason. To deal with import ordering issues, we pass ConfigObj instance around, and register options at runtime instead of import time, usually in an __init__ method. Registering an option more than once is fine. Yep, I would imagine that the nova/cmd/*.py command line entry points would trigger loading of the config file and pass the object into the service they run. The service may pass that config object on down to some classes, eg I'd expect the nova ComputeDriver to accept a config object in its constructor. Likewise the various manager classes like nova/compute/manager.py These would read the various config option values they care about and pass those into the various methods / objects that need them As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. There are, from time to time, specs proposed to provide ways for applications to reload their configuration settings without
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Fri, Jul 24, 2015 at 2:19 PM, Doug Hellmann d...@doughellmann.com wrote: One idea I've tossed around a bit is having options defined in data files that ship with the code, rather than being inside the Python code itself. Maybe a first pass at that would be to offload the help to a separate file? If that seems interesting, I could experiment with adding some features to oslo.config to support it. So, that's kind of what I was trying out. One idea was to put the help strings in a separate module and just reference them in the source code. My concern however is that if they're not with the code they wont get updated which things change. Instead, if we move the entire flag people are still forced to notice the help string and that its wrong when they tweak things. Its not perfect though, and ideas are very welcome. The basic problem is that if you try to configure SSL, there are a whole heap of different options available, and its not clear how they interact and what you need to twiddle to make things work unless you read the code. Michael -- Rackspace Australia __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Fri, Jul 24, 2015 at 09:56:41AM -0400, Doug Hellmann wrote: Excerpts from Daniel P. Berrange's message of 2015-07-24 09:48:15 +0100: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. We've tried to do this in a lot of places throughout Oslo. It mostly works, until you hit a driver that uses options that the other drivers don't (oslo.messaging has this problem especially). We had a ConfigFilter class in oslo.config to enforce the isolation (an option registered on a filter object is only visible to the code that owns the filter). However, that causes challenges for value interpolation. A deployer doesn't know which options are visible to each other, and has a flat file where they can clearly see all of the values together, so they expect %(foo)s to work no matter where foo is defined. Until we solve those issues, the ConfigFilter isn't really supported. The best solution we've come up with so far is to isolate the options into groups based on the driver name, and then not allow code outside of the driver to access those options for any reason. To deal with import ordering issues, we pass ConfigObj instance around, and register options at runtime instead of import time, usually in an __init__ method. Registering an option more than once is fine. Yep, I would imagine that the nova/cmd/*.py command line entry points would trigger loading of the config file and pass the object into the service they run. The service may pass that config object on down to some classes, eg I'd expect the nova ComputeDriver to accept a config object in its constructor. Likewise the various manager classes like nova/compute/manager.py These would read the various config option values they care about and pass those into the various methods / objects that need them As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. There are, from time to time, specs proposed to provide ways for applications to reload their configuration settings without restarting. So far we've said that was an application issue, because oslo.config can reload the files, but it doesn't know when (that's an app signal handling thing) and it doesn't know where
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Doug Hellmann wrote: Excerpts from Joshua Harlow's message of 2015-07-24 09:07:13 -0700: Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. Amen to that :) The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. +1 and IMHO if some driver needs some 'funky' new parameter that isn't getting passed previously, probably the driver may be built wrong, or it's not conforming to the API that is provided (and therefore either the API needs adjustments or the driver needs to be fixed); all the above IMHO is pretty standard OOP practices and I'd like to see more of it honestly :) While it's good to share common options as much as possible, there are a lot of perfectly legitimate reasons for drivers to need different configuration options. Different backends might use different authentication mechanisms, or need different ways to specify where the thing the driver is managing actually lives. The job of the driver API layer is to hide those differences so the application doesn't have to care about them. Pushing all of the options up to be API parameters defeats the purpose of that if not all drivers use all of the options. I get what u are saying, but at that point it does make me wonder what the API that is being provided really is, if the API is trying to hide those differences, and all drivers are different (and/or require different options via config) then I'm not really sure u can call that a common/shared API, especially if the sole option the API takes is a config object. I reckon this to usage of void* pointer in c/c++ (where the void* is nearly equivalent to the config object we pass around), having an API that takes a single void* pointer and then lets other functions do things/anything with it isn't exactly a API (by my definition). But if the API expects some standard arguments, and then as a final parameter takes a extra void* pointer, then this starts to become more acceptable IMHO (the extra void* pointer could be considered equivalent to **kwargs in python and the
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Excerpts from Joshua Harlow's message of 2015-07-24 10:09:10 -0700: Doug Hellmann wrote: Excerpts from Joshua Harlow's message of 2015-07-24 09:07:13 -0700: Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. Amen to that :) The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. +1 and IMHO if some driver needs some 'funky' new parameter that isn't getting passed previously, probably the driver may be built wrong, or it's not conforming to the API that is provided (and therefore either the API needs adjustments or the driver needs to be fixed); all the above IMHO is pretty standard OOP practices and I'd like to see more of it honestly :) While it's good to share common options as much as possible, there are a lot of perfectly legitimate reasons for drivers to need different configuration options. Different backends might use different authentication mechanisms, or need different ways to specify where the thing the driver is managing actually lives. The job of the driver API layer is to hide those differences so the application doesn't have to care about them. Pushing all of the options up to be API parameters defeats the purpose of that if not all drivers use all of the options. I get what u are saying, but at that point it does make me wonder what the API that is being provided really is, if the API is trying to hide those differences, and all drivers are different (and/or require different options via config) then I'm not really sure u can call that a common/shared API, especially if the sole option the API takes is a config object. I reckon this to usage of void* pointer in c/c++ (where the void* is nearly equivalent to the config object we pass around), having an API that takes a single void* pointer and then lets other functions do things/anything with it isn't exactly a API (by my definition). But if
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Fri, Jul 24, 2015 at 12:29:56PM -0400, Doug Hellmann wrote: Excerpts from Joshua Harlow's message of 2015-07-24 09:07:13 -0700: Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. Amen to that :) The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. +1 and IMHO if some driver needs some 'funky' new parameter that isn't getting passed previously, probably the driver may be built wrong, or it's not conforming to the API that is provided (and therefore either the API needs adjustments or the driver needs to be fixed); all the above IMHO is pretty standard OOP practices and I'd like to see more of it honestly :) While it's good to share common options as much as possible, there are a lot of perfectly legitimate reasons for drivers to need different configuration options. Different backends might use different authentication mechanisms, or need different ways to specify where the thing the driver is managing actually lives. The job of the driver API layer is to hide those differences so the application doesn't have to care about them. Pushing all of the options up to be API parameters defeats the purpose of that if not all drivers use all of the options. Agreed, that's why I suggested the ComputeDriver constructor would probably just accept a config object - each subclass has valid reasons for wanting its own set of config parameters in this case. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| __ OpenStack
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Excerpts from Daniel P. Berrange's message of 2015-07-24 09:48:15 +0100: On Thu, Jul 23, 2015 at 05:55:36PM +0300, mhorban wrote: Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? I tend to think that focusing on problems with dependancy ordering when modules import each others config options is merely attacking a symptom of the real root cause problem. The way we use config options is really entirely wrong. We have gone to the trouble of creating (or trying to create) structured code with isolated functional areas, files and object classes, and then we throw in these config options which are essentially global variables which are allowed to be accessed by any code anywhere. This destroys the isolation of the various classes we've created, and means their behaviour often based on side effects of config options from unrelated pieces of code. It is total madness in terms of good design practices to have such use of global variables. So IMHO, if we want to fix the real big problem with config options, we need to be looking to solution where we stop using config options as global variables. We should change our various classes so that the neccessary configurable options as passed into object constructors and/or methods as parameters. We've tried to do this in a lot of places throughout Oslo. It mostly works, until you hit a driver that uses options that the other drivers don't (oslo.messaging has this problem especially). We had a ConfigFilter class in oslo.config to enforce the isolation (an option registered on a filter object is only visible to the code that owns the filter). However, that causes challenges for value interpolation. A deployer doesn't know which options are visible to each other, and has a flat file where they can clearly see all of the values together, so they expect %(foo)s to work no matter where foo is defined. Until we solve those issues, the ConfigFilter isn't really supported. The best solution we've come up with so far is to isolate the options into groups based on the driver name, and then not allow code outside of the driver to access those options for any reason. To deal with import ordering issues, we pass ConfigObj instance around, and register options at runtime instead of import time, usually in an __init__ method. Registering an option more than once is fine. As an example in the libvirt driver. I would set it up so that /only/ the LibvirtDriver class in driver.py was allowed to access the CONF config options. In its constructor it would load all the various config options it needs, and either set class attributes for them, or pass them into other methods it calls. So in the driver.py, instead of calling CONF.libvirt.libvirt_migration_uri everywhere in the code, in the constructor we'd save that config param value to an attribute 'self.mig_uri = CONF.libvirt.libvirt_migration_uri' and then where needed, we'd just call self.mig_uri. There are, from time to time, specs proposed to provide ways for applications to reload their configuration settings without restarting. So far we've said that was an application issue, because oslo.config can reload the files, but it doesn't know when (that's an app signal handling thing) and it doesn't know where values might have been saved like you describe. I don't know if that's something the nova team wants to support. Now in the various other libvirt files, imagebackend.py, volume.py vif.py, etc. None of those files would /ever/ access CONF.*. Any time they needed a config parameter, it would be passed into their constructor or method, by the LibvirtDriver or whatever invoked them. Getting rid of the global CONF object usage in all these files trivially now solves the circular dependancy import problem, as well as improving the overall structure and isolation of our code, freeing all these methods from unexpected side-effects from global
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Excerpts from Michael Still's message of 2015-07-24 13:15:15 -0500: On Fri, Jul 24, 2015 at 3:55 AM, Daniel P. Berrange berra...@redhat.com wrote: On Thu, Jul 23, 2015 at 11:57:01AM -0500, Michael Still wrote: In fact, I did an example of what I thought it would look like already: https://review.openstack.org/#/c/205154/ I welcome discussion on this, especially from people who couldn't make it to the mid-cycle. Its up to y'all if you do that on this thread or in that review. I think this kind of thing needs to have a spec proposed for it, so we can go through the details of the problem and the design considerations for it. This is especially true considering this proposal comes out of a f2f meeting where the majority of the community was not present to participate in the discussion. So, I think discussion is totally fair here -- I want to be clear that what is in the review was a worked example of what we were thinking about, not a finished product. For example, I hit circular dependancy issues which caused the proposal to change. However, we weren't trying to solve all issues with flags ever here. Specifically what we were trying to address was ops feedback that the help text for our config options was unhelpfully terse, and that docs weren't covering the finer details that ops need to understand. Adding more help text is fine, but we were working through how to avoid having hundreds of lines of help text at the start of code files. I don't personally think that passing configuration options around as arguments really buys us much apart from an annoying user interface though. We already have to declare where we use a flag (especially if we move the flag definitions out of the code). That gives us a framework to enforce the interdependencies better, which in fact we partially do already via hacking rules. One idea I've tossed around a bit is having options defined in data files that ship with the code, rather than being inside the Python code itself. Maybe a first pass at that would be to offload the help to a separate file? If that seems interesting, I could experiment with adding some features to oslo.config to support it. Doug __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Fri, Jul 24, 2015 at 3:55 AM, Daniel P. Berrange berra...@redhat.com wrote: On Thu, Jul 23, 2015 at 11:57:01AM -0500, Michael Still wrote: In fact, I did an example of what I thought it would look like already: https://review.openstack.org/#/c/205154/ I welcome discussion on this, especially from people who couldn't make it to the mid-cycle. Its up to y'all if you do that on this thread or in that review. I think this kind of thing needs to have a spec proposed for it, so we can go through the details of the problem and the design considerations for it. This is especially true considering this proposal comes out of a f2f meeting where the majority of the community was not present to participate in the discussion. So, I think discussion is totally fair here -- I want to be clear that what is in the review was a worked example of what we were thinking about, not a finished product. For example, I hit circular dependancy issues which caused the proposal to change. However, we weren't trying to solve all issues with flags ever here. Specifically what we were trying to address was ops feedback that the help text for our config options was unhelpfully terse, and that docs weren't covering the finer details that ops need to understand. Adding more help text is fine, but we were working through how to avoid having hundreds of lines of help text at the start of code files. I don't personally think that passing configuration options around as arguments really buys us much apart from an annoying user interface though. We already have to declare where we use a flag (especially if we move the flag definitions out of the code). That gives us a framework to enforce the interdependencies better, which in fact we partially do already via hacking rules. Michael -- Rackspace Australia __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
To increase the readability of the help text of the config options,I pushed [1] to "oslo.config". [1] https://review.openstack.org/#/c/205708/ Regards, Markus Zoeller (markus_z) - Original message -From: Michael Still mi...@stillhq.comTo: "OpenStack Development Mailing List (not for usage questions)" openstack-dev@lists.openstack.orgCc:Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in novaDate: Fri, Jul 24, 2015 3:17 PM On Fri, Jul 24, 2015 at 2:19 PM, Doug Hellmann d...@doughellmann.com wrote: One idea I've tossed around a bit is having options defined in datafiles that ship with the code, rather than being inside the Pythoncode itself. Maybe a first pass at that would be to offload thehelp to a separate file? If that seems interesting, I could experimentwith adding some features to oslo.config to support it. So, that's kind of what I was trying out. One idea was to put the help strings in a separate module and just reference them in the source code. My concern however is that if they're not with the code they wont get updated which things change. Instead, if we move the entire flag people are still forced to notice the help string and that its wrong when they tweak things. Its not perfect though, and ideas are very welcome. The basic problem is that if you try to configure SSL, there are a whole heap of different options available, and its not clear how they interact and what you need to twiddle to make things work unless you read the code. Michael -- Rackspace Australia __OpenStack Development Mailing List (not for usage questions)Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribehttp://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Sean Dague s...@dague.net wrote on 07/23/2015 01:50:00 PM: From: Sean Dague s...@dague.net To: OpenStack Development Mailing List (not for usage questions) openstack-dev@lists.openstack.org Date: 07/23/2015 01:50 PM Subject: Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova [...] Maybe a directory is fine, especially if module mapped to [subsection]. nova/config/ default.py glance.py ... which makes it reasonably discoverable and mappable back and forth from config file to files. -Sean +1 Regards, Markus Zoeller (markus_z) __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
[openstack-dev] [openstack][nova] Streamlining of config options in nova
Hi all, During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. Implementations of this refactoring can be done piece by piece where piece is one package. What is your opinion about this idea? Marian __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Thu, 2015-07-23 at 17:55 +0300, mhorban wrote: During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. Isn't this use case what the import_opt() method of CONF is for? The description given in the docstring is: Import a module and check that a given option is registered. This is intended for use with global configuration objects like cfg.CONF where modules commonly register options with CONF at module load time. If one module requires an option defined by another module it can use this method to explicitly declare the dependency. It's used all over the place in nova for this purpose, as far as I can see. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. The problem with this reorganization is that it moves the options from the place where they're primarily intended to be used. This could make it harder to maintain, such as ensuring the help text is updated when the code is. If nova were a smaller code base, I think it would make sense to reorganize in this fashion, but given how large nova actually is… -- Kevin L. Mitchell kevin.mitch...@rackspace.com Rackspace __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
In fact, I did an example of what I thought it would look like already: https://review.openstack.org/#/c/205154/ I welcome discussion on this, especially from people who couldn't make it to the mid-cycle. Its up to y'all if you do that on this thread or in that review. Michael On Thu, Jul 23, 2015 at 11:41 AM, Sean Dague s...@dague.net wrote: On 07/23/2015 11:23 AM, Roman Podoliaka wrote: Hi all, FWIW, this is exactly what we have in oslo libs, e.g. in oslo.db [0] Putting all Nova options into one big file is probably not a good idea, still we could consider storing those per-package (per backend, per driver, etc), rather than per Python module to reduce the number of possible circular imports when using import_opt() helper. Thanks, Roman [0] https://github.com/openstack/oslo.db/blob/master/oslo_db/options.py Actually, we just happened to be discussing this at the Nova meetup this morning. And the general consensus was the opposite. It would be better to collect all the config options in one file, especially if we are going to expand the help (which we would like to do). Exceptions are done that way in Nova. Michael Still is going to propose some initial patches to get this rolling. We don't expect this to be a big bang, but in chunks as the help is being improved. -Sean -- Sean Dague http://dague.net __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev -- Rackspace Australia __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 07/23/2015 01:04 PM, Kevin L. Mitchell wrote: On Thu, 2015-07-23 at 11:41 -0500, Sean Dague wrote: On 07/23/2015 11:23 AM, Roman Podoliaka wrote: Hi all, FWIW, this is exactly what we have in oslo libs, e.g. in oslo.db [0] Putting all Nova options into one big file is probably not a good idea, still we could consider storing those per-package (per backend, per driver, etc), rather than per Python module to reduce the number of possible circular imports when using import_opt() helper. Thanks, Roman [0] https://github.com/openstack/oslo.db/blob/master/oslo_db/options.py Actually, we just happened to be discussing this at the Nova meetup this morning. And the general consensus was the opposite. It would be better to collect all the config options in one file, especially if we are going to expand the help (which we would like to do). Exceptions are done that way in Nova. Michael Still is going to propose some initial patches to get this rolling. We don't expect this to be a big bang, but in chunks as the help is being improved. I'm concerned because of how big the single configuration file will become. It is a true pain in the butt to review anything that touches the db API (or tests) because of how huge that one file is (traditional view in Gerrit performs like a dog on large files), and I'm worried that the same will become true of a single nova/flags.py if we go that route. I do like Roman's idea of centralizing them into a smattering of files, though. What if we were to create a new top-level package and split the config options up into a small number of individual files there? Would that be a reasonable compromise between Roman's suggestion and the one-file-of-config route? That's a possibility. We have number of files above 4KLOC 4168 nova/tests/unit/virt/xenapi/test_xenapi.py 4203 nova/compute/api.py 6288 nova/compute/manager.py 6397 nova/db/sqlalchemy/api.py 6818 nova/virt/libvirt/driver.py 8609 nova/tests/unit/db/test_db_api.py 11558 nova/tests/unit/compute/test_compute.py 13822 nova/tests/unit/virt/libvirt/test_driver.py Maybe a directory is fine, especially if module mapped to [subsection]. nova/config/ default.py glance.py ... which makes it reasonably discoverable and mappable back and forth from config file to files. -Sean -- Sean Dague http://dague.net signature.asc Description: OpenPGP digital signature __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Thu, 2015-07-23 at 13:50 -0500, Sean Dague wrote: Maybe a directory is fine, especially if module mapped to [subsection]. nova/config/ default.py glance.py ... which makes it reasonably discoverable and mappable back and forth from config file to files. I like that division based on subsection scheme; that seems perfect to me. -- Kevin L. Mitchell kevin.mitch...@rackspace.com Rackspace signature.asc Description: This is a digitally signed message part __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On Thu, 2015-07-23 at 11:41 -0500, Sean Dague wrote: On 07/23/2015 11:23 AM, Roman Podoliaka wrote: Hi all, FWIW, this is exactly what we have in oslo libs, e.g. in oslo.db [0] Putting all Nova options into one big file is probably not a good idea, still we could consider storing those per-package (per backend, per driver, etc), rather than per Python module to reduce the number of possible circular imports when using import_opt() helper. Thanks, Roman [0] https://github.com/openstack/oslo.db/blob/master/oslo_db/options.py Actually, we just happened to be discussing this at the Nova meetup this morning. And the general consensus was the opposite. It would be better to collect all the config options in one file, especially if we are going to expand the help (which we would like to do). Exceptions are done that way in Nova. Michael Still is going to propose some initial patches to get this rolling. We don't expect this to be a big bang, but in chunks as the help is being improved. I'm concerned because of how big the single configuration file will become. It is a true pain in the butt to review anything that touches the db API (or tests) because of how huge that one file is (traditional view in Gerrit performs like a dog on large files), and I'm worried that the same will become true of a single nova/flags.py if we go that route. I do like Roman's idea of centralizing them into a smattering of files, though. What if we were to create a new top-level package and split the config options up into a small number of individual files there? Would that be a reasonable compromise between Roman's suggestion and the one-file-of-config route? -- Kevin L. Mitchell kevin.mitch...@rackspace.com Rackspace __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 07/23/2015 11:23 AM, Roman Podoliaka wrote: Hi all, FWIW, this is exactly what we have in oslo libs, e.g. in oslo.db [0] Putting all Nova options into one big file is probably not a good idea, still we could consider storing those per-package (per backend, per driver, etc), rather than per Python module to reduce the number of possible circular imports when using import_opt() helper. Thanks, Roman [0] https://github.com/openstack/oslo.db/blob/master/oslo_db/options.py Actually, we just happened to be discussing this at the Nova meetup this morning. And the general consensus was the opposite. It would be better to collect all the config options in one file, especially if we are going to expand the help (which we would like to do). Exceptions are done that way in Nova. Michael Still is going to propose some initial patches to get this rolling. We don't expect this to be a big bang, but in chunks as the help is being improved. -Sean -- Sean Dague http://dague.net signature.asc Description: OpenPGP digital signature __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
Hi all, FWIW, this is exactly what we have in oslo libs, e.g. in oslo.db [0] Putting all Nova options into one big file is probably not a good idea, still we could consider storing those per-package (per backend, per driver, etc), rather than per Python module to reduce the number of possible circular imports when using import_opt() helper. Thanks, Roman [0] https://github.com/openstack/oslo.db/blob/master/oslo_db/options.py On Thu, Jul 23, 2015 at 6:39 PM, Kevin L. Mitchell kevin.mitch...@rackspace.com wrote: On Thu, 2015-07-23 at 17:55 +0300, mhorban wrote: During development process in nova I faced with an issue related with config options. Now we have lists of config options and registering options mixed with source code in regular files. From one side it can be convenient: to have module-encapsulated config options. But problems appear when we need to use some config option in different modules/packages. If some option is registered in module X and module X imports module Y for some reasons... and in one day we need to import this option in module Y we will get exception NoSuchOptError on import_opt in module Y. Because of circular dependency. To resolve it we can move registering of this option in Y module(in the inappropriate place) or use other tricks. Isn't this use case what the import_opt() method of CONF is for? The description given in the docstring is: Import a module and check that a given option is registered. This is intended for use with global configuration objects like cfg.CONF where modules commonly register options with CONF at module load time. If one module requires an option defined by another module it can use this method to explicitly declare the dependency. It's used all over the place in nova for this purpose, as far as I can see. I offer to create file options.py in each package and move all package's config options and registration code there. Such approach allows us to import any option in any place of nova without problems. The problem with this reorganization is that it moves the options from the place where they're primarily intended to be used. This could make it harder to maintain, such as ensuring the help text is updated when the code is. If nova were a smaller code base, I think it would make sense to reorganize in this fashion, but given how large nova actually is… -- Kevin L. Mitchell kevin.mitch...@rackspace.com Rackspace __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova
On 07/23/2015 11:41 AM, Sean Dague wrote: On 07/23/2015 11:23 AM, Roman Podoliaka wrote: Hi all, FWIW, this is exactly what we have in oslo libs, e.g. in oslo.db [0] Putting all Nova options into one big file is probably not a good idea, still we could consider storing those per-package (per backend, per driver, etc), rather than per Python module to reduce the number of possible circular imports when using import_opt() helper. Thanks, Roman [0] https://github.com/openstack/oslo.db/blob/master/oslo_db/options.py Actually, we just happened to be discussing this at the Nova meetup this morning. And the general consensus was the opposite. It would be better to collect all the config options in one file, especially if we are going to expand the help (which we would like to do). Exceptions are done that way in Nova. Michael Still is going to propose some initial patches to get this rolling. We don't expect this to be a big bang, but in chunks as the help is being improved. yay! I've always hated the define-a-config-option-in-a-module stuff that we decided to bring over from the days of using the gflags library. Best, -jay __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev