Fix invalid code generating in esx_vi_generator.py regarding deep copy
types that contain enum properties.
Add strptime and timegm to bootstrap.conf. Both are used to convert a
xsd:dateTime to calendar time.
---
bootstrap.conf | 2 +
src/esx/esx_driver.c | 468 +++++++++++++++++++++++++++++++++++++---
src/esx/esx_vi.c | 290 +++++++++++++++++++++++++
src/esx/esx_vi.h | 27 +++
src/esx/esx_vi_generator.input | 12 +
src/esx/esx_vi_generator.py | 25 ++-
src/esx/esx_vi_methods.c | 86 ++++++++
src/esx/esx_vi_methods.h | 14 ++
src/esx/esx_vi_types.c | 99 +++++++++
src/esx/esx_vi_types.h | 12 +
10 files changed, 990 insertions(+), 45 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index ac2f8e6..ca9332d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -52,9 +52,11 @@ stpcpy
strchrnul
strndup
strerror
+strptime
strsep
sys_stat
time_r
+timegm
useless-if-before-free
vasprintf
verify
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index eb06555..5272654 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -563,6 +563,7 @@ esxClose(virConnectPtr conn)
esxVI_Logout(priv->host) < 0) {
result = -1;
}
+
esxVI_Context_Free(&priv->host);
if (priv->vCenter != NULL) {
@@ -570,6 +571,7 @@ esxClose(virConnectPtr conn)
esxVI_Logout(priv->vCenter) < 0) {
result = -1;
}
+
esxVI_Context_Free(&priv->vCenter);
}
@@ -1742,23 +1744,8 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
goto failure;
}
- switch (powerState) {
- case esxVI_VirtualMachinePowerState_PoweredOff:
- info->state = VIR_DOMAIN_SHUTOFF;
- break;
-
- case esxVI_VirtualMachinePowerState_PoweredOn:
- info->state = VIR_DOMAIN_RUNNING;
- break;
-
- case esxVI_VirtualMachinePowerState_Suspended:
- info->state = VIR_DOMAIN_PAUSED;
- break;
-
- default:
- info->state = VIR_DOMAIN_NOSTATE;
- break;
- }
+ info->state = esxVI_VirtualMachinePowerState_ConvertToLibvirt
+ (powerState);
} else if (STREQ(dynamicProperty->name, "config.hardware.memoryMB"))
{
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Int) < 0) {
@@ -2329,7 +2316,6 @@ esxListDefinedDomains(virConnectPtr conn, char **const names, int
maxnames)
count = -1;
goto cleanup;
-
}
@@ -3308,6 +3294,418 @@ esxDomainIsPersistent(virDomainPtr domain ATTRIBUTE_UNUSED)
+static virDomainSnapshotPtr
+esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ esxPrivate *priv = domain->conn->privateData;
+ virDomainSnapshotDefPtr def = NULL;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotList = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
+ esxVI_ManagedObjectReference *task = NULL;
+ esxVI_TaskInfoState taskInfoState;
+ virDomainSnapshotPtr snapshot = NULL;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ def = virDomainSnapshotDefParseString(xmlDesc, 1);
+
+ if (def == NULL) {
+ goto failure;
+ }
+
+ if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
+ (priv->host, domain->uuid, NULL, &virtualMachine,
+ priv->autoAnswer) < 0 ||
+ esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ &rootSnapshotList) < 0 ||
+ esxVI_GetSnapshotTreeByName(rootSnapshotList, def->name,
+ &snapshotTree, &snapshotTreeParent,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto failure;
+ }
+
+ if (snapshotTree != NULL) {
+ ESX_ERROR(VIR_ERR_OPERATION_INVALID,
+ _("Snapshot '%s' already exists"), def->name);
+ goto failure;
+ }
+
+ if (esxVI_CreateSnapshot_Task(priv->host, virtualMachine->obj,
+ def->name, def->description,
+ esxVI_Boolean_True,
+ esxVI_Boolean_False, &task) < 0 ||
+ esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ priv->autoAnswer, &taskInfoState) < 0) {
+ goto failure;
+ }
+
+ if (taskInfoState != esxVI_TaskInfoState_Success) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create
snapshot"));
+ goto failure;
+ }
+
+ snapshot = virGetDomainSnapshot(domain, def->name);
+
+ cleanup:
+ virDomainSnapshotDefFree(def);
+ esxVI_ObjectContent_Free(&virtualMachine);
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
+ esxVI_ManagedObjectReference_Free(&task);
+
+ return snapshot;
+
+ failure:
+ domain = NULL;
+
+ goto cleanup;
+}
+
+
+
+static char *
+esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ esxPrivate *priv = snapshot->domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotList = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
+ virDomainSnapshotDef def;
+ char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+ char *xml = NULL;
+
+ memset(&def, 0, sizeof (virDomainSnapshotDef));
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
+ &rootSnapshotList) < 0 ||
+ esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
+ &snapshotTree, &snapshotTreeParent,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto failure;
+ }
+
+ def.name = snapshot->name;
+ def.description = snapshotTree->description;
+ def.parent = snapshotTreeParent != NULL ? snapshotTreeParent->name : NULL;
+
+ if (esxVI_DateTime_ConvertToCalendarTime(snapshotTree->createTime,
+ &def.creationTime) < 0) {
+ goto failure;
+ }
+
+ def.state = esxVI_VirtualMachinePowerState_ConvertToLibvirt
+ (snapshotTree->state);
+
+ virUUIDFormat(snapshot->domain->uuid, uuid_string);
+
+ xml = virDomainSnapshotDefFormat(uuid_string, &def, 0);
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
+
+ return xml;
+
+ failure:
+ VIR_FREE(xml);
+
+ goto cleanup;
+}
+
+
+
+static int
+esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = 0;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ &rootSnapshotTreeList) < 0) {
+ goto failure;
+ }
+
+ result = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList);
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
+
+ return result;
+
+ failure:
+ result = -1;
+
+ goto cleanup;
+}
+
+
+
+static int
+esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = 0;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL;
+
+ if (names == NULL || nameslen < 0) {
+ ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ if (nameslen == 0) {
+ return 0;
+ }
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ &rootSnapshotTreeList) < 0) {
+ goto failure;
+ }
+
+ result = esxVI_GetSnapshotTreeNames(rootSnapshotTreeList, names, nameslen);
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
+
+ return result;
+
+ failure:
+ result = -1;
+
+ goto cleanup;
+}
+
+
+
+static virDomainSnapshotPtr
+esxDomainSnapshotLookupByName(virDomainPtr domain, const char *name,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
+ virDomainSnapshotPtr snapshot = NULL;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ &rootSnapshotTreeList) < 0 ||
+ esxVI_GetSnapshotTreeByName(rootSnapshotTreeList, name, &snapshotTree,
+ &snapshotTreeParent,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto failure;
+ }
+
+ snapshot = virGetDomainSnapshot(domain, name);
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
+
+ return snapshot;
+
+ failure:
+ snapshot = NULL;
+
+ goto cleanup;
+}
+
+
+
+static int
+esxDomainHasCurrentSnapshot(virDomainPtr domain,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = 0;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *currentSnapshotTree = NULL;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid,
+ ¤tSnapshotTree,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto failure;
+ }
+
+ if (currentSnapshotTree != NULL) {
+ result = 1;
+ }
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(¤tSnapshotTree);
+
+ return result;
+
+ failure:
+ result = -1;
+
+ goto cleanup;
+}
+
+
+
+static virDomainSnapshotPtr
+esxDomainSnapshotCurrent(virDomainPtr domain,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+
+ virDomainSnapshotPtr snapshot = NULL;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *currentSnapshotTree = NULL;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid,
+ ¤tSnapshotTree,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto failure;
+ }
+
+ snapshot = virGetDomainSnapshot(domain, currentSnapshotTree->name);
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(¤tSnapshotTree);
+
+ return snapshot;
+
+ failure:
+ snapshot = NULL;
+
+ goto cleanup;
+}
+
+
+
+static int
+esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = 0;
+ esxPrivate *priv = snapshot->domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotList = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
+ esxVI_ManagedObjectReference *task = NULL;
+ esxVI_TaskInfoState taskInfoState;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
+ &rootSnapshotList) < 0 ||
+ esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
+ &snapshotTree, &snapshotTreeParent,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_RevertToSnapshot_Task(priv->host, snapshotTree->snapshot, NULL,
+ &task) < 0 ||
+ esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid,
+ priv->autoAnswer, &taskInfoState) < 0) {
+ goto failure;
+ }
+
+ if (taskInfoState != esxVI_TaskInfoState_Success) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not revert to snapshot '%s'"),
snapshot->name);
+ goto failure;
+ }
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
+ esxVI_ManagedObjectReference_Free(&task);
+
+ return result;
+
+ failure:
+ result = -1;
+
+ goto cleanup;
+}
+
+
+
+static int
+esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
+{
+ int result = 0;
+ esxPrivate *priv = snapshot->domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotList = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
+ esxVI_Boolean removeChildren = esxVI_Boolean_False;
+ esxVI_ManagedObjectReference *task = NULL;
+ esxVI_TaskInfoState taskInfoState;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) {
+ removeChildren = esxVI_Boolean_True;
+ }
+
+ if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
+ &rootSnapshotList) < 0 ||
+ esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
+ &snapshotTree, &snapshotTreeParent,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_RemoveSnapshot_Task(priv->host, snapshotTree->snapshot,
+ removeChildren, &task) < 0 ||
+ esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid,
+ priv->autoAnswer, &taskInfoState) < 0) {
+ goto failure;
+ }
+
+ if (taskInfoState != esxVI_TaskInfoState_Success) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not delete snapshot '%s'"),
snapshot->name);
+ goto failure;
+ }
+
+ cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
+ esxVI_ManagedObjectReference_Free(&task);
+
+ return result;
+
+ failure:
+ result = -1;
+
+ goto cleanup;
+}
+
+
+
static virDriver esxDriver = {
VIR_DRV_ESX,
"ESX",
@@ -3388,23 +3786,23 @@ static virDriver esxDriver = {
esxDomainIsPersistent, /* domainIsPersistent */
NULL, /* cpuCompare */
NULL, /* cpuBaseline */
- NULL, /* domainGetJobInfo */
- NULL, /* domainAbortJob */
- NULL, /* domainMigrateSetMaxDowntime */
- NULL, /* domainEventRegisterAny */
- NULL, /* domainEventDeregisterAny */
- NULL, /* domainManagedSave */
- NULL, /* domainHasManagedSaveImage */
- NULL, /* domainManagedSaveRemove */
- NULL, /* domainSnapshotCreateXML */
- NULL, /* domainSnapshotDumpXML */
- NULL, /* domainSnapshotNum */
- NULL, /* domainSnapshotListNames */
- NULL, /* domainSnapshotLookupByName */
- NULL, /* domainHasCurrentSnapshot */
- NULL, /* domainSnapshotCurrent */
- NULL, /* domainRevertToSnapshot */
- NULL, /* domainSnapshotDelete */
+ NULL, /* domainGetJobInfo */
+ NULL, /* domainAbortJob */
+ NULL, /* domainMigrateSetMaxDowntime */
+ NULL, /* domainEventRegisterAny */
+ NULL, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
+ esxDomainSnapshotCreateXML, /* domainSnapshotCreateXML */
+ esxDomainSnapshotDumpXML, /* domainSnapshotDumpXML */
+ esxDomainSnapshotNum, /* domainSnapshotNum */
+ esxDomainSnapshotListNames, /* domainSnapshotListNames */
+ esxDomainSnapshotLookupByName, /* domainSnapshotLookupByName */
+ esxDomainHasCurrentSnapshot, /* domainHasCurrentSnapshot */
+ esxDomainSnapshotCurrent, /* domainSnapshotCurrent */
+ esxDomainRevertToSnapshot, /* domainRevertToSnapshot */
+ esxDomainSnapshotDelete, /* domainSnapshotDelete */
};
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index c37dfa1..eb5371d 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -1719,6 +1719,152 @@ esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent
*virtualMachine,
int
+esxVI_GetNumberOfSnapshotTrees
+ (esxVI_VirtualMachineSnapshotTree *snapshotTreeList)
+{
+ int count = 0;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree;
+
+ for (snapshotTree = snapshotTreeList; snapshotTree != NULL;
+ snapshotTree = snapshotTree->_next) {
+ count += 1 + esxVI_GetNumberOfSnapshotTrees
+ (snapshotTree->childSnapshotList);
+ }
+
+ return count;
+}
+
+
+
+int
+esxVI_GetSnapshotTreeNames(esxVI_VirtualMachineSnapshotTree *snapshotTreeList,
+ char **names, int nameslen)
+{
+ int count = 0;
+ int result;
+ int i;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree;
+
+ for (snapshotTree = snapshotTreeList;
+ snapshotTree != NULL && count < nameslen;
+ snapshotTree = snapshotTree->_next) {
+ names[count] = strdup(snapshotTree->name);
+
+ if (names[count] == NULL) {
+ virReportOOMError();
+ goto failure;
+ }
+
+ count++;
+
+ if (count >= nameslen) {
+ break;
+ }
+
+ result = esxVI_GetSnapshotTreeNames(snapshotTree->childSnapshotList,
+ names + count, nameslen - count);
+
+ if (result < 0) {
+ goto failure;
+ }
+
+ count += result;
+ }
+
+ return count;
+
+ failure:
+ for (i = 0; i < count; ++i) {
+ VIR_FREE(names[i]);
+ }
+
+ return -1;
+}
+
+
+
+int
+esxVI_GetSnapshotTreeByName
+ (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, const char *name,
+ esxVI_VirtualMachineSnapshotTree **snapshotTree,
+ esxVI_VirtualMachineSnapshotTree **snapshotTreeParent,
+ esxVI_Occurrence occurrence)
+{
+ esxVI_VirtualMachineSnapshotTree *candidate;
+
+ if (snapshotTree == NULL || *snapshotTree != NULL ||
+ snapshotTreeParent == NULL || *snapshotTreeParent != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ for (candidate = snapshotTreeList; candidate != NULL;
+ candidate = candidate->_next) {
+ if (STREQ(candidate->name, name)) {
+ *snapshotTree = candidate;
+ *snapshotTreeParent = NULL;
+ return 1;
+ }
+
+ if (esxVI_GetSnapshotTreeByName(candidate->childSnapshotList, name,
+ snapshotTree, snapshotTreeParent,
+ occurrence) > 0) {
+ if (*snapshotTreeParent == NULL) {
+ *snapshotTreeParent = candidate;
+ }
+
+ return 1;
+ }
+ }
+
+ if (occurrence == esxVI_Occurrence_OptionalItem) {
+ return 0;
+ } else {
+ ESX_VI_ERROR(VIR_ERR_NO_DOMAIN_SNAPSHOT,
+ _("Could not find snapshot with name '%s'"),
name);
+
+ return -1;
+ }
+}
+
+
+
+int
+esxVI_GetSnapshotTreeBySnapshot
+ (esxVI_VirtualMachineSnapshotTree *snapshotTreeList,
+ esxVI_ManagedObjectReference *snapshot,
+ esxVI_VirtualMachineSnapshotTree **snapshotTree)
+{
+ esxVI_VirtualMachineSnapshotTree *candidate;
+
+ if (snapshotTree == NULL || *snapshotTree != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ for (candidate = snapshotTreeList; candidate != NULL;
+ candidate = candidate->_next) {
+ if (STREQ(candidate->snapshot->value, snapshot->value)) {
+ *snapshotTree = candidate;
+ return 0;
+ }
+
+ if (esxVI_GetSnapshotTreeBySnapshot(candidate->childSnapshotList,
+ snapshot, snapshotTree) >= 0) {
+ return 0;
+ }
+ }
+
+ ESX_VI_ERROR(VIR_ERR_NO_DOMAIN_SNAPSHOT,
+ _("Could not find domain snapshot with internal name
'%s'"),
+ snapshot->value);
+
+ return -1;
+}
+
+
+
+int
esxVI_LookupResourcePoolByHostSystem
(esxVI_Context *ctx, esxVI_ObjectContent *hostSystem,
esxVI_ManagedObjectReference **resourcePool)
@@ -2336,6 +2482,150 @@ esxVI_LookupAndHandleVirtualMachineQuestion(esxVI_Context *ctx,
int
+esxVI_LookupRootSnapshotTreeList
+ (esxVI_Context *ctx, const unsigned char *virtualMachineUuid,
+ esxVI_VirtualMachineSnapshotTree **rootSnapshotTreeList)
+{
+ int result = 0;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+
+ if (rootSnapshotTreeList == NULL || *rootSnapshotTreeList != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "snapshot.rootSnapshotList") < 0 ||
+ esxVI_LookupVirtualMachineByUuid(ctx, virtualMachineUuid,
+ propertyNameList, &virtualMachine,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto failure;
+ }
+
+ for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "snapshot.rootSnapshotList")) {
+ if (esxVI_VirtualMachineSnapshotTree_CastListFromAnyType
+ (dynamicProperty->val, rootSnapshotTreeList) < 0) {
+ goto failure;
+ }
+
+ break;
+ } else {
+ VIR_WARN("Unexpected '%s' property",
dynamicProperty->name);
+ }
+ }
+
+ if (*rootSnapshotTreeList == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not lookup root snapshot list"));
+ goto failure;
+ }
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&virtualMachine);
+
+ return result;
+
+ failure:
+ esxVI_VirtualMachineSnapshotTree_Free(rootSnapshotTreeList);
+
+ result = -1;
+
+ goto cleanup;
+}
+
+
+
+int
+esxVI_LookupCurrentSnapshotTree
+ (esxVI_Context *ctx, const unsigned char *virtualMachineUuid,
+ esxVI_VirtualMachineSnapshotTree **currentSnapshotTree,
+ esxVI_Occurrence occurrence)
+{
+ int result = 0;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_ManagedObjectReference *currentSnapshot = NULL;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
+
+ if (currentSnapshotTree == NULL || *currentSnapshotTree != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ if (esxVI_String_AppendValueListToList(&propertyNameList,
+ "snapshot.currentSnapshot\0"
+ "snapshot.rootSnapshotList\0") <
0 ||
+ esxVI_LookupVirtualMachineByUuid(ctx, virtualMachineUuid,
+ propertyNameList, &virtualMachine,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto failure;
+ }
+
+ for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "snapshot.currentSnapshot")) {
+ if (esxVI_ManagedObjectReference_CastFromAnyType
+ (dynamicProperty->val, ¤tSnapshot) < 0) {
+ goto failure;
+ }
+ } else if (STREQ(dynamicProperty->name,
"snapshot.rootSnapshotList")) {
+ if (esxVI_VirtualMachineSnapshotTree_CastListFromAnyType
+ (dynamicProperty->val, &rootSnapshotTreeList) < 0) {
+ goto failure;
+ }
+ } else {
+ VIR_WARN("Unexpected '%s' property",
dynamicProperty->name);
+ }
+ }
+
+ if (currentSnapshot == NULL) {
+ if (occurrence == esxVI_Occurrence_OptionalItem) {
+ return 0;
+ } else {
+ ESX_VI_ERROR(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
+ _("Domain has no current snapshot"));
+ goto failure;
+ }
+ }
+
+ if (rootSnapshotTreeList == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not lookup root snapshot list"));
+ goto failure;
+ }
+
+ if (esxVI_GetSnapshotTreeBySnapshot(rootSnapshotTreeList, currentSnapshot,
+ &snapshotTree) < 0 ||
+ esxVI_VirtualMachineSnapshotTree_DeepCopy(currentSnapshotTree,
+ snapshotTree) < 0) {
+ goto failure;
+ }
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&virtualMachine);
+ esxVI_ManagedObjectReference_Free(¤tSnapshot);
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
+
+ return result;
+
+ failure:
+
+ result = -1;
+
+ goto cleanup;
+}
+
+
+
+int
esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
esxVI_VirtualMachineQuestionInfo *questionInfo,
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 9b65e85..a8d4cc3 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -233,6 +233,24 @@ int esxVI_LookupNumberOfDomainsByPowerState
int esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
int *id, char **name, unsigned char *uuid);
+int esxVI_GetNumberOfSnapshotTrees
+ (esxVI_VirtualMachineSnapshotTree *snapshotTreeList);
+
+int esxVI_GetSnapshotTreeNames
+ (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, char **names,
+ int nameslen);
+
+int esxVI_GetSnapshotTreeByName
+ (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, const char *name,
+ esxVI_VirtualMachineSnapshotTree **snapshotTree,
+ esxVI_VirtualMachineSnapshotTree **snapshotTreeParent,
+ esxVI_Occurrence occurrence);
+
+int esxVI_GetSnapshotTreeBySnapshot
+ (esxVI_VirtualMachineSnapshotTree *snapshotTreeList,
+ esxVI_ManagedObjectReference *snapshot,
+ esxVI_VirtualMachineSnapshotTree **snapshotTree);
+
int esxVI_LookupResourcePoolByHostSystem
(esxVI_Context *ctx, esxVI_ObjectContent *hostSystem,
esxVI_ManagedObjectReference **resourcePool);
@@ -274,6 +292,15 @@ int esxVI_LookupAndHandleVirtualMachineQuestion(esxVI_Context *ctx,
const unsigned char *uuid,
esxVI_Boolean autoAnswer);
+int esxVI_LookupRootSnapshotTreeList
+ (esxVI_Context *ctx, const unsigned char *virtualMachineUuid,
+ esxVI_VirtualMachineSnapshotTree **rootSnapshotTreeList);
+
+int esxVI_LookupCurrentSnapshotTree
+ (esxVI_Context *ctx, const unsigned char *virtualMachineUuid,
+ esxVI_VirtualMachineSnapshotTree **currentSnapshotTree,
+ esxVI_Occurrence occurrence);
+
int esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 06dddbf..9c545eb 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -424,3 +424,15 @@ object VirtualMachineQuestionInfo
ChoiceOption choice r
VirtualMachineMessage message i
end
+
+
+object VirtualMachineSnapshotTree
+ ManagedObjectReference snapshot r
+ ManagedObjectReference vm r
+ String name r
+ String description r
+ DateTime createTime r
+ VirtualMachinePowerState state r
+ Boolean quiesced r
+ VirtualMachineSnapshotTree childSnapshotList ol
+end
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 5ca6138..b933d5b 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -95,6 +95,8 @@ class Property:
return " ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_LIST(%s, %s)\n" %
(self.type, self.name)
elif self.type == "String":
return " ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(String,
%s)\n" % self.name
+ elif self.is_enum():
+ return " (*dest)->%s = src->%s;\n" % (self.name,
self.name)
else:
return " ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY(%s, %s)\n" %
(self.type, self.name)
@@ -841,17 +843,19 @@ additional_object_features = { "Event"
: Object.FEATURE__LI
"SharesInfo" :
Object.FEATURE__ANY_TYPE,
"TaskInfo" :
Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST,
"UserSession" :
Object.FEATURE__ANY_TYPE,
- "VirtualMachineQuestionInfo" :
Object.FEATURE__ANY_TYPE }
+ "VirtualMachineQuestionInfo" :
Object.FEATURE__ANY_TYPE,
+ "VirtualMachineSnapshotTree" :
Object.FEATURE__DEEP_COPY | Object.FEATURE__ANY_TYPE }
-removed_object_features = { "DynamicProperty" :
Object.FEATURE__SERIALIZE,
- "ObjectContent" :
Object.FEATURE__SERIALIZE,
- "ObjectUpdate" :
Object.FEATURE__SERIALIZE,
- "PropertyChange" :
Object.FEATURE__SERIALIZE,
- "PropertyFilterUpdate" :
Object.FEATURE__SERIALIZE,
- "TaskInfo" :
Object.FEATURE__SERIALIZE,
- "UpdateSet" :
Object.FEATURE__SERIALIZE,
- "VirtualMachineConfigInfo" :
Object.FEATURE__SERIALIZE }
+removed_object_features = { "DynamicProperty" :
Object.FEATURE__SERIALIZE,
+ "ObjectContent" :
Object.FEATURE__SERIALIZE,
+ "ObjectUpdate" :
Object.FEATURE__SERIALIZE,
+ "PropertyChange" :
Object.FEATURE__SERIALIZE,
+ "PropertyFilterUpdate" :
Object.FEATURE__SERIALIZE,
+ "TaskInfo" :
Object.FEATURE__SERIALIZE,
+ "UpdateSet" :
Object.FEATURE__SERIALIZE,
+ "VirtualMachineConfigInfo" :
Object.FEATURE__SERIALIZE,
+ "VirtualMachineSnapshotTree" :
Object.FEATURE__SERIALIZE }
@@ -948,7 +952,8 @@ for obj in objects_by_name.values():
if obj.features & Object.FEATURE__DEEP_COPY:
for property in obj.properties:
if property.occurrence != Property.OCCURRENCE__IGNORED and \
- property.type not in predefined_objects:
+ property.type not in predefined_objects and \
+ property.type in objects_by_name:
objects_by_name[property.type].features |= Object.FEATURE__DEEP_COPY
# detect extended_by relation
diff --git a/src/esx/esx_vi_methods.c b/src/esx/esx_vi_methods.c
index 3e095c7..b2b3e8d 100644
--- a/src/esx/esx_vi_methods.c
+++ b/src/esx/esx_vi_methods.c
@@ -491,6 +491,92 @@ ESX_VI__METHOD(RegisterVM_Task,
+/* esxVI_CreateSnapshot_Task */
+ESX_VI__METHOD(CreateSnapshot_Task,
+ (esxVI_Context *ctx,
+ esxVI_ManagedObjectReference *virtualMachine,
+ const char *name, const char *description,
+ esxVI_Boolean memory, esxVI_Boolean quiesce,
+ esxVI_ManagedObjectReference **task),
+ RequiredItem,
+{
+ ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(task)
+},
+{
+ ESX_VI__METHOD__PARAMETER__REQUIRE_THIS(virtualMachine)
+ ESX_VI__METHOD__PARAMETER__REQUIRE(name)
+ ESX_VI__METHOD__PARAMETER__REQUIRE(memory)
+ ESX_VI__METHOD__PARAMETER__REQUIRE(quiesce)
+},
+{
+ ESX_VI__METHOD__PARAMETER__SERIALIZE_THIS(ManagedObjectReference,
+ virtualMachine)
+ ESX_VI__METHOD__PARAMETER__SERIALIZE_VALUE(String, name)
+ ESX_VI__METHOD__PARAMETER__SERIALIZE_VALUE(String, description)
+ ESX_VI__METHOD__PARAMETER__SERIALIZE(Boolean, memory)
+ ESX_VI__METHOD__PARAMETER__SERIALIZE(Boolean, quiesce)
+},
+{
+ if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
+ goto failure;
+ }
+})
+
+
+
+/* esxVI_RevertToSnapshot_Task */
+ESX_VI__METHOD(RevertToSnapshot_Task,
+ (esxVI_Context *ctx,
+ esxVI_ManagedObjectReference *virtualMachineSnapshot,
+ esxVI_ManagedObjectReference *host,
+ esxVI_ManagedObjectReference **task),
+ RequiredItem,
+{
+ ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(task)
+},
+{
+ ESX_VI__METHOD__PARAMETER__REQUIRE_THIS(virtualMachineSnapshot)
+},
+{
+ ESX_VI__METHOD__PARAMETER__SERIALIZE_THIS(ManagedObjectReference,
+ virtualMachineSnapshot)
+ ESX_VI__METHOD__PARAMETER__SERIALIZE(ManagedObjectReference, host)
+},
+{
+ if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
+ goto failure;
+ }
+})
+
+
+
+/* esxVI_RemoveSnapshot_Task */
+ESX_VI__METHOD(RemoveSnapshot_Task,
+ (esxVI_Context *ctx,
+ esxVI_ManagedObjectReference *virtualMachineSnapshot,
+ esxVI_Boolean removeChildren,
+ esxVI_ManagedObjectReference **task),
+ RequiredItem,
+{
+ ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(task)
+},
+{
+ ESX_VI__METHOD__PARAMETER__REQUIRE_THIS(virtualMachineSnapshot)
+ ESX_VI__METHOD__PARAMETER__REQUIRE(removeChildren)
+},
+{
+ ESX_VI__METHOD__PARAMETER__SERIALIZE_THIS(ManagedObjectReference,
+ virtualMachineSnapshot)
+ ESX_VI__METHOD__PARAMETER__SERIALIZE(Boolean, removeChildren)
+},
+{
+ if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
+ goto failure;
+ }
+})
+
+
+
/* esxVI_CancelTask */
ESX_VI__METHOD(CancelTask,
(esxVI_Context *ctx,
diff --git a/src/esx/esx_vi_methods.h b/src/esx/esx_vi_methods.h
index 40bff51..9ff8b4b 100644
--- a/src/esx/esx_vi_methods.h
+++ b/src/esx/esx_vi_methods.h
@@ -80,6 +80,20 @@ int esxVI_RegisterVM_Task(esxVI_Context *ctx,
esxVI_ManagedObjectReference *host,
esxVI_ManagedObjectReference **task);
+int esxVI_CreateSnapshot_Task(esxVI_Context *ctx,
+ esxVI_ManagedObjectReference *virtualMachine,
+ const char *name, const char *description,
+ esxVI_Boolean memory, esxVI_Boolean quiesce,
+ esxVI_ManagedObjectReference **task);
+
+int esxVI_RevertToSnapshot_Task
+ (esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachineSnapshot,
+ esxVI_ManagedObjectReference *host, esxVI_ManagedObjectReference **task);
+
+int esxVI_RemoveSnapshot_Task
+ (esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachineSnapshot,
+ esxVI_Boolean removeChildren, esxVI_ManagedObjectReference **task);
+
int esxVI_CancelTask(esxVI_Context *ctx, esxVI_ManagedObjectReference *task);
int esxVI_UnregisterVM(esxVI_Context *ctx,
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index a69ea44..40d8b9b 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -1177,6 +1177,12 @@ ESX_VI__TEMPLATE__VALIDATE(DateTime,
ESX_VI__TEMPLATE__PROPERTY__REQUIRE(value);
})
+/* esxVI_DateTime_DeepCopy */
+ESX_VI__TEMPLATE__DEEP_COPY(DateTime,
+{
+ ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(String, value)
+})
+
/* esxVI_DateTime_Serialize */
ESX_VI__TEMPLATE__SERIALIZE(DateTime,
{
@@ -1213,6 +1219,72 @@ esxVI_DateTime_Deserialize(xmlNodePtr node, esxVI_DateTime
**dateTime)
return -1;
}
+int
+esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
+ time_t *secondsSinceEpoch)
+{
+ char value[64] = "";
+ char *tmp;
+ struct tm tm;
+ int milliseconds;
+ char sign;
+ int tz_hours;
+ int tz_minutes;
+ int tz_offset = 0;
+
+ if (dateTime == NULL || secondsSinceEpoch == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ if (virStrcpyStatic(value, dateTime->value) == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("xsd:dateTime value '%s' too long for
destination"),
+ dateTime->value);
+ return -1;
+ }
+
+ /* expected format: 2010-04-05T12:13:55.316789+02:00 */
+ tmp = strptime(value, "%Y-%m-%dT%H:%M:%S", &tm);
+
+ if (tmp == NULL || *tmp != '.' ||
+ virStrToLong_i(tmp + 1, &tmp, 10, &milliseconds) < 0) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("xsd:dateTime value '%s' has unexpected
format"),
+ dateTime->value);
+ return -1;
+ }
+
+ sign = *tmp;
+
+ if ((sign != '+' && sign != '-') ||
+ virStrToLong_i(tmp + 1, &tmp, 10, &tz_hours) < 0 || *tmp !=
':' ||
+ virStrToLong_i(tmp + 1, NULL, 10, &tz_minutes) < 0) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("xsd:dateTime value '%s' has unexpected
format"),
+ dateTime->value);
+ return -1;
+ }
+
+ tz_offset = tz_hours * 60 * 60 + tz_minutes * 60;
+
+ if (sign == '-') {
+ tz_offset = -tz_offset;
+ }
+
+ /*
+ * xsd:dateTime represents local time relative to the timezone given
+ * as offset. pretend the local time is in UTC and use timegm in order
+ * to avoid interference with the timezone to this computer.
+ * apply timezone correction afterwards, because it's simpler than
+ * handling all the possible over- and underflows when trying to apply
+ * it to the tm struct.
+ */
+ *secondsSinceEpoch = timegm(&tm) - tz_offset;
+
+ return 0;
+}
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -1344,4 +1416,31 @@ esxVI_ManagedObjectReference_Deserialize
return -1;
}
+
+
#include "esx_vi_types.generated.c"
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * VI Enum: VirtualMachinePowerState (Additions)
+ */
+
+int
+esxVI_VirtualMachinePowerState_ConvertToLibvirt
+ (esxVI_VirtualMachinePowerState powerState)
+{
+ switch (powerState) {
+ case esxVI_VirtualMachinePowerState_PoweredOff:
+ return VIR_DOMAIN_SHUTOFF;
+
+ case esxVI_VirtualMachinePowerState_PoweredOn:
+ return VIR_DOMAIN_RUNNING;
+
+ case esxVI_VirtualMachinePowerState_Suspended:
+ return VIR_DOMAIN_PAUSED;
+
+ default:
+ return VIR_DOMAIN_NOSTATE;
+ }
+}
diff --git a/src/esx/esx_vi_types.h b/src/esx/esx_vi_types.h
index d3c7115..4bedca9 100644
--- a/src/esx/esx_vi_types.h
+++ b/src/esx/esx_vi_types.h
@@ -230,9 +230,12 @@ struct _esxVI_DateTime {
int esxVI_DateTime_Alloc(esxVI_DateTime **dateTime);
void esxVI_DateTime_Free(esxVI_DateTime **dateTime);
int esxVI_DateTime_Validate(esxVI_DateTime *dateTime);
+int esxVI_DateTime_DeepCopy(esxVI_DateTime **dest, esxVI_DateTime *src);
int esxVI_DateTime_Serialize(esxVI_DateTime *dateTime, const char *element,
virBufferPtr output);
int esxVI_DateTime_Deserialize(xmlNodePtr node, esxVI_DateTime **dateTime);
+int esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
+ time_t *secondsSinceEpoch);
@@ -295,4 +298,13 @@ int esxVI_ManagedObjectReference_Deserialize
# include "esx_vi_types.generated.h"
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * VI Enum: VirtualMachinePowerState (Additions)
+ */
+
+int esxVI_VirtualMachinePowerState_ConvertToLibvirt
+ (esxVI_VirtualMachinePowerState powerState);
+
#endif /* __ESX_VI_TYPES_H__ */
--
1.6.3.3