Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tools/virsh-domain.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 8 +++++
2 files changed, 102 insertions(+)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 49cd154..5075d0b 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9467,6 +9467,94 @@ cleanup:
/*
+ * "normalize" command
+ */
+static const vshCmdInfo info_normalize[] = {
+ {.name = "help",
+ .data = N_("reformat XML from a file")
+ },
+ {.name = "desc",
+ .data = N_("Parse XML from a file and format it back")},
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_normalize[] = {
+ {.name = "domain",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("domain name, id or uuid")
+ },
+ {.name = "file",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("XML file")
+ },
+ {.name = "inactive",
+ .type = VSH_OT_BOOL,
+ .help = N_("show inactive defined XML")
+ },
+ {.name = "security-info",
+ .type = VSH_OT_BOOL,
+ .help = N_("include security sensitive information in XML dump")
+ },
+ {.name = "update-cpu",
+ .type = VSH_OT_BOOL,
+ .help = N_("update guest CPU according to host CPU")
+ },
+ {.name = "migratable",
+ .type = VSH_OT_BOOL,
+ .help = N_("provide XML suitable for migrations")
+ },
+ {.name = NULL}
+};
+static bool
+cmdNormalize(vshControl *ctl, const vshCmd *cmd)
+{
+ bool ret = false;
+ virDomainPtr dom;
+ const char *from;
+ char *buffer = NULL;
+ char *bufferOut = 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");
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return ret;
+
+ if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
+ goto cleanup;
+
+ if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) {
+ vshReportError(ctl);
+ goto cleanup;
+ }
+
+ if (inactive)
+ flags |= VIR_DOMAIN_XML_INACTIVE;
+ if (secure)
+ flags |= VIR_DOMAIN_XML_SECURE;
+ if (update)
+ flags |= VIR_DOMAIN_XML_UPDATE_CPU;
+ if (migratable)
+ flags |= VIR_DOMAIN_XML_MIGRATABLE;
+
+ if (virDomainNormalizeXML(dom, buffer, &bufferOut, flags) < 0)
+ goto cleanup;
+
+ vshPrint(ctl, "%s", bufferOut);
+ ret = true;
+
+cleanup:
+ virDomainFree(dom);
+ VIR_FREE(buffer);
+ VIR_FREE(bufferOut);
+ return ret;
+}
+
+/*
* "detach-device" command
*/
static const vshCmdInfo info_detach_device[] = {
@@ -10743,6 +10831,12 @@ const vshCmdDef domManagementCmds[] = {
.info = info_migrate_getspeed,
.flags = 0
},
+ {.name = "normalize",
+ .handler = cmdNormalize,
+ .opts = opts_normalize,
+ .info = info_normalize,
+ .flags = 0
+ },
{.name = "numatune",
.handler = cmdNumatune,
.opts = opts_numatune,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 0ae5178..532b081 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1208,6 +1208,14 @@ migrated to another host.
Get the maximum migration bandwidth (in MiB/s) for a domain.
+=item B<normalize> I<domain> I<file> [I<--inactive>]
[I<--security-info>]
+[I<--update-cpu>] [I<--migratable>]
+
+Parse XML snippet stored in I<file> as it would be a part of I<domain> and
+format it back. This has advantage of all values are formatted uniformly. For
+instance, if I<file> contains address='0x0008' the output will reformat
this as
+address='0x08'. To control produced XML use the same options as
B<dumpxml>.
+
=item B<numatune> I<domain> [I<--mode> B<mode>]
[I<--nodeset> B<nodeset>]
[[I<--config>] [I<--live>] | [I<--current>]]
--
1.8.1.5