<div dir="ltr"><div><div><div><div>Martin and Daniel, are you making different scope assumptions here?  I suspect:<br></div>- Daniel is assuming that profiles and applications are orthogonal, and that any application has to be able to live with any profile dropped in;<br></div>- Martin is assuming that profiles are tied to applications; this is a tool for moving custom logic within an application to reusable tooling but each application has its own set of profiles.<br><br></div>Cheers,<br><br></div>- Peter<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 9 July 2018 at 15:01, Martin Kletzander <span dir="ltr"><<a href="mailto:mkletzan@redhat.com" target="_blank">mkletzan@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Thu, Jul 05, 2018 at 05:58:46PM +0100, Daniel P. Berrangé wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Tue, Jul 03, 2018 at 04:41:52PM -0400, Cole Robinson wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Nice work on the document! I'll duplicate the docs here and comment<br>
in-line, might help to get more eyeballs.<br>
<br>
On 06/20/2018 09:15 AM, Martin Kletzander wrote:<br>
> After some discussion with people from various management apps we<br>
> decided to try and create something that would help with common,<br>
> duplicated, and perhaps easy to extract things for which the code<br>
> exists in some (or most) of the projects. I'd be glad for any<br>
> feedback, so here is the rendered document:<br>
><br>
> <a href="https://github.com/nertpinx/virt-manager/blob/virtuned-docs/docs/virtuned.md" rel="noreferrer" target="_blank">https://github.com/nertpinx/vi<wbr>rt-manager/blob/virtuned-docs/<wbr>docs/virtuned.md</a><br>
><br>
> and here you can comment:<br>
><br>
> <a href="https://github.com/nertpinx/virt-manager/pull/1/files" rel="noreferrer" target="_blank">https://github.com/nertpinx/vi<wbr>rt-manager/pull/1/files</a><br>
><br>
> I'm sending this to this list because it might be beneficial to base<br>
> this on top of virt-manager's codebase.  We'll see how that goes, but<br>
> for now any feedback is welcome.<br>
><br>
<br>
<br>
Before I get into specific replies/questions, let me make sure I have<br>
the right idea:<br>
<br>
virtuned is an API for applying preset VM config changes (profiles) to<br>
libvirt domain XML. Current plan is to implement it in python, but<br>
provide a REST API wrapper for access from other languages. The library<br>
will ship with a set of profiles initially based on a collection of what<br>
existing apps are already doing. Apps using virtuned can mix and match<br>
which profiles they want to apply to new or existing libvirt domains.<br>
<br>
Sound correct so far?<br>
<br>
</blockquote></blockquote>
<br></div></div>
Yes.  They can also provide their own profiles.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> # Design document for virtuned implementation<br>
><br>
> This document serves as a place to have open discussion about the design of so<br>
> called *libvirt profiles*, a.k.a. **virtuned**. The project should provide a<br>
> common ground to few problems which are currently being fixed on different<br>
> layers (mostly up the stack). Starting from the small things first, virtuned is<br>
> currently supposed to manage policies for creating XML definitions for VMs<br>
> (domains).<br>
><br>
<br>
One small quibble: do we expect this to ever be a daemon? I gather the<br>
name is a play off of the existing 'tuned' project but the 'd' throws me<br>
off a bit<br>
</blockquote>
<br>
</blockquote>
<br></span>
For the REST API daemon is needed, yes.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
FWIW, I find the naming rather misleading since this really is separate from<br>
tuned. A better project name choice might simply be libvirt-profile or<br>
something along those lines. Whether this project then provides a library<br>
of binary or both is an impl detail.<br>
<br>
</blockquote>
<br></span>
I really really don't like the name, I used idfferent naming, but everyone was<br>
still saying "virtuned", so I just went with it.  I didn't want to bikeshed, but<br>
libvirt-profile is fine.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> ## Brief specification of functionality<br>
><br>
> Currently virtuned aims to provide a consistent way of applying profiles to<br>
> libvirt VM definitions.  That way management applications don't need to<br>
> duplicate the implementation in their codebases.<br>
><br>
> ### Functions<br>
><br>
> As a starting point virtuned exposes one function.  As input the function<br>
> accepts a VM definition with the only restriction being that it is a libvirt<br>
> domain XML.  However it doesn't have to be complete.  The function applies all<br>
> relevant profiles to that XML and produces a complete libvirt domain XML.<br>
><br>
> The outcome of this is twofold:<br>
> - Every libvirt domain XML is already working virtuned XML.<br>
> - Applications can select, by arbitrarily small steps, how much functionality<br>
>   they want to use from virtuned.<br>
</blockquote>
<br>
I'm not sure I understand this second point. IIUC, the contents of the profiles<br>
are supposed to be opaque to the mgmt application. So while they use virtuned,<br>
they'll be exposed to whatever arbitrary XML the profile contains, whether<br>
they understand it or not.<br>
<br>
</blockquote>
<br></span>
Why would they need to be opaque to the mgmt app?  Either you are using some of<br>
profiles that are shipped with it (in which case the mgmt app developers should<br>
know what they are using in the code) or the mgmt app can construct their own<br>
profile to be used in which case it should know what it is asking for.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
><br>
> The main advantage of this approach is that applications can adopt the new<br>
> functionality incrementally by small steps that they themselves can choose,<br>
> starting from nothing.  Simply plugging virtuned into the process of domain XML<br>
> creation shouldn't change anything until you explicitly start using profiles.<br>
</blockquote>
<br>
If you're not using profiles, what is virtuned actally doing for you ?<br>
<br>
</blockquote>
<br></span>
Nothing.  The point was that you can first plug it in, then add a profile that<br>
sets one option to some particular value, then add another, etc. and thanks to<br>
that adopt it incrementally.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This bit confused me for a while, describing a function that only takes<br>
domain XML as the input. But after a re-read I see the requested<br>
profiles are specified as their own xmlns in the domain <metadata><br>
section. That makes sense to me and provides a lot of flexibility<br>
</blockquote>
<br>
</blockquote>
<br></span>
And we don't have to come up with yet another virtual machine definition format.<br>
<br>
(although YAVMDF would be very slick and catchy format name as well as extension)<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> ### API endpoints ###<br>
><br>
> For now the API will be exposed as:<br>
><br>
> 1. Python module - trivial if we're basing it on virt-manager codebase which is<br>
>    using python<br>
</blockquote>
<br>
What's the key reasons/benefit to be part of virt-manager codebase as opposed<br>
to a standalone project ?<br>
<br>
</blockquote>
<br></span>
Few things:<br>
<br>
1) The XMLBuilder makes it easier to work with the XML, particularly the domain<br>
   XML.  This is not that big of a deal since libvirt-go-xml does a good job of<br>
   that as well<br>
<br>
2) There is an existing logic for "intermediate" devices.  By that I mean the<br>
   devices that are needed to add the requested one.  For example when<br>
   requesting an addition of a SATA disk, there is already a logic that figures<br>
   out if there is an existing SATA controller with a free slot and adds one if<br>
   there is not.  The reason for this is that there might be some defaults<br>
   specified which affect the intermediate devices.<br>
<br>
3) The possibility of exposing virt-xml and virt-install in the future.  The<br>
   former would be used for making changes to the XML and the latter is<br>
   something that stateless mgmt apps would like to use (cockpit currently).<br>
<br>
4) Last but not least (although this shouldn't be used as a point for decision)<br>
   it is easier to make it available in existing distributions and package<br>
   managers.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Personally I'm pretty disillusioned with the maint burden of python (and dynamic<br>
languages in general). For a new effort like this I'd encourage consideration<br>
of Go or Rust. That said since I'm not working on it, don't consider this a<br>
blocker, just an opinion.<br>
<br>
</blockquote>
<br></span>
It's still up for discussion.  I would love to use Rust, but I'm not as<br>
proficient in it.  I would go with Go as well, but there would again be some<br>
code duplication (e.g. for the logic that virt-manager has already).  Anyway,<br>
see open questions at the bottom (there's even demo in Go that utilizes the<br>
struct tags).<div><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> 2. RESTful service - this will just be a separate file handing the glue between<br>
>    the python module and the different way of API exposure.  For that reason<br>
>    (and simplicity's sake) this could be outsourced (to<br>
>    e.g. [hug](<a href="https://www.hug.rest/)" rel="noreferrer" target="_blank">https://www.hug.rest/)</a>), at least for now<sup<br>
>    id='fn1'>[[1]](#fn1d)</sup>.<br>
><br>
> This will make it usable by most known projects and additional APIs can be added<br>
> later on without much friction (similarly to the REST API).  If virt-manager's<br>
> codebase is used as a base, then it will also simplify the exposure of other<br>
> parts of virt-manager under that RESTful service, for example virt-xml and<br>
> virt-install.  As far as I know this is something cockpit project would like a<br>
> lot <sup id='fn2'>[[2]](#fn2d)</sup>.<br>
><br>
> <sub id='fn1d'>1. <a href='#fn1'>**^**</a><br>
> With hug we'll get CLI almost automatically as well.<br>
> </sub><br>
> <sub id='fn2d'>2. <a href='#fn2'>**^**</a><br>
> This is not a strict requirement for virtuned, just a helpful side-effect.<br>
> </sub><br>
><br>
> ## Data specifications<br>
><br>
> There are several data formats that need to be specified.  What is discussed<br>
> below is mainly:<br>
> - **Format of the profiles** - Syntax of the format itself<br>
> - **Profile behaviours** - Possible changes profiles can do to VM definitions<br>
> - **Connection between profiles and VM definitions** - how to select changes<br>
>   which should be applied<br>
> - **Behaviour of the above connection** - How to specify multiple profiles and<br>
>   under what circumstances do they mutually exclude.<br>
><br>
> For a TL;DR example, see [Full Example](#full-example) below.<br>
><br>
> ### Profile specification<br>
><br>
> The profile itself can influence the VM definition in three different ways:<br>
><br>
> - Requesting a specific part of the XML to (not) exist.  This includes:<br>
>   - Adding a specific XML snippet<br>
>   - Making sure specific XML snippet exists (without necessarily adding it)<br>
>   - Removing a specific XML snippet<br>
> - Setting default for existing parts of the XML (setting if unset)<br>
><br>
> Due to the fact that the profiles will influence how the resulting XML will look<br>
> like, virtuned profiles use XML as well, however that does not prevent the<br>
> support for other formats to be added later on.<br>
><br>
> Simple profile can look like this:<br>
><br>
> ``` xml<br>
> <profile name='add-qxl'><br>
>   <add><br>
>     <devices><br>
>       <video><br>
>         <model type='qxl'/><br>
>       </video><br>
>     <devices><br>
>   </add><br>
> </profile><br>
> ```<br>
><br>
> The above example will request a video card with model QXL to exist in the VM<br>
> definition.  The precise outcome of this depends on the existing devices in the<br>
> VM definition:<br>
><br>
> - **VM has no video device:** the XML snippet (`qxl` video card) will simply be<br>
>   added to the list of devices.<br>
> - **VM has video device with no model specified:** Just fill in the video model<br>
>   for the existing video card.<br>
> - **VM has video device with different model:** Add one more video device with<br>
>   the specified model since multiple video cards are perfectly fine.<br>
><br>
> The above is very concrete example, but it can be very easily and efficiently<br>
> generalized for any `<add/>` sub-element.  The only information which is<br>
> required for said generalization is the knowledge of libvirt's domain XML<br>
> format.  This could be one of the reasons for virtuned to be spun off of<br>
> virt-manager's codebase (since most of that information is already there).  The<br>
> other option would be using<br>
> [libvirt-go-xml](<a href="https://libvirt.org/git/?p=libvirt-go-xml.git" rel="noreferrer" target="_blank">https://libvi<wbr>rt.org/git/?p=libvirt-go-xml.<wbr>git</a>) as that should<br>
> have enough information for this as well <sup id='fn3'>[[3]](#fn3d)</sup>.<br>
</blockquote>
<br>
FYI, libvirt-go-xml should have 100% coverage of all XML constructs in the<br>
libvirt schema. Any ommissions are entirely due to libvirt's own master XML<br>
test files being incomplete. libvirt-go-xml unit tests check that it can<br>
roundtrip all XML files in libvirt.git without data loss. I don't think any<br>
other XML parser impl for libvirt has the same level of coverage, principally<br>
because none of them do similar kind of testing to prove it.<br>
<br>
</blockquote>
<br></div></div>
Coverage is one thing, but another thing is the logic that is in XMLBuilder<br>
(even though it's not there for all the elements).  For example if there are<br>
different sub-elements allowed based on an attribute.  But even simpler,<br>
elements that cannot be duplicated, but in the struct it is saved in a list.  If<br>
that is not fully introspectable from the struct tags, then we will need to<br>
duplicate the code that already exists in virt-manager if this is a side<br>
project.<div><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> As mentioned above this is not the only type of action that the profile format<br>
> supports.  Here is the proposed list of actions with optional attributes:<br>
><br>
> - **`add`** - Make sure such XML snippet exists.  Can have attribute `multiple`<br>
>   with the following values:<br>
>   - **`yes`** - Unconditionally add the snippet if it can exist multiple times<br>
>     (the lowest level that can exist multiple times to be precise) or fail if it<br>
>     cannot (machine type)<br>
>   - **`no`** - Adjust existing part of the XML so that it matches the<br>
>     requirements from the snippet, overriding values if needed.<br>
>   - **`auto`** (default) - Try adjusting existing part of the XML so that it<br>
>     matches the requirements, but only override values if there is no part of<br>
>     that snippet that could be specified multiple times.  If any part of it can<br>
>     be specified multiple times, then find the lowest such part and append that.<br>
> - **`remove`** - Make sure such XML snippet does not exists.  All matching XML<br>
>   snippets (even if they have more attributes or sub-elements) will be removed.<br>
> - **`default`** - If VM definition has an XML snippet which does fit this<br>
>   description except some values not existing, then fill in those values.  This<br>
>   can be used for example for default device model types or machine types.<br>
><br>
> The `<add multiple='X'/>` is just a naming and it can be changed in any way that<br>
> suits others, for example instead of having:<br>
><br>
> ``` xml<br>
> <add multiple='auto'/><br>
> <add multiple='yes'/><br>
> <add multiple='no'/><br>
> ```<br>
><br>
> There could be:<br>
><br>
> ``` xml<br>
> <append/><br>
> <set/><br>
> <force/> <!-- or <replace/> --><br>
> ```<br>
><br>
> All action elements can have optional attribute `constraint` with the following<br>
> possible values:<br>
> - **`soft`** (default) - Profiles with higher priority can override this value.<br>
>   This is the default and should be used whenever it is not absolutely necessary<br>
>   for the XML snippet to be kept.<br>
> - **`hard`** - If profile with higher priority needs to override this value,<br>
>   then error out.  This should be selected only when it is absolutely necessary<br>
>   for the XML snippet to exist in this way.  For example in the following cases:<br>
>   - The system would be unstable.<br>
>   - Data corruption might occur.<br>
>   - Other parts of the profile would cause harm without this set.<br>
><br>
> Yet another simple profile can look like this:<br>
> ``` xml<br>
> <profile name='some-interesting-things'<wbr>><br>
>   <add><br>
>     <iothreads>2</iothreads><br>
>   </add><br>
>   <add><br>
>     <devices><br>
>       <disk device='cdrom'><br>
>     </devices><br>
>   </add><br>
>   <add multiple='yes'><br>
>     <devices><br>
>       <redirdev bus='usb' type='spicevmc'/><br>
>       <redirdev bus='usb' type='spicevmc'/><br>
>     </devices><br>
>   </add><br>
>   <remove type='hard'><br>
>     <features><br>
>       <apic/><br>
>     </features><br>
>   </remove><br>
>   <defaults><br>
>     <devices><br>
>       <interface><br>
>         <model type='virtio'/><br>
>       </interface><br>
>     <devices><br>
>   </defaults><br>
> </profile><br>
> ```<br>
</blockquote>
<br>
This is where I really start to get very concerned. The examples you're giving<br>
a nice and simple, so composition of arbitrary profiles, together with application<br>
written XML looks like it'll work.<br>
<br>
I think it will be all too easy, however, to write profiles where the result of<br>
composition profiles and merging with app XML is an XML document that is<br>
semantically invalid / unrunnable.<br>
<br>
Consider if you have a two profiles, one sets up a XML doc with 'pc' machine<br>
type and other profile sets up an XML doc with 'q35' machine type.<br>
<br>
Now a third profile wants to setup NUMA for the guest such that PCI devices<br>
are associated with NUMA nodes. The way you do this is very different for<br>
'pc' and 'q35' machine types due to PCI vs PCI-Express topology changes.<br>
So if the 'numa' profile assumes 'pc' it will break if the app composes it<br>
with the 'q35' profile, or vica-verca.<br>
<br>
Now consider you have a 'networking-nfv' profile that is supposed to setup<br>
NICs in a way that is optimized for NFV use cases. This profile now needs<br>
to know if it should put the NICs in the default PCI bus, or in the NUMA<br>
specific PCI bus. So the result may or may not do the right thing if you<br>
compose it with the 'numa' profile.<br>
<br>
Solving these problems would require a combinatorial expansion in the<br>
number of profiles. eg a numa-pc, numa-q35 profile, and then a<br>
networking-nfv-pc, networking-nfv-q46, networking-nfv-numa-pc, and<br>
networking-nfv-numa-q35 profiles. There would then have to be dependancies<br>
expressed to tell the app which profiles can be composed with each other.<br>
<br>
</blockquote>
<br></div></div>
So this is how tuned does it and I didn't really like the way the matrix<br>
explodes with added dimensions.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This still only solves the problem of composing profiles, and does not<br>
consider how to merge with the application defined XML parts. The only<br>
way an application can know if the XML it wants to write, is compatible<br>
with the profiles it has used, is if it parses and understands all the<br>
parts of the profile.<br>
<br>
</blockquote>
<br></span>
I hear what you are saying, but I don't see why the app would need to parse the<br>
profiles.  There can be conditions in profiles (proposed in open questions) that<br>
would eliminated the need for multiple profiles for the same thing.  Yes, DSL<br>
would be better for this.  We could just right away use what "xq" provides (see<br>
open questions).  That would also solve erroring out.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If something was used in the profile that the app doesn't know about,<br>
it could ignore it, but the resulting VM config may well be unrunnable,<br>
or worse, runnable but doing something completely inappropriate.<br>
<br>
<br>
I think these kind of problems are inherant in any approach which allows<br>
arbitrary user defined XML as the schema for the profiles.<br>
<br>
This is one of reasons why libosinfo didn't base the information it<br>
provides around the libvirt XML schema. Instead it defines its own<br>
domain specific language, and applications only use the features in<br>
it that they actually know how to handle.<br>
<br>
This means if we add some new concept to libosinfo database, applications<br>
are not going to automagically use it, and instead have to add explicit<br>
support. As above though, I think this is inevitable, because it is too<br>
easy to create unrunnable/nonsensical XML configs if you allow arbitrary<br>
user specified XML inputs.<br>
<br>
</blockquote>
<br></span>
Thanks for the info with the NUMA locality example.  On one hand it would really<br>
save us a lot of work if we just used something that exists (by just extending<br>
it) and for DSL there is a solution we can use as well.  If not then we can<br>
build it from existing parts at least partially.<div><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> This profile consists of various actions and has the following implications for<br>
> the VM definition:<br>
><br>
> - The VM should have 2 I/O Threads (profiles with higher priority can override<br>
>   this setting)<br>
> - The VM should have a CDROM drive.  It will not be added multiple times if it<br>
>   already exists.<br>
> - Two spice redirdev ports will be added to the VM definition.  If there were<br>
>   some existing ones, these will be added<sup id='fn4'>[[4]](#fn4d)</sup>.<br>
> - The VM must not have APIC (cannot be overridden)<br>
> - Any interface should default to virtio model type.  That means model will be<br>
>   set to `virtio` unless already specified.<br>
><br>
> There are some open questions related to more actions being specified, however<br>
> they should be limited to minimum.<br>
><br>
> <sub id='fn3d'>3. <a href='#fn3'>**^**</a><br>
> Actually maybe even more since virt-manager's info is also incomplete.<br>
> </sub><br>
> <sub id='fn4d'>4. <a href='#fn4'>**^**</a><br>
> Without the `multiple='yes'` this would mean that **at least** 2 such ports<br>
> should exist.<br>
> </sub><br>
><br>
> ### VM <-> Profile connection<br>
><br>
> Not all profiles need to be applied to all VM definitions.  In order to select<br>
> only the relevant ones we need to specify the connection between the VM<br>
> definition and the profile.  That can can be done in multiple different ways<br>
> depending on the preference, however each approach has pros and cons so they are<br>
> discussed in this section.<br>
><br>
> Since multiple profiles can be applied to the same VM definition at the same<br>
> time, there also needs to be a way to deal with conflicts.  Even though this<br>
> issue seems orthogonal to the connection itself, it can be dealt with in<br>
> different ways depending on the connection specification used.  What is proposed<br>
> below are two ways how to handle the connection with a way how to deal with<br>
> profile clashes together with two ways that were removed from the consideration<br>
> (just to makes sure the decisions are covered for future observers).<br>
><br>
> #### Selectors in profiles<br>
><br>
> Similarly to KubeVirt's approach to [VM<br>
> Presets](<a href="https://github.com/kubevirt/kubevirt/blob/master/docs/vm-presets.md" rel="noreferrer" target="_blank">https://github.com/ku<wbr>bevirt/kubevirt/blob/master/do<wbr>cs/vm-presets.md</a>)<br>
> this is something that has a great power.  Each profile specification includes a<br>
> selector based on which that particular profile will (not) be selected.<br>
><br>
> Multiple profiles clash and error out in case they cannot be combined.  For this<br>
> we propose a solution in the later section.<br>
><br>
> Example:<br>
><br>
> ``` xml<br>
> <profile name='add-qxl-for-spice'><br>
>   <match><br>
>     <devices><br>
>       <graphics type='spice'/><br>
>     <devices><br>
>   </match><br>
>   <add><br>
>     <devices><br>
>       <video><br>
>         <model type='qxl'/><br>
>       </video><br>
>     <devices><br>
>   </add><br>
> </profile><br>
> ```<br>
><br>
> This profile is similar to the one in [Profile<br>
> specification](#profile-specif<wbr>ication) with one difference, which is a<br>
> `<match/>` element.   That element includes a condition under which the profile<br>
> actions will be executed.  In this particular case the profiles says that a QXL<br>
> video card should be present in case the VM has a SPICE graphics device.<br>
><br>
> These matches might include any part of the XML, even metadata, so this can<br>
> match guest OS (if provided as part of the VM metadata).<br>
><br>
> For example this condition:<br>
><br>
> ``` xml<br>
> <match><br>
>   <metadata><br>
>     <myapp:myapp><br>
>       <myapp:guest os_type='windows'/><br>
>     </myapp:myapp><br>
>   <metadata><br>
> </match><br>
> ```<br>
><br>
> would be matched on this VM definition:<br>
><br>
> ``` xml<br>
> <domain><br>
>   <name>Win10</name><br>
>   <metadata><br>
>     <myapp:myapp xmlns:myapp='<a href="http://example.org/myapp" rel="noreferrer" target="_blank">http://example.or<wbr>g/myapp</a>'><br>
>       <myapp:guest os_type='windows' os_version='10'/><br>
>     </myapp:myapp><br>
>   </metadata><br>
>   ...<br>
> </domain><br>
> ```<br>
><br>
> As you can see the metadata used for the condition don't need to be virtuned's<br>
> specific metadata, but rather any management applications metadata.<br>
><br>
<br>
I didn't really know where to cut in so this is a big comment...<br>
<br>
The idea here is that virtuned will ship with something like a<br>
profile/add-qxl.xml, and profile=add-qxl will then effectively be part<br>
of the virtuned API, like an osinfo ID value is to libosinfo; the<br>
profile will never go away, so apps can depend on it being there.<br>
Presumably we can extend the profile as necessary as long as it<br>
accomplishes its stated goal and we confirm it doesn't break apps.<br>
<br>
</blockquote></blockquote>
<br></div></div>
Yes, we're probably going to need to version it as well.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Using XML for this kind of thing makes me nervous, trying to model<br>
conditional actions with XML. I feel like it's a real quick slippery<br>
slope to implementing a turing complete schema. For example how would we<br>
handle complex examples like:<br>
<br>
</blockquote></blockquote>
<br></span>
The idea to use XML was sparkled by two facts:<br>
<br>
1) Apps will be able to create their own profiles.<br>
<br>
2) Simple profiles (addition of few elements) could be created by just taking<br>
   the specific part of the domain XML and wrapping it in a tag that says what<br>
   to do (e.g. `<add><existing_xml_snippet/><<wbr>/add>`).<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
* set graphics=spice. Except spice is only available for qemu depending<br>
on the _host_ arch. qemu-system-aarch64 on x86 has spice, but not<br>
qemu-system-aarch64<br>
<br>
* Give me USB tablet, if (os-supports-usb-tablet && (arch == x86 ||<br>
(arch == aarch64 && machine.startswith("virt")))<br>
<br>
* Give me USB3, if os-supports-usb3. If qemu version > X,<br>
model=qemu-xhci, else model=nec-xhci<br>
<br>
</blockquote></blockquote>
<br></span>
So there are three possibilities:<br>
<br>
1) We leave this out to the mgmt app,<br>
<br>
2) we "just do it" and leave it for someone else to error out properly,<br>
<br>
3) or we consult libvirt capabilities<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
What's the motivation for doing this in XML? So apps or distros can drop<br>
in their own profiles? Or extend system profiles? I'm wondering why XML<br>
over privately implemented. Maybe you can explain some specific app<br>
usecases that motivated this? I feel like I missed a lot in the previous<br>
discussion<br>
<br>
</blockquote></blockquote>
<br></span>
You didn't miss much and you hit the two points nicely, dropping in own profiles<br>
and, possibly, extend existing ones.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also do we expect the API to talk directly to libvirt? Like for checking<br>
domcapabilities?<br>
</blockquote>
<br>
</blockquote>
<br></span>
For KubeVirt that wouldn't be that much of a help as they need to do bunch of<br>
these things without libvirt running.  Also not being dependent on libvirt makes<br>
it independent from the host.  Capabilities might be provided as another input,<br>
but question is whether it should be full blown libvirt (dom)capabilities.  The<br>
reason is that you might need to migrate between various nodes and the mgmt<br>
app/cluster knows the minimal requirements better than host-oriented daemon.<br>
<br>
sidenote: I was also trying to come up with something that would take any number<br>
         of libvirt capabilities (one for each node) and based on few more<br>
         input points (e.g. minimum number of supported nodes) it would return<br>
         the maximal capability set that can be used for creating a VM.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think there's similar issues with have this overlaps / integrates with<br>
libosinfo. When using libosinfo we can dynamically query which type of<br>
device is appropriate on a per guest OS basis. We can also query the<br>
libvirt domain capabilities, and then determine the compatible overlap<br>
between libosinfo and QEMU and libvirt.<br>
<br>
The profiles appear to largely loose this ability, going back to having<br>
to write different protocols to cover different types of guest OS.<br>
<br>
A the very least I think this means profiles need to be able allow for<br>
complex conditional expressions, along with variable subsistitutions<br>
from external data sources.<br>
<br>
</blockquote>
<br></span>
Apart from external data sources it is written down in the open questions.<br>
External data sources should not be a problem given they are provided as a<br>
separate input.<div><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This gets hard though when you try to compose profiles with the app<br>
being opaque about what's in the profile. eg if the guest supports<br>
virtio-scsi the result is very different from if the guest supports<br>
virtio-blk.<br>
<br>
So if one base profile sets up controllers, a later add-on profile<br>
that works with disks needs to be able to write an expression to<br>
determine whether the existing XML as a virtio-scsi or IDE controller<br>
present and use those, vs deciding to add controller-less virtio-blk<br>
disks.  This rapidly becomes a turing complete problemspace I think.<br>
<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> ### Open Questions<br>
><br>
> There are still couple of things to be discussed, which I will only cover<br>
> slightly <sup id='fn5'>[[5]](#fn5d)</sup>.<br>
><br>
> 1. **How are profiles added**<br>
>    They can be files in a filesystem, there could be separate API for defining<br>
>    profiles.  Some of them will most probably be shared in the repository<br>
>    together with virtuned, but applications need to be able to define their own<br>
>    ones.  Filesystem-based storage seems fine for usage in a container for<br>
>    example, but might not be usable for some deployments.<br>
><br>
<br>
I get that applications will want to add their own profiles and tweak<br>
defaults. But is writing <profile> XML going to be much easier than<br>
editing the XML directly? It isn't clear to me one way or the other.<br>
</blockquote>
<br>
I tend to think writing the profiles is going to be more complex and<br>
error prone than directly writing the XML, because of the composability<br>
problems I mention above.<br>
<br>
My gut feeling is that it would be a more tractable problem if the profiles<br>
used a domain specific language (DSL), possibly still XML, but not libvirt<br>
domain XML. Applications would have to explicitly know about individual<br>
features in the DSL, but they could consume it in a way that the way they<br>
generate libvirt XML is more fully data-driven.<br>
<br>
ie, taking my example above, applications would need explicit knowledge<br>
of machine types, NUMA topologies, and attaching devices to NUMA nodes.<br>
Given that knowledge though, the decision about /when/ to use these<br>
respective features would be data driven from profiles that simply<br>
stated desired traits.<br>
<br>
</blockquote>
<br></div></div>
I lost you at the last paragraph.  Could you rephrase it or maybe give another<br>
example?  The idea is that mgmt app knows when it wants to use what profile.<br>
And what is provided as an API is the composition of the XML.  But you were<br>
probably addressing something else, right?  As I said, I lost you here.<div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Regards,<br>
Daniel<br>
-- <br>
|: <a href="https://berrange.com" rel="noreferrer" target="_blank">https://berrange.com</a>      -o-    <a href="https://www.flickr.com/photos/dberrange" rel="noreferrer" target="_blank">https://www.flickr.com/photos/<wbr>dberrange</a> :|<br>
|: <a href="https://libvirt.org" rel="noreferrer" target="_blank">https://libvirt.org</a>         -o-            <a href="https://fstop138.berrange.com" rel="noreferrer" target="_blank">https://fstop138.berrange.com</a> :|<br>
|: <a href="https://entangle-photo.org" rel="noreferrer" target="_blank">https://entangle-photo.org</a>    -o-    <a href="https://www.instagram.com/dberrange" rel="noreferrer" target="_blank">https://www.instagram.com/dber<wbr>range</a> :|<br>
</blockquote>
</div></div><br>______________________________<wbr>_________________<br>
virt-tools-list mailing list<br>
<a href="mailto:virt-tools-list@redhat.com">virt-tools-list@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/virt-tools-list" rel="noreferrer" target="_blank">https://www.redhat.com/<wbr>mailman/listinfo/virt-tools-<wbr>list</a><br></blockquote></div><br></div>