mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
virsh-snapshot: Refactor virsh snapshot-list
Simplify error handling and mutually exclusive option checking.
This commit is contained in:
parent
7e437ee78f
commit
55b3b15cd0
@ -1527,66 +1527,34 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
virDomainPtr dom = NULL;
|
virDomainPtr dom = NULL;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
bool show_parent = false;
|
|
||||||
int i;
|
int i;
|
||||||
xmlDocPtr xml = NULL;
|
xmlDocPtr xml = NULL;
|
||||||
xmlXPathContextPtr ctxt = NULL;
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
char *doc = NULL;
|
char *doc = NULL;
|
||||||
virDomainSnapshotPtr snapshot = NULL;
|
virDomainSnapshotPtr snapshot = NULL;
|
||||||
char *state = NULL;
|
char *state = NULL;
|
||||||
char *parent = NULL;
|
|
||||||
long long creation_longlong;
|
long long creation_longlong;
|
||||||
time_t creation_time_t;
|
time_t creation_time_t;
|
||||||
char timestr[100];
|
char timestr[100];
|
||||||
struct tm time_info;
|
struct tm time_info;
|
||||||
bool tree = vshCommandOptBool(cmd, "tree");
|
bool tree = vshCommandOptBool(cmd, "tree");
|
||||||
bool name = vshCommandOptBool(cmd, "name");
|
bool name = vshCommandOptBool(cmd, "name");
|
||||||
const char *from = NULL;
|
bool from = vshCommandOptBool(cmd, "from");
|
||||||
|
bool parent = vshCommandOptBool(cmd, "parent");
|
||||||
|
bool roots = vshCommandOptBool(cmd, "roots");
|
||||||
|
bool current = vshCommandOptBool(cmd, "current");
|
||||||
|
const char *from_snap = NULL;
|
||||||
|
char *parent_snap = NULL;
|
||||||
virDomainSnapshotPtr start = NULL;
|
virDomainSnapshotPtr start = NULL;
|
||||||
vshSnapshotListPtr snaplist = NULL;
|
vshSnapshotListPtr snaplist = NULL;
|
||||||
|
|
||||||
if (tree && name) {
|
VSH_EXCLUSIVE_OPTIONS_VAR(tree, name);
|
||||||
vshError(ctl, "%s",
|
VSH_EXCLUSIVE_OPTIONS_VAR(parent, roots);
|
||||||
_("--tree and --name are mutually exclusive"));
|
VSH_EXCLUSIVE_OPTIONS_VAR(parent, tree);
|
||||||
return false;
|
VSH_EXCLUSIVE_OPTIONS_VAR(roots, tree);
|
||||||
}
|
VSH_EXCLUSIVE_OPTIONS_VAR(roots, from);
|
||||||
|
VSH_EXCLUSIVE_OPTIONS_VAR(roots, current);
|
||||||
|
|
||||||
dom = vshCommandOptDomain(ctl, cmd, NULL);
|
|
||||||
if (dom == NULL)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if ((vshCommandOptBool(cmd, "from") ||
|
|
||||||
vshCommandOptBool(cmd, "current")) &&
|
|
||||||
vshLookupSnapshot(ctl, cmd, "from", true, dom, &start, &from) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (vshCommandOptBool(cmd, "parent")) {
|
|
||||||
if (vshCommandOptBool(cmd, "roots")) {
|
|
||||||
vshError(ctl, "%s",
|
|
||||||
_("--parent and --roots are mutually exclusive"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (tree) {
|
|
||||||
vshError(ctl, "%s",
|
|
||||||
_("--parent and --tree are mutually exclusive"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
show_parent = true;
|
|
||||||
} else if (vshCommandOptBool(cmd, "roots")) {
|
|
||||||
if (tree) {
|
|
||||||
vshError(ctl, "%s",
|
|
||||||
_("--roots and --tree are mutually exclusive"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (from) {
|
|
||||||
vshError(ctl, "%s",
|
|
||||||
vshCommandOptBool(cmd, "current") ?
|
|
||||||
_("--roots and --current are mutually exclusive") :
|
|
||||||
_("--roots and --from are mutually exclusive"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
|
|
||||||
}
|
|
||||||
#define FILTER(option, flag) \
|
#define FILTER(option, flag) \
|
||||||
do { \
|
do { \
|
||||||
if (vshCommandOptBool(cmd, option)) { \
|
if (vshCommandOptBool(cmd, option)) { \
|
||||||
@ -1594,7 +1562,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
vshError(ctl, \
|
vshError(ctl, \
|
||||||
_("--%s and --tree are mutually exclusive"), \
|
_("--%s and --tree are mutually exclusive"), \
|
||||||
option); \
|
option); \
|
||||||
goto cleanup; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
flags |= VIR_DOMAIN_SNAPSHOT_LIST_ ## flag; \
|
flags |= VIR_DOMAIN_SNAPSHOT_LIST_ ## flag; \
|
||||||
} \
|
} \
|
||||||
@ -1609,28 +1577,36 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
FILTER("external", EXTERNAL);
|
FILTER("external", EXTERNAL);
|
||||||
#undef FILTER
|
#undef FILTER
|
||||||
|
|
||||||
if (vshCommandOptBool(cmd, "metadata")) {
|
if (roots)
|
||||||
|
flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
|
||||||
|
|
||||||
|
if (vshCommandOptBool(cmd, "metadata"))
|
||||||
flags |= VIR_DOMAIN_SNAPSHOT_LIST_METADATA;
|
flags |= VIR_DOMAIN_SNAPSHOT_LIST_METADATA;
|
||||||
}
|
|
||||||
if (vshCommandOptBool(cmd, "no-metadata")) {
|
if (vshCommandOptBool(cmd, "no-metadata"))
|
||||||
flags |= VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA;
|
flags |= VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA;
|
||||||
}
|
|
||||||
|
|
||||||
if (vshCommandOptBool(cmd, "descendants")) {
|
if (vshCommandOptBool(cmd, "descendants")) {
|
||||||
if (!from) {
|
if (!from && !current) {
|
||||||
vshError(ctl, "%s",
|
vshError(ctl, "%s",
|
||||||
_("--descendants requires either --from or --current"));
|
_("--descendants requires either --from or --current"));
|
||||||
goto cleanup;
|
return false;
|
||||||
}
|
}
|
||||||
flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
|
flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((snaplist = vshSnapshotListCollect(ctl, dom, start, flags,
|
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
||||||
tree)) == NULL)
|
return false;
|
||||||
|
|
||||||
|
if ((from || current) &&
|
||||||
|
vshLookupSnapshot(ctl, cmd, "from", true, dom, &start, &from_snap) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(snaplist = vshSnapshotListCollect(ctl, dom, start, flags, tree)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!tree && !name) {
|
if (!tree && !name) {
|
||||||
if (show_parent)
|
if (parent)
|
||||||
vshPrintExtra(ctl, " %-20s %-25s %-15s %s",
|
vshPrintExtra(ctl, " %-20s %-25s %-15s %s",
|
||||||
_("Name"), _("Creation Time"), _("State"),
|
_("Name"), _("Creation Time"), _("State"),
|
||||||
_("Parent"));
|
_("Parent"));
|
||||||
@ -1638,12 +1614,8 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
vshPrintExtra(ctl, " %-20s %-25s %s",
|
vshPrintExtra(ctl, " %-20s %-25s %s",
|
||||||
_("Name"), _("Creation Time"), _("State"));
|
_("Name"), _("Creation Time"), _("State"));
|
||||||
vshPrintExtra(ctl, "\n"
|
vshPrintExtra(ctl, "\n"
|
||||||
"------------------------------------------------------------\n");
|
"------------------------------"
|
||||||
}
|
"------------------------------\n");
|
||||||
|
|
||||||
if (!snaplist->nsnaps) {
|
|
||||||
ret = true;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree) {
|
if (tree) {
|
||||||
@ -1661,7 +1633,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
const char *snap_name;
|
const char *snap_name;
|
||||||
|
|
||||||
/* free up memory from previous iterations of the loop */
|
/* free up memory from previous iterations of the loop */
|
||||||
VIR_FREE(parent);
|
VIR_FREE(parent_snap);
|
||||||
VIR_FREE(state);
|
VIR_FREE(state);
|
||||||
xmlXPathFreeContext(ctxt);
|
xmlXPathFreeContext(ctxt);
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
@ -1672,25 +1644,24 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
assert(snap_name);
|
assert(snap_name);
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
|
/* just print the snapshot name */
|
||||||
vshPrint(ctl, "%s\n", snap_name);
|
vshPrint(ctl, "%s\n", snap_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc = virDomainSnapshotGetXMLDesc(snapshot, 0);
|
if (!(doc = virDomainSnapshotGetXMLDesc(snapshot, 0)))
|
||||||
if (!doc)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xml = virXMLParseStringCtxt(doc, _("(domain_snapshot)"), &ctxt);
|
if (!(xml = virXMLParseStringCtxt(doc, _("(domain_snapshot)"), &ctxt)))
|
||||||
if (!xml)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (show_parent)
|
if (parent)
|
||||||
parent = virXPathString("string(/domainsnapshot/parent/name)",
|
parent_snap = virXPathString("string(/domainsnapshot/parent/name)",
|
||||||
ctxt);
|
ctxt);
|
||||||
|
|
||||||
state = virXPathString("string(/domainsnapshot/state)", ctxt);
|
if (!(state = virXPathString("string(/domainsnapshot/state)", ctxt)))
|
||||||
if (state == NULL)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (virXPathLongLong("string(/domainsnapshot/creationTime)", ctxt,
|
if (virXPathLongLong("string(/domainsnapshot/creationTime)", ctxt,
|
||||||
&creation_longlong) < 0)
|
&creation_longlong) < 0)
|
||||||
continue;
|
continue;
|
||||||
@ -1705,7 +1676,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
vshPrint(ctl, " %-20s %-25s %-15s %s\n",
|
vshPrint(ctl, " %-20s %-25s %-15s %s\n",
|
||||||
snap_name, timestr, state, parent);
|
snap_name, timestr, state, parent_snap);
|
||||||
else
|
else
|
||||||
vshPrint(ctl, " %-20s %-25s %s\n", snap_name, timestr, state);
|
vshPrint(ctl, " %-20s %-25s %s\n", snap_name, timestr, state);
|
||||||
}
|
}
|
||||||
@ -1715,14 +1686,12 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
cleanup:
|
cleanup:
|
||||||
/* this frees up memory from the last iteration of the loop */
|
/* this frees up memory from the last iteration of the loop */
|
||||||
vshSnapshotListFree(snaplist);
|
vshSnapshotListFree(snaplist);
|
||||||
VIR_FREE(parent);
|
VIR_FREE(parent_snap);
|
||||||
VIR_FREE(state);
|
VIR_FREE(state);
|
||||||
if (start)
|
|
||||||
virDomainSnapshotFree(start);
|
virDomainSnapshotFree(start);
|
||||||
xmlXPathFreeContext(ctxt);
|
xmlXPathFreeContext(ctxt);
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
VIR_FREE(doc);
|
VIR_FREE(doc);
|
||||||
if (dom)
|
|
||||||
virDomainFree(dom);
|
virDomainFree(dom);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user