Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
tools/virsh.c | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 367 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 5c56fa6..1eb4bef 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -49,6 +49,7 @@
#include "console.h"
#include "util.h"
#include "memory.h"
+#include "ignore-value.h"
static char *progname;
@@ -8137,6 +8138,364 @@ cmdQuit(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
}
/*
+ * "snapshot-create" command
+ */
+static const vshCmdInfo info_snapshot_create[] = {
+ {"help", N_("Create a snapshot")},
+ {"desc", N_("Snapshot create")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_snapshot_create[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {"file", VSH_OT_DATA, 0, N_("domain snapshot XML")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ char *from;
+ char *buffer = NULL;
+ virDomainSnapshotPtr snapshot;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ from = vshCommandOptString(cmd, "file", NULL);
+ if (from == NULL)
+ buffer = strdup("<domainsnapshot/>");
+ else
+ ignore_value(virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer));
+ if (buffer == NULL)
+ goto cleanup;
+
+ snapshot = virDomainSnapshotCreateXML(dom, buffer, 0);
+ if (snapshot == NULL)
+ goto cleanup;
+
+ virDomainSnapshotFree(snapshot);
+
+ ret = TRUE;
+
+cleanup:
+ VIR_FREE(buffer);
+ if (dom)
+ virDomainFree(dom);
+
+ return ret;
+}
+
+/*
+ * "snapshot-current" command
+ */
+static const vshCmdInfo info_snapshot_current[] = {
+ {"help", N_("Get the current snapshot")},
+ {"desc", N_("Get the current snapshot")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_snapshot_current[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ int current;
+ virDomainSnapshotPtr snapshot = NULL;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ current = virDomainHasCurrentSnapshot(dom, 0);
+ if (current < 0)
+ goto cleanup;
+ else if (current) {
+ char *xml;
+
+ if (!(snapshot = virDomainSnapshotCurrent(dom, 0)))
+ goto cleanup;
+
+ xml = virDomainSnapshotGetXMLDesc(snapshot, 0);
+ if (!xml)
+ goto cleanup;
+
+ vshPrint(ctl, "%s", xml);
+ VIR_FREE(xml);
+ }
+
+ ret = TRUE;
+
+cleanup:
+ if (snapshot)
+ virDomainSnapshotFree(snapshot);
+ if (dom)
+ virDomainFree(dom);
+
+ return ret;
+}
+
+/*
+ * "snapshot-list" command
+ */
+static const vshCmdInfo info_snapshot_list[] = {
+ {"help", N_("List snapshots for a domain")},
+ {"desc", N_("Snapshot List")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_snapshot_list[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ int numsnaps;
+ char **names = NULL;
+ int actual;
+ int i;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ numsnaps = virDomainSnapshotNum(dom, 0);
+
+ if (numsnaps < 0)
+ goto cleanup;
+
+ if (numsnaps) {
+ if (VIR_ALLOC_N(names, numsnaps) < 0)
+ goto cleanup;
+
+ actual = virDomainSnapshotListNames(dom, names, numsnaps, 0);
+ if (actual < 0)
+ goto cleanup;
+
+ for (i = 0; i < actual; i++)
+ vshPrint(ctl, "%d: %s\n", i, names[i]);
+ }
+
+ ret = TRUE;
+
+cleanup:
+ VIR_FREE(names);
+ if (dom)
+ virDomainFree(dom);
+
+ return ret;
+}
+
+/*
+ * "snapshot-dumpxml" command
+ */
+static const vshCmdInfo info_snapshot_dumpxml[] = {
+ {"help", N_("Dump XML for a domain snapshot")},
+ {"desc", N_("Snapshot Dump XML")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_snapshot_dumpxml[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotDumpXML(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ char *name;
+ virDomainSnapshotPtr snapshot = NULL;
+ char *xml = NULL;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ name = vshCommandOptString(cmd, "name", NULL);
+ if (name == NULL)
+ goto cleanup;
+
+ snapshot = virDomainSnapshotLookupByName(dom, name, 0);
+ if (snapshot == NULL)
+ goto cleanup;
+
+ xml = virDomainSnapshotGetXMLDesc(snapshot, 0);
+ if (!xml)
+ goto cleanup;
+
+ printf("%s", xml);
+
+ ret = TRUE;
+
+cleanup:
+ VIR_FREE(xml);
+ if (snapshot)
+ virDomainSnapshotFree(snapshot);
+ if (dom)
+ virDomainFree(dom);
+
+ return ret;
+}
+
+/*
+ * "start-from-snapshot" command
+ */
+static const vshCmdInfo info_start_from_snapshot[] = {
+ {"help", N_("Start a domain from a snapshot")},
+ {"desc", N_("Domain start from snapshot")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_start_from_snapshot[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
+#ifndef WIN32
+ {"console", VSH_OT_BOOL, 0, N_("attach to console after
creation")},
+#endif
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdDomainStartFromSnapshot(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ char *name;
+ virDomainSnapshotPtr snapshot = NULL;
+#ifndef WIN32
+ int console = vshCommandOptBool(cmd, "console");
+#endif
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ name = vshCommandOptString(cmd, "name", NULL);
+ if (name == NULL)
+ goto cleanup;
+
+ snapshot = virDomainSnapshotLookupByName(dom, name, 0);
+ if (snapshot == NULL)
+ goto cleanup;
+
+ if (virDomainCreateFromSnapshot(snapshot, 0) < 0)
+ goto cleanup;
+
+#ifndef WIN32
+ if (console)
+ cmdRunConsole(ctl, dom);
+#endif
+
+ ret = TRUE;
+
+cleanup:
+ if (snapshot)
+ virDomainSnapshotFree(snapshot);
+ if (dom)
+ virDomainFree(dom);
+
+ return ret;
+}
+
+/*
+ * "snapshot-delete" command
+ */
+static const vshCmdInfo info_snapshot_delete[] = {
+ {"help", N_("Delete a domain snapshot")},
+ {"desc", N_("Snapshot Delete")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_snapshot_delete[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
+ {"merge", VSH_OT_BOOL, 0, N_("merge snapshot")},
+ {"delete", VSH_OT_BOOL, 0, N_("delete snapshot")},
+ {"merge-force", VSH_OT_BOOL, 0, N_("merge snapshot, discard
children")},
+ {"delete-force", VSH_OT_BOOL, 0, N_("delete snapshot and all
children")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ char *name;
+ virDomainSnapshotPtr snapshot = NULL;
+ unsigned int flags = 0;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ name = vshCommandOptString(cmd, "name", NULL);
+ if (name == NULL)
+ goto cleanup;
+
+ if (vshCommandOptBool(cmd, "merge"))
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_MERGE;
+ if (vshCommandOptBool(cmd, "delete"))
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD;
+ if (vshCommandOptBool(cmd, "merge-force"))
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_MERGE_FORCE;
+ if (vshCommandOptBool(cmd, "delete-force"))
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD_FORCE;
+
+ /* FIXME: throw an error if more than one flag is passed */
+
+ snapshot = virDomainSnapshotLookupByName(dom, name, 0);
+ if (snapshot == NULL)
+ goto cleanup;
+
+ if (virDomainSnapshotDelete(snapshot, flags) < 0)
+ goto cleanup;
+
+ ret = TRUE;
+
+cleanup:
+ if (snapshot)
+ virDomainSnapshotFree(snapshot);
+ if (dom)
+ virDomainFree(dom);
+
+ return ret;
+}
+
+/*
* Commands
*/
static const vshCmdDef commands[] = {
@@ -8288,6 +8647,14 @@ static const vshCmdDef commands[] = {
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
{"version", cmdVersion, NULL, info_version},
{"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay},
+
+ {"snapshot-create", cmdSnapshotCreate, opts_snapshot_create,
info_snapshot_create},
+ {"snapshot-current", cmdSnapshotCurrent, opts_snapshot_current,
info_snapshot_current},
+ {"snapshot-delete", cmdSnapshotDelete, opts_snapshot_delete,
info_snapshot_delete},
+ {"snapshot-dumpxml", cmdSnapshotDumpXML, opts_snapshot_dumpxml,
info_snapshot_dumpxml},
+ {"snapshot-list", cmdSnapshotList, opts_snapshot_list,
info_snapshot_list},
+ {"start-from-snapshot", cmdDomainStartFromSnapshot,
opts_start_from_snapshot, info_start_from_snapshot},
+
{NULL, NULL, NULL, NULL}
};
--
1.6.6.1