private PushButton createButton(final Pair<T, V> item, boolean plusButton) { final T value = item.getFirst(); final V widget = item.getSecond(); final PushButton button = new PushButton(new Image(plusButton ? resources.increaseIcon() : resources.decreaseIcon())); button.addStyleName(style.buttonStyle()); button.addStyleName("buttonStyle_pfly_fix"); // $NON-NLS-1$ button.addClickHandler( plusButton ? new ClickHandler() { @Override public void onClick(ClickEvent event) { getEntry(widget).removeLastButton(); Pair<T, V> item = addGhostEntry(); onAdd(item.getFirst(), item.getSecond()); } } : new ClickHandler() { @Override public void onClick(ClickEvent event) { if (vetoRemoveWidget(item, value, widget)) { return; } doRemoveItem(item, value, widget); } }); return button; }
private static GraphicsDevice getCompatibleGraphics( VmDeviceType videoDeviceType, Version clusterVersion, VmBase vmBase) { GraphicsDevice graphicsDevice = null; GraphicsType compatibleType = null; OsRepository osRepository = SimpleDependencyInjector.getInstance().get(OsRepository.class); for (Pair<GraphicsType, DisplayType> graphicsDisplayPair : osRepository.getGraphicsAndDisplays(vmBase.getOsId(), clusterVersion)) { if (graphicsDisplayPair.getSecond().getDefaultVmDeviceType() == videoDeviceType) { compatibleType = graphicsDisplayPair.getFirst(); // previously to spice+vnc, QXL was only used by spice, so prefer spice if available if (videoDeviceType == VmDeviceType.QXL && compatibleType == GraphicsType.SPICE) { break; } } } if (compatibleType != null) { graphicsDevice = new GraphicsDevice(compatibleType.getCorrespondingDeviceType()); graphicsDevice.setId(new VmDeviceId(Guid.newGuid(), vmBase.getId())); } return graphicsDevice; }
/** * Retrieve a storage domain using a specified storage domain ID. * * @param storageDomainId the domain's ID * @return the storage domain */ @SuppressWarnings("unchecked") protected StorageDomain getStorageDomainById(Guid storageDomainId) { VDSReturnValue returnValue; try { returnValue = executeHSMGetStorageDomainInfo( new HSMGetStorageDomainInfoVDSCommandParameters( getParameters().getVdsId(), storageDomainId)); } catch (RuntimeException e) { log.error( "Could not get info for storage domain ID: '{}': {}", storageDomainId, e.getMessage()); log.debug("Exception", e); return null; } Pair<StorageDomainStatic, SANState> result = (Pair<StorageDomainStatic, SANState>) returnValue.getReturnValue(); StorageDomainStatic storageDomainStatic = result.getFirst(); storageDomainStatic.setStorageType(getParameters().getStorageType()); StorageDomain storageDomain = new StorageDomain(); storageDomain.setStorageStaticData(storageDomainStatic); return storageDomain; }
@Override protected void executeVdsBrokerCommand() { result = getBroker().getStorageDomainInfo(getParameters().getStorageDomainId().toString()); proceedProxyReturnValue(); Pair<StorageDomainStatic, Guid> pairSdStatic = BuildStorageStaticFromXmlRpcStruct(result.storageInfo); pairSdStatic.getFirst().setId(getParameters().getStorageDomainId()); setReturnValue(pairSdStatic); }
@Override public M flush() { modelItems.clear(); for (Pair<T, V> item : items) { T value = item.getFirst(); if (!isGhost(value)) { modelItems.add(value); } } return model; }
private static Pair<StorageDomainStatic, Guid> BuildStorageStaticFromXmlRpcStruct( Map<String, Object> xmlRpcStruct) { Pair<StorageDomainStatic, Guid> returnValue = new Pair<StorageDomainStatic, Guid>(); StorageDomainStatic sdStatic = new StorageDomainStatic(); if (xmlRpcStruct.containsKey("name")) { sdStatic.setStorageName(xmlRpcStruct.get("name").toString()); } if (xmlRpcStruct.containsKey("type")) { sdStatic.setStorageType( EnumUtils.valueOf(StorageType.class, xmlRpcStruct.get("type").toString(), true)); } if (xmlRpcStruct.containsKey("class")) { String domainType = xmlRpcStruct.get("class").toString(); if ("backup".equalsIgnoreCase(domainType)) { sdStatic.setStorageDomainType(StorageDomainType.ImportExport); } else { sdStatic.setStorageDomainType(EnumUtils.valueOf(StorageDomainType.class, domainType, true)); } } if (xmlRpcStruct.containsKey("version")) { sdStatic.setStorageFormat(StorageFormatType.forValue(xmlRpcStruct.get("version").toString())); } if (sdStatic.getStorageType() != StorageType.UNKNOWN) { if (sdStatic.getStorageType().isFileDomain() && xmlRpcStruct.containsKey("remotePath")) { String path = xmlRpcStruct.get("remotePath").toString(); List<StorageServerConnections> connections = DbFacade.getInstance().getStorageServerConnectionDao().getAllForStorage(path); if (connections.isEmpty()) { sdStatic.setConnection(new StorageServerConnections()); sdStatic.getConnection().setconnection(path); sdStatic.getConnection().setstorage_type(sdStatic.getStorageType()); } else { sdStatic.setStorage(connections.get(0).getid()); sdStatic.setConnection(connections.get(0)); } } else if (sdStatic.getStorageType() != StorageType.NFS && (xmlRpcStruct.containsKey("vguuid"))) { sdStatic.setStorage(xmlRpcStruct.get("vguuid").toString()); } } if (xmlRpcStruct.containsKey("state")) { sdStatic.setSanState( EnumUtils.valueOf( SANState.class, xmlRpcStruct.get("state").toString().toUpperCase(), false)); } returnValue.setFirst(sdStatic); Object[] poolUUIDs = (Object[]) xmlRpcStruct.get("pool"); if (poolUUIDs.length != 0) { returnValue.setSecond(Guid.createGuidFromString(poolUUIDs[0].toString())); } return returnValue; }
@Override protected void executeQueryCommand() { ArrayList<StorageDomain> returnValue = new ArrayList<>(); VDSReturnValue vdsReturnValue = runVdsCommand( VDSCommandType.HSMGetStorageDomainsList, new HSMGetStorageDomainsListVDSCommandParameters( getParameters().getId(), Guid.Empty, null, getParameters().getStorageDomainType(), getParameters().getPath())); if (vdsReturnValue.getSucceeded()) { ArrayList<Guid> guidsFromIrs = (ArrayList<Guid>) vdsReturnValue.getReturnValue(); HashSet<Guid> guidsFromDb = new HashSet<>(); if (guidsFromIrs.size() > 0) { List<StorageDomain> domainsInDb = storageDomainDao.getAll(); for (StorageDomain domain : domainsInDb) { guidsFromDb.add(domain.getId()); } for (Guid domainId : guidsFromIrs) { if (!guidsFromDb.contains(domainId)) { Pair<StorageDomainStatic, Guid> domainFromIrs = (Pair<StorageDomainStatic, Guid>) runVdsCommand( VDSCommandType.HSMGetStorageDomainInfo, new HSMGetStorageDomainInfoVDSCommandParameters( getParameters().getId(), domainId)) .getReturnValue(); StorageDomain domain = new StorageDomain(); domain.setStorageStaticData(domainFromIrs.getFirst()); domain.setStoragePoolId(domainFromIrs.getSecond()); if (getParameters().getStorageFormatType() == null || getParameters().getStorageFormatType() == domain.getStorageFormat()) { if (getParameters().getStorageType() != null && domain.getStorageType().getValue() != getParameters().getStorageType().getValue()) { log.warn( "The storage type of domain {} has been changed from {} to {}", domain.getStorageName(), domain.getStorageType().toString(), getParameters().getStorageType().toString()); domain.setStorageType(getParameters().getStorageType()); } returnValue.add(domain); } } } } getQueryReturnValue().setReturnValue(returnValue); } }
@Override protected void executeQueryCommand() { Guid vdsGroupId = getParameters().getId(); List<VM> vms = getDbFacade().getVmDao().getAllForVdsGroup(vdsGroupId); List<Pair<Guid, VmNumaNode>> nodes = getDbFacade().getVmNumaNodeDao().getVmNumaNodeInfoByVdsGroupId(vdsGroupId); for (VM vm : vms) { for (Pair<Guid, VmNumaNode> pairnode : nodes) { if (vm.getId().equals(pairnode.getFirst())) { vm.getvNumaNodeList().add(pairnode.getSecond()); } } } getQueryReturnValue().setReturnValue(vms); }
/** * lock Vms which has db entity i.e they are managed by a VmManager * * @param pair * @return true if lock acquired */ private boolean tryLockVmForUpdate(Pair<VM, VmInternalData> pair) { Guid vmId = getVmId(pair); if (vmId != null) { VmManager vmManager = getResourceManager().getVmManager(vmId); if (vmManager.trylock()) { if (!vmManager.isLatestData(pair.getSecond(), vdsManager.getVdsId())) { log.warn( "skipping VM '{}' from this monitoring cycle" + " - newer VM data was already processed", vmId); vmManager.unlock(); } else if (vmManager.getVmDataChangedTime() != null && fetchTime - vmManager.getVmDataChangedTime() <= 0) { log.warn( "skipping VM '{}' from this monitoring cycle" + " - the VM data has changed since fetching the data", vmId); vmManager.unlock(); } else { // store the locked managers to finally release them at the end of the cycle vmManagers.put(vmId, vmManager); return true; } } else { log.debug( "skipping VM '{}' from this monitoring cycle" + " - the VM is locked by its VmManager ", getVmId(pair)); } } return false; }
protected T getMethod() { if (method == null) { VdsStatic vdsStatic = getAndSetVdsStatic(); Pair<String, URL> urlInfo = XmlRpcUtils.getConnectionUrl( vdsStatic.getHostName(), vdsStatic.getPort(), "", Config.<Boolean>getValue(ConfigValues.EncryptHostCommunication)); method = concreteCreateMethod(urlInfo.getFirst()); } return method; }
protected void processExternallyManagedVms() { // Fetching for details from the host // and marking the VMs for addition List<String> vmsToQuery = new ArrayList<>(externalVms.size()); for (Pair<VM, VmInternalData> pair : externalVms) { vmsToQuery.add(pair.getSecond().getVmDynamic().getId().toString()); } if (!vmsToQuery.isEmpty()) { // Query VDSM for VMs info, and creating a proper VMStatic to be used when importing them Map[] vmsInfo = getVmInfo(vmsToQuery); for (Map vmInfo : vmsInfo) { Guid vmId = Guid.createGuidFromString((String) vmInfo.get(VdsProperties.vm_guid)); VmStatic vmStatic = new VmStatic(); vmStatic.setId(vmId); vmStatic.setCreationDate(new Date()); vmStatic.setVdsGroupId(vdsManager.getVdsGroupId()); String vmNameOnHost = (String) vmInfo.get(VdsProperties.vm_name); if (StringUtils.equals( Config.<String>getValue(ConfigValues.HostedEngineVmName), vmNameOnHost)) { // its a hosted engine VM -> import it and skip the external VM phase importHostedEngineVM(vmInfo); continue; } else { vmStatic.setName(String.format(EXTERNAL_VM_NAME_FORMAT, vmNameOnHost)); vmStatic.setOrigin(OriginType.EXTERNAL); } vmStatic.setNumOfSockets( VdsBrokerObjectsBuilder.parseIntVdsProperty(vmInfo.get(VdsProperties.num_of_cpus))); vmStatic.setMemSizeMb( VdsBrokerObjectsBuilder.parseIntVdsProperty(vmInfo.get(VdsProperties.mem_size_mb))); vmStatic.setSingleQxlPci(false); externalVmsToAdd.add(vmStatic); log.info( "Importing VM '{}' as '{}', as it is running on the on Host, but does not exist in the engine.", vmNameOnHost, vmStatic.getName()); } } }
protected void doRemoveItem(Pair<T, V> item, T value, V widget) { ListIterator<Pair<T, V>> last = items.listIterator(items.size()); if (!last.hasPrevious()) { // just a precaution; if there's no item, there should be no button return; } if (item == last.previous() && last.hasPrevious() && this.showAddButton) { // add plus button to previous item Pair<T, V> previousItem = last.previous(); getEntry(previousItem.getSecond()).appendButton(createButton(previousItem, true)); } removeEntry(item); onRemove(value, widget); if (items.isEmpty() && this.showGhost) { Pair<T, V> ghostItem = addGhostEntry(); onAdd(ghostItem.getFirst(), ghostItem.getSecond()); } }
@Override protected void executeCommand() { initConnectionList(true); for (Map.Entry<StorageType, List<StorageServerConnections>> connectionToType : getConnectionsTypeMap().entrySet()) { disconnectStorageByType(connectionToType.getKey(), connectionToType.getValue()); Pair<Boolean, AuditLogType> result = StorageHelperDirector.getInstance() .getItem(connectionToType.getKey()) .disconnectHostFromStoragePoolServersCommandCompleted(getParameters()); if (!result.getFirst()) { auditLogDirector.log(new AuditLogableBase(getParameters().getVdsId()), result.getSecond()); } } // Unregister libvirt secrets when required (for Cinder storage domains). CINDERStorageHelper CINDERStorageHelper = new CINDERStorageHelper(); if (CINDERStorageHelper.isActiveCinderDomainAvailable(getStoragePool().getId())) { unregisterLibvirtSecrets(); } }
private void addDefaultGraphicsDevice() { VmDevice device = VmDeviceCommonUtils.findVmDeviceByGeneralType( vmBase.getManagedDeviceMap(), VmDeviceGeneralType.GRAPHICS); if (device != null) { return; } List<Pair<GraphicsType, DisplayType>> graphicsAndDisplays = osRepository.getGraphicsAndDisplays(vmBase.getOsId(), new Version(getVersion())); GraphicsType graphicsType = vmBase.getDefaultDisplayType() == DisplayType.cirrus ? GraphicsType.VNC : GraphicsType.SPICE; GraphicsType supportedGraphicsType = null; for (Pair<GraphicsType, DisplayType> pair : graphicsAndDisplays) { if (pair.getSecond() == vmBase.getDefaultDisplayType()) { if (pair.getFirst() == graphicsType) { supportedGraphicsType = graphicsType; break; } if (supportedGraphicsType == null) { supportedGraphicsType = pair.getFirst(); } } } if (supportedGraphicsType != null) { device = new GraphicsDevice(supportedGraphicsType.getCorrespondingDeviceType()); device.setId(new VmDeviceId(Guid.newGuid(), vmBase.getId())); addManagedVmDevice(device); } else { log.warn( "Cannot find any graphics type for display type {} supported by OS {} in compatibility version {}", vmBase.getDefaultDisplayType().name(), osRepository.getOsName(vmBase.getOsId()), getVersion()); } }
private void processVmsWithDevicesChange() { // Handle VM devices were changed (for 3.1 cluster and above) if (!VmDeviceCommonUtils.isOldClusterVersion(vdsManager.getGroupCompatibilityVersion())) { // If there are vms that require updating, // get the new info from VDSM in one call, and then update them all if (!vmsWithChangedDevices.isEmpty()) { ArrayList<String> vmsToUpdate = new ArrayList<>(vmsWithChangedDevices.size()); for (Pair<VM, VmInternalData> pair : vmsWithChangedDevices) { Guid vmId = pair.getFirst().getId(); // update only if the vm marked to change, otherwise it might have skipped because data // invalidated // this ensure the vmManager lock is taken if (vmDynamicToSave.containsKey(vmId)) { vmDynamicToSave.get(vmId).setHash(pair.getSecond().getVmDynamic().getHash()); vmsToUpdate.add(vmId.toString()); } else { log.warn("VM '{}' not in changed list, skipping devices update.", vmId); } } updateVmDevices(vmsToUpdate); } } }
private List<ClusterPolicyUnit> getclusterPolicyUnit(ClusterPolicy entity) { Map<Guid, ClusterPolicyUnit> map = new HashMap<Guid, ClusterPolicyUnit>(); ClusterPolicyUnit unit; if (entity.getFilters() != null) { for (Guid policyUnitId : entity.getFilters()) { unit = getClusterPolicyUnit(entity, policyUnitId, map); if (entity.getFilterPositionMap() != null) { Integer position = entity.getFilterPositionMap().get(policyUnitId); unit.setFilterSequence(position != null ? position : 0); } } } if (entity.getFunctions() != null) { for (Pair<Guid, Integer> pair : entity.getFunctions()) { unit = getClusterPolicyUnit(entity, pair.getFirst(), map); unit.setFactor(pair.getSecond()); } } if (entity.getBalance() != null) { getClusterPolicyUnit(entity, entity.getBalance(), map); } return new ArrayList<ClusterPolicyUnit>(map.values()); }
@Test public void testSnmpManagersParsing() { List<Snmp.Host> expectedManagers = new ArrayList<>(); StringBuilder snmpManagers = new StringBuilder(); for (Pair<String, String> host : hosts) { expectedManagers.add(new Snmp.Host(host.getFirst(), host.getSecond())); snmpManagers.append(host.getFirst()); if (host.getSecond() != null) { snmpManagers.append(":").append(host.getSecond()); } snmpManagers.append(" "); } Snmp.Profile profile = new Snmp.Profile(snmpManagers.toString(), "public", "1.3.6.1.4.1.2312.13.1.1"); for (int i = 0; i < expectedManagers.size(); i++) { Snmp.Host parsed = profile.hosts.get(i); Snmp.Host expected = expectedManagers.get(i); Assert.assertEquals(parsed.name, expected.name); Assert.assertEquals(parsed.port, expected.port); } }
private void removeEntry(Pair<T, V> item) { items.remove(item); removeWidget(item.getSecond()); }
private static void assertCredentials( Pair<String, String> credentials, String userName, String password) { assertEquals(userName, credentials.getFirst()); assertEquals(password, credentials.getSecond()); }
private void updateEnabled() { for (Pair<T, V> item : items) { toggleEnabled(item.getFirst(), item.getSecond()); } }
protected VmAnalyzer getVmAnalyzer(Pair<VM, VmInternalData> pair) { return new VmAnalyzer(pair.getFirst(), pair.getSecond(), this, auditLogDirector); }
private Guid getVmId(Pair<VM, VmInternalData> pair) { return (pair.getFirst() != null) ? pair.getFirst().getId() : ((pair.getSecond() != null) ? pair.getSecond().getVmDynamic().getId() : null); }
protected boolean checkAddEditValidations() { List<ClusterPolicy> clusterPolicies = schedulingManager.getClusterPolicies(); if (getClusterPolicy() == null) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_PARAMETERS_INVALID); } for (ClusterPolicy clusterPolicy : clusterPolicies) { if (!clusterPolicy.getId().equals(getClusterPolicy().getId()) && clusterPolicy.getName().equals(getClusterPolicy().getName())) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_NAME_INUSE); } } Map<Guid, PolicyUnitImpl> map = schedulingManager.getPolicyUnitsMap(); Set<Guid> existingPolicyUnits = new HashSet<>(); // check filter policy units if (getClusterPolicy().getFilters() != null) { for (Guid filterId : getClusterPolicy().getFilters()) { if (isPolicyUnitExists(filterId, existingPolicyUnits)) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_DUPLICATE_POLICY_UNIT); } PolicyUnitImpl policyUnitImpl = map.get(filterId); if (policyUnitImpl == null) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_UNKNOWN_POLICY_UNIT); } if (policyUnitImpl.getPolicyUnit().getPolicyUnitType() != PolicyUnitType.FILTER) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_FILTER_NOT_IMPLEMENTED); } } } // check filters positions (there could be only one filter attached to first (-1) and last (-1) if (getClusterPolicy().getFilterPositionMap() != null) { boolean hasFirst = false; boolean hasLast = false; for (Integer position : getClusterPolicy().getFilterPositionMap().values()) { if (position == -1) { if (!hasFirst) { hasFirst = true; } else { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_ONLY_ONE_FILTER_CAN_BE_FIRST); } } else if (position == 1) { if (!hasLast) { hasLast = true; } else { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_ONLY_ONE_FILTER_CAN_BE_LAST); } } } } // check function policy units if (getClusterPolicy().getFunctions() != null) { for (Pair<Guid, Integer> functionPair : getClusterPolicy().getFunctions()) { if (isPolicyUnitExists(functionPair.getFirst(), existingPolicyUnits)) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_DUPLICATE_POLICY_UNIT); } PolicyUnitImpl policyUnitImpl = map.get(functionPair.getFirst()); if (policyUnitImpl == null) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_UNKNOWN_POLICY_UNIT); } if (policyUnitImpl.getPolicyUnit().getPolicyUnitType() != PolicyUnitType.WEIGHT) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_FUNCTION_NOT_IMPLEMENTED); } if (functionPair.getSecond() < 0) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_FUNCTION_FACTOR_NEGATIVE); } } } // check balance policy unit if (getClusterPolicy().getBalance() != null) { PolicyUnitImpl policyUnitImpl = map.get(getClusterPolicy().getBalance()); if (policyUnitImpl == null) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_UNKNOWN_POLICY_UNIT); } if (policyUnitImpl.getPolicyUnit().getPolicyUnitType() != PolicyUnitType.LOAD_BALANCING) { return failValidation( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_POLICY_BALANCE_NOT_IMPLEMENTED); } } List<ValidationError> validationErrors = SimpleCustomPropertiesUtil.getInstance() .validateProperties( schedulingManager.getCustomPropertiesRegexMap(getClusterPolicy()), getClusterPolicy().getParameterMap()); if (!validationErrors.isEmpty()) { SimpleCustomPropertiesUtil.getInstance() .handleCustomPropertiesError(validationErrors, getReturnValue().getValidationMessages()); return false; } return true; }
public void proceedCommandExecution() { // Steps are executed such that: // a) all logic before the command runs is idempotent // b) the command is the last action in the step // This allows for recovery after a crash at any point during command execution. log.debug("Proceeding with execution of RemoveSnapshotSingleDiskLiveCommand"); if (getParameters().getCommandStep() == null) { getParameters().setCommandStep(getInitialMergeStepForImage(getParameters().getImageId())); getParameters().setChildCommands(new HashMap<RemoveSnapshotSingleDiskLiveStep, Guid>()); } // Upon recovery or after invoking a new child command, our map may be missing an entry syncChildCommandList(); Guid currentChildId = getCurrentChildId(); VdcReturnValueBase vdcReturnValue = null; if (currentChildId != null) { switch (CommandCoordinatorUtil.getCommandStatus(currentChildId)) { case ACTIVE: case NOT_STARTED: log.info( "Waiting on Live Merge command step '{}' to complete", getParameters().getCommandStep()); return; case SUCCEEDED: CommandEntity cmdEntity = CommandCoordinatorUtil.getCommandEntity(currentChildId); if (cmdEntity.isCallbackEnabled() && !cmdEntity.isCallbackNotified()) { log.info( "Waiting on Live Merge command step '{}' to finalize", getParameters().getCommandStep()); return; } vdcReturnValue = CommandCoordinatorUtil.getCommandReturnValue(currentChildId); if (vdcReturnValue != null && vdcReturnValue.getSucceeded()) { log.debug("Child command '{}' succeeded", getParameters().getCommandStep()); getParameters().setCommandStep(getParameters().getNextCommandStep()); break; } else { log.error( "Child command '{}' failed: {}", getParameters().getCommandStep(), (vdcReturnValue != null ? vdcReturnValue.getExecuteFailedMessages() : "null return value")); setCommandStatus(CommandStatus.FAILED); return; } case FAILED: case FAILED_RESTARTED: log.error("Failed child command status for step '{}'", getParameters().getCommandStep()); setCommandStatus(CommandStatus.FAILED); return; case UNKNOWN: log.error("Unknown child command status for step '{}'", getParameters().getCommandStep()); setCommandStatus(CommandStatus.FAILED); return; } } log.info("Executing Live Merge command step '{}'", getParameters().getCommandStep()); Pair<VdcActionType, ? extends VdcActionParametersBase> nextCommand = null; switch (getParameters().getCommandStep()) { case EXTEND: nextCommand = new Pair<>(VdcActionType.MergeExtend, buildMergeParameters()); getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.MERGE); break; case MERGE: nextCommand = new Pair<>(VdcActionType.Merge, buildMergeParameters()); getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.MERGE_STATUS); break; case MERGE_STATUS: getParameters().setMergeCommandComplete(true); nextCommand = new Pair<>(VdcActionType.MergeStatus, buildMergeParameters()); getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.DESTROY_IMAGE); break; case DESTROY_IMAGE: if (vdcReturnValue != null) { getParameters() .setMergeStatusReturnValue( (MergeStatusReturnValue) vdcReturnValue.getActionReturnValue()); } else if (getParameters().getMergeStatusReturnValue() == null) { // If the images were already merged, just add the orphaned image getParameters().setMergeStatusReturnValue(synthesizeMergeStatusReturnValue()); } nextCommand = new Pair<>(VdcActionType.DestroyImage, buildDestroyImageParameters()); getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.COMPLETE); break; case COMPLETE: getParameters().setDestroyImageCommandComplete(true); setCommandStatus(CommandStatus.SUCCEEDED); break; } persistCommand(getParameters().getParentCommand(), true); if (nextCommand != null) { CommandCoordinatorUtil.executeAsyncCommand( nextCommand.getFirst(), nextCommand.getSecond(), cloneContextAndDetachFromParent()); // Add the child, but wait, it's a race! child will start, task may spawn, get polled, and we // won't have the child id } }