<font face="arial" size="2"><p style="margin:0;padding:0;">This is a very good point.</p>
<p style="margin:0;padding:0;"> </p>
<p style="margin:0;padding:0;">+1 to accepting an enum or classname, unless there is an even better solution.</p>
<p style="margin:0;padding:0;"> </p>
<p style="margin:0;padding:0;">How do we currently handle the mapping of extensions that are turned on or off?</p>
<p style="margin:0;padding:0;"> </p>
<p style="margin:0;padding:0;">-Alex</p>
<p style="margin:0;padding:0;"> </p>
<p style="margin:0;padding:0;">-----Original Message-----<br />From: "Anne Gentle" <anne@openstack.org><br />Sent: Wednesday, February 6, 2013 1:26pm<br />To: "Daniel P. Berrange" <berrange@redhat.com>, "OpenStack Development Mailing List" <openstack-dev@lists.openstack.org><br />Subject: Re: [openstack-dev] RFC: Classnames in config parameters harmful to users / upgrades<br /><br /></p>
<div id="SafeStyles1360176593">
<div dir="ltr"><br />
<div class="gmail_extra"><br /><br />
<div class="gmail_quote">On Wed, Feb 6, 2013 at 9:22 AM, Daniel P. Berrange <span dir="ltr"><<a href="mailto:berrange@redhat.com" target="_blank">berrange@redhat.com</a>></span> wrote:<br />
<blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;">Nova (and most other OpenStack components) have an ever increasing<br /> number of configuration parameters which accept classnames.<br /> Obviously, we're doing this to make it possible to plug in custom<br /> implementations of various interfaces, which is great.<br /><br /> There are two downsides to this<br /><br /> - The user has to know about obscure, often undocumented, python<br /> module names.<br /><br /></blockquote>
<div>Thanks for shining a light on this particular difficulty. While we now have a sample nova.conf with descriptions, any use of and changes to class names in both nova and quantum have caused headaches for users. And doc bugs too.</div>
<div></div>
<blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;">- Any time we rename a class, or refactor code possibly deleting<br /> or merging classes, we break the end config file upon upgrade.<br /><br /> The first point is a mere usability matter, but the second point<br /> is a serious deployment issue IMHO, which can only get worse as<br /> usage of OpenStack increases & people expect more stability and<br /> consistency across upgrades.<br /><br /> Historically code changes have been pretty fast & loose config<br /> parameters, arbitrarily changing them at any time for any reason.<br /> AFAIK there are no formal rules defined about changing config<br /> paramaters, but in some of the recent changes I've submitted<br /> which involved config changes, reviewers wanted backwards compat<br /> to be maintained. The result that when renaming, or obsoleting<br /> existing classses we're having to keep around stubs for the old<br /> classes to avoid breaking user config files. This is not a good<br /> approach for long term maintainability of the codebase.<br /><br /> IMHO the core issue here is that by using classnames in config<br /> parameters we are exposing what we (developers) generally consider<br /> to be internal/private implementation details to the end user. End<br /> user expectations wrt upgrades are thus restricting what we can do<br /> with our internal implementations.<br /><br /> I don't think it is acceptable to have a situation where configuration<br /> file parameters restrict what we can do in terms of re-arranging /<br /> refactoring our codebase. Provided we maintain the same featureset<br /> compatibility, we should be free todo any code refactoring we desire.<br /><br /> The only way we can do this is if we do *NOT* require the use of<br /> classnames in config parameters. Instead we should treat all these<br /> config parameters as being more like enumerations, and map those to<br /> classnames internally<br /></blockquote>
<div>I would completely support this and wish I had dev resources to put behind the effort. Is there a group who wants to work on this? <br /><br /></div>
<div>44 isn't bad out of over 600 I might add.</div>
<div>Let me help any way I can.<br /><br />Anne</div>
<div></div>
<blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><br /> eg for the compute_driver instead of having the user set<br /><br /> compute_driver=nova.virt.libvirt.LibvirtDriver<br /><br /> they would do<br /><br /> compute_driver=libvirt<br /><br /> and internally nova would resolve this to the classname. Obviously the<br /> key issue is how we deal with the mapping of enum values to classnames.<br /> If we just had a table of mappings in the codebase, then it ceases to<br /> be possible for people to drop in custom out-of-tree implementations<br /> from 3rd parties.<br /><br /> One option to this would be to allow the config parameters to take a<br /> enum value, or a classname. We would declare the enum values as<br /> "stable, guaranteed upgrade compatibility", and the use of classnames<br /> as "liable to break on upgrade". The intent would be that all our<br /> documentation / tools like devstack, etc would use the short enum<br /> names by default. The only people who would ever use classnames for the<br /> config parameters, would be those who need to plug in a 3rd party impl<br /> that is not part of the main openstack codebase.<br /><br /> A different option would be to only ever allow for enum values in the<br /> config parameter, but define a way for 3rd parties to register their<br /> new impls. For example, you could have them do something like<br /><br /> # cd /usr/share/openstack/nova/configmap/compute_driver<br /> # echo "nova.virt.libvirt.LibvirtDriver" > libvirt<br /><br /> as a way to register that the 'compute_driver' parameter gets a new<br /> valid option of 'libvirt' mapping to the classname<br /> "nova.virt.libvirt.LibvirtDriver"<br /><br /> Regards,<br /> Daniel<br /><br /> [1] In fact Nova currently has at least 44 classname based options<br /><br /> $ grep 'nova\.' etc/nova/nova.conf.sample  | grep -v "# " | sort | sed -e 's/#//'<br /> allowed_rpc_exception_modules=nova.openstack.common.exception,nova.exception,cinder.exception,exceptions<br /> cert_manager=nova.cert.manager.CertManager<br /> compute_api_class=nova.compute.api.API<br /> compute_manager=nova.compute.manager.ComputeManager<br /> compute_scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler<br /> compute_stats_class=nova.compute.stats.Stats<br /> consoleauth_manager=nova.consoleauth.manager.ConsoleAuthManager<br /> console_driver=nova.console.xvp.XVPConsoleProxy<br /> console_manager=nova.console.manager.ConsoleProxyManager<br /> db_driver=nova.db<br /> default_scheduler_driver=nova.scheduler.chance.ChanceScheduler<br /> driver=nova.cells.rpc_driver.CellsRPCDriver<br /> driver=nova.virt.baremetal.pxe.PXE<br /> floating_ip_dns_manager=nova.network.noop_dns_driver.NoopDNSDriver<br /> instance_dns_manager=nova.network.noop_dns_driver.NoopDNSDriver<br /> l3_lib=nova.network.l3.LinuxNetL3<br /> libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtBridgeDriver<br /> libvirt_volume_drivers=iscsi=nova.virt.libvirt.volume.LibvirtISCSIVolumeDriver,local=nova.virt.libvirt.volume.LibvirtVolumeDriver,fake=nova.virt.libvirt.volume.LibvirtFakeVolumeDriver,rbd=nova.virt.libvirt.volume.LibvirtNetVolumeDriver,sheepdog=nova.virt.libvirt.volume.LibvirtNetVolumeDriver,nfs=nova.virt.libvirt.volume_nfs.NfsVolumeDriver<br /> linuxnet_interface_driver=nova.network.linux_net.LinuxBridgeInterfaceDriver<br /> manager=nova.cells.manager.CellsManager<br /> manager=nova.conductor.manager.ConductorManager<br /> metadata_manager=nova.api.manager.MetadataManager<br /> monkey_patch_modules=nova.api.ec2.cloud:nova.notifier.api.notify_decorator,nova.compute.api:nova.notifier.api.notify_decorator<br /> network_api_class=nova.network.api.API<br /> network_driver=nova.network.linux_net<br /> network_manager=nova.network.manager.VlanManager<br /> osapi_compute_extension=nova.api.openstack.compute.contrib.standard_extensions<br /> power_manager=nova.virt.baremetal.ipmi.IPMI<br /> quota_driver=nova.quota.DbQuotaDriver<br /> rpc_backend=nova.openstack.common.rpc.impl_kombu<br /> rpc_zmq_matchmaker=nova.openstack.common.rpc.matchmaker.MatchMakerLocalhost<br /> scheduler_available_filters=nova.scheduler.filters.all_filters<br /> scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler<br /> scheduler_host_manager=nova.scheduler.host_manager.HostManager<br /> scheduler_manager=nova.scheduler.manager.SchedulerManager<br /> scheduler=nova.cells.scheduler.CellsScheduler<br /> scheduler_weight_classes=nova.scheduler.weights.all_weighers<br /> security_group_api=nova.compute.api.SecurityGroupAPI<br /> security_group_handler=nova.network.sg.NullSecurityGroupHandler<br /> sqlite_db=nova.sqlite<br /> vif_driver=nova.virt.baremetal.vif_driver.BareMetalVIFDriver<br /> volume_api_class=nova.volume.cinder.API<br /> volume_driver=nova.virt.baremetal.volume_driver.LibvirtVolumeDriver<br /> xenapi_vif_driver=nova.virt.xenapi.vif.XenAPIBridgeDriver<br /><span class="HOEnZb"><span style="color: #888888;"><br /> --<br /> |: <a href="http://berrange.com" target="_blank">http://berrange.com</a> -o-    <a href="http://www.flickr.com/photos/dberrange/" target="_blank">http://www.flickr.com/photos/dberrange/</a> :|<br /> |: <a href="http://libvirt.org" target="_blank">http://libvirt.org</a> -o-             <a href="http://virt-manager.org" target="_blank">http://virt-manager.org</a> :|<br /> |: <a href="http://autobuild.org" target="_blank">http://autobuild.org</a> -o-         <a href="http://search.cpan.org/~danberr/" target="_blank">http://search.cpan.org/~danberr/</a> :|<br /> |: <a href="http://entangle-photo.org" target="_blank">http://entangle-photo.org</a> -o-       <a href="http://live.gnome.org/gtk-vnc" target="_blank">http://live.gnome.org/gtk-vnc</a> :|<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 /></span></span></blockquote>
</div>
</div>
</div>
</div></font>