[openstack-dev] RFC: Classnames in config parameters harmful to users / upgrades

Daniel P. Berrange berrange at redhat.com
Wed Feb 6 15:22:20 UTC 2013


Nova (and most other OpenStack components) have an ever increasing
number of configuration parameters which accept classnames.
Obviously, we're doing this to make it possible to plug in custom
implementations of various interfaces, which is great.

There are two downsides to this

 - The user has to know about obscure, often undocumented, python
   module names.

 - Any time we rename a class, or refactor code possibly deleting
   or merging classes, we break the end config file upon upgrade.

The first point is a mere usability matter, but the second point
is a serious deployment issue IMHO, which can only get worse as
usage of OpenStack increases & people expect more stability and
consistency across upgrades.

Historically code changes have been pretty fast & loose config
parameters, arbitrarily changing them at any time for any reason.
AFAIK there are no formal rules defined about changing config
paramaters, but in some of the recent changes I've submitted
which involved config changes, reviewers wanted backwards compat
to be maintained. The result that when renaming, or obsoleting
existing classses we're having to keep around stubs for the old
classes to avoid breaking user config files. This is not a good
approach for long term maintainability of the codebase.

IMHO the core issue here is that by using classnames in config
parameters we are exposing what we (developers) generally consider
to be internal/private implementation details to the end user. End
user expectations wrt upgrades are thus restricting what we can do
with our internal implementations.

I don't think it is acceptable to have a situation where configuration
file parameters restrict what we can do in terms of re-arranging /
refactoring our codebase. Provided we maintain the same featureset
compatibility, we should be free todo any code refactoring we desire.

The only way we can do this is if we do *NOT* require the use of
classnames in config parameters. Instead we should treat all these
config parameters as being more like enumerations, and map those to
classnames internally

eg for the compute_driver instead of having the user set

  compute_driver=nova.virt.libvirt.LibvirtDriver

they would do

  compute_driver=libvirt

and internally nova would resolve this to the classname. Obviously the
key issue is how we deal with the mapping of enum values to classnames.
If we just had a table of mappings in the codebase, then it ceases to
be possible for people to drop in custom out-of-tree implementations
from 3rd parties.

One option to this would be to allow the config parameters to take a
enum value, or a classname. We would declare the enum values as
"stable, guaranteed upgrade compatibility", and the use of classnames
as "liable to break on upgrade". The intent would be that all our
documentation / tools like devstack, etc would use the short enum
names by default. The only people who would ever use classnames for the
config parameters, would be those who need to plug in a 3rd party impl
that is not part of the main openstack codebase.

A different option would be to only ever allow for enum values in the
config parameter, but define a way for 3rd parties to register their
new impls. For example, you could have them do something like

  # cd /usr/share/openstack/nova/configmap/compute_driver
  # echo "nova.virt.libvirt.LibvirtDriver" > libvirt

as a way to register that the 'compute_driver' parameter gets a new
valid option of 'libvirt' mapping to the classname
"nova.virt.libvirt.LibvirtDriver"

Regards,
Daniel

[1] In fact Nova currently has at least 44 classname based options

$ grep 'nova\.' etc/nova/nova.conf.sample  | grep -v "# " | sort | sed -e 's/#//'
allowed_rpc_exception_modules=nova.openstack.common.exception,nova.exception,cinder.exception,exceptions
cert_manager=nova.cert.manager.CertManager
compute_api_class=nova.compute.api.API
compute_manager=nova.compute.manager.ComputeManager
compute_scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler
compute_stats_class=nova.compute.stats.Stats
consoleauth_manager=nova.consoleauth.manager.ConsoleAuthManager
console_driver=nova.console.xvp.XVPConsoleProxy
console_manager=nova.console.manager.ConsoleProxyManager
db_driver=nova.db
default_scheduler_driver=nova.scheduler.chance.ChanceScheduler
driver=nova.cells.rpc_driver.CellsRPCDriver
driver=nova.virt.baremetal.pxe.PXE
floating_ip_dns_manager=nova.network.noop_dns_driver.NoopDNSDriver
instance_dns_manager=nova.network.noop_dns_driver.NoopDNSDriver
l3_lib=nova.network.l3.LinuxNetL3
libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtBridgeDriver
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
linuxnet_interface_driver=nova.network.linux_net.LinuxBridgeInterfaceDriver
manager=nova.cells.manager.CellsManager
manager=nova.conductor.manager.ConductorManager
metadata_manager=nova.api.manager.MetadataManager
monkey_patch_modules=nova.api.ec2.cloud:nova.notifier.api.notify_decorator,nova.compute.api:nova.notifier.api.notify_decorator
network_api_class=nova.network.api.API
network_driver=nova.network.linux_net
network_manager=nova.network.manager.VlanManager
osapi_compute_extension=nova.api.openstack.compute.contrib.standard_extensions
power_manager=nova.virt.baremetal.ipmi.IPMI
quota_driver=nova.quota.DbQuotaDriver
rpc_backend=nova.openstack.common.rpc.impl_kombu
rpc_zmq_matchmaker=nova.openstack.common.rpc.matchmaker.MatchMakerLocalhost
scheduler_available_filters=nova.scheduler.filters.all_filters
scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler
scheduler_host_manager=nova.scheduler.host_manager.HostManager
scheduler_manager=nova.scheduler.manager.SchedulerManager
scheduler=nova.cells.scheduler.CellsScheduler
scheduler_weight_classes=nova.scheduler.weights.all_weighers
security_group_api=nova.compute.api.SecurityGroupAPI
security_group_handler=nova.network.sg.NullSecurityGroupHandler
sqlite_db=nova.sqlite
vif_driver=nova.virt.baremetal.vif_driver.BareMetalVIFDriver
volume_api_class=nova.volume.cinder.API
volume_driver=nova.virt.baremetal.volume_driver.LibvirtVolumeDriver
xenapi_vif_driver=nova.virt.xenapi.vif.XenAPIBridgeDriver

-- 
|: 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 :|



More information about the OpenStack-dev mailing list