Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list