Search in sources :

Example 41 with NoTransitionException

use of com.cloud.utils.fsm.NoTransitionException in project cloudstack by apache.

the class VirtualMachineManagerImpl method migrate.

protected void migrate(final VMInstanceVO vm, final long srcHostId, final DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException {
    s_logger.info("Migrating " + vm + " to " + dest);
    final long dstHostId = dest.getHost().getId();
    final Host fromHost = _hostDao.findById(srcHostId);
    if (fromHost == null) {
        s_logger.info("Unable to find the host to migrate from: " + srcHostId);
        throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
    }
    if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
        final List<VolumeVO> volumes = _volsDao.findCreatedByInstance(vm.getId());
        for (final VolumeVO volume : volumes) {
            if (!_storagePoolDao.findById(volume.getPoolId()).getScope().equals(ScopeType.ZONE)) {
                s_logger.info("Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: " + dest.getHost().getId());
                throw new CloudRuntimeException("Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: " + dest.getHost().getId());
            }
        }
    }
    final VirtualMachineGuru vmGuru = getVmGuru(vm);
    if (vm.getState() != State.Running) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
        }
        throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
    }
    AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
    if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
        alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
    } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
        alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
    }
    final VirtualMachineProfile vmSrc = new VirtualMachineProfileImpl(vm);
    for (final NicProfile nic : _networkMgr.getNicProfiles(vm)) {
        vmSrc.addNic(nic);
    }
    final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null);
    _networkMgr.prepareNicForMigration(profile, dest);
    volumeMgr.prepareForMigration(profile, dest);
    profile.setConfigDriveLabel(VmConfigDriveLabel.value());
    final VirtualMachineTO to = toVmTO(profile);
    final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
    ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
    work.setStep(Step.Prepare);
    work.setResourceType(ItWorkVO.ResourceType.Host);
    work.setResourceId(dstHostId);
    work = _workDao.persist(work);
    Answer pfma = null;
    try {
        pfma = _agentMgr.send(dstHostId, pfmc);
        if (pfma == null || !pfma.getResult()) {
            final String details = pfma != null ? pfma.getDetails() : "null answer returned";
            final String msg = "Unable to prepare for migration due to " + details;
            pfma = null;
            throw new AgentUnavailableException(msg, dstHostId);
        }
    } catch (final OperationTimedoutException e1) {
        throw new AgentUnavailableException("Operation timed out", dstHostId);
    } finally {
        if (pfma == null) {
            _networkMgr.rollbackNicForMigration(vmSrc, profile);
            work.setStep(Step.Done);
            _workDao.update(work.getId(), work);
        }
    }
    vm.setLastHostId(srcHostId);
    try {
        if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
            _networkMgr.rollbackNicForMigration(vmSrc, profile);
            s_logger.info("Migration cancelled because state has changed: " + vm);
            throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
        }
    } catch (final NoTransitionException e1) {
        _networkMgr.rollbackNicForMigration(vmSrc, profile);
        s_logger.info("Migration cancelled because " + e1.getMessage());
        throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
    }
    boolean migrated = false;
    try {
        final boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
        final MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows, to, getExecuteInSequence(vm.getHypervisorType()));
        mc.setHostGuid(dest.getHost().getGuid());
        try {
            final Answer ma = _agentMgr.send(vm.getLastHostId(), mc);
            if (ma == null || !ma.getResult()) {
                final String details = ma != null ? ma.getDetails() : "null answer returned";
                throw new CloudRuntimeException(details);
            }
        } catch (final OperationTimedoutException e) {
            if (e.isActive()) {
                s_logger.warn("Active migration command so scheduling a restart for " + vm);
                _haMgr.scheduleRestart(vm, true);
            }
            throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
        }
        try {
            if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
                throw new ConcurrentOperationException("Unable to change the state for " + vm);
            }
        } catch (final NoTransitionException e1) {
            throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
        }
        try {
            if (!checkVmOnHost(vm, dstHostId)) {
                s_logger.error("Unable to complete migration for " + vm);
                try {
                    _agentMgr.send(srcHostId, new Commands(cleanup(vm)), null);
                } catch (final AgentUnavailableException e) {
                    s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
                }
                cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
                throw new CloudRuntimeException("Unable to complete migration for " + vm);
            }
        } catch (final OperationTimedoutException e) {
            s_logger.debug("Error while checking the vm " + vm + " on host " + dstHostId, e);
        }
        migrated = true;
    } finally {
        if (!migrated) {
            s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
            _networkMgr.rollbackNicForMigration(vmSrc, profile);
            _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed.  Please check logs.");
            try {
                _agentMgr.send(dstHostId, new Commands(cleanup(vm)), null);
            } catch (final AgentUnavailableException ae) {
                s_logger.info("Looks like the destination Host is unavailable for cleanup");
            }
            try {
                stateTransitTo(vm, Event.OperationFailed, srcHostId);
            } catch (final NoTransitionException e) {
                s_logger.warn(e.getMessage());
            }
        } else {
            _networkMgr.commitNicForMigration(vmSrc, profile);
        }
        work.setStep(Step.Done);
        _workDao.update(work.getId(), work);
    }
}
Also used : AlertManager(com.cloud.alert.AlertManager) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) Host(com.cloud.host.Host) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VirtualMachineTO(com.cloud.agent.api.to.VirtualMachineTO) MigrateCommand(com.cloud.agent.api.MigrateCommand) AgentControlAnswer(com.cloud.agent.api.AgentControlAnswer) RebootAnswer(com.cloud.agent.api.RebootAnswer) StartAnswer(com.cloud.agent.api.StartAnswer) RestoreVMSnapshotAnswer(com.cloud.agent.api.RestoreVMSnapshotAnswer) PlugNicAnswer(com.cloud.agent.api.PlugNicAnswer) StopAnswer(com.cloud.agent.api.StopAnswer) Answer(com.cloud.agent.api.Answer) UnPlugNicAnswer(com.cloud.agent.api.UnPlugNicAnswer) ClusterVMMetaDataSyncAnswer(com.cloud.agent.api.ClusterVMMetaDataSyncAnswer) CheckVirtualMachineAnswer(com.cloud.agent.api.CheckVirtualMachineAnswer) VolumeVO(com.cloud.storage.VolumeVO) PrepareForMigrationCommand(com.cloud.agent.api.PrepareForMigrationCommand) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) Commands(com.cloud.agent.manager.Commands)

Example 42 with NoTransitionException

use of com.cloud.utils.fsm.NoTransitionException in project cloudstack by apache.

the class VirtualMachineManagerImpl method advanceStop.

private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnableToStop) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
    final State state = vm.getState();
    if (state == State.Stopped) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM is already stopped: " + vm);
        }
        return;
    }
    if (state == State.Destroyed || state == State.Expunging || state == State.Error) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Stopped called on " + vm + " but the state is " + state);
        }
        return;
    }
    // grab outstanding work item if any
    final ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState());
    if (work != null) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Found an outstanding work item for this vm " + vm + " with state:" + vm.getState() + ", work id:" + work.getId());
        }
    }
    final Long hostId = vm.getHostId();
    if (hostId == null) {
        if (!cleanUpEvenIfUnableToStop) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("HostId is null but this is not a forced stop, cannot stop vm " + vm + " with state:" + vm.getState());
            }
            throw new CloudRuntimeException("Unable to stop " + vm);
        }
        try {
            stateTransitTo(vm, Event.AgentReportStopped, null, null);
        } catch (final NoTransitionException e) {
            s_logger.warn(e.getMessage());
        }
        // mark outstanding work item if any as done
        if (work != null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Updating work item to Done, id:" + work.getId());
            }
            work.setStep(Step.Done);
            _workDao.update(work.getId(), work);
        }
        return;
    }
    final VirtualMachineGuru vmGuru = getVmGuru(vm);
    final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
    try {
        if (!stateTransitTo(vm, Event.StopRequested, vm.getHostId())) {
            throw new ConcurrentOperationException("VM is being operated on.");
        }
    } catch (final NoTransitionException e1) {
        if (!cleanUpEvenIfUnableToStop) {
            throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState());
        }
        final boolean doCleanup = true;
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Unable to transition the state but we're moving on because it's forced stop");
        }
        if (doCleanup) {
            if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, cleanUpEvenIfUnableToStop)) {
                try {
                    if (s_logger.isDebugEnabled() && work != null) {
                        s_logger.debug("Updating work item to Done, id:" + work.getId());
                    }
                    if (!changeState(vm, Event.AgentReportStopped, null, work, Step.Done)) {
                        throw new CloudRuntimeException("Unable to stop " + vm);
                    }
                } catch (final NoTransitionException e) {
                    s_logger.warn("Unable to cleanup " + vm);
                    throw new CloudRuntimeException("Unable to stop " + vm, e);
                }
            } else {
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Failed to cleanup VM: " + vm);
                }
                throw new CloudRuntimeException("Failed to cleanup " + vm + " , current state " + vm.getState());
            }
        }
    }
    if (vm.getState() != State.Stopping) {
        throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState());
    }
    vmGuru.prepareStop(profile);
    StopCommand stpCmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false);
    stpCmd.setControlIp(getControlNicIpForVM(vm));
    final StopCommand stop = stpCmd;
    boolean stopped = false;
    Answer answer = null;
    try {
        answer = _agentMgr.send(vm.getHostId(), stop);
        if (answer != null) {
            if (answer instanceof StopAnswer) {
                final StopAnswer stopAns = (StopAnswer) answer;
                if (vm.getType() == VirtualMachine.Type.User) {
                    final String platform = stopAns.getPlatform();
                    if (platform != null) {
                        final UserVmVO userVm = _userVmDao.findById(vm.getId());
                        _userVmDao.loadDetails(userVm);
                        userVm.setDetail("platform", platform);
                        _userVmDao.saveDetails(userVm);
                    }
                }
            }
            stopped = answer.getResult();
            if (!stopped) {
                throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails());
            }
            vmGuru.finalizeStop(profile, answer);
            final GPUDeviceTO gpuDevice = stop.getGpuDevice();
            if (gpuDevice != null) {
                _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
            }
        } else {
            throw new CloudRuntimeException("Invalid answer received in response to a StopCommand on " + vm.instanceName);
        }
    } catch (final AgentUnavailableException e) {
        s_logger.warn("Unable to stop vm, agent unavailable: " + e.toString());
    } catch (final OperationTimedoutException e) {
        s_logger.warn("Unable to stop vm, operation timed out: " + e.toString());
    } finally {
        if (!stopped) {
            if (!cleanUpEvenIfUnableToStop) {
                s_logger.warn("Unable to stop vm " + vm);
                try {
                    stateTransitTo(vm, Event.OperationFailed, vm.getHostId());
                } catch (final NoTransitionException e) {
                    s_logger.warn("Unable to transition the state " + vm);
                }
                throw new CloudRuntimeException("Unable to stop " + vm);
            } else {
                s_logger.warn("Unable to actually stop " + vm + " but continue with release because it's a force stop");
                vmGuru.finalizeStop(profile, answer);
            }
        }
    }
    if (s_logger.isDebugEnabled()) {
        s_logger.debug(vm + " is stopped on the host.  Proceeding to release resource held.");
    }
    try {
        _networkMgr.release(profile, cleanUpEvenIfUnableToStop);
        s_logger.debug("Successfully released network resources for the vm " + vm);
    } catch (final Exception e) {
        s_logger.warn("Unable to release some network resources.", e);
    }
    try {
        if (vm.getHypervisorType() != HypervisorType.BareMetal) {
            volumeMgr.release(profile);
            s_logger.debug("Successfully released storage resources for the vm " + vm);
        }
    } catch (final Exception e) {
        s_logger.warn("Unable to release storage resources.", e);
    }
    try {
        if (work != null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Updating the outstanding work item to Done, id:" + work.getId());
            }
            work.setStep(Step.Done);
            _workDao.update(work.getId(), work);
        }
        if (!stateTransitTo(vm, Event.OperationSucceeded, null)) {
            throw new CloudRuntimeException("unable to stop " + vm);
        }
    } catch (final NoTransitionException e) {
        s_logger.warn(e.getMessage());
        throw new CloudRuntimeException("Unable to stop " + vm);
    }
}
Also used : OperationTimedoutException(com.cloud.exception.OperationTimedoutException) GPUDeviceTO(com.cloud.agent.api.to.GPUDeviceTO) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) ExecutionException(com.cloud.utils.exception.ExecutionException) ConnectionException(com.cloud.exception.ConnectionException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) InsufficientServerCapacityException(com.cloud.exception.InsufficientServerCapacityException) InsufficientAddressCapacityException(com.cloud.exception.InsufficientAddressCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SQLException(java.sql.SQLException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) AffinityConflictException(com.cloud.exception.AffinityConflictException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) InsufficientVirtualNetworkCapacityException(com.cloud.exception.InsufficientVirtualNetworkCapacityException) ConfigurationException(javax.naming.ConfigurationException) AgentControlAnswer(com.cloud.agent.api.AgentControlAnswer) RebootAnswer(com.cloud.agent.api.RebootAnswer) StartAnswer(com.cloud.agent.api.StartAnswer) RestoreVMSnapshotAnswer(com.cloud.agent.api.RestoreVMSnapshotAnswer) PlugNicAnswer(com.cloud.agent.api.PlugNicAnswer) StopAnswer(com.cloud.agent.api.StopAnswer) Answer(com.cloud.agent.api.Answer) UnPlugNicAnswer(com.cloud.agent.api.UnPlugNicAnswer) ClusterVMMetaDataSyncAnswer(com.cloud.agent.api.ClusterVMMetaDataSyncAnswer) CheckVirtualMachineAnswer(com.cloud.agent.api.CheckVirtualMachineAnswer) StopCommand(com.cloud.agent.api.StopCommand) PowerState(com.cloud.vm.VirtualMachine.PowerState) State(com.cloud.vm.VirtualMachine.State) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) StopAnswer(com.cloud.agent.api.StopAnswer)

Example 43 with NoTransitionException

use of com.cloud.utils.fsm.NoTransitionException in project cloudstack by apache.

the class VirtualMachineManagerImpl method orchestrateMigrateForScale.

private void orchestrateMigrateForScale(final String vmUuid, final long srcHostId, final DeployDestination dest, final Long oldSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException {
    VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
    s_logger.info("Migrating " + vm + " to " + dest);
    vm.getServiceOfferingId();
    final long dstHostId = dest.getHost().getId();
    final Host fromHost = _hostDao.findById(srcHostId);
    if (fromHost == null) {
        s_logger.info("Unable to find the host to migrate from: " + srcHostId);
        throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
    }
    if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
        s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dstHostId);
        throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
    }
    final VirtualMachineGuru vmGuru = getVmGuru(vm);
    final long vmId = vm.getId();
    vm = _vmDao.findByUuid(vmUuid);
    if (vm == null) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Unable to find the vm " + vm);
        }
        throw new CloudRuntimeException("Unable to find a virtual machine with id " + vmId);
    }
    if (vm.getState() != State.Running) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
        }
        throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
    }
    AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
    if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
        alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
    } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
        alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
    }
    final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
    _networkMgr.prepareNicForMigration(profile, dest);
    volumeMgr.prepareForMigration(profile, dest);
    final VirtualMachineTO to = toVmTO(profile);
    final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
    ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
    work.setStep(Step.Prepare);
    work.setResourceType(ItWorkVO.ResourceType.Host);
    work.setResourceId(dstHostId);
    work = _workDao.persist(work);
    Answer pfma = null;
    try {
        pfma = _agentMgr.send(dstHostId, pfmc);
        if (pfma == null || !pfma.getResult()) {
            final String details = pfma != null ? pfma.getDetails() : "null answer returned";
            final String msg = "Unable to prepare for migration due to " + details;
            pfma = null;
            throw new AgentUnavailableException(msg, dstHostId);
        }
    } catch (final OperationTimedoutException e1) {
        throw new AgentUnavailableException("Operation timed out", dstHostId);
    } finally {
        if (pfma == null) {
            work.setStep(Step.Done);
            _workDao.update(work.getId(), work);
        }
    }
    vm.setLastHostId(srcHostId);
    try {
        if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
            s_logger.info("Migration cancelled because state has changed: " + vm);
            throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
        }
    } catch (final NoTransitionException e1) {
        s_logger.info("Migration cancelled because " + e1.getMessage());
        throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
    }
    boolean migrated = false;
    try {
        final boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
        final MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows, to, getExecuteInSequence(vm.getHypervisorType()));
        mc.setHostGuid(dest.getHost().getGuid());
        try {
            final Answer ma = _agentMgr.send(vm.getLastHostId(), mc);
            if (ma == null || !ma.getResult()) {
                final String details = ma != null ? ma.getDetails() : "null answer returned";
                final String msg = "Unable to migrate due to " + details;
                s_logger.error(msg);
                throw new CloudRuntimeException(msg);
            }
        } catch (final OperationTimedoutException e) {
            if (e.isActive()) {
                s_logger.warn("Active migration command so scheduling a restart for " + vm);
                _haMgr.scheduleRestart(vm, true);
            }
            throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
        }
        try {
            final long newServiceOfferingId = vm.getServiceOfferingId();
            // release capacity for the old service offering only
            vm.setServiceOfferingId(oldSvcOfferingId);
            if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
                throw new ConcurrentOperationException("Unable to change the state for " + vm);
            }
            vm.setServiceOfferingId(newServiceOfferingId);
        } catch (final NoTransitionException e1) {
            throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
        }
        try {
            if (!checkVmOnHost(vm, dstHostId)) {
                s_logger.error("Unable to complete migration for " + vm);
                try {
                    _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
                } catch (final AgentUnavailableException e) {
                    s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
                }
                cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
                throw new CloudRuntimeException("Unable to complete migration for " + vm);
            }
        } catch (final OperationTimedoutException e) {
            s_logger.debug("Error while checking the vm " + vm + " on host " + dstHostId, e);
        }
        migrated = true;
    } finally {
        if (!migrated) {
            s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
            _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed.  Please check logs.");
            try {
                _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null);
            } catch (final AgentUnavailableException ae) {
                s_logger.info("Looks like the destination Host is unavailable for cleanup");
            }
            try {
                stateTransitTo(vm, Event.OperationFailed, srcHostId);
            } catch (final NoTransitionException e) {
                s_logger.warn(e.getMessage());
            }
        }
        work.setStep(Step.Done);
        _workDao.update(work.getId(), work);
    }
}
Also used : AlertManager(com.cloud.alert.AlertManager) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) Host(com.cloud.host.Host) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VirtualMachineTO(com.cloud.agent.api.to.VirtualMachineTO) MigrateCommand(com.cloud.agent.api.MigrateCommand) AgentControlAnswer(com.cloud.agent.api.AgentControlAnswer) RebootAnswer(com.cloud.agent.api.RebootAnswer) StartAnswer(com.cloud.agent.api.StartAnswer) RestoreVMSnapshotAnswer(com.cloud.agent.api.RestoreVMSnapshotAnswer) PlugNicAnswer(com.cloud.agent.api.PlugNicAnswer) StopAnswer(com.cloud.agent.api.StopAnswer) Answer(com.cloud.agent.api.Answer) UnPlugNicAnswer(com.cloud.agent.api.UnPlugNicAnswer) ClusterVMMetaDataSyncAnswer(com.cloud.agent.api.ClusterVMMetaDataSyncAnswer) CheckVirtualMachineAnswer(com.cloud.agent.api.CheckVirtualMachineAnswer) PrepareForMigrationCommand(com.cloud.agent.api.PrepareForMigrationCommand) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) Commands(com.cloud.agent.manager.Commands)

Example 44 with NoTransitionException

use of com.cloud.utils.fsm.NoTransitionException in project cloudstack by apache.

the class VirtualMachineManagerImpl method changeToStartState.

@DB
protected Ternary<VMInstanceVO, ReservationContext, ItWorkVO> changeToStartState(final VirtualMachineGuru vmGuru, final VMInstanceVO vm, final User caller, final Account account) throws ConcurrentOperationException {
    final long vmId = vm.getId();
    ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId());
    int retry = VmOpLockStateRetry.value();
    while (retry-- != 0) {
        try {
            final ItWorkVO workFinal = work;
            final Ternary<VMInstanceVO, ReservationContext, ItWorkVO> result = Transaction.execute(new TransactionCallbackWithException<Ternary<VMInstanceVO, ReservationContext, ItWorkVO>, NoTransitionException>() {

                @Override
                public Ternary<VMInstanceVO, ReservationContext, ItWorkVO> doInTransaction(final TransactionStatus status) throws NoTransitionException {
                    final Journal journal = new Journal.LogJournal("Creating " + vm, s_logger);
                    final ItWorkVO work = _workDao.persist(workFinal);
                    final ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account);
                    if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) {
                        if (s_logger.isDebugEnabled()) {
                            s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId());
                        }
                        return new Ternary<VMInstanceVO, ReservationContext, ItWorkVO>(vm, context, work);
                    }
                    return new Ternary<VMInstanceVO, ReservationContext, ItWorkVO>(null, null, work);
                }
            });
            work = result.third();
            if (result.first() != null) {
                return result;
            }
        } catch (final NoTransitionException e) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Unable to transition into Starting state due to " + e.getMessage());
            }
        }
        final VMInstanceVO instance = _vmDao.findById(vmId);
        if (instance == null) {
            throw new ConcurrentOperationException("Unable to acquire lock on " + vm);
        }
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Determining why we're unable to update the state to Starting for " + instance + ".  Retry=" + retry);
        }
        final State state = instance.getState();
        if (state == State.Running) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("VM is already started: " + vm);
            }
            return null;
        }
        if (state.isTransitional()) {
            if (!checkWorkItems(vm, state)) {
                throw new ConcurrentOperationException("There are concurrent operations on " + vm);
            } else {
                continue;
            }
        }
        if (state != State.Stopped) {
            s_logger.debug("VM " + vm + " is not in a state to be started: " + state);
            return null;
        }
    }
    throw new ConcurrentOperationException("Unable to change the state of " + vm);
}
Also used : Ternary(com.cloud.utils.Ternary) TransactionStatus(com.cloud.utils.db.TransactionStatus) Journal(com.cloud.utils.Journal) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) PowerState(com.cloud.vm.VirtualMachine.PowerState) State(com.cloud.vm.VirtualMachine.State) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) DB(com.cloud.utils.db.DB)

Example 45 with NoTransitionException

use of com.cloud.utils.fsm.NoTransitionException in project cloudstack by apache.

the class AgentManagerImpl method agentStatusTransitTo.

@Override
public boolean agentStatusTransitTo(final HostVO host, final Status.Event e, final long msId) {
    try {
        _agentStatusLock.lock();
        if (status_logger.isDebugEnabled()) {
            final ResourceState state = host.getResourceState();
            final StringBuilder msg = new StringBuilder("Transition:");
            msg.append("[Resource state = ").append(state);
            msg.append(", Agent event = ").append(e.toString());
            msg.append(", Host id = ").append(host.getId()).append(", name = " + host.getName()).append("]");
            status_logger.debug(msg);
        }
        host.setManagementServerId(msId);
        try {
            return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
        } catch (final NoTransitionException e1) {
            status_logger.debug("Cannot transit agent status with event " + e + " for host " + host.getId() + ", name=" + host.getName() + ", mangement server id is " + msId);
            throw new CloudRuntimeException("Cannot transit agent status with event " + e + " for host " + host.getId() + ", mangement server id is " + msId + "," + e1.getMessage());
        }
    } finally {
        _agentStatusLock.unlock();
    }
}
Also used : CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) ResourceState(com.cloud.resource.ResourceState)

Aggregations

NoTransitionException (com.cloud.utils.fsm.NoTransitionException)47 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)36 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)17 HostVO (com.cloud.host.HostVO)12 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)11 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)11 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)10 DB (com.cloud.utils.db.DB)9 Answer (com.cloud.agent.api.Answer)7 CopyCommandResult (org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)7 CreateCmdResult (org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult)7 VolumeVO (com.cloud.storage.VolumeVO)6 VMInstanceVO (com.cloud.vm.VMInstanceVO)6 AgentControlAnswer (com.cloud.agent.api.AgentControlAnswer)5 CheckVirtualMachineAnswer (com.cloud.agent.api.CheckVirtualMachineAnswer)5 ClusterVMMetaDataSyncAnswer (com.cloud.agent.api.ClusterVMMetaDataSyncAnswer)5 PlugNicAnswer (com.cloud.agent.api.PlugNicAnswer)5 RebootAnswer (com.cloud.agent.api.RebootAnswer)5 RestoreVMSnapshotAnswer (com.cloud.agent.api.RestoreVMSnapshotAnswer)5 StartAnswer (com.cloud.agent.api.StartAnswer)5