public boolean canStartNewInstance() { if (getErrorInfo() != null) { LOG.debug("Can't start new instance, if image is erroneous"); return false; } if (myImageDetails.getBehaviour().isUseOriginal()) { final VmwareCloudInstance myInstance = myInstances.get(myImageDetails.getSourceName()); if (myInstance == null) { return false; } return myInstance.getStatus() == InstanceStatus.STOPPED; } final boolean countStoppedVmsInLimit = TeamCityProperties.getBooleanOrTrue(VmwareConstants.CONSIDER_STOPPED_VMS_LIMIT) && myImageDetails.getBehaviour().isDeleteAfterStop(); final List<String> consideredInstances = new ArrayList<String>(); for (Map.Entry<String, VmwareCloudInstance> entry : myInstances.entrySet()) { if (entry.getValue().getStatus() != InstanceStatus.STOPPED || countStoppedVmsInLimit) consideredInstances.add(entry.getKey()); } final boolean canStartMore = consideredInstances.size() < myImageDetails.getMaxInstances(); LOG.debug( String.format( "Instances count: %d %s, can start more: %s", consideredInstances.size(), Arrays.toString(consideredInstances.toArray()), String.valueOf(canStartMore))); return canStartMore; }
@Override public synchronized VmwareCloudInstance startNewInstance( @NotNull final CloudInstanceUserData cloudInstanceUserData) throws QuotaException { try { final VmwareCloudInstance instance = getOrCreateInstance(); if (instance == null) { return null; } boolean willClone = !myApiConnector.checkVirtualMachineExists(instance.getName()); LOG.info("Will clone for " + instance.getName() + ": " + willClone); if (willClone && myImageDetails.getMaxInstances() <= myInstances.size()) { throw new QuotaException( String.format( "Cannot clone '%s' into '%s' - limit exceeded", myImageDetails.getSourceName(), instance.getName())); } instance.setStatus(InstanceStatus.SCHEDULED_TO_START); if (!myInstances.containsKey(instance.getName())) { addInstance(instance); } if (willClone) { myAsyncTaskExecutor.executeAsync( new VmwareTaskWrapper( new Callable<Task>() { public Task call() throws Exception { return myApiConnector.cloneAndStartVm( instance, myImageDetails.getResourcePoolId(), myImageDetails.getFolderId()); } }, "Clone and start instance " + instance.getName()), new ImageStatusTaskWrapper(instance) { @Override public void onSuccess() { reconfigureVmTask(instance, cloudInstanceUserData); } @Override public void onError(final Throwable th) { super.onError(th); removeInstance(instance.getName()); } }); } else { startVM(instance, cloudInstanceUserData); } return instance; } catch (QuotaException e) { throw e; } catch (VmwareCheckedCloudException e) { throw new CloudException("Unable to start new instance: " + e.toString()); } }