Search in sources :

Example 6 with AzureVMAgent

use of com.microsoft.azure.vmagent.AzureVMAgent in project azure-vm-agents-plugin by jenkinsci.

the class AzureVMAgentSSHLauncher method launch.

@Override
public void launch(SlaveComputer agentComputer, TaskListener listener) {
    if (!(agentComputer instanceof AzureVMComputer)) {
        LOGGER.log(Level.INFO, "AgentComputer is invalid {0}", agentComputer);
        return;
    }
    AzureVMComputer computer = (AzureVMComputer) agentComputer;
    AzureVMAgent agent = computer.getNode();
    if (agent == null) {
        LOGGER.log(Level.INFO, "Agent node is null");
        return;
    }
    LOGGER.log(Level.FINE, "launching agent {0}", computer.getName());
    final boolean isUnix = agent.getOsType().equals(OperatingSystemTypes.LINUX);
    // This still means that a delete agent will eventually get cleaned up.
    try {
        if (!agent.isVMAliveOrHealthy()) {
            LOGGER.log(Level.INFO, "Agent {0} is shut down, deleted, etc. Not attempting to connect", computer.getName());
            return;
        }
    } catch (Exception e1) {
    // ignoring exception purposefully
    }
    // Block cleanup while we attempt to start.
    agent.blockCleanUpAction();
    PrintStream logger = listener.getLogger();
    boolean successful = false;
    Session session = null;
    SlaveComputer slaveComputer = agent.getComputer();
    if (slaveComputer == null) {
        LOGGER.log(Level.SEVERE, "Got null computer.");
        handleLaunchFailure(agent, Constants.AGENT_POST_PROV_NULL_COMPUTER);
        return;
    }
    try {
        session = connectToSsh(agent);
    } catch (UnknownHostException e) {
        LOGGER.log(Level.SEVERE, "Got unknown host exception. Virtual machine might have been deleted already", e);
    } catch (ConnectException e) {
        LOGGER.log(Level.SEVERE, "Got connect exception while launching " + agent.getNodeName() + ". Might be due to firewall rules", e);
        handleLaunchFailure(agent, Constants.AGENT_POST_PROV_CONN_FAIL);
    } catch (Exception e) {
        // Checking if we need to mark template as disabled. Need to re-visit this logic based on tests.
        if (e.getMessage() != null && e.getMessage().equalsIgnoreCase("Auth fail")) {
            LOGGER.log(Level.SEVERE, "Authentication failure launching " + agent.getNodeName() + ". Image may not be supporting password authentication", e);
            handleLaunchFailure(agent, Constants.AGENT_POST_PROV_AUTH_FAIL);
        } else {
            LOGGER.log(Level.SEVERE, "Exception launching" + agent.getNodeName(), e);
            handleLaunchFailure(agent, Constants.AGENT_POST_PROV_CONN_FAIL + e.getMessage());
        }
    } finally {
        if (session == null) {
            slaveComputer.setAcceptingTasks(false);
            agent.setCleanUpAction(CleanUpAction.DELETE, Messages._Agent_Failed_To_Connect());
            return;
        }
    }
    Localizable cleanUpReason = null;
    try {
        final Session cleanupSession = session;
        String initScript = agent.getInitScript();
        // Executing script only if script is not executed even once
        String command;
        if (isUnix) {
            command = "test -e ~/.azure-agent-init";
        } else {
            command = "dir C:\\.azure-agent-init";
        }
        if (StringUtils.isNotBlank(initScript) && executeRemoteCommand(session, command, logger, isUnix) != 0) {
            LOGGER.fine("Init script is not null, " + "preparing to execute script remotely on " + agent.getNodeName());
            if (isUnix) {
                copyFileToRemote(session, new ByteArrayInputStream(initScript.getBytes(StandardCharsets.UTF_8)), REMOTE_INIT_FILE_NAME);
            } else {
                copyFileToRemote(session, new ByteArrayInputStream(initScript.getBytes(StandardCharsets.UTF_8)), REMOTE_INIT_FILE_NAME_WINDOWS);
            }
            // Execute initialization script
            // Make sure to change file permission for execute if needed. TODO: need to test
            // Grab the username/pass
            StandardUsernamePasswordCredentials creds = AzureUtil.getCredentials(agent.getVMCredentialsId());
            if (isUnix) {
                command = "sh " + REMOTE_INIT_FILE_NAME;
            } else {
                command = "powershell " + REMOTE_INIT_FILE_NAME_WINDOWS;
            }
            int exitStatus = executeRemoteCommand(session, command, logger, isUnix, agent.getExecuteInitScriptAsRoot(), creds.getPassword().getPlainText());
            if (exitStatus != 0) {
                if (agent.getDoNotUseMachineIfInitFails()) {
                    LOGGER.log(Level.SEVERE, "Init script failed on " + agent.getNodeName() + ": exit code={0} " + "(marking agent for deletion)", exitStatus);
                    cleanUpReason = Messages._Agent_Failed_Init_Script();
                    return;
                } else {
                    LOGGER.log(Level.INFO, "Init script failed on " + agent.getNodeName() + ": exit code={0} (ignoring)", exitStatus);
                }
            } else {
                LOGGER.fine("Init script on " + agent.getNodeName() + " got executed successfully");
            }
            // In Windows, restart sshd to get new system environment variables
            if (!isUnix) {
                executeRemoteCommand(session, "powershell -ExecutionPolicy Bypass Restart-Service sshd", logger, isUnix);
            }
            /* Create a new session after the init script has executed to
                 * make sure we pick up whatever new settings have been set up
                 * for our user
                 *
                 * https://issues.jenkins-ci.org/browse/JENKINS-40291
                 */
            session.disconnect();
            session = connectToSsh(agent);
            // Create tracking file
            if (isUnix) {
                command = "touch ~/.azure-agent-init";
            } else {
                command = "copy NUL C:\\.azure-agent-init";
            }
            executeRemoteCommand(session, command, logger, isUnix);
        }
        LOGGER.fine("Checking for java runtime on " + agent.getNodeName());
        if (executeRemoteCommand(session, agent.getJavaPath() + " -fullversion", logger, isUnix) != 0) {
            LOGGER.info("Java not found on " + agent.getNodeName() + ". " + "At a minimum init script should ensure that java runtime is installed");
            handleLaunchFailure(agent, Constants.AGENT_POST_PROV_JAVA_NOT_FOUND);
            return;
        }
        LOGGER.fine("Java runtime present on " + agent.getNodeName() + ", copying remoting.jar to remote");
        InputStream inputStream = new ByteArrayInputStream(Jenkins.get().getJnlpJars("remoting.jar").readFully());
        copyFileToRemote(session, inputStream, "remoting.jar");
        String remotingWorkingDirectory = getRemotingWorkingDirectory(isUnix);
        String remotingDefaultOptions = "-workDir " + remotingWorkingDirectory;
        String remotingOptions = Util.fixEmpty(agent.getRemotingOptions()) != null ? agent.getRemotingOptions() : remotingDefaultOptions;
        String jvmopts = agent.getJvmOptions();
        String execCommand = agent.getJavaPath() + " " + (StringUtils.isNotBlank(jvmopts) ? jvmopts : "") + " -jar remoting.jar " + remotingOptions;
        LOGGER.log(Level.INFO, "Launching agent " + agent.getNodeName() + ": {0}", execCommand);
        final ChannelExec jschChannel = (ChannelExec) session.openChannel("exec");
        jschChannel.setCommand(execCommand);
        jschChannel.connect();
        LOGGER.info("Connected " + agent.getNodeName() + " successfully");
        computer.setChannel(jschChannel.getInputStream(), jschChannel.getOutputStream(), logger, new Listener() {

            @Override
            public void onClosed(Channel channel, IOException cause) {
                jschChannel.disconnect();
                cleanupSession.disconnect();
            }
        });
        LOGGER.info("Launched agent " + agent.getNodeName() + " successfully");
        // There's a chance that it was marked as delete for instance, if the node
        // was unreachable and then someone hit connect and it worked.  Reset the node cleanup
        // state to the default for the node.
        agent.clearCleanUpAction();
        successful = true;
    } catch (Exception e) {
        LOGGER.log(Level.SEVERE, "Got exception on agent " + agent.getNodeName(), e);
    } finally {
        if (!successful) {
            session.disconnect();
            if (cleanUpReason == null) {
                cleanUpReason = Messages._Agent_Failed_To_Connect();
            }
            slaveComputer.setAcceptingTasks(false);
            // Set the machine to be deleted by the cleanup task
            agent.setCleanUpAction(CleanUpAction.DELETE, cleanUpReason);
        }
    }
}
Also used : SlaveComputer(hudson.slaves.SlaveComputer) Listener(hudson.remoting.Channel.Listener) TaskListener(hudson.model.TaskListener) AzureVMComputer(com.microsoft.azure.vmagent.AzureVMComputer) UnknownHostException(java.net.UnknownHostException) AzureVMAgent(com.microsoft.azure.vmagent.AzureVMAgent) Channel(hudson.remoting.Channel) ConnectException(java.net.ConnectException) UnknownHostException(java.net.UnknownHostException) Localizable(org.jvnet.localizer.Localizable) StandardUsernamePasswordCredentials(com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials) ConnectException(java.net.ConnectException)

Example 7 with AzureVMAgent

use of com.microsoft.azure.vmagent.AzureVMAgent in project azure-vm-agents-plugin by jenkinsci.

the class ITAzureVMCloud method createProvisionedAgentWorksWhenDeploymentExists.

@Ignore
@Test
public void createProvisionedAgentWorksWhenDeploymentExists() {
    try {
        final AzureVMDeploymentInfo deploymentInfo = createDefaultDeployment(1, null);
        final String vmName = deploymentInfo.getVmBaseName() + "0";
        final String vmDNS = azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, vmName).getPrimaryPublicIPAddress().fqdn();
        final String deploymentName = deploymentInfo.getDeploymentName();
        final String templateName = "createTemplate";
        final String templateDesc = "createTemplateDesc";
        final String agentWorkspace = "createTemplateAgentWorkspace";
        final int noOfParallelJobs = 2;
        final Node.Mode useAgentAlwaysIfAvail = Node.Mode.NORMAL;
        final String templateLabels = "label1 label2";
        final String credentialsId = "cred_id";
        final String jvmOptions = "";
        final boolean isShutdownOnIdle = false;
        final int retentionTimeInMin = 30;
        final String initScript = "";
        final String terminateScript = "";
        final String agentLaunchMethod = Constants.LAUNCH_METHOD_SSH;
        final boolean executeInitScriptAsRoot = true;
        final boolean doNotUseMachineIfInitFails = true;
        final boolean enableMSI = false;
        final boolean enableUAMI = false;
        final boolean ephemeralOSDisk = false;
        final ProvisioningActivity.Id provisioningId = new ProvisioningActivity.Id(vmName, deploymentName);
        AzureVMAgentTemplate templateMock = mock(AzureVMAgentTemplate.class);
        AzureVMCloud cloudMock = spy(new AzureVMCloud("", credentialsId, "42", "30", "new", testEnv.azureResourceGroup, null, null));
        when(templateMock.retrieveAzureCloudReference()).thenReturn(cloudMock);
        when(templateMock.getTemplateName()).thenReturn(templateName);
        when(templateMock.getTemplateDesc()).thenReturn(templateDesc);
        when(templateMock.getAgentWorkspace()).thenReturn(agentWorkspace);
        when(templateMock.getNoOfParallelJobs()).thenReturn(noOfParallelJobs);
        when(templateMock.getUsageMode()).thenReturn(useAgentAlwaysIfAvail);
        when(templateMock.getLabels()).thenReturn(templateLabels);
        when(templateMock.getCredentialsId()).thenReturn(credentialsId);
        when(templateMock.getJvmOptions()).thenReturn(jvmOptions);
        when(templateMock.isShutdownOnIdle()).thenReturn(isShutdownOnIdle);
        when(templateMock.getRetentionTimeInMin()).thenReturn(retentionTimeInMin);
        when(templateMock.getInitScript()).thenReturn(initScript);
        when(templateMock.getTerminateScript()).thenReturn(terminateScript);
        when(templateMock.getAgentLaunchMethod()).thenReturn(agentLaunchMethod);
        when(templateMock.getResourceGroupName()).thenReturn(testEnv.azureResourceGroup);
        when(templateMock.getExecuteInitScriptAsRoot()).thenReturn(executeInitScriptAsRoot);
        when(templateMock.getDoNotUseMachineIfInitFails()).thenReturn(doNotUseMachineIfInitFails);
        when(templateMock.isEnableMSI()).thenReturn(enableMSI);
        when(templateMock.isEnableUAMI()).thenReturn(enableUAMI);
        when(templateMock.isEphemeralOSDisk()).thenReturn(ephemeralOSDisk);
        AzureVMAgent newAgent = cloudMock.createProvisionedAgent(provisioningId, templateMock, vmName, deploymentName);
        Assert.assertEquals(vmDNS, newAgent.getPublicDNSName());
        Assert.assertEquals(Constants.DEFAULT_SSH_PORT, newAgent.getSshPort());
        Assert.assertEquals(templateName, newAgent.getTemplateName());
        Assert.assertEquals(templateDesc, newAgent.getNodeDescription());
        Assert.assertEquals(noOfParallelJobs, newAgent.getNumExecutors());
        Assert.assertEquals(useAgentAlwaysIfAvail, newAgent.getMode());
        Assert.assertEquals(templateLabels, newAgent.getLabelString());
        Assert.assertEquals(jvmOptions, newAgent.getJvmOptions());
        Assert.assertEquals(retentionTimeInMin, newAgent.getRetentionTimeInMin());
        Assert.assertEquals(initScript, newAgent.getInitScript());
        Assert.assertEquals(terminateScript, newAgent.getTerminateScript());
        Assert.assertEquals(agentLaunchMethod, newAgent.getAgentLaunchMethod());
        Assert.assertEquals(executeInitScriptAsRoot, newAgent.getExecuteInitScriptAsRoot());
        Assert.assertEquals(doNotUseMachineIfInitFails, newAgent.getDoNotUseMachineIfInitFails());
        Assert.assertEquals(enableMSI, newAgent.isEnableMSI());
        Assert.assertEquals(enableUAMI, newAgent.isEnableUAMI());
        Assert.assertEquals(ephemeralOSDisk, newAgent.isEphemeralOSDisk());
    } catch (Exception e) {
        LOGGER.log(Level.SEVERE, null, e);
        Assert.fail(e.getMessage());
    }
}
Also used : AzureVMAgent(com.microsoft.azure.vmagent.AzureVMAgent) AzureVMDeploymentInfo(com.microsoft.azure.vmagent.AzureVMDeploymentInfo) Node(hudson.model.Node) AzureVMAgentTemplate(com.microsoft.azure.vmagent.AzureVMAgentTemplate) AzureCloudException(com.microsoft.azure.vmagent.exceptions.AzureCloudException) ProvisioningActivity(org.jenkinsci.plugins.cloudstats.ProvisioningActivity) AzureVMCloud(com.microsoft.azure.vmagent.AzureVMCloud) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 8 with AzureVMAgent

use of com.microsoft.azure.vmagent.AzureVMAgent in project azure-vm-agents-plugin by jenkinsci.

the class ITAzureVMManagementServiceDelegate method attachPublicIP.

@Test
public void attachPublicIP() {
    try {
        final AzureVMDeploymentInfo deploymentInfo = createDefaultDeployment(1, false, null);
        final String nodeName = deploymentInfo.getVmBaseName() + "0";
        final String privateIP = azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, nodeName).getPrimaryNetworkInterface().primaryPrivateIP();
        AzureVMAgent agentMock = mock(AzureVMAgent.class);
        AzureVMAgentTemplate templateMock = mock(AzureVMAgentTemplate.class);
        AzureVMCloud cloudMock = mock(AzureVMCloud.class);
        when(templateMock.retrieveAzureCloudReference()).thenReturn(cloudMock);
        when(templateMock.getResourceGroupName()).thenReturn(testEnv.azureResourceGroup);
        when(templateMock.getLocation()).thenReturn(testEnv.azureLocation);
        when(agentMock.getNodeName()).thenReturn(nodeName);
        delegate.attachPublicIP(agentMock, templateMock);
        final PublicIpAddress publicIP = azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, nodeName).getPrimaryPublicIPAddress();
        Assert.assertNotNull(publicIP);
        verify(agentMock).setPublicDNSName(publicIP.fqdn());
        verify(agentMock).setSshPort(Constants.DEFAULT_SSH_PORT);
        verify(agentMock).setPublicIP(publicIP.ipAddress());
        verify(agentMock).setPrivateIP(privateIP);
    } catch (Exception e) {
        LOGGER.log(Level.SEVERE, null, e);
        Assert.fail(e.getMessage());
    }
}
Also used : PublicIpAddress(com.azure.resourcemanager.network.models.PublicIpAddress) AzureVMAgent(com.microsoft.azure.vmagent.AzureVMAgent) AzureVMDeploymentInfo(com.microsoft.azure.vmagent.AzureVMDeploymentInfo) AzureVMCloud(com.microsoft.azure.vmagent.AzureVMCloud) AzureVMAgentTemplate(com.microsoft.azure.vmagent.AzureVMAgentTemplate) AzureCloudException(com.microsoft.azure.vmagent.exceptions.AzureCloudException) IOException(java.io.IOException) ManagementException(com.azure.core.management.exception.ManagementException) Test(org.junit.Test)

Example 9 with AzureVMAgent

use of com.microsoft.azure.vmagent.AzureVMAgent in project azure-vm-agents-plugin by jenkinsci.

the class ITAzureVMManagementServiceDelegate method attachPublicIPIsNoOpWhenAlreadyExists.

@Test
public void attachPublicIPIsNoOpWhenAlreadyExists() {
    try {
        final AzureVMDeploymentInfo deploymentInfo = createDefaultDeployment(1, true, null);
        final String nodeName = deploymentInfo.getVmBaseName() + "0";
        AzureVMAgent agentMock = mock(AzureVMAgent.class);
        AzureVMAgentTemplate templateMock = mock(AzureVMAgentTemplate.class);
        AzureVMCloud cloudMock = mock(AzureVMCloud.class);
        when(templateMock.retrieveAzureCloudReference()).thenReturn(cloudMock);
        when(templateMock.getResourceGroupName()).thenReturn(testEnv.azureResourceGroup);
        when(templateMock.getLocation()).thenReturn(testEnv.azureLocation);
        when(agentMock.getNodeName()).thenReturn(nodeName);
        final String initialPublicIPId = azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, nodeName).getPrimaryPublicIPAddress().id();
        delegate.attachPublicIP(agentMock, templateMock);
        final PublicIpAddress publicIP = azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, nodeName).getPrimaryPublicIPAddress();
        Assert.assertNotNull(publicIP);
        Assert.assertEquals(initialPublicIPId, publicIP.id());
        verify(agentMock, never()).setPublicDNSName(any(String.class));
        verify(agentMock, never()).setSshPort(any(int.class));
        verify(agentMock, never()).setPublicIP(any(String.class));
        verify(agentMock, never()).setPrivateIP(any(String.class));
    } catch (Exception e) {
        LOGGER.log(Level.SEVERE, null, e);
        Assert.fail(e.getMessage());
    }
}
Also used : PublicIpAddress(com.azure.resourcemanager.network.models.PublicIpAddress) AzureVMAgent(com.microsoft.azure.vmagent.AzureVMAgent) AzureVMDeploymentInfo(com.microsoft.azure.vmagent.AzureVMDeploymentInfo) AzureVMCloud(com.microsoft.azure.vmagent.AzureVMCloud) AzureVMAgentTemplate(com.microsoft.azure.vmagent.AzureVMAgentTemplate) AzureCloudException(com.microsoft.azure.vmagent.exceptions.AzureCloudException) IOException(java.io.IOException) ManagementException(com.azure.core.management.exception.ManagementException) Test(org.junit.Test)

Example 10 with AzureVMAgent

use of com.microsoft.azure.vmagent.AzureVMAgent in project azure-vm-agents-plugin by jenkinsci.

the class ITAzureVMManagementServiceDelegate method restartVMTest.

@Test
public void restartVMTest() throws IOException, AzureCloudException {
    final String vmName = "vmrestart";
    VirtualMachine vm = createAzureVM(vmName);
    Assert.assertEquals(PowerState.RUNNING, vm.powerState());
    AzureVMAgent agentMock = mock(AzureVMAgent.class);
    when(agentMock.getNodeName()).thenReturn(vmName);
    when(agentMock.getResourceGroupName()).thenReturn(testEnv.azureResourceGroup);
    delegate.restartVirtualMachine(agentMock);
    PowerState state = azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, vmName).powerState();
    Assert.assertTrue(state.equals(PowerState.RUNNING) || state.equals(PowerState.STARTING));
    azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, vmName).powerOff();
    PowerState state2 = azureClient.virtualMachines().getByResourceGroup(testEnv.azureResourceGroup, vmName).powerState();
    Assert.assertTrue(state2.toString(), state2.equals(PowerState.STOPPED) || state2.toString().equalsIgnoreCase("powerstate/stopping"));
    try {
        // restart throws exception when the VM is already stopped
        delegate.restartVirtualMachine(agentMock);
        Assert.fail("Expect throwing AzureCloudException but not");
    } catch (AzureCloudException ex) {
    // Expect exception
    }
}
Also used : AzureVMAgent(com.microsoft.azure.vmagent.AzureVMAgent) AzureCloudException(com.microsoft.azure.vmagent.exceptions.AzureCloudException) PowerState(com.azure.resourcemanager.compute.models.PowerState) VirtualMachine(com.azure.resourcemanager.compute.models.VirtualMachine) Test(org.junit.Test)

Aggregations

AzureVMAgent (com.microsoft.azure.vmagent.AzureVMAgent)10 Test (org.junit.Test)8 AzureCloudException (com.microsoft.azure.vmagent.exceptions.AzureCloudException)7 ManagementException (com.azure.core.management.exception.ManagementException)5 IOException (java.io.IOException)5 VirtualMachine (com.azure.resourcemanager.compute.models.VirtualMachine)4 AzureVMAgentTemplate (com.microsoft.azure.vmagent.AzureVMAgentTemplate)4 AzureVMCloud (com.microsoft.azure.vmagent.AzureVMCloud)4 PowerState (com.azure.resourcemanager.compute.models.PowerState)3 AzureVMDeploymentInfo (com.microsoft.azure.vmagent.AzureVMDeploymentInfo)3 PublicIpAddress (com.azure.resourcemanager.network.models.PublicIpAddress)2 StandardUsernamePasswordCredentials (com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials)1 AzureVMComputer (com.microsoft.azure.vmagent.AzureVMComputer)1 Node (hudson.model.Node)1 TaskListener (hudson.model.TaskListener)1 Channel (hudson.remoting.Channel)1 Listener (hudson.remoting.Channel.Listener)1 SlaveComputer (hudson.slaves.SlaveComputer)1 ConnectException (java.net.ConnectException)1 UnknownHostException (java.net.UnknownHostException)1