Re: [openstack-dev] [openstack][nova] Streamlining of config options in nova

2015-08-28 Thread Davanum Srinivas
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

2015-08-28 Thread Markus Zoeller
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

2015-08-19 Thread Markus Zoeller
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

2015-08-17 Thread Markus Zoeller
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

2015-08-13 Thread Daniel P. Berrange
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

2015-08-13 Thread Sean Dague
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

2015-08-12 Thread Markus Zoeller
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

2015-08-12 Thread Jay Pipes

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

2015-08-12 Thread Sean Dague
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

2015-08-12 Thread Michael Still
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

2015-07-27 Thread Sean Dague
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

2015-07-27 Thread Daniel P. Berrange
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

2015-07-27 Thread Sean Dague
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

2015-07-25 Thread Jay Pipes

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

2015-07-24 Thread Daniel P. Berrange
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

2015-07-24 Thread Daniel P. Berrange
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

2015-07-24 Thread Doug Hellmann
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

2015-07-24 Thread Joshua Harlow

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

2015-07-24 Thread Doug Hellmann
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

2015-07-24 Thread Michael Still
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

2015-07-24 Thread Daniel P. Berrange
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

2015-07-24 Thread Joshua Harlow

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

2015-07-24 Thread Doug Hellmann
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

2015-07-24 Thread Daniel P. Berrange
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

2015-07-24 Thread Doug Hellmann
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

2015-07-24 Thread Doug Hellmann
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

2015-07-24 Thread Michael Still
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

2015-07-24 Thread Markus Zoeller
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

2015-07-23 Thread Markus Zoeller
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

2015-07-23 Thread mhorban

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

2015-07-23 Thread Kevin L. Mitchell
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

2015-07-23 Thread Michael Still
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

2015-07-23 Thread Sean Dague
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

2015-07-23 Thread Kevin L. Mitchell
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

2015-07-23 Thread Kevin L. Mitchell
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

2015-07-23 Thread Sean Dague
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

2015-07-23 Thread Roman Podoliaka
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

2015-07-23 Thread Jay Pipes

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