Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow core-admin extension to extend libvirt xml templates #5085

Open
marmarek opened this issue Jun 8, 2019 · 7 comments
Open

Allow core-admin extension to extend libvirt xml templates #5085

marmarek opened this issue Jun 8, 2019 · 7 comments
Labels
C: core P: default Priority: default. Default priority for new issues, to be replaced given sufficient information.

Comments

@marmarek
Copy link
Member

marmarek commented Jun 8, 2019

The problem you're addressing (if any)
Ability for an extension to add/remove elements of libvirt xml for some (or all) VMs

Describe the solution you'd like
An extension could define extra directory where jinja template loader could search. Some more design work is needed to allow multiple templates to use this mechanism and to allow override only parts of the template, and load original template (extends jinja directive by default doesn't allow to load same-named template from a different directory).
This mechanism should also allow multiple extensions to use it, possibly to modify different parts of the libvirt xml.

Where is the value to a user, and who might that user be?
Write extensions that depends on libvirt xml modifications. Example use cases include #5051 or #4688

Describe alternatives you've considered

  1. Use /etc/qubes/templates/libvirt/xen/by-name/..., but it doesn't allow multiple extensions to use it for the same VM.
  2. Add a hook that allows post-process the libvirt xml at python level - this looks very unfriendly (need to parse xml and format it back), especially when we already have template engine in place.

Additional context
Right now it's mostly for #5051, to allow extension to replace network device xml.

Relevant documentation you've consulted
http://jinja.pocoo.org/docs/2.10/api/#loaders
http://jinja.pocoo.org/docs/2.10/templates/#template-inheritance
https://dev.qubes-os.org/projects/core-admin/en/latest/libvirt.html

Related, non-duplicate issues

cc @fepitre

@marmarek marmarek added T: enhancement P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. labels Jun 8, 2019
@marmarek
Copy link
Member Author

marmarek commented Jun 8, 2019

@woju any idea?

@andrewdavidwong andrewdavidwong added this to the Release 4.1 milestone Jun 8, 2019
@woju
Copy link
Member

woju commented Jun 19, 2019 via email

@marmarek
Copy link
Member Author

Is it needed in extensions in particular?

Not necessary extensions, but some way allowing cleanly applying multiple modifications to the libvirt xml. The current solution allows only one entity to do so, directed for use by the user. Applying multiple modifications of the same XML file with salt seems fragile at least. Do you know some reliable method for xml modification in salt? That would be useful in other places too (like configuring xfce).

If sticking with extensions, this is also what I and @fepitre have considered, but since we already have template engine in place we hoped there is a better way.

BTW this is example modification: https://github.com/fepitre/qubes-core-admin-addon-bridged-netvm/blob/master/bridge.xml

@woju
Copy link
Member

woju commented Jun 19, 2019 via email

@marmarek
Copy link
Member Author

In principle, jinja2 {% extends %} are constrained to whatever was forseen by original template writer,

In theory this should be fine, as we're template writers and we can add blocks for all kind of nodes we have there (or are supported in libvirt). as for variables, we expose vm object, so this is also quite flexible. The problem is I don't see a way to stack such templates, like extends / super referencing "parent" template whatever it is (i.e. without explicitly naming it in the template itself). Maybe it could be worked around with a call to python "I'm template shipped by extension XYZ, what is my parent template?", like:

{% extends get_parent_template("extension-xyz") %}
...

but that doesn't sound like an elegant solution...
If you don't have any better idea, then indeed modifying libvirt xml directly from extension may be the way to go. With the problem you've mentioned that user no longer have the final word in what ends up in that xml.

@woju
Copy link
Member

woju commented Jun 20, 2019 via email

@fepitre
Copy link
Member

fepitre commented Jun 20, 2019

It would be something like this: python class XMLExtension(qubes.ext.Extension): @qubes.ext.handler('domain-libvirt-xml') # ? def on_libvirt_xml(self, vm, event, libvirt_xml): # ? if vm.features.get(...): bridge = lxml.etree.XML(''' <interface type="bridge"> <source bridge="{vm.features[bridge_name]}" /> <mac address="{vm.features[bridge_mac]}" /> <backenddomain name="{vm.features[bridge_backenddomain]}" /> <script path="vif-bridge" /> </interface> '''.format(vm=vm)) devices, = libvirt_xml.xpath('//devices') devices.append(bridge) I don't think this is much worse from the snippet you linked.
@woju : thank you I will use it and adapt it for multiple interfaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: core P: default Priority: default. Default priority for new issues, to be replaced given sufficient information.
Projects
None yet
Development

No branches or pull requests

4 participants