Producing an xml file just for name and description fields is overkill; this makes life easier from virsh. * tools/virsh.c (cmdSnapshotCreateAs): New command. (snapshotCmds): Install it. * tools/virsh.pod: Document it. --- tools/virsh.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 8 ++++- 2 files changed, 109 insertions(+), 1 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 6b5f3d9..3a59acd 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -11042,6 +11042,106 @@ cleanup: } /* + * "snapshot-create-as" command + */ +static const vshCmdInfo info_snapshot_create_as[] = { + {"help", N_("Create a snapshot from a set of args")}, + {"desc", N_("Create a snapshot (disk and RAM) from arguments")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_snapshot_create_as[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"name", VSH_OT_DATA, 0, N_("name of snapshot")}, + {"description", VSH_OT_DATA, 0, N_("description of snapshot")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + bool ret = false; + char *buffer = NULL; + virDomainSnapshotPtr snapshot = NULL; + xmlDocPtr xml = NULL; + xmlXPathContextPtr ctxt = NULL; + char *doc = NULL; + const char *name = NULL; + const char *desc = NULL; + char *parsed_name = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (!vshConnectionUsability(ctl, ctl->conn)) + goto cleanup; + + dom = vshCommandOptDomain(ctl, cmd, NULL); + if (dom == NULL) + goto cleanup; + + if (vshCommandOptString(cmd, "name", &name) < 0 || + vshCommandOptString(cmd, "description", &desc) < 0) { + vshError(ctl, _("argument must not be argument")); + goto cleanup; + } + + virBufferAddLit(&buf, "<domainsnapshot>\n"); + if (name) + virBufferAsprintf(&buf, " <name>%s</name>\n", name); + if (desc) + virBufferAsprintf(&buf, " <description>%s</description>\n", desc); + virBufferAddLit(&buf, "</domainsnapshot>\n"); + + buffer = virBufferContentAndReset(&buf); + if (buffer == NULL) { + vshError(ctl, "%s", _("Out of memory")); + goto cleanup; + } + + snapshot = virDomainSnapshotCreateXML(dom, buffer, 0); + if (snapshot == NULL) + goto cleanup; + + doc = virDomainSnapshotGetXMLDesc(snapshot, 0); + if (!doc) + goto cleanup; + + xml = xmlReadDoc((const xmlChar *) doc, "domainsnapshot.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) + goto cleanup; + ctxt = xmlXPathNewContext(xml); + if (!ctxt) + goto cleanup; + + parsed_name = virXPathString("string(/domainsnapshot/name)", ctxt); + if (!parsed_name) { + vshError(ctl, "%s", + _("Could not find 'name' element in domain snapshot XML")); + goto cleanup; + } + + vshPrint(ctl, _("Domain snapshot %s created\n"), name ? name : parsed_name); + + ret = true; + +cleanup: + VIR_FREE(parsed_name); + xmlXPathFreeContext(ctxt); + if (xml) + xmlFreeDoc(xml); + if (snapshot) + virDomainSnapshotFree(snapshot); + VIR_FREE(doc); + VIR_FREE(buffer); + if (dom) + virDomainFree(dom); + + return ret; +} + +/* * "snapshot-current" command */ static const vshCmdInfo info_snapshot_current[] = { @@ -11679,6 +11779,8 @@ static const vshCmdDef virshCmds[] = { static const vshCmdDef snapshotCmds[] = { {"snapshot-create", cmdSnapshotCreate, opts_snapshot_create, info_snapshot_create, 0}, + {"snapshot-create-as", cmdSnapshotCreateAs, opts_snapshot_create_as, + info_snapshot_create_as, 0}, {"snapshot-current", cmdSnapshotCurrent, opts_snapshot_current, info_snapshot_current, 0}, {"snapshot-delete", cmdSnapshotDelete, opts_snapshot_delete, diff --git a/tools/virsh.pod b/tools/virsh.pod index 33f72ed..44f2e25 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1394,7 +1394,7 @@ used to represent properties of snapshots. =over 4 -=item B<snapshot-create> I<domain> I<xmlfile> +=item B<snapshot-create> I<domain> optional I<xmlfile> Create a snapshot for domain I<domain> with the properties specified in I<xmlfile>. The only properties settable for a domain snapshot are the @@ -1402,6 +1402,12 @@ I<xmlfile>. The only properties settable for a domain snapshot are the automatically filled in by libvirt. If I<xmlfile> is completely omitted, then libvirt will choose a value for all fields. +=item B<snapshot-create-as> I<domain> optional I<name> I<description> + +Create a snapshot for domain I<domain> with the given <name> and +<description>; if either value is omitted, libvirt will choose a +value. + =item B<snapshot-current> I<domain> Output the snapshot XML for the domain's current snapshot (if any). -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list