use of com.vmware.vim25.mo.Task in project photon-model by vmware.
the class VSphereAdapterInstanceService method createCheckForIpTask.
private Runnable createCheckForIpTask(VSphereIOThreadPool pool, Operation taskFinisher, ManagedObjectReference vmRef, Connection connection, String computeLink, ProvisionContext ctx) {
return new Runnable() {
int attemptsLeft = IP_CHECK_TOTAL_WAIT_SECONDS / IP_CHECK_INTERVAL_SECONDS - 1;
@Override
public void run() {
String ip;
Map<String, List<String>> ipV4Addresses = null;
try {
GetMoRef get = new GetMoRef(connection);
// fetch enough to make guessPublicIpV4Address() work
Map<String, Object> props = get.entityProps(vmRef, VimPath.vm_guest_net);
VmOverlay vm = new VmOverlay(vmRef, props);
ip = vm.findPublicIpV4Address(ctx.nics);
ipV4Addresses = vm.getMapNic2IpV4Addresses();
} catch (InvalidPropertyFaultMsg | RuntimeFaultFaultMsg e) {
log(Level.WARNING, "Error getting IP of vm %s, %s, aborting ", VimUtils.convertMoRefToString(vmRef), computeLink);
// complete the task, IP could be assigned during next enumeration cycle
taskFinisher.sendWith(VSphereAdapterInstanceService.this);
connection.close();
return;
}
if (ip != null && ipV4Addresses.entrySet().stream().allMatch(entry -> !entry.getValue().isEmpty())) {
connection.close();
List<String> ips = ipV4Addresses.values().stream().flatMap(List::stream).collect(Collectors.toList());
List<Operation> updateIpAddressOperations = createUpdateIPOperationsForComputeAndNics(computeLink, ip, ipV4Addresses, ctx);
OperationJoin.create(updateIpAddressOperations).setCompletion((o, e) -> {
log(Level.INFO, "Update compute IP [%s] and networkInterfaces ip" + " addresses [%s] for computeLink [%s]: ", ip, ips, computeLink);
// finish task
taskFinisher.sendWith(VSphereAdapterInstanceService.this);
}).sendWith(VSphereAdapterInstanceService.this);
} else if (attemptsLeft > 0) {
attemptsLeft--;
log(Level.INFO, "IP of %s not ready, retrying", computeLink);
// reschedule
pool.schedule(this, IP_CHECK_INTERVAL_SECONDS, TimeUnit.SECONDS);
} else {
connection.close();
if (ip == null && ipV4Addresses.entrySet().stream().allMatch(entry -> entry.getValue().isEmpty())) {
log(Level.INFO, "IP of %s are not ready, giving up", computeLink);
taskFinisher.sendWith(VSphereAdapterInstanceService.this);
} else {
// not all ips are ready still update the ones that are ready
List<Operation> updateIpAddressOperations = createUpdateIPOperationsForComputeAndNics(computeLink, ip, ipV4Addresses, ctx);
List<String> ips = ipV4Addresses.values().stream().flatMap(List::stream).collect(Collectors.toList());
OperationJoin.create(updateIpAddressOperations).setCompletion((o, e) -> {
log(Level.INFO, "Not all ips are ready. Update compute IP [%s] and " + "networkInterfaces ip addresses [%s] for " + "computeLink [%s]: ", ip != null ? ip : "", ips, computeLink);
taskFinisher.sendWith(VSphereAdapterInstanceService.this);
}).sendWith(VSphereAdapterInstanceService.this);
}
}
}
};
}
use of com.vmware.vim25.mo.Task in project photon-model by vmware.
the class VSphereAdapterInstanceService method handleCreateInstance.
private void handleCreateInstance(ProvisionContext ctx) {
ctx.pool.submit(ctx.getAdapterManagementReference(), ctx.vSphereCredentials, (connection, ce) -> {
if (ctx.fail(ce)) {
return;
}
try {
InstanceClient client = new InstanceClient(connection, ctx);
ComputeState state;
if (ctx.templateMoRef != null) {
state = client.createInstanceFromTemplate(ctx.templateMoRef);
} else if (ctx.image != null) {
ManagedObjectReference moRef = CustomProperties.of(ctx.image).getMoRef(CustomProperties.MOREF);
if (moRef != null) {
// the image is backed by a template VM
state = client.createInstanceFromTemplate(moRef);
} else {
// library item
state = client.createInstanceFromLibraryItem(ctx.image);
}
} else if (ctx.snapshotMoRef != null) {
state = client.createInstanceFromSnapshot();
} else {
state = client.createInstance();
}
if (state == null) {
// assume they will patch the task if they have provisioned the vm
return;
}
// populate state, MAC address being very important
VmOverlay vmOverlay = client.enrichStateFromVm(state);
Operation[] finishTask = new Operation[1];
for (NetworkInterfaceStateWithDetails nic : ctx.nics) {
// request guest customization while vm of powered off
SubnetState subnet = nic.subnet;
if (subnet != null && nic.description != null && nic.description.assignment == IpAssignment.STATIC) {
CustomizationClient cc = new CustomizationClient(connection, ctx.child, vmOverlay.getGuestId());
CustomizationSpec template = new CustomizationSpec();
cc.customizeNic(vmOverlay.getPrimaryMac(), ctx.child.hostName, nic.address, subnet, template);
cc.customizeDns(subnet.dnsServerAddresses, subnet.dnsSearchDomains, template);
ManagedObjectReference task = cc.customizeGuest(client.getVm(), template);
TaskInfo taskInfo = VimUtils.waitTaskEnd(connection, task);
if (taskInfo.getState() == TaskInfoState.ERROR) {
VimUtils.rethrow(taskInfo.getError());
}
}
}
// power on machine before enrichment
if (ctx.child.powerState == PowerState.ON) {
new PowerStateClient(connection).changePowerState(client.getVm(), PowerState.ON, null, 0);
state.powerState = PowerState.ON;
Operation op = ctx.mgr.createTaskPatch(TaskStage.FINISHED);
Boolean awaitIp = CustomProperties.of(ctx.child).getBoolean(ComputeProperties.CUSTOM_PROP_COMPUTE_AWAIT_IP, true);
if (awaitIp) {
Runnable runnable = createCheckForIpTask(ctx.pool, op, client.getVm(), connection.createUnmanagedCopy(), ctx.child.documentSelfLink, ctx);
ctx.pool.schedule(runnable, IP_CHECK_INTERVAL_SECONDS, TimeUnit.SECONDS);
} else {
finishTask[0] = op;
}
} else {
// only finish the task without waiting for IP
finishTask[0] = ctx.mgr.createTaskPatch(TaskStage.FINISHED);
}
updateNicsAfterProvisionSuccess(vmOverlay.getNics(), ctx);
updateDiskLinksAfterProvisionSuccess(state, vmOverlay.getDisks(), ctx);
state.lifecycleState = LifecycleState.READY;
// Find the host link where the computed is provisioned and patch the
// compute state.
queryHostDocumentAndUpdateCompute(ctx, vmOverlay.getHost()).thenCompose(computeState -> {
ComputeState hostState = computeState.iterator().next();
CustomProperties.of(state).put(VC_UUID, CustomProperties.of(hostState).getString(VC_UUID)).put(DATACENTER_SELF_LINK, CustomProperties.of(hostState).getString(DATACENTER_SELF_LINK)).put(COMPUTE_HOST_LINK_PROP_NAME, hostState.documentSelfLink);
return createComputeResourcePatch(state, ctx.computeReference);
}).whenComplete((o, e) -> {
if (e != null) {
ctx.fail(e);
return;
}
if (finishTask.length > 0) {
finishTask[0].sendWith(this);
}
});
} catch (Exception e) {
ctx.fail(e);
}
});
}
use of com.vmware.vim25.mo.Task in project photon-model by vmware.
the class VSphereAdapterSnapshotService method deleteSnapshot.
private void deleteSnapshot(SnapshotContext context, Connection connection, DeferredResult<SnapshotContext> deferredResult) {
final SnapshotState snapshot = context.snapshotState;
// Physical snapshot processing
ManagedObjectReference snapshotMoref = CustomProperties.of(snapshot).getMoRef(CustomProperties.MOREF);
if (snapshotMoref == null) {
deferredResult.fail(new IllegalStateException(String.format("Cannot find the snapshot %s to removed", snapshotMoref)));
return;
}
ManagedObjectReference task;
TaskInfo info;
try {
logInfo("Deleting snapshot with name %s", context.snapshotState.name);
task = connection.getVimPort().removeSnapshotTask(snapshotMoref, REMOVE_CHILDREN, SNAPSHOT_CONSOLIDATION);
info = VimUtils.waitTaskEnd(connection, task);
if (info.getState() != TaskInfoState.SUCCESS) {
VimUtils.rethrow(info.getError());
}
} catch (Exception e) {
logSevere("Deleting the snapshot %s failed", context.snapshotState.name);
deferredResult.fail(e);
return;
}
logInfo("Deleted the snapshot with name %s successfully", context.snapshotState.name);
// Once the actual snapshot delete is successful, process the update of the children
// snapshot states and the next current snapshot
final List<SnapshotState> childSnapshots = new ArrayList<>();
DeferredResult<List<SnapshotState>> dr = getChildSnapshots(snapshot.documentSelfLink);
List<SnapshotState> updatedChildSnapshots = new ArrayList<>();
dr.whenComplete((o, e) -> {
if (e != null) {
logSevere("Retrieving the details of children snapshots failed");
deferredResult.fail(e);
return;
}
childSnapshots.addAll(o);
logInfo("Retrieving the details of %s children snapshots ", childSnapshots.size());
// Update the children
if (!childSnapshots.isEmpty()) {
logInfo("Updating the state of child snapshots of: %s", snapshot.name);
childSnapshots.forEach(c -> {
c.parentLink = snapshot.parentLink;
updatedChildSnapshots.add(c);
});
context.snapshotOperations = updatedChildSnapshots.stream().map(childSnapshot -> Operation.createPatch(PhotonModelUriUtils.createInventoryUri(getHost(), childSnapshot.documentSelfLink)).setBody(childSnapshot).setReferer(getUri())).collect(Collectors.toList());
}
processNextStepsForDeleteOperation(context, deferredResult);
});
}
use of com.vmware.vim25.mo.Task in project photon-model by vmware.
the class VSphereAdapterSnapshotService method createSnapshot.
private void createSnapshot(Connection connection, SnapshotContext context, DeferredResult<SnapshotContext> deferredResult) {
ManagedObjectReference vmMoRef = CustomProperties.of(context.computeDescription).getMoRef(CustomProperties.MOREF);
if (vmMoRef == null) {
deferredResult.fail(new IllegalStateException("Cannot find VM to snapshot"));
return;
}
ManagedObjectReference task;
TaskInfo info;
try {
logInfo("Creating snapshot for compute resource %s", context.computeDescription.name);
task = connection.getVimPort().createSnapshotTask(vmMoRef, context.snapshotState.name, context.snapshotState.description, context.snapshotMemory, false);
info = VimUtils.waitTaskEnd(connection, task);
if (info.getState() != TaskInfoState.SUCCESS) {
VimUtils.rethrow(info.getError());
}
} catch (Exception e) {
deferredResult.fail(e);
return;
}
CustomProperties.of(context.snapshotState).put(CustomProperties.MOREF, (ManagedObjectReference) info.getResult());
// mark this as current snapshot
context.snapshotState.isCurrent = true;
// create a new xenon SnapshotState
logInfo(String.format("Creating a new snapshot state for compute : %s", context.computeDescription.name));
Operation createSnapshotState = Operation.createPost(PhotonModelUriUtils.createInventoryUri(getHost(), SnapshotService.FACTORY_LINK)).setBody(context.snapshotState);
if (context.existingSnapshotState != null) {
// un-mark old snapshot as current snapshot
context.existingSnapshotState.isCurrent = false;
Operation patchOldSnapshot = Operation.createPatch(UriUtils.buildUri(getHost(), context.existingSnapshotState.documentSelfLink)).setBody(context.existingSnapshotState);
OperationSequence.create(createSnapshotState).next(patchOldSnapshot).setCompletion((o, e) -> {
if (e != null && !e.isEmpty()) {
deferredResult.fail(e.values().iterator().next());
}
deferredResult.complete(context);
}).sendWith(this);
} else {
context.computeDescription.customProperties.put(ComputeProperties.CUSTOM_PROP_COMPUTE_HAS_SNAPSHOTS, "true");
// patch compute adding the property '_hasSnapshots' with true
Operation patchCompute = Operation.createPatch(UriUtils.buildUri(getHost(), context.snapshotState.computeLink)).setBody(context.computeDescription);
OperationSequence.create(createSnapshotState).next(patchCompute).setCompletion((o, e) -> {
if (e != null && !e.isEmpty()) {
deferredResult.fail(e.values().iterator().next());
}
logInfo(String.format("Created a new snapshot state for compute : %s", context.computeDescription.name));
deferredResult.complete(context);
}).sendWith(this);
}
}
use of com.vmware.vim25.mo.Task in project photon-model by vmware.
the class VSphereIncrementalEnumerationService method collectAllEndpointResources.
private DeferredResult<Set<String>> collectAllEndpointResources(ComputeEnumerateResourceRequest req, String parentLink) {
QueryTask.Query combinedClause = new QueryTask.Query().setOccurance(Occurance.MUST_OCCUR);
// The next clauses are the boolean clauses that will be added to the
// combinedClause. At the top, all further queries should have SHOULD_OCCUR
QueryTask.Query resourceClause = QueryTask.Query.Builder.create().addFieldClause(ResourceState.FIELD_NAME_ENDPOINT_LINK, req.endpointLink).addFieldClause(ComputeService.ComputeState.FIELD_NAME_LIFECYCLE_STATE, ComputeService.LifecycleState.PROVISIONING.toString(), QueryTask.QueryTerm.MatchType.TERM, QueryTask.Query.Occurance.MUST_NOT_OCCUR).addFieldClause(ServiceDocument.FIELD_NAME_SELF_LINK, parentLink, QueryTask.Query.Occurance.MUST_NOT_OCCUR).addInClause(ServiceDocument.FIELD_NAME_KIND, Arrays.asList(Utils.buildKind(ComputeService.ComputeState.class), Utils.buildKind(NetworkService.NetworkState.class), Utils.buildKind(StorageDescriptionService.StorageDescription.class), Utils.buildKind(SubnetService.SubnetState.class))).build().setOccurance(Occurance.SHOULD_OCCUR);
// The below two queries are added to get the Folders and Datacenters that are enumerated
// They are persisted as ResourceGroupState documents, and there are other documents of the same
// kind (which have a different lifecycle), we're filtering on the "__computeType" property
// Adding these documents here will enable automatic deletion of "untouched" resources in
// the further logic
QueryTask.Query folderClause = QueryTask.Query.Builder.create().addCompositeFieldClause(ResourceState.FIELD_NAME_CUSTOM_PROPERTIES, CustomProperties.TYPE, VimNames.TYPE_FOLDER).addKindFieldClause(ResourceGroupState.class).build().setOccurance(Occurance.SHOULD_OCCUR);
QueryTask.Query datacenterClause = QueryTask.Query.Builder.create().addCompositeFieldClause(ResourceState.FIELD_NAME_CUSTOM_PROPERTIES, CustomProperties.TYPE, VimNames.TYPE_DATACENTER).addKindFieldClause(ResourceGroupState.class).build().setOccurance(Occurance.SHOULD_OCCUR);
// Add all the clauses to the combined clause
// The query structure is now --> MUST(SHOULD A + SHOULD B + SHOULD C)
// where A, B, C are independent queries
combinedClause.addBooleanClause(resourceClause).addBooleanClause(folderClause).addBooleanClause(datacenterClause);
QueryTask task = QueryTask.Builder.createDirectTask().setQuery(combinedClause).setResultLimit(QueryUtils.DEFAULT_RESULT_LIMIT).build();
DeferredResult<Set<String>> res = new DeferredResult<>();
Set<String> links = new ConcurrentSkipListSet<>();
QueryUtils.startInventoryQueryTask(this, task).whenComplete((result, e) -> {
if (e != null) {
res.complete(new HashSet<>());
return;
}
if (result.results.nextPageLink == null) {
res.complete(links);
return;
}
Operation.createGet(PhotonModelUriUtils.createInventoryUri(getHost(), result.results.nextPageLink)).setCompletion(makeCompletion(links, res)).sendWith(this);
});
return res;
}
Aggregations