use of org.jenkinsci.plugins.cloudstats.TrackedPlannedNode in project azure-vm-agents-plugin by jenkinsci.
the class AzureVMCloud method doProvision.
public void doProvision(final int numberOfNewAgents, List<PlannedNode> plannedNodes, final AzureVMAgentTemplate template, final boolean isProvisionOutside) {
Callable<AzureVMDeploymentInfo> callableTask = new Callable<AzureVMDeploymentInfo>() {
@Override
public AzureVMDeploymentInfo call() throws AzureCloudException {
try {
return template.provisionAgents(new StreamTaskListener(System.out, Charset.defaultCharset()), numberOfNewAgents);
} catch (AzureCloudException e) {
throw e;
} catch (Exception e) {
throw AzureCloudException.create(e);
}
}
};
final Future<AzureVMDeploymentInfo> deploymentFuture = getThreadPool().submit(callableTask);
for (int i = 0; i < numberOfNewAgents; i++) {
final int index = i;
final ProvisioningActivity.Id provisioningId = new ProvisioningActivity.Id(this.name, template.getTemplateName());
plannedNodes.add(new TrackedPlannedNode(provisioningId, template.getNoOfParallelJobs(), Computer.threadPoolForRemoting.submit(new Callable<Node>() {
@Override
public Node call() throws AzureCloudException {
// Wait for the future to complete
try {
// Only lock for pool maintaining.
PoolLock.provisionLock(template);
if (isProvisionOutside) {
CloudStatistics.ProvisioningListener.get().onStarted(provisioningId);
}
AzureVMDeploymentInfo info;
try {
info = deploymentFuture.get();
} catch (InterruptedException | ExecutionException e) {
handleFailure(template, null, e, FailureStage.DEPLOYMENT);
throw AzureCloudException.create(e);
}
final String deploymentName = info.getDeploymentName();
final String vmBaseName = info.getVmBaseName();
final String vmName = String.format("%s%d", vmBaseName, index);
AzureVMAgent agent;
try {
agent = createProvisionedAgent(provisioningId, template, vmName, deploymentName);
} catch (AzureCloudException e) {
LOGGER.log(Level.SEVERE, String.format("Failure creating provisioned agent '%s'", vmName), e);
handleFailure(template, vmName, e, FailureStage.PROVISIONING);
throw e;
}
try {
LOGGER.log(Level.INFO, "Adding agent {0} to Jenkins nodes", agent.getNodeName());
// Place the node in blocked state while it starts.
try {
agent.blockCleanUpAction();
Jenkins.get().addNode(agent);
Computer computer = agent.toComputer();
if (agent.getAgentLaunchMethod().equalsIgnoreCase("SSH") && computer != null) {
computer.connect(false).get();
} else if (agent.getAgentLaunchMethod().equalsIgnoreCase("JNLP")) {
// Wait until node is online
waitUntilJNLPNodeIsOnline(agent);
}
} finally {
// Place node in default state, now can be
// dealt with by the cleanup task.
agent.clearCleanUpAction();
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE, String.format("Failure to in post-provisioning for '%s'", vmName), e);
handleFailure(template, vmName, e, FailureStage.POSTPROVISIONING);
// Remove the node from jenkins
try {
Jenkins.get().removeNode(agent);
} catch (IOException nodeRemoveEx) {
LOGGER.log(Level.SEVERE, String.format("Failure removing Jenkins node for '%s'", vmName), nodeRemoveEx);
// Do not throw to avoid it being recorded
}
throw AzureCloudException.create(e);
}
if (isProvisionOutside) {
CloudStatistics.ProvisioningListener.get().onComplete(provisioningId, agent);
}
template.getTemplateProvisionStrategy().success();
return agent;
} catch (AzureCloudException e) {
if (isProvisionOutside) {
CloudStatistics.ProvisioningListener.get().onFailure(provisioningId, e);
}
throw e;
} finally {
PoolLock.provisionUnlock(template);
}
}
private void handleFailure(AzureVMAgentTemplate template, String vmName, Exception e, FailureStage stage) {
// Attempt to terminate whatever was created if any
if (vmName != null) {
try {
getServiceDelegate().terminateVirtualMachine(vmName, template.getResourceGroupName());
} catch (AzureCloudException terminateEx) {
LOGGER.log(Level.SEVERE, String.format("Failure terminating previous failed agent '%s'", vmName), terminateEx);
// Do not throw to avoid it being recorded
}
}
template.retrieveAzureCloudReference().adjustVirtualMachineCount(-1, template.getMaxVirtualMachinesLimit());
// Update the template status given this new issue.
template.handleTemplateProvisioningFailure(e.getMessage(), stage);
}
})));
}
}
Aggregations