@Override public Flow marshalVmOperationFlow( String previousFlowName, String nextFlowName, FlowChain chain, VmInstanceSpec spec) { if (VmAllocatePrimaryStorageFlow.class.getName().equals(nextFlowName)) { if (spec.getCurrentVmOperation() == VmOperation.NewCreate) { if (getLocalStorageInCluster(spec.getDestHost().getClusterUuid()) != null) { return new LocalStorageAllocateCapacityFlow(); } } } else if (spec.getCurrentVmOperation() == VmOperation.AttachVolume) { VolumeInventory volume = spec.getDestDataVolumes().get(0); if (VolumeStatus.NotInstantiated.toString().equals(volume.getStatus()) && VmAllocatePrimaryStorageForAttachingDiskFlow.class.getName().equals(nextFlowName)) { if (isRootVolumeOnLocalStorage(spec.getVmInventory().getRootVolumeUuid())) { return new LocalStorageAllocateCapacityForAttachingVolumeFlow(); } } } else if (spec.getCurrentVmOperation() == VmOperation.Migrate && isRootVolumeOnLocalStorage(spec.getVmInventory().getRootVolumeUuid()) && VmMigrateOnHypervisorFlow.class.getName().equals(nextFlowName)) { if (KVMConstant.KVM_HYPERVISOR_TYPE.equals(spec.getVmInventory().getHypervisorType())) { return new LocalStorageKvmMigrateVmFlow(); } else { throw new OperationFailureException( errf.stringToOperationError( String.format( "local storage doesn't support live migration for hypervisor[%s]", spec.getVmInventory().getHypervisorType()))); } } return null; }
private void releaseNetworkServices( final VmInstanceSpec spec, NetworkServiceExtensionPosition position, final NoErrorCompletion completion) { if (!spec.getVmInventory().getType().equals(VmInstanceConstant.USER_VM_TYPE)) { completion.done(); return; } if (nsExts.isEmpty()) { completion.done(); return; } // we run into this situation when VM nics are all detached and the // VM is being rebooted if (spec.getDestNics().isEmpty()) { completion.done(); return; } List<String> nsTypes = spec.getRequiredNetworkServiceTypes(); FlowChain schain = FlowChainBuilder.newSimpleFlowChain() .setName( String.format( "release-network-services-from-vm-%s", spec.getVmInventory().getUuid())); schain.allowEmptyFlow(); for (final NetworkServiceExtensionPoint ns : nsExts) { if (position != null && ns.getNetworkServiceExtensionPosition() != position) { continue; } if (!nsTypes.contains(ns.getNetworkServiceType().toString())) { continue; } NoRollbackFlow flow = new NoRollbackFlow() { String __name__ = String.format("release-network-service-%s", ns.getNetworkServiceType()); @Override public void run(final FlowTrigger chain, Map data) { logger.debug( String.format( "NetworkServiceExtensionPoint[%s] is asking back ends to release network service[%s] if needed", ns.getClass().getName(), ns.getNetworkServiceType())); ns.releaseNetworkService( spec, data, new NoErrorCompletion() { @Override public void done() { chain.next(); } }); } }; schain.then(flow); } schain .done( new FlowDoneHandler(completion) { @Override public void handle(Map data) { logger.debug( String.format( "successfully released network services for vm[uuid:%s, name:%s]", spec.getVmInventory().getUuid(), spec.getVmInventory().getName())); completion.done(); } }) .start(); }