Libvirt driver class refactoring¶
https://blueprints.launchpad.net/nova/+spec/libvirt-driver-class-refactor
The libvirt driver.py class is growing ever larger and more complicated. There are circular dependencies between this class and other libvirt classes. This work aims to split some of the functionality out into new classes
Problem description¶
The libvirt driver.py class is growing ever larger over time. This is increasing the complexity of the code and also resulting in larger test suites.
The driver.py class is serving what are really a number of distinct use cases. Primarily it is the interface for the compute manager class to consume. It also, however, has alot of helper APIs for dealing with the libvirt connection and the host operating system, as well as helpers for dealing with guest instance configuration. A number of these helpers are required by other libvirt modules such as the vif, volume and image backend drivers. This has resulted in circular dependancies between the driver.py and the other libvirt modules. For example, LibvirtDriver uses NWFilterFirewall, but also has to pass a ‘get_connection’ callback so that NWFilterFirewall can obtain the libvirt connection from the LibvirtDriver class. There are a number of other similar deps.
Proposed change¶
The intention is to introduce two new modules to the codebase
host.py - this will encapsulate access to libvirt and the host operating system state. It will contain a ‘Host’ class, which manages a single libvirt connection. It will contain the methods for connecting to libvirt, getting lists of domains, querying host performance metrics and so on (see the work-items section for specifics). This is not to be confused with the existing HostState class which is just a trivial helper for the driver ‘host_state’ method.
guest.py - this will encapsulate interaction with libvirt guest domain instances. It will contain a ‘Guest’ class, which manages a single libvirt guest domain. It will contain all methods used to construct the guest XML configuration during instance startup that currently live in driver.py
The code for host.py and guest.py will be pulled out of the existing driver.py class. Other libvirt modules will be updated as needed to access the new APIs. To minimize the risk of creating regressions changes to the methods being moved will be minimized, to just minor renames & fixups where appropriate.
The intended end result is that none of the modules in the libvirt driver directory should need to access the driver.py file. They should be able to consume the host.py and guest.py APIs instead, thus breaking the circular dependancies. For example the NWFilterFirewall class can be given an instance of the Host class instead of a callback to LibvirtDriver.
The new structure should also reduce the size of the test_driver.py file and make it possible to create simpler, self contained tests for the functionality that’s in host.py and guest.py, since it will be isolated from the overall virt driver API.
It is not anticipated that any configuration parameters will move. The high level desire is that the new APIs will not directly use any Nova configuration parameters. Instead the LibvirtDriver would be responsible for reading the config parameters and then setting attributes on the new class or passing method parameters where appropriate.
At the end of the work there should be absolutely no functional change on the libvirt driver. This is intended to be purely refactoring work that is invisible to anyone except the people writing libvirt driver code.
Alternatives¶
Doing nothing is always an option, but it isn’t very appealing because it leaves us with an ever growing monster ready to devour us at any moment.
Data model impact¶
None
REST API impact¶
None
Security impact¶
None
Notifications impact¶
None
Other end user impact¶
None
Performance Impact¶
None
Other deployer impact¶
None
Developer impact¶
There are liable to be conflicts with any developers who have patches touching driver.py or test_driver.py
Implementation¶
Assignee(s)¶
- Primary assignee:
berrange
Work Items¶
Create a host.py module and move the basic connection handling code out of driver.py into the new Host class. This will cover the following methods:
_conn_has_min_version
_has_min_version
_native_thread
_dispatch_thread
_event_lifecycle_callback
_queue_Event
_dispatch_events
_init_events_pipe
_init_events
_get_new_connection
_close_callback
_test_connection
_connect
Move helpers used by HostState out into the Host class. This will cover the following methods
_get_vcpu_total
_get_memory_mb_total
_get_vcpu_used
_get_memory_mb_used
_get_hypervisor_type
_get_hypervisor_version
_get_hypervisor_hostname
_get_cpu_info
_get_disk_available_least
Create a guest.py module and move the code for creating the guest XML configuration out of driver.py into the new Guest class. This will cover the following methods
_get_guest_cpu_model_config
_get_guest_cpu_config
_get_guest_disk_config
_get_guest_storage_config
_get_guest_config_sysinfo
_get_guest_pci_device
_get_guest_config
_get_guest_xml
Move the code for listing domains into the new Host class. This will cover the ‘_list_instance_domains’ method.
Change NWFilterFirewall and LibvirtBaseVIFDriver so that they accept a ‘Host’ object instance, instead of requiring a callback to the LibvirtDriver class.
Anything else that appears relevant to move :-)
Dependencies¶
None
Testing¶
Since it is intended that there is no functional change in this work, the existing test coverage should be sufficient. The existing unit tests will need some refactoring as code is moved, and some more unit tests will be written where appropriate.
Documentation Impact¶
None
References¶
None