[ I fixed up ovirt-devel(a)redhat.com to be devel(a)ovirt.org since the
former is deprecated. I'm also not trimming down much of the reply so
that they can get the whole picture. Sorry for the confusion ]
On Tue, Mar 20, 2018 at 03:10:12PM +0000, Daniel P. Berrangé wrote:
On Tue, Mar 20, 2018 at 03:20:31PM +0100, Martin Kletzander wrote:
> 1) Default devices/values
> Libvirt itself must default to whatever values there were before any
> particular element was introduced due to the fact that it strives to
> keep the guest ABI stable. That means, for example, that it can't just
> add -vmcoreinfo option (for KASLR support) or magically add the pvpanic
> device to all QEMU machines, even though it would be useful, as that
> would change the guest ABI.
> For default values this is even more obvious. Let's say someone figures
> out some "pretty good" default values for various HyperV enlightenment
> feature tunables. Libvirt can't magically change them, but each one of
> the projects building on top of it doesn't want to keep that list
> updated and take care of setting them in every new XML. Some projects
> don't even expose those to the end user as a knob, while others might.
This gets very tricky, very fast.
Lets say that you have an initial good set of hyperv config
tunables. Now sometime passes and it is decided that there is a
different, better set of config tunables. If the module that is
providing this policy to apps like OpenStack just updates itself
to provide this new policy, this can cause problems with the
existing deployed applications in a number of ways.
First the new config probably depends on specific versions of
libvirt and QEMU, and you can't mandate to consuming apps which
versions they must be using. So you need a matrix of libvirt +
QEMU + config option settings.
Even if you have the matching libvirt & QEMU versions, it is not
safe to assume the application will want to use the new policy.
An application may need live migration compatibility with older
versions. Or it may need to retain guaranteed ABI compatibility
with the way the VM was previously launched and be using transient
guests, generating the XML fresh each time.
The application will have knowledge about when it wants to use new
vs old hyperv tunable policy, but exposing that to your policy module
is very tricky because it is inherantly application specific logic
largely determined by the way the application code is written.
The idea was for updating XML based on policy, which is something you
want for new machines. You should then keep the XML per domain and only
do changes to if requested by the user or when libvirt fills in new
values in a guest ABI compatible fashion.
> One more thing could be automatically figuring out best values based on
> libosinfo-provided data.
> 2) Policies
> Lot of the time there are parts of the domain definition that need to be
> added, but nobody really cares about them. Sometimes it's enough to
> have few templates, another time you might want to have a policy
> per-scenario and want to combine them in various ways. For example with
> the data provided by point 1).
> For example if you want PCI-Express, you need the q35 machine type, but
> you don't really want to care about the machine type. Or you want to
> use SPICE, but you don't want to care about adding QXL.
> What if some of these policies could be specified once (using some DSL
> for example), and used by virtuned to merge them in a unified and
> predictable way?
> 3) Abstracting the XML
> This is probably just usable for stateless apps, but it might happen
> that some apps don't really want to care about the XML at all. They
> just want an abstract view of the domain, possibly add/remove a device
> and that's it. We could do that as well. I can't really tell how much
> of a demand there is for it, though.
It is safe to say that applications do not want to touch XML at all.
Any non-trivial application has created an abstraction around XML,
so that they have an API to express what they want, rather than
manipulating of strings to format/parse XML.
Sure, this was just meant to be a question as to whether it's worth
pursuing or not. You make a good point on why it is not (at least for
However, since this was optional, the way this would look without the
XML abstraction is that both input and output would be valid domain
definitions, ultimately resulting in something similar to virt-xml with
the added benefit of applying a policy from a file/string either
supplied by the application itself. Whether that policy was taken from
a common repository of such knowledge is orthogonal to this idea. Since
you would work with the same data, the upgrade could be incremental as
you'd only let virtuned fill in values for new options and could slowly
move on to using it for some pre-existing ones. None of the previous
approaches did this, if I'm not mistaken. Of course it gets more
difficult when you need to expose all the bits libvirt does and keep
them in sync (as you write below).
If there was something higher level that gets more interesting,
but the hard bit is that you still need a way to get at all the
low level bits becuase a higher level abstracted API will never
cover every niche use case.
Oh, definitely not every, but I see two groups of projects that have a
lot in common between themselves and between the groups as well. On the
other hand just templating and defaults is something that's easy enough
to do that it's not worth outsourcing that into another one's codebase.
> 4) Identifying devices properly
> In contrast to the previous point, stateful apps might have a problem
> identifying devices after hotplug. For example, let's say you don't
> care about the addresses and leave that up to libvirt. You hotplug a
> device into the domain and dump the new XML of it. Depending on what
> type of device it was, you might need to identify it based on different
> values. It could be <target dev=''/> for disks, <mac
> interfaces etc. For some devices it might not even be possible and you
> need to remember the addresses of all the previous devices and then
> parse them just to identify that one device and then throw them away.
> With new enough libvirt you could use the user aliases for that, but
> turns out it's not that easy to use them properly anyway. Also the
> aliases won't help users identify that device inside the guest.
NB, relating between host device config and guest visible device
config is a massive problem space in its own right, and not very
easy to address. In OpenStack we ended up defining a concept of
"device tagging" via cloud-init metadata, where openstack allows
users to set opaque string tags against devices their VM has.
OpenStack that generates a metadata file that records various
pieces of identifying hardware attributes (PCI address, MAC
addr, disk serial, etc) alongside the user tag. This metadata
file is exposed to the guest with the hope that there's enough
info to allow the user to decide which device is to be used for
This is good point, but I was mostly thinking about identifying devices
from the host POV between two different XMLs (pre- and post- some
XML-modifying action, like hotplug).
> We really should've gone with new attribute for the user alias instead
> of using an existing one, given how many problems that is causing.
> 5) Generating the right XML snippet for device hot-(un)plug
> This is kind of related to some previous points.
> When hot-plugging a device and creating an XML snippet for it, you want
> to keep the defaults from point 1) and policies from 2) in mind. Or
> something related to the already existing domain which you can describe
> systematically. And adding something for identification (see previous
> Doing the hot-unplug is easy depending on how much information about
> that device is saved by your application. The less you save about the
> device (or show to the user in a GUI, if applicable) the harder it might
> be to generate an XML that libvirt will accept. Again, some problems
> with this should be fixed in libvirt, some of them are easy to
> workaround. But having a common ground that takes care of this should
> help some projects.
> Hot-unplug could be implemented just based on the alias. This is
> something that would fit into libvirt as well.
> To mention some pre-existing solutions:
> - I understand OpenStack has some really sensible and wisely chosen
> and/or tested default values.
In terms of default devices and OS specific choices, OpenStack's
decisions have been largely inspired by previous work in oVirt
and / or virt-manager. So there's obviously overlap in the
conceptual area, but there's also plenty that is very specific
to OpenStack - untangling the two extract the common bits from
the app specific bits is hard.
It definitely is, but do you think it's so difficult it's worthless to
pursuit? I did a tiny PoC based on the code from virt-manager, which
was trivial mainly thanks to the XMLBuilder for the domain objects.
Maybe exposing an easy way to work with the XML would be enough for some
Little birdie from oVirt told me that they would like some of sort of
thing that does what you can achieve with virt-xml if we, for example,
made it work on pure XML definitions without connecting to libvirt.
> - I know KubeVirt has VirtualMachinePresets. That is something
> related to points 1) and 2). Also their abstraction of the XML might
> be usable for point 3).
> - There was an effort on creating policy based configuration of libvirt
> objects called libvirt-designer. This is closely related to points 2)
> and 3). Unfortunately there was no much going on lately and part of
> virt-manager repository has currently more features implemented with
> the same ideas in mind, just not exported for public use.
This is the same kind of problem we faced wrt libvirt-gconfig and
libvirt-gobject usage from virt-manager - it has an extensive code
base that already works, and rewriting it to use something new
is alot of work for no short-term benefit. libvirt-gconfig/gobject
were supposed to be the "easy" bits for virt-manager to adopt, as
they don't really include much logic that would step on virt-manager's
toes. libvirt-designer was going to be a very opinionated library
and in retrospective that makes it even harder to consider adopting
it for usage in virt-manager, as it'll have signficant liklihood
of making functionally significant changes in behaviour.
The initial idea (which I forgot to mention) was that all the decisions
libvirt currently does (so that it keeps the guest ABI stable) would be
moved into data (let's say some DSL) and it could then be switched or
adjusted if that's not what the mgmt app wants (on a per-definition
basis, of course). I didn't feel very optimistic about the upstream
acceptance for that idea, so I figured that there could be something
that lives beside libvirt, helps with some policies if requested and
then the resulting XML could be fed into libvirt for determining the
There's also the problem with use of native libraries that would
impact many apps. We only got OpenStack to grudgingly allow the
By native you mean actual binary libraries or native to the OpenStack
code as in python module? Because what I had in mind for this project
was a python module with optional wrapper for REST API.
use of libosinfo native library via GObject Introspection, by
promising to do work to turn the osinfo database into an approved
stable format which OpenStack could then consume directly, dropping
the native API usage :-( Incidentally, the former was done (formal
spec for the DB format), but the latter was not yet (direct DB usage
BTW, I don't like that I'm being so negative to your proposal :-(
I used to hope that we would be able to build higher level APIs on
top of libvirt to reduce the overlap between different applications
reinventing the wheel. Even the simplest bits we tried like the
gconfig/gobject API are barely used. libvirt-designer is basically
a failure. Though admittedly it didn't have enough development resource
applied to make it compelling, in retrospect adoption was always going
to be a hard sell except in greenfield developments.
I'm glad for the knowledge you provided. So maybe instead of focusing
on de-duplication of existing codebases we could _at least_ aim at
future mgmt apps. OTOH improving documentation on how to properly build
higher level concepts on top of libvirt would benefit them as well.
Libosinfo is probably the bit we've had most success with, and
most promise for the future, particularly now that we formally allow
apps to read the osinfo database directly and bypass the API. It is
quite easy to fit into existing application codebases which helps alot.
Even there I'm still disappointed that we only have GNOME Boxes using
the kickstart generator part of osinfo - oVirt and Oz both still have
their own kickstart generator code for automating OS installs.
In general though, I fear anything API based is going to be a really
hard sell to get wide adoption for based on what we've seen before.
I think the biggest bang-for-buck is identifying more areas where we
can turn code into data. There's definitely scope for recording more
types of information in the osinfo database. There might also be
scope for defining entirely new databases to complement the osinfo
data, if something looks out of scope for libosinfo.