<div dir="ltr"><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 11, 2014 at 4:38 PM, Shaun McCance <span dir="ltr"><<a href="mailto:shaunm@gnome.org" target="_blank">shaunm@gnome.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Mon, 2014-02-10 at 10:50 -0500, Doug Hellmann wrote:<br>
><br>
>         2) It locates options based on them being defined at the top<br>
>         level of a<br>
>         module (not in function or packed into some object), but it<br>
>         gets info by<br>
>         looking at cfg.CONF, which require registration. This fails if<br>
>         an option<br>
>         is defined by only registered when some function is called.<br>
>         This happens<br>
>         right now with the ip_lib_force_root option in Neutron. Both<br>
>         the config<br>
>         file generator and config docs generator currently crash on<br>
>         Neutron<br>
>         because of this.<br>
><br>
><br>
> The option definition needs to be in a variable at the module top<br>
> level, even if the registration call happens at run time. Can you file<br>
> a bug against Neutron about that?<br>
<br>
</div>The option *is* currently defined at the module top level, though it's<br>
only registered when a function is called. _guess_groups in generator.py<br>
raises an error, because it looks for all instantiated options in the<br>
cfg.CONF object, and it's not there.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:small">Ah, OK, I think we should consider that a bug in the generator.</div><br></div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im"><br>
<br>
>         3) It's completely incapable of finding options that aren't<br>
>         defined or<br>
>         registered until some function is called or some object is<br>
>         instantiated.<br>
>         I don't have a general solution to this, although I do have<br>
>         special-case<br>
>         code that detects projects that use oslo.messaging and ensures<br>
>         those<br>
>         options get registered.<br>
><br>
><br>
> I did some work to address this under<br>
> <a href="https://blueprints.launchpad.net/oslo/+spec/improve-config-discovery-for-docs" target="_blank">https://blueprints.launchpad.net/oslo/+spec/improve-config-discovery-for-docs</a> so that libraries can register entry points that declare configuration options. I think the only library using this feature so far is oslo.messaging, but the other oslo libraries will use it when they graduate from the incubator.<br>

<br>
</div>Oh, thanks. That's much cleaner than my workaround for oslo.messaging:<br>
<br>
<a href="https://review.openstack.org/#/c/68196/" target="_blank">https://review.openstack.org/#/c/68196/</a><br>
<div class="im"><br>
<br>
<br>
>         To address these issues, I'd like to get oslo.config to know<br>
>         about the<br>
>         defining module for each option. It can get that using<br>
>         something like<br>
>         this in Opt.__init__:<br>
><br>
>         for frame in inspect.stack():<br>
>             mod = inspect.getmodule(frame[0])<br>
>             if mod == sys.modules[__name__]:<br>
>                 continue<br>
>             self.module = mod.__name__<br>
>                 break<br>
><br>
><br>
> I'm not sure we want deployers to have to worry about where the option<br>
> is defined. How would you use the information in the documentation? I<br>
> guess we include it in the sample config output?<br>
<br>
</div>I agree that deployers shouldn't have to care about the defining module.<br>
The only reason I've proposed it is that the entire architecture of the<br>
sample config generator is geared around poking into modules looking for<br>
options, because it wants to group options by module. This one addition<br>
to Opt.__init__ would make things simpler and faster for the sample<br>
config generator.<br>
<br>
As for the docs, I'm not sure if we want that info in there or not. I<br>
wouldn't push hard for it if it's not already there. Whether we'd bother<br>
with it if it is available is something I'd have to ask the rest of the<br>
docs team.<br>
<div class="im"><br>
><br>
>         We'd also have to modify __eq__ and __ne__, because it's valid<br>
>         for an<br>
>         option to be defined in two different modules as long as all<br>
>         its<br>
>         parameters are the same. Checking vars() equality would trip<br>
>         up on the<br>
>         module. (There's the further issue that the defining module is<br>
>         non-deterministic in those cases.)<br>
><br>
><br>
> It's valid for an option to be registered with the same definition<br>
> more than once, but having the definition live in more than one place<br>
> is just asking for maintenance trouble later. Do we actually have this<br>
> situation now?<br>
<br>
</div>auth_strategy is defined in both neutron/common/config.py and<br>
neutron/agent/linux/interface.py. It would also be defined in<br>
neutron/agent/metadata/agent.py, except it's defined in a class variable<br>
and only registered by calling main().<br>
<div class="im"><br>
><br>
><br>
>         Then I'd like to get both the config file generator and the<br>
>         config docs<br>
>         generator using something like the OptionsCache class I wrote<br>
>         for the<br>
>         config docs generator:<br>
><br>
>         <a href="http://git.openstack.org/cgit/openstack/openstack-doc-tools/tree/autogenerate_config_docs/common.py#n88" target="_blank">http://git.openstack.org/cgit/openstack/openstack-doc-tools/tree/autogenerate_config_docs/common.py#n88</a><br>

><br>
>         This could be simpler and faster and avoid the crash mentioned<br>
>         above<br>
>         with the module info attached to each option.<br>
><br>
><br>
> Having 2 programs that discover options in 2 ways is a bad thing, so<br>
> yes, let's combine them in oslo.config and let them share code.<br>
<br>
</div>Great. So I think there's three things we'll have to figure out:<br>
<br>
1) What's the best way to group things by module? The answer might just<br>
be "It's not really worth grouping things by module."<br>
<br>
2) Is it sufficient to just ask cfg.CONF for options, or do we need to<br>
poke around looking for unregistered options? If the latter, where do we<br>
put that poking around code?<br>
<br>
3) Where do we put the code that sanitizes the defaults? That's the<br>
other piece of the sample config generator I'm using. It's a _private<br>
function right now, so I'm a bit uneasy about using it. I don't know if<br>
that belongs in oslo.config proper. It's only useful to these generator<br>
programs.<br>
<div class="HOEnZb"><div class="h5"><br>
--<br>
Shaun<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</div></div></blockquote></div><br></div></div>