Search in sources :

Example 1 with MigrateWithStorageReceiveAnswer

use of com.cloud.agent.api.MigrateWithStorageReceiveAnswer in project cloudstack by apache.

the class XenServerStorageMotionStrategy method migrateVmWithVolumesAcrossCluster.

private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map<VolumeInfo, DataStore> volumeToPool) throws AgentUnavailableException {
    try {
        List<Pair<VolumeTO, String>> volumeToStorageUuid = new ArrayList<>();
        for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
            VolumeInfo volumeInfo = entry.getKey();
            StoragePool storagePool = storagePoolDao.findById(volumeInfo.getPoolId());
            VolumeTO volumeTo = new VolumeTO(volumeInfo, storagePool);
            if (storagePool.isManaged()) {
                String iqn = handleManagedVolumePreMigration(volumeInfo, storagePool, destHost);
                volumeToStorageUuid.add(new Pair<>(volumeTo, iqn));
            } else {
                volumeToStorageUuid.add(new Pair<>(volumeTo, ((StoragePool) entry.getValue()).getPath()));
            }
        }
        // Migration across cluster needs to be done in three phases.
        // 1. Send a migrate receive command to the destination host so that it is ready to receive a vm.
        // 2. Send a migrate send command to the source host. This actually migrates the vm to the destination.
        // 3. Complete the process. Update the volume details.
        MigrateWithStorageReceiveCommand receiveCmd = new MigrateWithStorageReceiveCommand(to, volumeToStorageUuid);
        MigrateWithStorageReceiveAnswer receiveAnswer = (MigrateWithStorageReceiveAnswer) agentMgr.send(destHost.getId(), receiveCmd);
        if (receiveAnswer == null) {
            s_logger.error("Migration with storage of vm " + vm + " to host " + destHost + " failed.");
            throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
        } else if (!receiveAnswer.getResult()) {
            s_logger.error("Migration with storage of vm " + vm + " failed. Details: " + receiveAnswer.getDetails());
            throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
        }
        MigrateWithStorageSendCommand sendCmd = new MigrateWithStorageSendCommand(to, receiveAnswer.getVolumeToSr(), receiveAnswer.getNicToNetwork(), receiveAnswer.getToken());
        MigrateWithStorageSendAnswer sendAnswer = (MigrateWithStorageSendAnswer) agentMgr.send(srcHost.getId(), sendCmd);
        if (sendAnswer == null) {
            handleManagedVolumesAfterFailedMigration(volumeToPool, destHost);
            s_logger.error("Migration with storage of vm " + vm + " to host " + destHost + " failed.");
            throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
        } else if (!sendAnswer.getResult()) {
            handleManagedVolumesAfterFailedMigration(volumeToPool, destHost);
            s_logger.error("Migration with storage of vm " + vm + " failed. Details: " + sendAnswer.getDetails());
            throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
        }
        MigrateWithStorageCompleteCommand command = new MigrateWithStorageCompleteCommand(to);
        MigrateWithStorageCompleteAnswer answer = (MigrateWithStorageCompleteAnswer) agentMgr.send(destHost.getId(), command);
        if (answer == null) {
            s_logger.error("Migration with storage of vm " + vm + " failed.");
            throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
        } else if (!answer.getResult()) {
            s_logger.error("Migration with storage of vm " + vm + " failed. Details: " + answer.getDetails());
            throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
        } else {
            // Update the volume details after migration.
            updateVolumePathsAfterMigration(volumeToPool, answer.getVolumeTos(), srcHost);
        }
        return answer;
    } catch (OperationTimedoutException e) {
        s_logger.error("Error while migrating vm " + vm + " to host " + destHost, e);
        throw new AgentUnavailableException("Operation timed out on storage motion for " + vm, destHost.getId());
    }
}
Also used : OperationTimedoutException(com.cloud.exception.OperationTimedoutException) StoragePool(com.cloud.storage.StoragePool) MigrateWithStorageSendAnswer(com.cloud.agent.api.MigrateWithStorageSendAnswer) ArrayList(java.util.ArrayList) MigrateWithStorageCompleteCommand(com.cloud.agent.api.MigrateWithStorageCompleteCommand) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) MigrateWithStorageCompleteAnswer(com.cloud.agent.api.MigrateWithStorageCompleteAnswer) MigrateWithStorageReceiveCommand(com.cloud.agent.api.MigrateWithStorageReceiveCommand) VolumeTO(com.cloud.agent.api.to.VolumeTO) MigrateWithStorageReceiveAnswer(com.cloud.agent.api.MigrateWithStorageReceiveAnswer) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) MigrateWithStorageSendCommand(com.cloud.agent.api.MigrateWithStorageSendCommand) HashMap(java.util.HashMap) Map(java.util.Map) Pair(com.cloud.utils.Pair)

Example 2 with MigrateWithStorageReceiveAnswer

use of com.cloud.agent.api.MigrateWithStorageReceiveAnswer in project cloudstack by apache.

the class XenServer610MigrateWithStorageReceiveCommandWrapper method execute.

@Override
public Answer execute(final MigrateWithStorageReceiveCommand command, final XenServer610Resource xenServer610Resource) {
    final Connection connection = xenServer610Resource.getConnection();
    final VirtualMachineTO vmSpec = command.getVirtualMachine();
    final List<Pair<VolumeTO, String>> volumeToStorageUuid = command.getVolumeToStorageUuid();
    try {
        // In a cluster management server setup, the migrate with storage receive and send
        // commands and answers may have to be forwarded to another management server. This
        // happens when the host/resource on which the command has to be executed is owned
        // by the second management server. The serialization/deserialization of the command
        // and answers fails as the xapi SR and Network class type isn't understand by the
        // agent attache. Seriliaze the SR and Network objects here to a string and pass in
        // the answer object. It'll be deserialzed and object created in migrate with
        // storage send command execution.
        Gson gson = new Gson();
        // Get a map of all the SRs to which the vdis will be migrated.
        final List<Pair<VolumeTO, Object>> volumeToSr = new ArrayList<>();
        for (final Pair<VolumeTO, String> entry : volumeToStorageUuid) {
            final String storageUuid = entry.second();
            final SR sr = xenServer610Resource.getStorageRepository(connection, storageUuid);
            volumeToSr.add(new Pair<VolumeTO, Object>(entry.first(), sr));
        }
        // Get the list of networks to which the vifs will attach.
        final List<Pair<NicTO, Object>> nicToNetwork = new ArrayList<Pair<NicTO, Object>>();
        for (final NicTO nicTo : vmSpec.getNics()) {
            final Network network = xenServer610Resource.getNetwork(connection, nicTo);
            nicToNetwork.add(new Pair<NicTO, Object>(nicTo, network));
        }
        final XsLocalNetwork nativeNetworkForTraffic = xenServer610Resource.getNativeNetworkForTraffic(connection, TrafficType.Storage, null);
        final Network network = nativeNetworkForTraffic.getNetwork();
        final XsHost xsHost = xenServer610Resource.getHost();
        final String uuid = xsHost.getUuid();
        final Map<String, String> other = new HashMap<String, String>();
        other.put("live", "true");
        final Host host = Host.getByUuid(connection, uuid);
        final Map<String, String> token = host.migrateReceive(connection, network, other);
        return new MigrateWithStorageReceiveAnswer(command, volumeToSr, nicToNetwork, token);
    } catch (final CloudRuntimeException e) {
        s_logger.error("Migration of vm " + vmSpec.getName() + " with storage failed due to " + e.toString(), e);
        return new MigrateWithStorageReceiveAnswer(command, e);
    } catch (final Exception e) {
        s_logger.error("Migration of vm " + vmSpec.getName() + " with storage failed due to " + e.toString(), e);
        return new MigrateWithStorageReceiveAnswer(command, e);
    }
}
Also used : XsHost(com.cloud.hypervisor.xenserver.resource.XsHost) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Gson(com.google.gson.Gson) VirtualMachineTO(com.cloud.agent.api.to.VirtualMachineTO) VolumeTO(com.cloud.agent.api.to.VolumeTO) XsLocalNetwork(com.cloud.hypervisor.xenserver.resource.XsLocalNetwork) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) XsLocalNetwork(com.cloud.hypervisor.xenserver.resource.XsLocalNetwork) Network(com.xensource.xenapi.Network) Pair(com.cloud.utils.Pair) SR(com.xensource.xenapi.SR) NicTO(com.cloud.agent.api.to.NicTO) Connection(com.xensource.xenapi.Connection) Host(com.xensource.xenapi.Host) XsHost(com.cloud.hypervisor.xenserver.resource.XsHost) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) MigrateWithStorageReceiveAnswer(com.cloud.agent.api.MigrateWithStorageReceiveAnswer)

Example 3 with MigrateWithStorageReceiveAnswer

use of com.cloud.agent.api.MigrateWithStorageReceiveAnswer in project cloudstack by apache.

the class VirtualMachineManagerImplTest method initializeMockConfigForMigratingVmWithVolumes.

private void initializeMockConfigForMigratingVmWithVolumes() throws OperationTimedoutException, ResourceUnavailableException {
    // Mock the source and destination hosts.
    when(_srcHostMock.getId()).thenReturn(5L);
    when(_destHostMock.getId()).thenReturn(6L);
    when(_hostDao.findById(5L)).thenReturn(_srcHostMock);
    when(_hostDao.findById(6L)).thenReturn(_destHostMock);
    // Mock the vm being migrated.
    when(_vmMock.getId()).thenReturn(1L);
    when(_vmMock.getHypervisorType()).thenReturn(HypervisorType.XenServer);
    when(_vmMock.getState()).thenReturn(State.Running).thenReturn(State.Running).thenReturn(State.Migrating).thenReturn(State.Migrating);
    when(_vmMock.getHostId()).thenReturn(5L);
    when(_vmInstance.getId()).thenReturn(1L);
    when(_vmInstance.getServiceOfferingId()).thenReturn(2L);
    when(_vmInstance.getInstanceName()).thenReturn("myVm");
    when(_vmInstance.getHostId()).thenReturn(5L);
    when(_vmInstance.getType()).thenReturn(VirtualMachine.Type.User);
    when(_vmInstance.getState()).thenReturn(State.Running).thenReturn(State.Running).thenReturn(State.Migrating).thenReturn(State.Migrating);
    // Mock the work item.
    when(_workDao.persist(any(ItWorkVO.class))).thenReturn(_work);
    when(_workDao.update("1", _work)).thenReturn(true);
    when(_work.getId()).thenReturn("1");
    doNothing().when(_work).setStep(ItWorkVO.Step.Done);
    // Mock the vm guru and the user vm object that gets returned.
    _vmMgr._vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru>();
    //        UserVmManagerImpl userVmManager = mock(UserVmManagerImpl.class);
    //        _vmMgr.registerGuru(VirtualMachine.Type.User, userVmManager);
    // Mock the iteration over all the volumes of an instance.
    Iterator<VolumeVO> volumeIterator = mock(Iterator.class);
    when(_volsDao.findUsableVolumesForInstance(anyLong())).thenReturn(_rootVols);
    when(_rootVols.iterator()).thenReturn(volumeIterator);
    when(volumeIterator.hasNext()).thenReturn(true, false);
    when(volumeIterator.next()).thenReturn(_volumeMock);
    // Mock the disk offering and pool objects for a volume.
    when(_volumeMock.getDiskOfferingId()).thenReturn(5L);
    when(_volumeMock.getPoolId()).thenReturn(200L);
    when(_volumeMock.getId()).thenReturn(5L);
    when(_diskOfferingDao.findById(anyLong())).thenReturn(_diskOfferingMock);
    when(_storagePoolDao.findById(200L)).thenReturn(_srcStoragePoolMock);
    when(_storagePoolDao.findById(201L)).thenReturn(_destStoragePoolMock);
    // Mock the volume to pool mapping.
    when(_volumeToPoolMock.get(5L)).thenReturn(201L);
    when(_destStoragePoolMock.getId()).thenReturn(201L);
    when(_srcStoragePoolMock.getId()).thenReturn(200L);
    when(_destStoragePoolMock.isLocal()).thenReturn(false);
    when(_diskOfferingMock.getUseLocalStorage()).thenReturn(false);
    when(_poolHostDao.findByPoolHost(anyLong(), anyLong())).thenReturn(mock(StoragePoolHostVO.class));
    // Mock hypervisor guru.
    HypervisorGuru guruMock = mock(HypervisorGuru.class);
    when(_hvGuruMgr.getGuru(HypervisorType.XenServer)).thenReturn(guruMock);
    when(_srcHostMock.getClusterId()).thenReturn(3L);
    when(_destHostMock.getClusterId()).thenReturn(3L);
    // Mock the commands and answers to the agent.
    PrepareForMigrationAnswer prepAnswerMock = mock(PrepareForMigrationAnswer.class);
    when(prepAnswerMock.getResult()).thenReturn(true);
    when(_agentMgr.send(anyLong(), isA(PrepareForMigrationCommand.class))).thenReturn(prepAnswerMock);
    MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
    when(migAnswerMock.getResult()).thenReturn(true);
    when(_agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
    MigrateWithStorageReceiveAnswer migRecAnswerMock = mock(MigrateWithStorageReceiveAnswer.class);
    when(migRecAnswerMock.getResult()).thenReturn(true);
    when(_agentMgr.send(anyLong(), isA(MigrateWithStorageReceiveCommand.class))).thenReturn(migRecAnswerMock);
    MigrateWithStorageSendAnswer migSendAnswerMock = mock(MigrateWithStorageSendAnswer.class);
    when(migSendAnswerMock.getResult()).thenReturn(true);
    when(_agentMgr.send(anyLong(), isA(MigrateWithStorageSendCommand.class))).thenReturn(migSendAnswerMock);
    MigrateWithStorageCompleteAnswer migCompleteAnswerMock = mock(MigrateWithStorageCompleteAnswer.class);
    when(migCompleteAnswerMock.getResult()).thenReturn(true);
    when(_agentMgr.send(anyLong(), isA(MigrateWithStorageCompleteCommand.class))).thenReturn(migCompleteAnswerMock);
    CheckVirtualMachineAnswer checkVmAnswerMock = mock(CheckVirtualMachineAnswer.class);
    when(checkVmAnswerMock.getResult()).thenReturn(true);
    when(checkVmAnswerMock.getState()).thenReturn(PowerState.PowerOn);
    when(_agentMgr.send(anyLong(), isA(CheckVirtualMachineCommand.class))).thenReturn(checkVmAnswerMock);
    // Mock the state transitions of vm.
    Pair<Long, Long> opaqueMock = new Pair<Long, Long>(_vmMock.getHostId(), _destHostMock.getId());
    when(_vmSnapshotMgr.hasActiveVMSnapshotTasks(anyLong())).thenReturn(false);
    when(_vmInstanceDao.updateState(State.Running, Event.MigrationRequested, State.Migrating, _vmMock, opaqueMock)).thenReturn(true);
    when(_vmInstanceDao.updateState(State.Migrating, Event.OperationSucceeded, State.Running, _vmMock, opaqueMock)).thenReturn(true);
}
Also used : MigrateWithStorageAnswer(com.cloud.agent.api.MigrateWithStorageAnswer) CheckVirtualMachineAnswer(com.cloud.agent.api.CheckVirtualMachineAnswer) MigrateWithStorageCommand(com.cloud.agent.api.MigrateWithStorageCommand) MigrateWithStorageSendAnswer(com.cloud.agent.api.MigrateWithStorageSendAnswer) StoragePoolHostVO(com.cloud.storage.StoragePoolHostVO) MigrateWithStorageCompleteCommand(com.cloud.agent.api.MigrateWithStorageCompleteCommand) MigrateWithStorageCompleteAnswer(com.cloud.agent.api.MigrateWithStorageCompleteAnswer) PrepareForMigrationAnswer(com.cloud.agent.api.PrepareForMigrationAnswer) MigrateWithStorageReceiveCommand(com.cloud.agent.api.MigrateWithStorageReceiveCommand) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) ProvisioningType(com.cloud.storage.Storage.ProvisioningType) MigrateWithStorageReceiveAnswer(com.cloud.agent.api.MigrateWithStorageReceiveAnswer) HypervisorGuru(com.cloud.hypervisor.HypervisorGuru) VolumeVO(com.cloud.storage.VolumeVO) PrepareForMigrationCommand(com.cloud.agent.api.PrepareForMigrationCommand) Matchers.anyLong(org.mockito.Matchers.anyLong) MigrateWithStorageSendCommand(com.cloud.agent.api.MigrateWithStorageSendCommand) CheckVirtualMachineCommand(com.cloud.agent.api.CheckVirtualMachineCommand) Pair(com.cloud.utils.Pair)

Aggregations

MigrateWithStorageReceiveAnswer (com.cloud.agent.api.MigrateWithStorageReceiveAnswer)3 Pair (com.cloud.utils.Pair)3 MigrateWithStorageCompleteAnswer (com.cloud.agent.api.MigrateWithStorageCompleteAnswer)2 MigrateWithStorageCompleteCommand (com.cloud.agent.api.MigrateWithStorageCompleteCommand)2 MigrateWithStorageReceiveCommand (com.cloud.agent.api.MigrateWithStorageReceiveCommand)2 MigrateWithStorageSendAnswer (com.cloud.agent.api.MigrateWithStorageSendAnswer)2 MigrateWithStorageSendCommand (com.cloud.agent.api.MigrateWithStorageSendCommand)2 VolumeTO (com.cloud.agent.api.to.VolumeTO)2 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 CheckVirtualMachineAnswer (com.cloud.agent.api.CheckVirtualMachineAnswer)1 CheckVirtualMachineCommand (com.cloud.agent.api.CheckVirtualMachineCommand)1 MigrateWithStorageAnswer (com.cloud.agent.api.MigrateWithStorageAnswer)1 MigrateWithStorageCommand (com.cloud.agent.api.MigrateWithStorageCommand)1 PrepareForMigrationAnswer (com.cloud.agent.api.PrepareForMigrationAnswer)1 PrepareForMigrationCommand (com.cloud.agent.api.PrepareForMigrationCommand)1 NicTO (com.cloud.agent.api.to.NicTO)1 VirtualMachineTO (com.cloud.agent.api.to.VirtualMachineTO)1 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)1