tools: add '--xpath EXPRESSION --wrap' args to all dumpxml commands

While you can chain the virsh output up to a later 'xmllint' or 'xpath'
command, integrating it into virsh avoids needs for installing extra
binaries which we've often found to be missing on production installs
of libvirt. It also gives better response if the initial virsh command
hits an error, as you don't get an aborted pipeline.

    $ virsh pool-dumpxml --xpath //permissions default
    <permissions>
      <mode>0711</mode>
      <owner>1000</owner>
      <group>1000</group>
      <label>unconfined_u:object_r:svirt_home_t:s0</label>
    </permissions>

If multiple nodes match, they are emitted individually:

    $ virsh dumpxml --xpath '//devices/*/address[@type="pci"]' --wrap demo
    <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
    <address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
    ...snip...
    <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
    <address type="pci" domain="0x0000" bus="0x07" slot="0x00" function="0x0"/>

but if intending to post-process the output further, the results
can be wrapped in a parent node

    $ virsh dumpxml --xpath '//devices/*/address[@type="pci"]' --wrap demo
    <nodes>
      <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
      <address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      ...snip...
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
      <address type="pci" domain="0x0000" bus="0x07" slot="0x00" function="0x0"/>
    </nodes>

Fixes https://gitlab.com/libvirt/libvirt/-/issues/244
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2022-06-16 16:29:54 +01:00
parent 8615c19b5d
commit 8603b3d76c
12 changed files with 370 additions and 84 deletions

View File

@ -1959,10 +1959,16 @@ backup-dumpxml
::
backup-dumpxml domain
backup-dumpxml [--xpath EXPRESSION] [--wrap] domain
Output XML describing the current backup job.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
domiflist
---------
@ -2652,7 +2658,8 @@ dumpxml
::
dumpxml domain [--inactive] [--security-info] [--update-cpu] [--migratable]
dumpxml [--inactive] [--security-info] [--update-cpu] [--migratable]
[--xpath EXPRESSION] [--wrap] domain
Output the domain information as an XML dump to stdout, this format can be used
by the ``create`` command. Additional options affecting the XML dump may be
@ -2665,6 +2672,13 @@ migrations, i.e., compatible with older libvirt releases and possibly amended
with internal run-time options. This option may automatically enable other
options (*--update-cpu*, *--security-info*, ...) as necessary.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
edit
----
@ -3090,12 +3104,19 @@ managedsave-dumpxml
::
managedsave-dumpxml domain [--security-info]
managedsave-dumpxml [--security-info] [--xpath EXPRESSION] [--wrap] domain
Extract the domain XML that was in effect at the time the saved state
file *file* was created with the ``managedsave`` command. Using
*--security-info* will also include security sensitive information.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
managedsave-edit
----------------
@ -3890,12 +3911,19 @@ save-image-dumpxml
::
save-image-dumpxml file [--security-info]
save-image-dumpxml [--security-info] [--xpath EXPRESSION] [--wrap] file
Extract the domain XML that was in effect at the time the saved state
file *file* was created with the ``save`` command. Using
*--security-info* will also include security sensitive information.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
save-image-edit
---------------
@ -5244,7 +5272,7 @@ nodedev-dumpxml
::
nodedev-dumpxml device
nodedev-dumpxml [--xpath EXPRESSION] [--wrap] device
Dump a <device> XML representation for the given node device, including
such information as the device name, which bus owns the device, the
@ -5253,6 +5281,13 @@ libvirt (such as whether device reset is supported). *device* can
be either device name or wwn pair in "wwnn,wwpn" format (only works
for HBA).
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
nodedev-info
------------
@ -5433,13 +5468,20 @@ net-dumpxml
::
net-dumpxml network [--inactive]
net-dumpxml [--inactive] [--xpath EXPRESSION] [--wrap] network
Output the virtual network information as an XML dump to stdout.
If *--inactive* is specified, then physical functions are not
expanded into their associated virtual functions.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
net-edit
--------
@ -5695,10 +5737,17 @@ net-port-dumpxml
::
net-port-dumpxml network port
net-port-dumpxml [--xpath EXPRESSION] [--wrap] network port
Output the network port information as an XML dump to stdout.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
net-port-delete
---------------
@ -5782,12 +5831,19 @@ iface-dumpxml
::
iface-dumpxml interface [--inactive]
iface-dumpxml [--inactive] [--xpath EXPRESSION] [--wrap] interface
Output the host interface information as an XML dump to stdout. If
*--inactive* is specified, then the output reflects the persistent
state of the interface that will be used the next time it is started.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
iface-edit
----------
@ -6258,12 +6314,19 @@ pool-dumpxml
::
pool-dumpxml [--inactive] pool-or-uuid
pool-dumpxml [--inactive] [--xpath EXPRESSION] [--wrap] pool-or-uuid
Returns the XML information about the *pool* object.
*--inactive* tells virsh to dump pool configuration that will be used
on next start of the pool as opposed to the current pool configuration.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
pool-edit
---------
@ -6750,7 +6813,8 @@ vol-dumpxml
::
vol-dumpxml vol-name-or-key-or-path [--pool pool-or-uuid]
vol-dumpxml [--pool pool-or-uuid] [--xpath EXPRESSION] [--wrap]
vol-name-or-key-or-path
Output the volume information as an XML dump to stdout.
@ -6762,6 +6826,13 @@ is in. If the volume name is provided instead of the key or path, then
providing the pool is necessary to find the volume to be uploaded into;
otherwise, the first volume found by the key or path will be used.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
vol-info
--------
@ -6949,10 +7020,17 @@ secret-dumpxml
::
secret-dumpxml secret
secret-dumpxml [--xpath EXPRESSION] [--wrap] secret
Output properties of *secret* (specified by its UUID) as an XML dump to stdout.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
secret-event
------------
@ -7370,12 +7448,20 @@ snapshot-dumpxml
::
snapshot-dumpxml domain snapshot [--security-info]
snapshot-dumpxml [--security-info] [--xpath EXPRESSION] [--wrap]
domain snapshot
Output the snapshot XML for the domain's snapshot named *snapshot*.
Using *--security-info* will also include security sensitive information.
Use ``snapshot-current`` to easily access the XML of the current snapshot.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
snapshot-parent
---------------
@ -7655,7 +7741,8 @@ checkpoint-dumpxml
::
checkpoint-dumpxml domain checkpoint [--security-info] [--no-domain] [--size]
checkpoint-dumpxml [--security-info] [--no-domain] [--size]
[--xpath EXPRESSION] [--wrap] domain checkpoint
Output the checkpoint XML for the domain's checkpoint named
*checkpoint*. Using
@ -7671,6 +7758,13 @@ space). Note that some hypervisors may require that *domain* is running when
Using *--no-domain* will omit the <domain> element from the
output for a more compact view.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
checkpoint-parent
-----------------
@ -7773,10 +7867,17 @@ nwfilter-dumpxml
::
nwfilter-dumpxml nwfilter-name
nwfilter-dumpxml [--xpath EXPRESSION] [--wrap] nwfilter-name
Output the network filter XML.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
nwfilter-edit
-------------
@ -7876,11 +7977,18 @@ nwfilter-binding-dumpxml
::
nwfilter-binding-dumpxml port-name
nwfilter-binding-dumpxml [--xpath EXPRESSION] [--wrap] port-name
Output the network filter binding XML for the network device called
``port-name``.
If the **--xpath** argument provides an XPath expression, it will be
evaluated against the output XML and only those matching nodes will
be printed. The default behaviour is to print each matching node as
a standalone document, however, for ease of additional processing,
the **--wrap** argument will cause the matching node to be wrapped
in a common root node.
HYPERVISOR-SPECIFIC COMMANDS
============================

View File

@ -115,6 +115,15 @@ static const vshCmdInfo info_backup_dumpxml[] = {
static const vshCmdOptDef opts_backup_dumpxml[] = {
VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -124,15 +133,19 @@ cmdBackupDumpXML(vshControl *ctl,
{
g_autoptr(virshDomain) dom = NULL;
g_autofree char *xml = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
if (!(xml = virDomainBackupGetXMLDesc(dom, 0)))
return false;
vshPrint(ctl, "%s", xml);
return true;
return virshDumpXML(ctl, xml, "domain-backup", xpath, wrap);
}

View File

@ -852,6 +852,15 @@ static const vshCmdOptDef opts_checkpoint_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("include backup size estimate in XML dump")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -864,6 +873,8 @@ cmdCheckpointDumpXML(vshControl *ctl,
g_autoptr(virshDomainCheckpoint) checkpoint = NULL;
g_autofree char *xml = NULL;
unsigned int flags = 0;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (vshCommandOptBool(cmd, "security-info"))
flags |= VIR_DOMAIN_CHECKPOINT_XML_SECURE;
@ -875,6 +886,9 @@ cmdCheckpointDumpXML(vshControl *ctl,
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
if (virshLookupCheckpoint(ctl, cmd, "checkpointname", dom,
&checkpoint, &name) < 0)
return false;
@ -882,8 +896,7 @@ cmdCheckpointDumpXML(vshControl *ctl,
if (!(xml = virDomainCheckpointGetXMLDesc(checkpoint, flags)))
return false;
vshPrint(ctl, "%s", xml);
return true;
return virshDumpXML(ctl, xml, "domain-checkpoint", xpath, wrap);
}

View File

@ -4527,6 +4527,15 @@ static const vshCmdOptDef opts_save_image_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("include security sensitive information in XML dump")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -4537,6 +4546,8 @@ cmdSaveImageDumpxml(vshControl *ctl, const vshCmd *cmd)
unsigned int flags = 0;
g_autofree char *xml = NULL;
virshControl *priv = ctl->privData;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (vshCommandOptBool(cmd, "security-info"))
flags |= VIR_DOMAIN_XML_SECURE;
@ -4544,12 +4555,14 @@ cmdSaveImageDumpxml(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptStringReq(ctl, cmd, "file", &file) < 0)
return false;
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
xml = virDomainSaveImageGetXMLDesc(priv->conn, file, flags);
if (!xml)
return false;
vshPrint(ctl, "%s", xml);
return true;
return virshDumpXML(ctl, xml, "domain-save-image", xpath, wrap);
}
/*
@ -4946,6 +4959,15 @@ static const vshCmdOptDef opts_managed_save_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("include security sensitive information in XML dump")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -4955,6 +4977,8 @@ cmdManagedSaveDumpxml(vshControl *ctl, const vshCmd *cmd)
g_autoptr(virshDomain) dom = NULL;
unsigned int flags = 0;
g_autofree char *xml = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (vshCommandOptBool(cmd, "security-info"))
flags |= VIR_DOMAIN_XML_SECURE;
@ -4962,11 +4986,13 @@ cmdManagedSaveDumpxml(vshControl *ctl, const vshCmd *cmd)
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
if (!(xml = virDomainManagedSaveGetXMLDesc(dom, flags)))
return false;
vshPrint(ctl, "%s", xml);
return true;
return virshDumpXML(ctl, xml, "domain-save-image", xpath, wrap);
}
/*
@ -10433,6 +10459,15 @@ static const vshCmdOptDef opts_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("provide XML suitable for migrations")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -10440,12 +10475,14 @@ static bool
cmdDumpXML(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(virshDomain) dom = NULL;
g_autofree char *dump = NULL;
g_autofree char *xml = NULL;
unsigned int flags = 0;
bool inactive = vshCommandOptBool(cmd, "inactive");
bool secure = vshCommandOptBool(cmd, "security-info");
bool update = vshCommandOptBool(cmd, "update-cpu");
bool migratable = vshCommandOptBool(cmd, "migratable");
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (inactive)
flags |= VIR_DOMAIN_XML_INACTIVE;
@ -10459,11 +10496,13 @@ cmdDumpXML(vshControl *ctl, const vshCmd *cmd)
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (!(dump = virDomainGetXMLDesc(dom, flags)))
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
vshPrint(ctl, "%s", dump);
return true;
if (!(xml = virDomainGetXMLDesc(dom, flags)))
return false;
return virshDumpXML(ctl, xml, "domain", xpath, wrap);
}
/*

View File

@ -470,6 +470,16 @@ static const vshCmdOptDef opts_interface_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("show inactive defined XML")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -477,7 +487,9 @@ static bool
cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(virshInterface) iface = NULL;
g_autofree char *dump = NULL;
g_autofree char *xml = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
unsigned int flags = 0;
if (vshCommandOptBool(cmd, "inactive"))
@ -486,11 +498,13 @@ cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd)
if (!(iface = virshCommandOptInterface(ctl, cmd, NULL)))
return false;
if (!(dump = virInterfaceGetXMLDesc(iface, flags)))
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
vshPrint(ctl, "%s", dump);
return true;
if (!(xml = virInterfaceGetXMLDesc(iface, flags)))
return false;
return virshDumpXML(ctl, xml, "interface", xpath, wrap);
}
/*

View File

@ -349,6 +349,15 @@ static const vshCmdOptDef opts_network_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("show inactive defined XML")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -356,8 +365,10 @@ static bool
cmdNetworkDumpXML(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(virshNetwork) network = NULL;
g_autofree char *dump = NULL;
g_autofree char *xml = NULL;
unsigned int flags = 0;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (!(network = virshCommandOptNetwork(ctl, cmd, NULL)))
return false;
@ -365,12 +376,13 @@ cmdNetworkDumpXML(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "inactive"))
flags |= VIR_NETWORK_XML_INACTIVE;
if (!(dump = virNetworkGetXMLDesc(network, flags))) {
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
}
vshPrint(ctl, "%s", dump);
return true;
if (!(xml = virNetworkGetXMLDesc(network, flags)))
return false;
return virshDumpXML(ctl, xml, "network", xpath, wrap);
}
/*
@ -1542,6 +1554,15 @@ static const vshCmdInfo info_network_port_dumpxml[] = {
static const vshCmdOptDef opts_network_port_dumpxml[] = {
VIRSH_COMMON_OPT_NETWORK_FULL(VIR_CONNECT_LIST_NETWORKS_ACTIVE),
VIRSH_COMMON_OPT_NETWORK_PORT(0),
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -1551,8 +1572,10 @@ cmdNetworkPortDumpXML(vshControl *ctl, const vshCmd *cmd)
g_autoptr(virshNetwork) network = NULL;
virNetworkPortPtr port = NULL;
bool ret = true;
g_autofree char *dump = NULL;
g_autofree char *xml = NULL;
unsigned int flags = 0;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (!(network = virshCommandOptNetwork(ctl, cmd, NULL)))
goto cleanup;
@ -1560,13 +1583,13 @@ cmdNetworkPortDumpXML(vshControl *ctl, const vshCmd *cmd)
if (!(port = virshCommandOptNetworkPort(ctl, cmd, network, NULL)))
goto cleanup;
dump = virNetworkPortGetXMLDesc(port, flags);
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
if (dump != NULL) {
vshPrint(ctl, "%s", dump);
} else {
ret = false;
}
if (!(xml = virNetworkPortGetXMLDesc(port, flags)))
goto cleanup;
ret = virshDumpXML(ctl, xml, "network-port", xpath, wrap);
cleanup:
if (port)

View File

@ -565,6 +565,15 @@ static const vshCmdOptDef opts_node_device_dumpxml[] = {
.help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
.completer = virshNodeDeviceNameCompleter,
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -574,10 +583,15 @@ cmdNodeDeviceDumpXML(vshControl *ctl, const vshCmd *cmd)
g_autoptr(virshNodeDevice) device = NULL;
g_autofree char *xml = NULL;
const char *device_value = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (vshCommandOptStringReq(ctl, cmd, "device", &device_value) < 0)
return false;
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
device = vshFindNodeDevice(ctl, device_value);
if (!device)
@ -586,8 +600,7 @@ cmdNodeDeviceDumpXML(vshControl *ctl, const vshCmd *cmd)
if (!(xml = virNodeDeviceGetXMLDesc(device, 0)))
return false;
vshPrint(ctl, "%s\n", xml);
return true;
return virshDumpXML(ctl, xml, "node-device", xpath, wrap);
}
/*

View File

@ -186,6 +186,15 @@ static const vshCmdOptDef opts_nwfilter_dumpxml[] = {
.help = N_("network filter name or uuid"),
.completer = virshNWFilterNameCompleter,
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -193,20 +202,20 @@ static bool
cmdNWFilterDumpXML(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(virshNWFilter) nwfilter = NULL;
bool ret = true;
g_autofree char *dump = NULL;
g_autofree char *xml = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (!(nwfilter = virshCommandOptNWFilter(ctl, cmd, NULL)))
return false;
dump = virNWFilterGetXMLDesc(nwfilter, 0);
if (dump != NULL) {
vshPrint(ctl, "%s", dump);
} else {
ret = false;
}
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
return ret;
if (!(xml = virNWFilterGetXMLDesc(nwfilter, 0)))
return false;
return virshDumpXML(ctl, xml, "nwfilter", xpath, wrap);
}
static int
@ -599,6 +608,15 @@ static const vshCmdOptDef opts_nwfilter_binding_dumpxml[] = {
.help = N_("network filter binding portdev"),
.completer = virshNWFilterBindingNameCompleter,
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -607,18 +625,19 @@ cmdNWFilterBindingDumpXML(vshControl *ctl, const vshCmd *cmd)
{
virNWFilterBindingPtr binding;
bool ret = true;
g_autofree char *dump = NULL;
g_autofree char *xml = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (!(binding = virshCommandOptNWFilterBinding(ctl, cmd, NULL)))
return false;
dump = virNWFilterBindingGetXMLDesc(binding, 0);
if (dump != NULL) {
vshPrint(ctl, "%s", dump);
} else {
ret = false;
}
if (!(xml = virNWFilterBindingGetXMLDesc(binding, 0)))
goto cleanup;
ret = virshDumpXML(ctl, xml, "nwfilter-binding", xpath, wrap);
cleanup:
virNWFilterBindingFree(binding);
return ret;
}

View File

@ -775,6 +775,15 @@ static const vshCmdOptDef opts_pool_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("show inactive defined XML")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -782,10 +791,11 @@ static bool
cmdPoolDumpXML(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(virshStoragePool) pool = NULL;
bool ret = true;
bool inactive = vshCommandOptBool(cmd, "inactive");
unsigned int flags = 0;
g_autofree char *dump = NULL;
g_autofree char *xml = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (inactive)
flags |= VIR_STORAGE_XML_INACTIVE;
@ -793,14 +803,13 @@ cmdPoolDumpXML(vshControl *ctl, const vshCmd *cmd)
if (!(pool = virshCommandOptPool(ctl, cmd, "pool", NULL)))
return false;
dump = virStoragePoolGetXMLDesc(pool, flags);
if (dump != NULL) {
vshPrint(ctl, "%s", dump);
} else {
ret = false;
}
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
return ret;
if (!(xml = virStoragePoolGetXMLDesc(pool, flags)))
return false;
return virshDumpXML(ctl, xml, "pool", xpath, wrap);
}
static int

View File

@ -138,6 +138,15 @@ static const vshCmdOptDef opts_secret_dumpxml[] = {
.help = N_("secret UUID"),
.completer = virshSecretUUIDCompleter,
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -147,16 +156,21 @@ cmdSecretDumpXML(vshControl *ctl, const vshCmd *cmd)
virSecretPtr secret;
bool ret = false;
g_autofree char *xml = NULL;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
secret = virshCommandOptSecret(ctl, cmd, NULL);
if (secret == NULL)
return false;
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
xml = virSecretGetXMLDesc(secret, 0);
if (xml == NULL)
goto cleanup;
vshPrint(ctl, "%s", xml);
ret = true;
ret = virshDumpXML(ctl, xml, "secret", xpath, wrap);
cleanup:
virshSecretFree(secret);

View File

@ -1607,6 +1607,15 @@ static const vshCmdOptDef opts_snapshot_dumpxml[] = {
.type = VSH_OT_BOOL,
.help = N_("include security sensitive information in XML dump")
},
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -1618,6 +1627,8 @@ cmdSnapshotDumpXML(vshControl *ctl, const vshCmd *cmd)
g_autoptr(virshDomainSnapshot) snapshot = NULL;
g_autofree char *xml = NULL;
unsigned int flags = 0;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
if (vshCommandOptBool(cmd, "security-info"))
flags |= VIR_DOMAIN_XML_SECURE;
@ -1631,11 +1642,13 @@ cmdSnapshotDumpXML(vshControl *ctl, const vshCmd *cmd)
if (!(snapshot = virDomainSnapshotLookupByName(dom, name, 0)))
return false;
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
if (!(xml = virDomainSnapshotGetXMLDesc(snapshot, flags)))
return false;
vshPrint(ctl, "%s", xml);
return true;
return virshDumpXML(ctl, xml, "domain-snapshot", xpath, wrap);
}
/*

View File

@ -1159,6 +1159,15 @@ static const vshCmdInfo info_vol_dumpxml[] = {
static const vshCmdOptDef opts_vol_dumpxml[] = {
VIRSH_COMMON_OPT_VOL_FULL,
VIRSH_COMMON_OPT_POOL_OPTIONAL,
{.name = "xpath",
.type = VSH_OT_STRING,
.completer = virshCompleteEmpty,
.help = N_("xpath expression to filter the XML document")
},
{.name = "wrap",
.type = VSH_OT_BOOL,
.help = N_("wrap xpath results in an common root element"),
},
{.name = NULL}
};
@ -1166,21 +1175,20 @@ static bool
cmdVolDumpXML(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(virshStorageVol) vol = NULL;
bool ret = true;
char *dump;
bool wrap = vshCommandOptBool(cmd, "wrap");
const char *xpath = NULL;
g_autofree char *xml = NULL;
if (!(vol = virshCommandOptVol(ctl, cmd, "vol", "pool", NULL)))
return false;
dump = virStorageVolGetXMLDesc(vol, 0);
if (dump != NULL) {
vshPrint(ctl, "%s", dump);
VIR_FREE(dump);
} else {
ret = false;
}
if (vshCommandOptStringQuiet(ctl, cmd, "xpath", &xpath) < 0)
return false;
return ret;
if (!(xml = virStorageVolGetXMLDesc(vol, 0)))
return false;
return virshDumpXML(ctl, xml, "volume", xpath, wrap);
}
static int