private void extendImageSize() { Guid diskImageId = getParameters().getBaseImage().getImageId(); long sizeInBytes = getParameters().getTopImage().getSize(); ExtendImageSizeParameters parameters = new ExtendImageSizeParameters(diskImageId, sizeInBytes, true); parameters.setStoragePoolId(getParameters().getBaseImage().getStoragePoolId()); parameters.setStorageDomainId(getParameters().getBaseImage().getStorageIds().get(0)); parameters.setImageGroupID(getParameters().getBaseImage().getId()); parameters.setParentCommand(VdcActionType.MergeExtend); parameters.setParentParameters(getParameters()); CommandCoordinatorUtil.executeAsyncCommand( VdcActionType.ExtendImageSize, parameters, cloneContextAndDetachFromParent()); log.info("Extending size of base volume {} to {} bytes", diskImageId, sizeInBytes); }
/** * The following method performs a removing of all cinder disks from vm. These is only DB * operation */ private void removeCinderDisks(List<CinderDisk> cinderDisks) { RemoveAllVmCinderDisksParameters removeParam = new RemoveAllVmCinderDisksParameters(getVmTemplateId(), cinderDisks); removeParam.setParentHasTasks(!getReturnValue().getVdsmTaskIdList().isEmpty()); Future<VdcReturnValueBase> future = CommandCoordinatorUtil.executeAsyncCommand( VdcActionType.RemoveAllVmCinderDisks, withRootCommandInfo(removeParam), cloneContextAndDetachFromParent(), CINDERStorageHelper.getStorageEntities(cinderDisks)); try { future.get().getActionReturnValue(); } catch (InterruptedException | ExecutionException e) { log.error("Exception", e); } }
@Override protected void executeCommand() { VDSStatus statusBeforeUpgrade = getVds().getStatus(); if (statusBeforeUpgrade != VDSStatus.Maintenance) { Future<VdcReturnValueBase> maintenanceCmd = CommandCoordinatorUtil.executeAsyncCommand( VdcActionType.MaintenanceNumberOfVdss, createMaintenanceParams(), cloneContext()); VdcReturnValueBase result; try { result = maintenanceCmd.get(); if (!result.getSucceeded()) { propagateFailure(result); return; } } catch (InterruptedException | ExecutionException e) { log.error("Exception", e); return; } } setSucceeded(true); }
/** * The following method will perform a removing of all cinder disks from vm. These is only DB * operation */ private Collection<CinderDisk> removeCinderDisks() { Collection<CinderDisk> failedRemoveCinderDisks = null; if (getParameters().isRemoveDisks()) { List<CinderDisk> cinderDisks = getCinderDisks(); if (cinderDisks.isEmpty()) { return Collections.emptyList(); } RemoveAllVmCinderDisksParameters param = new RemoveAllVmCinderDisksParameters(getVmId(), cinderDisks); param.setEndProcedure(EndProcedure.COMMAND_MANAGED); Future<VdcReturnValueBase> future = CommandCoordinatorUtil.executeAsyncCommand( VdcActionType.RemoveAllVmCinderDisks, withRootCommandInfo(param), cloneContextAndDetachFromParent()); try { failedRemoveCinderDisks = future.get().getActionReturnValue(); } catch (InterruptedException | ExecutionException e) { failedRemoveCinderDisks = cinderDisks; log.error("Exception", e); } } return failedRemoveCinderDisks; }
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 } }