From db8e192db8774ec2fd20d0d0c1e6eab237479843 Mon Sep 17 00:00:00 2001 From: Shubham Verma Date: Wed, 28 Mar 2018 17:26:37 -0400 Subject: [PATCH] Jenkins Create new node job - Added CreateNewNode job - Updated readme file to include the new job - Moved string constants to the vars directory of the Node helper API - added a input parameter for SSH key id in CreateNewNode issue #10 Signed-off-by: Shubham Verma --- Jenkins_jobs/CreateNewNode.groovy | 78 +++++++++++++++++++++++++++++++ README.md | 13 ++++++ src/NodeHelper.groovy | 14 +++--- vars/Constants.groovy | 14 ++++++ 4 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 Jenkins_jobs/CreateNewNode.groovy create mode 100644 vars/Constants.groovy diff --git a/Jenkins_jobs/CreateNewNode.groovy b/Jenkins_jobs/CreateNewNode.groovy new file mode 100644 index 0000000..91fe065 --- /dev/null +++ b/Jenkins_jobs/CreateNewNode.groovy @@ -0,0 +1,78 @@ +@Library('NodeHelper') _ +import hudson.slaves.CommandLauncher; +import hudson.plugins.sshslaves.SSHLauncher +import hudson.model.Node.Mode; +import hudson.plugins.sshslaves.verifiers.NonVerifyingKeyVerificationStrategy; +import jenkins.model.Jenkins; +import hudson.model.Computer; +import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval; +import hudson.model.Slave; +import hudson.slaves.JNLPLauncher; + +node { + stage('AddNewNode') { + def nodeHelper = new NodeHelper(); + + String[] machines = params.machineNames.split(",") + String[] machineIPs = params.machineIPs.split(",") + String[] labels = params.labelStrings.split(",") + + def launcher + String remoteFS + String newMachineLabels + String os + String newMachineName + + for (int index = 0; index < machineIPs.length; index++) { + + if (nodeHelper.getComputer(machines[index]) != null) { + println "Machine(${machines[index]}) already exists." + } else { + if (Integer.parseInt(machineIPs[index].split("\\.")[0]) == 10) { + launcher = new CommandLauncher(Constants.SSH_COMMAND + "${machineIPs[index]} " + Constants.WGET_SLAVE_JAR); + remoteFS = Constants.REMOTE_FS; + } else if (machines[index].contains("win")) { + launcher = new JNLPLauncher("", "", new jenkins.slaves.RemotingWorkDirSettings(false, "", "remoting", false)); + remoteFS = Constants.WIN_REMOTE_FS; + } else { + launcher = new SSHLauncher( + machines[index], + 22, + params.SSHCredentialId.isEmpty() ? Constants.SSH_CREDENTIAL_ID : params.SSHCredentialId, + null, null, null, null, null, null, null, + new NonVerifyingKeyVerificationStrategy()); + remoteFS = Constants.REMOTE_FS; + } + + newMachineLabels = labels[index%labels.length] + + newMachineName = nodeHelper.addNewNode( + machines[index], + machineIPs[index], + remoteFS, + 1, // Number of executers + Mode.EXCLUSIVE, + newMachineLabels.toLowerCase(), + launcher + ); + + // This part is to approve the script used to add a 10. machine + def scripts = ScriptApproval.get() + def scriptSet = scripts.getPendingScripts() + def iterator = scriptSet.iterator() + if (launcher.getClass().toString().contains("slaves.CommandLauncher")) { + for (ScriptApproval.PendingScript script : scriptSet) { + if (script.script.contains(Constants.SSH_COMMAND + machineIPs[index])) { + println "Script Approved" + scripts.approveScript(script.getHash()); + } + } + (Jenkins.getInstance().getComputer(newMachineName)).connect(false); + } + + println "Machine ${newMachineName} was added with following labels ${newMachineLabels}"; + } + } + + } +} diff --git a/README.md b/README.md index a1b5dd2..f0a6e0d 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,19 @@ Iterates over online nodes on Jenkins and prints the contents of the workspace d * The computers it iterates over can be limited by input parameter, ```projectLabel``` * As of now, it only works for linux, aix, and mac +### Create New Node (CreateNewNode.groovy) +Used to create new nodes with any basic labels + +* This job expects 3 parameters + * ```String machineNames``` + * Comma seperated host names of the machine(s) + * ```String machineIPs``` + * Comma seperated IP address of the machine(s) + * ```String labelStrings``` + * Labels you would like to be added to the machine. + * Each label must be separated by spaces and labels for different machines must be separated by `,` + * If identical labels need to be applied to all the machines, only one set of labels need to be supplied + ## How-to ### Setup diff --git a/src/NodeHelper.groovy b/src/NodeHelper.groovy index b4aa66f..afa856c 100644 --- a/src/NodeHelper.groovy +++ b/src/NodeHelper.groovy @@ -26,8 +26,6 @@ import hudson.plugins.sshslaves.SSHLauncher; class NodeHelper { - // TODO: Move strings out to a config file - /* Java Web Start (Windows) - Internal data directory: remoting SSH (most linux machines) @@ -74,7 +72,7 @@ class NodeHelper { String ret = "INVALID_NODE_NAME"; - if (newNodeName.length() > 2) { // TODO: Some sort of validation for node names + if (newNodeName.length() > 2) { DumbSlave newSlave = new DumbSlave( newNodeName, newNodeRemoteFS, @@ -1030,7 +1028,7 @@ class NodeHelper { return ret; } - private String execGroovy(String cmd, Computer computer) { // TODO: Also check for invalid command (?) + private String execGroovy(String cmd, Computer computer) { String ret = "execGroovy:INVALID_COMMAND"; if (cmd.length() > 1 && computer != null) { @@ -1115,9 +1113,11 @@ class NodeHelper { * the 2 */ ret = Jenkins.getInstance().getComputer(computerName); - if (ret == null) { - // tries to search for computer without the domain - ret = Jenkins.getInstance().getComputer(computerName.substring(0,computerName.indexOf("."))); + if (ret == null) { // tries to search for computer without the domain + int endIndex = computerName.indexOf("."); + if ( endIndex > 0) { + ret = Jenkins.getInstance().getComputer(computerName.substring(0,endIndex)); + } } } diff --git a/vars/Constants.groovy b/vars/Constants.groovy new file mode 100644 index 0000000..f781839 --- /dev/null +++ b/vars/Constants.groovy @@ -0,0 +1,14 @@ +class Constants { + static final String[] IGNORE_LABELS = ['.ignore']; + static final String REMOTE_FS = "/home/jenkins"; + static final String WIN_REMOTE_FS = "C:\\Users\\jenkins"; + + // This the key that'll be used for SSHLauncher in CreateNewNode + static final String SSH_CREDENTIAL_ID = ""; + + static final String SLAVE_JAR_LOCATION = "/jnlpJars/slave.jar"; + static final String WGET_SLAVE_JAR = "\"wget -q --no-check-certificate -O slave.jar ${SLAVE_JAR_LOCATION} ; java -jar slave.jar\""; + static final String SSH_COMMAND = "ssh -C -i ${SSH_KEY_LOCATION} @"; + static final String SSH_KEY_LOCATION = ""; +} +