Search in sources :

Example 1 with TrackedPlannedNode

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);
            }
        })));
    }
}
Also used : StreamTaskListener(hudson.util.StreamTaskListener) TrackedPlannedNode(org.jenkinsci.plugins.cloudstats.TrackedPlannedNode) Node(hudson.model.Node) TrackedPlannedNode(org.jenkinsci.plugins.cloudstats.TrackedPlannedNode) PlannedNode(hudson.slaves.NodeProvisioner.PlannedNode) AzureCloudException(com.microsoft.azure.vmagent.exceptions.AzureCloudException) IOException(java.io.IOException) Callable(java.util.concurrent.Callable) ServletException(javax.servlet.ServletException) AzureCloudException(com.microsoft.azure.vmagent.exceptions.AzureCloudException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ProvisioningActivity(org.jenkinsci.plugins.cloudstats.ProvisioningActivity) SlaveComputer(hudson.slaves.SlaveComputer) Computer(hudson.model.Computer) FailureStage(com.microsoft.azure.vmagent.util.FailureStage)

Aggregations

AzureCloudException (com.microsoft.azure.vmagent.exceptions.AzureCloudException)1 FailureStage (com.microsoft.azure.vmagent.util.FailureStage)1 Computer (hudson.model.Computer)1 Node (hudson.model.Node)1 PlannedNode (hudson.slaves.NodeProvisioner.PlannedNode)1 SlaveComputer (hudson.slaves.SlaveComputer)1 StreamTaskListener (hudson.util.StreamTaskListener)1 IOException (java.io.IOException)1 Callable (java.util.concurrent.Callable)1 ExecutionException (java.util.concurrent.ExecutionException)1 ServletException (javax.servlet.ServletException)1 ProvisioningActivity (org.jenkinsci.plugins.cloudstats.ProvisioningActivity)1 TrackedPlannedNode (org.jenkinsci.plugins.cloudstats.TrackedPlannedNode)1