@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; }
@Override public void run(final FlowTrigger trigger, final Map data) { final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); VolumeInventory volume = spec.getDestDataVolumes().get(0); SimpleQuery<LocalStorageResourceRefVO> q = dbf.createQuery(LocalStorageResourceRefVO.class); q.select(LocalStorageResourceRefVO_.hostUuid, LocalStorageResourceRefVO_.primaryStorageUuid); q.add( LocalStorageResourceRefVO_.resourceUuid, Op.EQ, spec.getVmInventory().getRootVolumeUuid()); Tuple t = q.findTuple(); final String hostUuid = t.get(0, String.class); String priUuid = t.get(1, String.class); AllocatePrimaryStorageMsg msg = new AllocatePrimaryStorageMsg(); if (isThereOtherStorageForTheHost(hostUuid, priUuid)) { // use network-shared primary storage msg.addExcludeAllocatorStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY); msg.addExcludePrimaryStoratgeUuid(priUuid); } else { msg.setAllocationStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY); msg.setRequiredPrimaryStorageUuid( spec.getVmInventory().getRootVolume().getPrimaryStorageUuid()); } msg.setRequiredHostUuid(hostUuid); msg.setVmInstanceUuid(spec.getVmInventory().getUuid()); msg.setSize(volume.getSize()); msg.setPurpose(PrimaryStorageAllocationPurpose.CreateVolume.toString()); bus.makeLocalServiceId(msg, PrimaryStorageConstant.SERVICE_ID); bus.send( msg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { trigger.fail(reply.getError()); return; } spec.setDestHost(HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class))); AllocatePrimaryStorageReply ar = (AllocatePrimaryStorageReply) reply; data.put( VmInstanceConstant.Params.DestPrimaryStorageInventoryForAttachingVolume.toString(), ar.getPrimaryStorageInventory()); data.put(LocalStorageAllocateCapacityForAttachingVolumeFlow.class, ar.getSize()); trigger.next(); } }); }