Jenkins Slave - How to add or update ENVIRONMENT variables
Asked Answered
I

4

11

Has anyone tried a way to add or update an ENVIRONMENT variable in a Jenkins slave's configuration using Jenkins Rest/API or any other way.

Using Jenkins Swarm plugin, I created a slave (it uses JLNP to connect to the Jenkins master) but ENVIRONMENT variables (checkbox is not ticked) and there are no ENVIRONMENT variables created by Swarm client jar (by default). A user can manually add if reqd but I'm looking if there's a way to add / update ENV variables in a slave.

enter image description here

I want to create multiple swarm slaves (where each slave has different tools with different values i.e. slave01 JAVA_HOME=/path/jdk1.7.0.67 and other slave02 JAVA_HOME=/path/jdk1.8.0_45 etc etc).

I tried looking into http://javadoc.jenkins-ci.org/hudson/model/Node.html or http://javadoc.jenkins-ci.org/hudson/model/Slave.html or http://javadoc.jenkins-ci.org/hudson/slaves/DumbSlave.html but it doesn't provide any method / way to set Node's properties / ENV variables. There's no setNodeProperties or something like that (if that's the correct method to set the ENV variables/properties).

What I'm looking for is a way to add the following variables to the slave.

enter image description here

This post (by Villiam) reflects that someone tried groovy piece to do the same but I don't see how he can set ENV variables using the same API to Create/Manage Nodes

Jenkins-CLI has an option to run groovy scripts:

java -jar path/to/jenkins-cli.jar -s http://localhost:8080 groovy path/to/script

script:

import jenkins.model.*
import hudson.model.*
import hudson.slaves.*
Jenkins.instance.addNode(new DumbSlave("test-script","test slave description","C:\\Jenkins","1",Node.Mode.NORMAL,"test-slave-label",new JNLPLauncher(),new RetentionStrategy.Always(),new LinkedList())) 

(see docs for other options: http://javadoc.jenkins-ci.org/)

You can also run an interactive groovy shell with

java -jar jenkins-cli.jar -s http://localhost:8080 groovysh

Ipecac answered 9/12, 2015 at 18:55 Comment(0)
S
3

A method that will work if the "Environment Variables" checkbox has not been ticked is to use nodeProperties.add(new EnvironmentVariablesNodeProperty)

The full script I'm using to set Environment Variables on Jenkins when deploying is below (intended to be called with jenkins-cli.jar):

import jenkins.model.*
import hudson.model.*
import hudson.slaves.*

String node_name = args[0]
String env_key = args[1]
String env_value = args[2]

instance = Jenkins.getInstance()
if (node_name == "master") {
  node = instance
} else {
  instance.getNode(node_name)
}
props = node.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)

if(props.empty) {
  def entry = new EnvironmentVariablesNodeProperty.Entry(env_key, env_value)
  def evnp = new EnvironmentVariablesNodeProperty(entry)
  node.nodeProperties.add(evnp)
} else {
  for (prop in props) {
    prop.envVars.put(env_key, env_value)
  }
}

instance.save()
Singh answered 4/5, 2016 at 12:13 Comment(0)
T
3

When creating the node, you can pass the variables as the last parameter:

import jenkins.model.*
import hudson.model.*
import hudson.slaves.*

entry = new EnvironmentVariablesNodeProperty(new EnvironmentVariablesNodeProperty.Entry("MY_NAME", "my_value"))

list = new LinkedList()
list.add(entry)

Jenkins.instance.addNode(new DumbSlave("test-slave", "test slave description", "C:\\Jenkins", "1", Node.Mode.NORMAL, "test-slave-label", new JNLPLauncher(), new RetentionStrategy.Always(), list))

From DumbSlave here and EnvironmentVariablesNodeProperty here.

To add variables to an existing slave, we can use the following:

import jenkins.model.*
import hudson.model.*
import hudson.slaves.*

jenkins = Jenkins.instance
node = jenkins.getNode('test-slave')

props = node.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)
for (prop in props) {
  prop.envVars.put("MY_OTHER_NAME", "my_other_value")
}
jenkins.save()
Toomin answered 10/12, 2015 at 9:21 Comment(3)
Great! Can you point out what if the node is already created (in some fashion) and I want to use the above code (but instead of using addNode and new DumbSlave functions, I can use something like updateNode and just change/add/update an ENV variable? I updated your answer with what I meant (we can add if-then-else later and make this groovy script parameter driven). Also, if we can enhance this script as a generic script (i.e. it can be used for any Jenkins master instance)Ipecac
Your solution worked ONLY if the check box for "Environment variables" is manually checked/ticked first. When Swarm plugin jar is used to create the slave, the "Environment variable" checkbox is NOT check marked. Running the add environmental variable to an existing slave (solution) is working only if I manually check mark this box first. Save the slave and then run the above script. I did actually achieve the same last week but currently baffled by "How to automatically set the check box for Environmental variables" in the slave configuration before running the above precious piece.Ipecac
Hi @ArunSangal, did you ever solve the problem of enabling the environment variables checkbox automatically? I'm facing the exact same problem, and can't seem to solve it.Singh
S
3

A method that will work if the "Environment Variables" checkbox has not been ticked is to use nodeProperties.add(new EnvironmentVariablesNodeProperty)

The full script I'm using to set Environment Variables on Jenkins when deploying is below (intended to be called with jenkins-cli.jar):

import jenkins.model.*
import hudson.model.*
import hudson.slaves.*

String node_name = args[0]
String env_key = args[1]
String env_value = args[2]

instance = Jenkins.getInstance()
if (node_name == "master") {
  node = instance
} else {
  instance.getNode(node_name)
}
props = node.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)

if(props.empty) {
  def entry = new EnvironmentVariablesNodeProperty.Entry(env_key, env_value)
  def evnp = new EnvironmentVariablesNodeProperty(entry)
  node.nodeProperties.add(evnp)
} else {
  for (prop in props) {
    prop.envVars.put(env_key, env_value)
  }
}

instance.save()
Singh answered 4/5, 2016 at 12:13 Comment(0)
P
1

My answer is a bit of a mish-mash of other answers, but it will turn 'Environment variables' on if it's off.

public class KeyValuePair {
    String key
    String value
}

...

KeyValuePair[] environmentVariables = [...]

...

import hudson.slaves.EnvironmentVariablesNodeProperty

Jenkins jenkins = Jenkins.instance

List<EnvironmentVariablesNodeProperty> nodeProperties = jenkins.globalNodeProperties.getAll(EnvironmentVariablesNodeProperty.class)

if (nodeProperties.empty) { // Enable 'Environment variables' under 'Global properties'
    jenkins.globalNodeProperties.add(new EnvironmentVariablesNodeProperty())
    nodeProperties = jenkins.globalNodeProperties.getAll(EnvironmentVariablesNodeProperty.class)
}

for (int nodePropertyIndex = 0; nodePropertyIndex < nodeProperties.size(); nodePropertyIndex++) {
    EnvironmentVariablesNodeProperty nodeProperty = nodeProperties[nodePropertyIndex]
    for (int environmentVariableIndex = 0; environmentVariableIndex < environmentVariables.size(); environmentVariableIndex++) {
        KeyValuePair environmentVariable = environmentVariables[environmentVariableIndex]
        nodeProperty.envVars.put(environmentVariable.key, environmentVariable.value)
    }
}

jenkins.save()
Peasant answered 9/1, 2017 at 21:57 Comment(0)
C
0

whipped this up to update a limited set of nodes (includes enabling checkbox):

import hudson.model.*
import hudson.slaves.*

hudson = hudson.model.Hudson.instance
hudson.slaves.findAll { it.nodeName.matches("nodename.*") }.each { slave -> 
    slave.nodeProperties.add(new EnvironmentVariablesNodeProperty())
    props = slave.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)
    for (prop in props) {
        prop.envVars.put("GIT_CEILING_DIRECTORIES", "/home")
    }
}
hudson.save()
Catercorner answered 27/4, 2022 at 15:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.