virsh: add snapshot-create-as command

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.
This commit is contained in:
Eric Blake 2011-06-15 16:19:13 -06:00
parent ea71d82816
commit 1546dcf866
2 changed files with 109 additions and 1 deletions

View File

@ -11129,6 +11129,106 @@ cleanup:
return ret; return ret;
} }
/*
* "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 empty"));
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 * "snapshot-current" command
*/ */
@ -11768,6 +11868,8 @@ static const vshCmdDef virshCmds[] = {
static const vshCmdDef snapshotCmds[] = { static const vshCmdDef snapshotCmds[] = {
{"snapshot-create", cmdSnapshotCreate, opts_snapshot_create, {"snapshot-create", cmdSnapshotCreate, opts_snapshot_create,
info_snapshot_create, 0}, info_snapshot_create, 0},
{"snapshot-create-as", cmdSnapshotCreateAs, opts_snapshot_create_as,
info_snapshot_create_as, 0},
{"snapshot-current", cmdSnapshotCurrent, opts_snapshot_current, {"snapshot-current", cmdSnapshotCurrent, opts_snapshot_current,
info_snapshot_current, 0}, info_snapshot_current, 0},
{"snapshot-delete", cmdSnapshotDelete, opts_snapshot_delete, {"snapshot-delete", cmdSnapshotDelete, opts_snapshot_delete,

View File

@ -1414,7 +1414,7 @@ used to represent properties of snapshots.
=over 4 =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 Create a snapshot for domain I<domain> with the properties specified in
I<xmlfile>. The only properties settable for a domain snapshot are the I<xmlfile>. The only properties settable for a domain snapshot are the
@ -1422,6 +1422,12 @@ I<xmlfile>. The only properties settable for a domain snapshot are the
automatically filled in by libvirt. If I<xmlfile> is completely omitted, automatically filled in by libvirt. If I<xmlfile> is completely omitted,
then libvirt will choose a value for all fields. 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> =item B<snapshot-current> I<domain>
Output the snapshot XML for the domain's current snapshot (if any). Output the snapshot XML for the domain's current snapshot (if any).