mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-03-09 08:58:27 +03:00
guest: Add support for qemu cli passthrough
This is for xml like: <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'> ... </devices> <qemu:commandline> <qemu:arg value='-newarg'/> <qemu:env name='QEMU_ENV' value='VAL'/> </qemu:commandline> </domain> Requires some extensions to the xmlbuilder infrastructure
This commit is contained in:
parent
e7e9369989
commit
22b6becd5d
@ -54,6 +54,7 @@ from .pm import PM
|
|||||||
from .seclabel import Seclabel
|
from .seclabel import Seclabel
|
||||||
from .sysinfo import SYSInfo
|
from .sysinfo import SYSInfo
|
||||||
from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
|
from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
|
||||||
|
from .xmlnsqemu import XMLNSQemu
|
||||||
|
|
||||||
|
|
||||||
class Guest(XMLBuilder):
|
class Guest(XMLBuilder):
|
||||||
@ -188,6 +189,7 @@ class Guest(XMLBuilder):
|
|||||||
validate_cb=lambda s, v: util.validate_uuid(v),
|
validate_cb=lambda s, v: util.validate_uuid(v),
|
||||||
default_cb=_get_default_uuid)
|
default_cb=_get_default_uuid)
|
||||||
|
|
||||||
|
|
||||||
id = XMLProperty("./@id", is_int=True)
|
id = XMLProperty("./@id", is_int=True)
|
||||||
type = XMLProperty("./@type", default_cb=lambda s: "xen")
|
type = XMLProperty("./@type", default_cb=lambda s: "xen")
|
||||||
bootloader = XMLProperty("./bootloader")
|
bootloader = XMLProperty("./bootloader")
|
||||||
@ -214,6 +216,8 @@ class Guest(XMLBuilder):
|
|||||||
resource = XMLChildProperty(DomainResource, is_single=True)
|
resource = XMLChildProperty(DomainResource, is_single=True)
|
||||||
sysinfo = XMLChildProperty(SYSInfo, is_single=True)
|
sysinfo = XMLChildProperty(SYSInfo, is_single=True)
|
||||||
|
|
||||||
|
xmlns_qemu = XMLChildProperty(XMLNSQemu, is_single=True)
|
||||||
|
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# Distro detection properties #
|
# Distro detection properties #
|
||||||
|
@ -42,6 +42,10 @@ _seenprops = []
|
|||||||
# top relavtive node in certain cases
|
# top relavtive node in certain cases
|
||||||
_top_node = None
|
_top_node = None
|
||||||
|
|
||||||
|
_namespaces = {
|
||||||
|
"qemu": "http://libvirt.org/schemas/domain/qemu/1.0",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class _DocCleanupWrapper(object):
|
class _DocCleanupWrapper(object):
|
||||||
def __init__(self, doc):
|
def __init__(self, doc):
|
||||||
@ -64,6 +68,7 @@ def _make_xml_context(node):
|
|||||||
doc = node.doc
|
doc = node.doc
|
||||||
ctx = _CtxCleanupWrapper(doc.xpathNewContext())
|
ctx = _CtxCleanupWrapper(doc.xpathNewContext())
|
||||||
ctx.setContextNode(node)
|
ctx.setContextNode(node)
|
||||||
|
ctx.xpathRegisterNs("qemu", _namespaces["qemu"])
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
@ -98,6 +103,13 @@ def _get_xpath_node(ctx, xpath):
|
|||||||
return (node and node[0] or None)
|
return (node and node[0] or None)
|
||||||
|
|
||||||
|
|
||||||
|
def _add_namespace(node, nsname):
|
||||||
|
for ns in util.listify(node.nsDefs()):
|
||||||
|
if ns.name == nsname:
|
||||||
|
return ns
|
||||||
|
return node.newNs(_namespaces[nsname], nsname)
|
||||||
|
|
||||||
|
|
||||||
def _add_pretty_child(parentnode, newnode):
|
def _add_pretty_child(parentnode, newnode):
|
||||||
"""
|
"""
|
||||||
Add 'newnode' as a child of 'parentnode', but try to preserve
|
Add 'newnode' as a child of 'parentnode', but try to preserve
|
||||||
@ -206,10 +218,17 @@ def _build_xpath_node(ctx, xpath):
|
|||||||
# Remove conditional xpath elements for node creation. We preserved
|
# Remove conditional xpath elements for node creation. We preserved
|
||||||
# them up until this point since it was needed for proper xpath
|
# them up until this point since it was needed for proper xpath
|
||||||
# lookup, but they aren't valid syntax when creating the node
|
# lookup, but they aren't valid syntax when creating the node
|
||||||
if nodename.count("["):
|
if "[" in nodename:
|
||||||
nodename = nodename[:nodename.index("[")]
|
nodename = nodename[:nodename.index("[")]
|
||||||
|
|
||||||
|
nsname = None
|
||||||
|
if ":" in nodename:
|
||||||
|
nsname, nodename = nodename.split(":")
|
||||||
|
|
||||||
newnode = libxml2.newNode(nodename)
|
newnode = libxml2.newNode(nodename)
|
||||||
|
if nsname:
|
||||||
|
ns = _add_namespace(ctx.contextNode(), nsname)
|
||||||
|
newnode.setNs(ns)
|
||||||
return _add_pretty_child(parentnode, newnode), parentpath
|
return _add_pretty_child(parentnode, newnode), parentpath
|
||||||
|
|
||||||
|
|
||||||
@ -719,7 +738,12 @@ class _XMLState(object):
|
|||||||
|
|
||||||
|
|
||||||
def make_xml_stub(self):
|
def make_xml_stub(self):
|
||||||
return "<%s/>" % self._root_name
|
ret = "<%s" % self._root_name
|
||||||
|
if ":" in self._root_name:
|
||||||
|
ns = self._root_name.split(":")[0]
|
||||||
|
ret += " xmlns:%s='%s'" % (ns, _namespaces[ns])
|
||||||
|
ret += "/>"
|
||||||
|
return ret
|
||||||
|
|
||||||
def set_relative_object_xpath(self, xpath):
|
def set_relative_object_xpath(self, xpath):
|
||||||
self._relative_object_xpath = xpath or ""
|
self._relative_object_xpath = xpath or ""
|
||||||
@ -835,7 +859,7 @@ class XMLBuilder(object):
|
|||||||
for child_class in xmlprop.child_classes:
|
for child_class in xmlprop.child_classes:
|
||||||
prop_path = xmlprop.get_prop_xpath(self, child_class)
|
prop_path = xmlprop.get_prop_xpath(self, child_class)
|
||||||
|
|
||||||
nodecount = int(self._xmlstate.xml_node.xpathEval(
|
nodecount = int(self._xmlstate.xml_ctx.xpathEval(
|
||||||
"count(%s)" % self.fix_relative_xpath(prop_path)))
|
"count(%s)" % self.fix_relative_xpath(prop_path)))
|
||||||
for idx in range(nodecount):
|
for idx in range(nodecount):
|
||||||
idxstr = "[%d]" % (idx + 1)
|
idxstr = "[%d]" % (idx + 1)
|
||||||
|
52
virtinst/xmlnsqemu.py
Normal file
52
virtinst/xmlnsqemu.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# Copyright 2017 Red Hat, Inc.
|
||||||
|
# Cole Robinson <crobinso@redhat.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
# MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
|
||||||
|
|
||||||
|
|
||||||
|
class _XMLNSQemuArg(XMLBuilder):
|
||||||
|
_XML_ROOT_NAME = "qemu:arg"
|
||||||
|
|
||||||
|
value = XMLProperty("./@value")
|
||||||
|
|
||||||
|
|
||||||
|
class _XMLNSQemuEnv(XMLBuilder):
|
||||||
|
_XML_ROOT_NAME = "qemu:env"
|
||||||
|
|
||||||
|
name = XMLProperty("./@name")
|
||||||
|
value = XMLProperty("./@value")
|
||||||
|
|
||||||
|
|
||||||
|
class XMLNSQemu(XMLBuilder):
|
||||||
|
"""
|
||||||
|
Class for generating <qemu:commandline> XML
|
||||||
|
"""
|
||||||
|
_XML_ROOT_NAME = "qemu:commandline"
|
||||||
|
|
||||||
|
args = XMLChildProperty(_XMLNSQemuArg)
|
||||||
|
def add_arg(self, value):
|
||||||
|
arg = _XMLNSQemuArg(conn=self.conn)
|
||||||
|
arg.value = value
|
||||||
|
self.add_child(arg)
|
||||||
|
|
||||||
|
envs = XMLChildProperty(_XMLNSQemuEnv)
|
||||||
|
def add_env(self, name, value):
|
||||||
|
env = _XMLNSQemuEnv(conn=self.conn)
|
||||||
|
env.name = name
|
||||||
|
env.value = value
|
||||||
|
self.add_child(env)
|
Loading…
x
Reference in New Issue
Block a user